comparison flys-client/src/main/java/de/intevation/flys/client/server/DescribeCollectionServiceImpl.java @ 905:478a571f1f94

Refactored server code - HTTP related code moved to ArtifactsHelper and CollectionHelper which makes us able to combine Artifact and Collection protocol stuff in a single RPC service. flys-client/trunk@2757 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Thu, 15 Sep 2011 12:55:36 +0000
parents ec5c75da5c7a
children ab8eb2f544f2
comparison
equal deleted inserted replaced
904:1e08a5b0add9 905:478a571f1f94
1 package de.intevation.flys.client.server; 1 package de.intevation.flys.client.server;
2 2
3 import java.util.ArrayList;
4 import java.util.HashMap;
5 import java.util.List;
6 import java.util.Map;
7
8 import javax.xml.xpath.XPathConstants;
9
10 import org.w3c.dom.Document; 3 import org.w3c.dom.Document;
11 import org.w3c.dom.Element;
12 import org.w3c.dom.NamedNodeMap;
13 import org.w3c.dom.Node;
14 import org.w3c.dom.NodeList;
15 4
16 import com.google.gwt.user.server.rpc.RemoteServiceServlet; 5 import com.google.gwt.user.server.rpc.RemoteServiceServlet;
17 6
18 import de.intevation.artifacts.common.ArtifactNamespaceContext;
19 import de.intevation.artifacts.common.utils.ClientProtocolUtils; 7 import de.intevation.artifacts.common.utils.ClientProtocolUtils;
20 import de.intevation.artifacts.common.utils.XMLUtils;
21 8
22 import de.intevation.artifacts.httpclient.exceptions.ConnectionException; 9 import de.intevation.artifacts.httpclient.exceptions.ConnectionException;
23 import de.intevation.artifacts.httpclient.http.HttpClient; 10 import de.intevation.artifacts.httpclient.http.HttpClient;
24 import de.intevation.artifacts.httpclient.http.HttpClientImpl; 11 import de.intevation.artifacts.httpclient.http.HttpClientImpl;
25 import de.intevation.artifacts.httpclient.http.response.DocumentResponseHandler; 12 import de.intevation.artifacts.httpclient.http.response.DocumentResponseHandler;
26 13
27 import de.intevation.flys.client.shared.exceptions.ServerException; 14 import de.intevation.flys.client.shared.exceptions.ServerException;
28 import de.intevation.flys.client.shared.model.AttributedTheme;
29 import de.intevation.flys.client.shared.model.Collection; 15 import de.intevation.flys.client.shared.model.Collection;
30 import de.intevation.flys.client.shared.model.CollectionItem; 16
31 import de.intevation.flys.client.shared.model.DefaultCollection;
32 import de.intevation.flys.client.shared.model.DefaultCollectionItem;
33 import de.intevation.flys.client.shared.model.DefaultFacet;
34 import de.intevation.flys.client.shared.model.ChartMode;
35 import de.intevation.flys.client.shared.model.ExportMode;
36 import de.intevation.flys.client.shared.model.MapMode;
37 import de.intevation.flys.client.shared.model.ReportMode;
38 import de.intevation.flys.client.shared.model.Facet;
39 import de.intevation.flys.client.shared.model.OutputMode;
40 import de.intevation.flys.client.shared.model.Recommendation;
41 import de.intevation.flys.client.shared.model.Theme;
42 import de.intevation.flys.client.shared.model.ThemeList;
43 import de.intevation.flys.client.client.services.DescribeCollectionService; 17 import de.intevation.flys.client.client.services.DescribeCollectionService;
44 18
45 19
46 /** 20 /**
47 * This service implements a method that queries the DESCRIBE document of a 21 * This service implements a method that queries the DESCRIBE document of a
57 /** The error message key that is thrown if an error occured while 31 /** The error message key that is thrown if an error occured while
58 * describe() a Collection.*/ 32 * describe() a Collection.*/
59 public static final String ERROR_DESCRIBE_COLLECTION = 33 public static final String ERROR_DESCRIBE_COLLECTION =
60 "error_describe_collection"; 34 "error_describe_collection";
61 35
62 public static final String XPATH_FACETS = "art:facets/art:facet";
63
64 public static final String XPATH_LOADED_RECOMMENDATIONS =
65 "/art:artifact-collection/art:attribute/art:loaded-recommendations/art:recommendation";
66
67 36
68 public Collection describe(String uuid, String serverUrl, String locale) 37 public Collection describe(String uuid, String serverUrl, String locale)
69 throws ServerException 38 throws ServerException
70 { 39 {
71 System.out.println("DescribeCollectionServiceImpl.describe"); 40 System.out.println("DescribeCollectionServiceImpl.describe");
77 46
78 try { 47 try {
79 Document response = (Document) client.doCollectionAction( 48 Document response = (Document) client.doCollectionAction(
80 describe, uuid, new DocumentResponseHandler()); 49 describe, uuid, new DocumentResponseHandler());
81 50
82 Collection c = parseCollection(response); 51 Collection c = CollectionHelper.parseCollection(response);
83 52
84 if (c == null) { 53 if (c == null) {
85 throw new ServerException(ERROR_DESCRIBE_COLLECTION); 54 throw new ServerException(ERROR_DESCRIBE_COLLECTION);
86 } 55 }
87 56
93 System.err.println(ce.getLocalizedMessage()); 62 System.err.println(ce.getLocalizedMessage());
94 } 63 }
95 64
96 throw new ServerException(ERROR_DESCRIBE_COLLECTION); 65 throw new ServerException(ERROR_DESCRIBE_COLLECTION);
97 } 66 }
98
99
100 /**
101 * This method takes the DESCRIBE document of the Collections describe()
102 * operation and extracts the information about the collection itself and
103 * the collection items.
104 *
105 * @param description The DESCRIBE document of the Collections describe()
106 * operation.
107 *
108 * @return a Collection with CollectionItems.
109 */
110 protected Collection parseCollection(Document description) {
111 System.out.println("AddArtifactServiceImpl.parseCollection");
112
113 if (description == null) {
114 System.err.println("The DESCRIBE of the Collection is null!");
115 return null;
116 }
117
118 String uuid = XMLUtils.xpathString(
119 description,
120 "art:artifact-collection/@art:uuid",
121 ArtifactNamespaceContext.INSTANCE);
122
123 String ttlStr = XMLUtils.xpathString(
124 description,
125 "art:artifact-collection/@art:ttl",
126 ArtifactNamespaceContext.INSTANCE);
127
128 String name = XMLUtils.xpathString(
129 description,
130 "art:artifact-collection/@art:name",
131 ArtifactNamespaceContext.INSTANCE);
132
133 if (uuid.length() == 0 || ttlStr.length() == 0) {
134 System.err.println("Found an invalid Collection!");
135 return null;
136 }
137
138
139 long ttl = -1;
140 try {
141 ttl = Long.valueOf(ttlStr);
142 }
143 catch (NumberFormatException nfe) {
144 // do nothing
145 }
146
147 Map<String, ThemeList> themeList = parseThemeLists(description);
148 List<Recommendation> recommended = parseRecommendations(description);
149
150 name = (name != null && name.length() > 0) ? name : uuid;
151
152 Collection c = !themeList.isEmpty()
153 ? new DefaultCollection(uuid, ttl, name, recommended, themeList)
154 : new DefaultCollection(uuid, ttl, name, recommended);
155
156 NodeList items = (NodeList) XMLUtils.xpath(
157 description,
158 "art:artifact-collection/art:artifacts/art:artifact",
159 XPathConstants.NODESET,
160 ArtifactNamespaceContext.INSTANCE);
161
162 if (items == null || items.getLength() == 0) {
163 System.out.println("No collection item found for this collection.");
164
165 return c;
166 }
167
168 int size = items.getLength();
169
170 for (int i = 0; i < size; i++) {
171 CollectionItem item = parseCollectionItem(
172 (Element)items.item(i),
173 i == 0);
174
175 if (item != null) {
176 c.addItem(item);
177 }
178 }
179
180 System.out.println(
181 "Found " + c.getItemLength() + " collection items " +
182 "for the Collection '" + c.identifier() + "'.");
183
184 return c;
185 }
186
187
188 protected Map<String, ThemeList> parseThemeLists(Document description) {
189 System.out.println("DescribeCollectionServiceImpl.parseThemeLists");
190
191 NodeList lists = (NodeList) XMLUtils.xpath(
192 description,
193 "/art:artifact-collection/art:attribute/art:outputs/art:output",
194 XPathConstants.NODESET,
195 ArtifactNamespaceContext.INSTANCE);
196
197 int num = lists != null ? lists.getLength() : 0;
198
199 Map<String, ThemeList> themeList = new HashMap<String, ThemeList>(num);
200
201 String uri = ArtifactNamespaceContext.NAMESPACE_URI;
202
203 for (int i = 0; i < num; i++) {
204 Element node = (Element)lists.item(i);
205
206 String outName = node.getAttribute("name");
207
208 if (outName.length() > 0) {
209 ThemeList list = parseThemeList(node);
210 if (list.getThemeCount() > 0) {
211 themeList.put(outName, list);
212 }
213 }
214 }
215
216 return themeList;
217 }
218
219
220 protected ThemeList parseThemeList(Element node) {
221 System.out.println("DescribeCollectionServiceImpl.parseThemeList");
222
223 NodeList themes = node.getElementsByTagNameNS(
224 ArtifactNamespaceContext.NAMESPACE_URI,
225 "facet");
226
227 int num = themes != null ? themes.getLength() : 0;
228
229 List<Theme> themeList = new ArrayList<Theme>(num);
230
231 for (int i = 0; i < num; i++) {
232 Theme theme = parseTheme((Element)themes.item(i));
233
234 if (theme != null) {
235 themeList.add(theme);
236 }
237 }
238
239 return new ThemeList(themeList);
240 }
241
242
243 protected Theme parseTheme(Element ele) {
244 System.out.println("DescribeCollectionServiceImpl.parseTheme");
245
246 String uri = ArtifactNamespaceContext.NAMESPACE_URI;
247
248 NamedNodeMap attrMap = ele.getAttributes();
249 int attrNum = attrMap != null ? attrMap.getLength() : 0;
250
251 AttributedTheme t = new AttributedTheme();
252
253 for (int i = 0; i < attrNum; i++) {
254 Node attr = attrMap.item(i);
255
256 String prefix = attr.getPrefix();
257 String name = attr.getNodeName().replace(prefix + ":", "");
258 String value = attr.getNodeValue();
259
260 t.addAttr(name, value);
261 }
262
263 return t;
264 }
265
266
267 /**
268 * This method extracts the CollectionItem from <i>node</i> with its output
269 * modes. The output modes are parsed using the parseOutputModes() method.
270 *
271 * @param node A node that contains information about a CollectionItem.
272 *
273 * @return a CollectionItem.
274 */
275 protected CollectionItem parseCollectionItem(Element node, boolean outs) {
276 System.out.println("AddArtifactServiceImpl.parseCollectionItem");
277
278 if (node == null) {
279 System.err.println("The node for parsing CollectionItem is null!");
280 return null;
281 }
282
283 String uri = ArtifactNamespaceContext.NAMESPACE_URI;
284
285 String uuid = node.getAttributeNS(uri, "uuid");
286 String hash = node.getAttributeNS(uri, "hash");
287
288 if (uuid == null || uuid.length() == 0) {
289 System.err.println("Found an invalid CollectionItem!");
290 return null;
291 }
292
293 List<OutputMode> modes = new ArrayList<OutputMode>();
294
295 if (outs) {
296 NodeList outputmodes = node.getElementsByTagNameNS(
297 uri, "outputmodes");
298
299 if (outputmodes.getLength() < 1) {
300 return null;
301 }
302
303 Element om = (Element)outputmodes.item(0);
304
305 modes = parseOutputModes(om);
306 }
307
308 return new DefaultCollectionItem(uuid, hash, modes);
309 }
310
311
312 /**
313 * This method extracts the OutputModes available for a specific
314 * CollectionItem and returns them as list.
315 *
316 * @param node The root node of the outputmodes list.
317 *
318 * @return a list of OutputModes.
319 */
320 protected List<OutputMode> parseOutputModes(Element node) {
321 System.out.println("AddArtifactServiceImpl.parseOutputModes");
322
323 if (node == null) {
324 System.err.println("The node for parsing OutputModes is null!");
325 return null;
326 }
327
328 String uri = ArtifactNamespaceContext.NAMESPACE_URI;
329
330 NodeList list = node.getElementsByTagNameNS(uri, "output");
331
332 int size = list.getLength();
333
334 if (size == 0) {
335 System.err.println("No outputmode nodes found!");
336 return null;
337 }
338
339 List<OutputMode> modes = new ArrayList<OutputMode>(size);
340
341 for (int i = 0; i < size; i++) {
342 Element tmp = (Element)list.item(i);
343
344 String name = tmp.getAttributeNS(uri, "name");
345 String desc = tmp.getAttributeNS(uri, "description");
346 String mime = tmp.getAttributeNS(uri, "mime-type");
347 String type = tmp.getAttributeNS(uri, "type");
348
349 if (name.length() == 0) {
350 System.err.println("Found an invalid output mode.");
351 continue;
352 }
353
354 OutputMode outmode = null;
355 List<Facet> fs = extractFacets(tmp);
356
357 if (type.equals("export")) {
358 outmode = new ExportMode(name, desc, mime, fs);
359 }
360 else if (type.equals("report")) {
361 outmode = new ReportMode(name, desc, mime, fs);
362 }
363 else if (type.equals("chart")){
364 outmode = new ChartMode(name, desc, mime, fs);
365 }
366 else if (type.equals("map")){
367 outmode = new MapMode(name, desc, mime, fs);
368 }
369 else {
370 System.err.println("Broken Output mode without type found.");
371 continue;
372 }
373
374 modes.add(outmode);
375 }
376
377 return modes;
378 }
379
380
381 protected static List<Facet> extractFacets(Element outmode) {
382 System.out.println("DescribeCollectionServiceImpl - extractFacets()");
383
384 NodeList facetList = (NodeList) XMLUtils.xpath(
385 outmode,
386 XPATH_FACETS,
387 XPathConstants.NODESET,
388 ArtifactNamespaceContext.INSTANCE);
389
390 int num = facetList != null ? facetList.getLength() : 0;
391
392 List<Facet> facets = new ArrayList<Facet>(num);
393
394 String uri = ArtifactNamespaceContext.NAMESPACE_URI;
395
396 for (int i = 0; i < num; i++) {
397 Element facetEl = (Element) facetList.item(i);
398
399 String name = facetEl.getAttributeNS(uri, "name");
400 String desc = facetEl.getAttributeNS(uri, "description");
401 String index = facetEl.getAttributeNS(uri, "index");
402
403 if (name != null && name.length() > 0 && index != null) {
404 facets.add(new DefaultFacet(name, Integer.valueOf(index),desc));
405 }
406 }
407
408 return facets;
409 }
410
411
412 public static List<Recommendation> parseRecommendations(Document doc) {
413 System.out.println("DescribeCollectionServiceImpl.parseRecommendations");
414
415 NodeList list = (NodeList) XMLUtils.xpath(
416 doc,
417 XPATH_LOADED_RECOMMENDATIONS,
418 XPathConstants.NODESET,
419 ArtifactNamespaceContext.INSTANCE);
420
421 int num = list != null ? list.getLength() : 0;
422
423 List<Recommendation> recs = new ArrayList<Recommendation>(num);
424
425 String uri = ArtifactNamespaceContext.NAMESPACE_URI;
426
427 for (int i = 0; i < num; i++) {
428 Element rec = (Element) list.item(i);
429
430 String factory = rec.getAttributeNS(uri, "factory");
431 String dbids = rec.getAttributeNS(uri, "ids");
432
433 if (factory != null && factory.length() > 0) {
434 recs.add(new Recommendation(factory, dbids));
435 }
436 }
437
438 return recs;
439 }
440 } 67 }
441 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : 68 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org