Mercurial > dive4elements > river
diff flys-client/src/main/java/de/intevation/flys/client/server/CollectionHelper.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 | 0fe456332785 |
children | ecd0243bc09e |
line wrap: on
line diff
--- a/flys-client/src/main/java/de/intevation/flys/client/server/CollectionHelper.java Thu Sep 15 08:39:07 2011 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/server/CollectionHelper.java Thu Sep 15 12:55:36 2011 +0000 @@ -1,19 +1,43 @@ package de.intevation.flys.client.server; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; +import javax.xml.xpath.XPathConstants; + import org.w3c.dom.Document; import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; import de.intevation.artifacts.common.ArtifactNamespaceContext; +import de.intevation.artifacts.common.utils.ClientProtocolUtils; import de.intevation.artifacts.common.utils.XMLUtils; import de.intevation.artifacts.common.utils.XMLUtils.ElementCreator; +import de.intevation.artifacts.httpclient.exceptions.ConnectionException; +import de.intevation.artifacts.httpclient.http.HttpClient; +import de.intevation.artifacts.httpclient.http.HttpClientImpl; +import de.intevation.artifacts.httpclient.http.response.DocumentResponseHandler; + +import de.intevation.flys.client.shared.exceptions.ServerException; +import de.intevation.flys.client.shared.model.Artifact; import de.intevation.flys.client.shared.model.AttributedTheme; +import de.intevation.flys.client.shared.model.ChartMode; import de.intevation.flys.client.shared.model.Collection; +import de.intevation.flys.client.shared.model.CollectionItem; +import de.intevation.flys.client.shared.model.DefaultCollection; +import de.intevation.flys.client.shared.model.DefaultCollectionItem; +import de.intevation.flys.client.shared.model.DefaultFacet; +import de.intevation.flys.client.shared.model.ExportMode; +import de.intevation.flys.client.shared.model.Facet; +import de.intevation.flys.client.shared.model.MapMode; import de.intevation.flys.client.shared.model.OutputMode; +import de.intevation.flys.client.shared.model.ReportMode; import de.intevation.flys.client.shared.model.Recommendation; import de.intevation.flys.client.shared.model.Theme; import de.intevation.flys.client.shared.model.ThemeList; @@ -24,6 +48,14 @@ */ public class CollectionHelper { + public static final String ERROR_ADD_ARTIFACT = "error_add_artifact"; + + public static final String XPATH_FACETS = "art:facets/art:facet"; + + public static final String XPATH_LOADED_RECOMMENDATIONS = + "/art:artifact-collection/art:attribute/art:loaded-recommendations/art:recommendation"; + + public static Document createAttribute(Collection collection) { System.out.println("CollectionHelper.createAttribute"); @@ -232,5 +264,397 @@ return recommendation; } + + + /** + * This method takes the DESCRIBE document of the Collections describe() + * operation and extracts the information about the collection itself and + * the collection items. + * + * @param description The DESCRIBE document of the Collections describe() + * operation. + * + * @return a Collection with CollectionItems. + */ + public static Collection parseCollection(Document description) { + System.out.println("AddArtifactServiceImpl.parseCollection"); + + if (description == null) { + System.err.println("The DESCRIBE of the Collection is null!"); + return null; + } + + String uuid = XMLUtils.xpathString( + description, + "art:artifact-collection/@art:uuid", + ArtifactNamespaceContext.INSTANCE); + + String ttlStr = XMLUtils.xpathString( + description, + "art:artifact-collection/@art:ttl", + ArtifactNamespaceContext.INSTANCE); + + String name = XMLUtils.xpathString( + description, + "art:artifact-collection/@art:name", + ArtifactNamespaceContext.INSTANCE); + + if (uuid.length() == 0 || ttlStr.length() == 0) { + System.err.println("Found an invalid Collection!"); + return null; + } + + + long ttl = -1; + try { + ttl = Long.valueOf(ttlStr); + } + catch (NumberFormatException nfe) { + // do nothing + } + + Map<String, ThemeList> themeList = parseThemeLists(description); + List<Recommendation> recommended = parseRecommendations(description); + + name = (name != null && name.length() > 0) ? name : uuid; + + Collection c = !themeList.isEmpty() + ? new DefaultCollection(uuid, ttl, name, recommended, themeList) + : new DefaultCollection(uuid, ttl, name, recommended); + + NodeList items = (NodeList) XMLUtils.xpath( + description, + "art:artifact-collection/art:artifacts/art:artifact", + XPathConstants.NODESET, + ArtifactNamespaceContext.INSTANCE); + + if (items == null || items.getLength() == 0) { + System.out.println("No collection item found for this collection."); + + return c; + } + + int size = items.getLength(); + + for (int i = 0; i < size; i++) { + CollectionItem item = parseCollectionItem( + (Element)items.item(i), + i == 0); + + if (item != null) { + c.addItem(item); + } + } + + System.out.println( + "Found " + c.getItemLength() + " collection items " + + "for the Collection '" + c.identifier() + "'."); + + return c; + } + + + protected static Map<String, ThemeList> parseThemeLists(Document desc) { + System.out.println("DescribeCollectionServiceImpl.parseThemeLists"); + + NodeList lists = (NodeList) XMLUtils.xpath( + desc, + "/art:artifact-collection/art:attribute/art:outputs/art:output", + XPathConstants.NODESET, + ArtifactNamespaceContext.INSTANCE); + + int num = lists != null ? lists.getLength() : 0; + + Map<String, ThemeList> themeList = new HashMap<String, ThemeList>(num); + + String uri = ArtifactNamespaceContext.NAMESPACE_URI; + + for (int i = 0; i < num; i++) { + Element node = (Element)lists.item(i); + + String outName = node.getAttribute("name"); + + if (outName.length() > 0) { + ThemeList list = parseThemeList(node); + if (list.getThemeCount() > 0) { + themeList.put(outName, list); + } + } + } + + return themeList; + } + + + protected static ThemeList parseThemeList(Element node) { + System.out.println("DescribeCollectionServiceImpl.parseThemeList"); + + NodeList themes = node.getElementsByTagNameNS( + ArtifactNamespaceContext.NAMESPACE_URI, + "facet"); + + int num = themes != null ? themes.getLength() : 0; + + List<Theme> themeList = new ArrayList<Theme>(num); + + for (int i = 0; i < num; i++) { + Theme theme = parseTheme((Element)themes.item(i)); + + if (theme != null) { + themeList.add(theme); + } + } + + return new ThemeList(themeList); + } + + + protected static Theme parseTheme(Element ele) { + System.out.println("DescribeCollectionServiceImpl.parseTheme"); + + String uri = ArtifactNamespaceContext.NAMESPACE_URI; + + NamedNodeMap attrMap = ele.getAttributes(); + int attrNum = attrMap != null ? attrMap.getLength() : 0; + + AttributedTheme t = new AttributedTheme(); + + for (int i = 0; i < attrNum; i++) { + Node attr = attrMap.item(i); + + String prefix = attr.getPrefix(); + String name = attr.getNodeName().replace(prefix + ":", ""); + String value = attr.getNodeValue(); + + t.addAttr(name, value); + } + + return t; + } + + + /** + * This method extracts the CollectionItem from <i>node</i> with its output + * modes. The output modes are parsed using the parseOutputModes() method. + * + * @param node A node that contains information about a CollectionItem. + * + * @return a CollectionItem. + */ + protected static CollectionItem parseCollectionItem( + Element node, + boolean outs + ) { + System.out.println("AddArtifactServiceImpl.parseCollectionItem"); + + if (node == null) { + System.err.println("The node for parsing CollectionItem is null!"); + return null; + } + + String uri = ArtifactNamespaceContext.NAMESPACE_URI; + + String uuid = node.getAttributeNS(uri, "uuid"); + String hash = node.getAttributeNS(uri, "hash"); + + if (uuid == null || uuid.length() == 0) { + System.err.println("Found an invalid CollectionItem!"); + return null; + } + + List<OutputMode> modes = new ArrayList<OutputMode>(); + + if (outs) { + NodeList outputmodes = node.getElementsByTagNameNS( + uri, "outputmodes"); + + if (outputmodes.getLength() < 1) { + return null; + } + + Element om = (Element)outputmodes.item(0); + + modes = parseOutputModes(om); + } + + return new DefaultCollectionItem(uuid, hash, modes); + } + + + /** + * This method extracts the OutputModes available for a specific + * CollectionItem and returns them as list. + * + * @param node The root node of the outputmodes list. + * + * @return a list of OutputModes. + */ + protected static List<OutputMode> parseOutputModes(Element node) { + System.out.println("AddArtifactServiceImpl.parseOutputModes"); + + if (node == null) { + System.err.println("The node for parsing OutputModes is null!"); + return null; + } + + String uri = ArtifactNamespaceContext.NAMESPACE_URI; + + NodeList list = node.getElementsByTagNameNS(uri, "output"); + + int size = list.getLength(); + + if (size == 0) { + System.err.println("No outputmode nodes found!"); + return null; + } + + List<OutputMode> modes = new ArrayList<OutputMode>(size); + + for (int i = 0; i < size; i++) { + Element tmp = (Element)list.item(i); + + String name = tmp.getAttributeNS(uri, "name"); + String desc = tmp.getAttributeNS(uri, "description"); + String mime = tmp.getAttributeNS(uri, "mime-type"); + String type = tmp.getAttributeNS(uri, "type"); + + if (name.length() == 0) { + System.err.println("Found an invalid output mode."); + continue; + } + + OutputMode outmode = null; + List<Facet> fs = extractFacets(tmp); + + if (type.equals("export")) { + outmode = new ExportMode(name, desc, mime, fs); + } + else if (type.equals("report")) { + outmode = new ReportMode(name, desc, mime, fs); + } + else if (type.equals("chart")){ + outmode = new ChartMode(name, desc, mime, fs); + } + else if (type.equals("map")){ + outmode = new MapMode(name, desc, mime, fs); + } + else { + System.err.println("Broken Output mode without type found."); + continue; + } + + modes.add(outmode); + } + + return modes; + } + + + protected static List<Facet> extractFacets(Element outmode) { + System.out.println("DescribeCollectionServiceImpl - extractFacets()"); + + NodeList facetList = (NodeList) XMLUtils.xpath( + outmode, + XPATH_FACETS, + XPathConstants.NODESET, + ArtifactNamespaceContext.INSTANCE); + + int num = facetList != null ? facetList.getLength() : 0; + + List<Facet> facets = new ArrayList<Facet>(num); + + String uri = ArtifactNamespaceContext.NAMESPACE_URI; + + for (int i = 0; i < num; i++) { + Element facetEl = (Element) facetList.item(i); + + String name = facetEl.getAttributeNS(uri, "name"); + String desc = facetEl.getAttributeNS(uri, "description"); + String index = facetEl.getAttributeNS(uri, "index"); + + if (name != null && name.length() > 0 && index != null) { + facets.add(new DefaultFacet(name, Integer.valueOf(index),desc)); + } + } + + return facets; + } + + + public static List<Recommendation> parseRecommendations(Document doc) { + System.out.println("DescribeCollectionServiceImpl.parseRecommendations"); + + NodeList list = (NodeList) XMLUtils.xpath( + doc, + XPATH_LOADED_RECOMMENDATIONS, + XPathConstants.NODESET, + ArtifactNamespaceContext.INSTANCE); + + int num = list != null ? list.getLength() : 0; + + List<Recommendation> recs = new ArrayList<Recommendation>(num); + + String uri = ArtifactNamespaceContext.NAMESPACE_URI; + + for (int i = 0; i < num; i++) { + Element rec = (Element) list.item(i); + + String factory = rec.getAttributeNS(uri, "factory"); + String dbids = rec.getAttributeNS(uri, "ids"); + + if (factory != null && factory.length() > 0) { + recs.add(new Recommendation(factory, dbids)); + } + } + + return recs; + } + + + public static Collection addArtifact( + Collection collection, + Artifact artifact, + String url, + String locale) + throws ServerException + { + System.out.println("Collection.addArtifact"); + + if (collection == null) { + System.err.println("The given Collection is null!"); + return null; + } + + Document add = ClientProtocolUtils.newAddArtifactDocument( + artifact.getUuid(), null); + + HttpClient client = new HttpClientImpl(url, locale); + + try { + System.out.println("Do HTTP request now."); + + Document response = (Document) client.doCollectionAction( + add, collection.identifier(), new DocumentResponseHandler()); + + System.out.println( + "Finished HTTP request successfully. Parse Collection now."); + + Collection c = CollectionHelper.parseCollection(response); + + if (c == null) { + throw new ServerException(ERROR_ADD_ARTIFACT); + } + + return c; + } + catch (ConnectionException ce) { + System.err.println(ce.getLocalizedMessage()); + } + catch (Exception e) { + e.printStackTrace(); + } + + throw new ServerException(ERROR_ADD_ARTIFACT); + } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :