ingo@99: package de.intevation.flys.client.server;
ingo@99:
ingo@99: import java.util.ArrayList;
ingo@524: import java.util.HashMap;
ingo@99: import java.util.List;
ingo@524: import java.util.Map;
ingo@99:
ingo@99: import javax.xml.xpath.XPathConstants;
ingo@99:
ingo@99: import org.w3c.dom.Document;
ingo@575: import org.w3c.dom.Element;
ingo@99: import org.w3c.dom.NodeList;
ingo@99:
ingo@99: import com.google.gwt.user.server.rpc.RemoteServiceServlet;
ingo@99:
ingo@99: import de.intevation.artifacts.common.ArtifactNamespaceContext;
ingo@99: import de.intevation.artifacts.common.utils.ClientProtocolUtils;
ingo@99: import de.intevation.artifacts.common.utils.XMLUtils;
ingo@99:
ingo@99: import de.intevation.artifacts.httpclient.exceptions.ConnectionException;
ingo@99: import de.intevation.artifacts.httpclient.http.HttpClient;
ingo@99: import de.intevation.artifacts.httpclient.http.HttpClientImpl;
ingo@99: import de.intevation.artifacts.httpclient.http.response.DocumentResponseHandler;
ingo@99:
ingo@215: import de.intevation.flys.client.shared.exceptions.ServerException;
ingo@99: import de.intevation.flys.client.shared.model.Collection;
ingo@99: import de.intevation.flys.client.shared.model.CollectionItem;
ingo@99: import de.intevation.flys.client.shared.model.DefaultCollection;
ingo@99: import de.intevation.flys.client.shared.model.DefaultCollectionItem;
ingo@270: import de.intevation.flys.client.shared.model.DefaultFacet;
ingo@99: import de.intevation.flys.client.shared.model.DefaultOutputMode;
ingo@524: import de.intevation.flys.client.shared.model.DefaultTheme;
ingo@270: import de.intevation.flys.client.shared.model.ExportMode;
sascha@589: import de.intevation.flys.client.shared.model.ReportMode;
ingo@270: import de.intevation.flys.client.shared.model.Facet;
ingo@99: import de.intevation.flys.client.shared.model.OutputMode;
ingo@524: import de.intevation.flys.client.shared.model.Theme;
ingo@524: import de.intevation.flys.client.shared.model.ThemeList;
ingo@99: import de.intevation.flys.client.client.services.DescribeCollectionService;
ingo@99:
ingo@99:
ingo@99: /**
ingo@99: * This service implements a method that queries the DESCRIBE document of a
ingo@99: * specific collection and returns a Collection object with the information of
ingo@99: * the document.
ingo@99: *
ingo@99: * @author Ingo Weinzierl
ingo@99: */
ingo@99: public class DescribeCollectionServiceImpl
ingo@99: extends RemoteServiceServlet
ingo@99: implements DescribeCollectionService
ingo@99: {
ingo@215: /** The error message key that is thrown if an error occured while
ingo@215: * describe() a Collection.*/
ingo@215: public static final String ERROR_DESCRIBE_COLLECTION =
ingo@215: "error_describe_collection";
ingo@215:
ingo@270: public static final String XPATH_FACETS = "art:facets/art:facet";
ingo@270:
ingo@215:
ingo@229: public Collection describe(String uuid, String serverUrl, String locale)
ingo@215: throws ServerException
ingo@215: {
ingo@99: System.out.println("DescribeCollectionServiceImpl.describe");
ingo@99:
ingo@99: Document describe = ClientProtocolUtils.newDescribeCollectionDocument(
ingo@99: uuid);
ingo@99:
ingo@229: HttpClient client = new HttpClientImpl(serverUrl, locale);
ingo@99:
ingo@99: try {
ingo@99: Document response = (Document) client.doCollectionAction(
ingo@99: describe, uuid, new DocumentResponseHandler());
ingo@99:
ingo@99: Collection c = parseCollection(response);
ingo@99:
ingo@99: if (c == null) {
ingo@215: throw new ServerException(ERROR_DESCRIBE_COLLECTION);
ingo@99: }
ingo@99:
ingo@524: System.out.println("Collection successfully parsed.");
ingo@524:
ingo@99: return c;
ingo@99: }
ingo@99: catch (ConnectionException ce) {
ingo@99: System.err.println(ce.getLocalizedMessage());
ingo@99: }
ingo@99:
ingo@215: throw new ServerException(ERROR_DESCRIBE_COLLECTION);
ingo@99: }
ingo@99:
ingo@99:
ingo@99: /**
ingo@99: * This method takes the DESCRIBE document of the Collections describe()
ingo@99: * operation and extracts the information about the collection itself and
ingo@99: * the collection items.
ingo@99: *
ingo@99: * @param description The DESCRIBE document of the Collections describe()
ingo@99: * operation.
ingo@99: *
ingo@99: * @return a Collection with CollectionItems.
ingo@99: */
ingo@99: protected Collection parseCollection(Document description) {
ingo@99: System.out.println("AddArtifactServiceImpl.parseCollection");
ingo@99:
ingo@99: if (description == null) {
ingo@99: System.err.println("The DESCRIBE of the Collection is null!");
ingo@99: return null;
ingo@99: }
ingo@99:
ingo@99: String uuid = XMLUtils.xpathString(
ingo@99: description,
ingo@99: "art:artifact-collection/@art:uuid",
ingo@99: ArtifactNamespaceContext.INSTANCE);
ingo@99:
ingo@587: String ttlStr = XMLUtils.xpathString(
ingo@587: description,
ingo@587: "art:artifact-collection/@art:ttl",
ingo@587: ArtifactNamespaceContext.INSTANCE);
ingo@587:
ingo@587: if (uuid.length() == 0 || ttlStr.length() == 0) {
ingo@99: System.err.println("Found an invalid Collection!");
ingo@99: return null;
ingo@99: }
ingo@99:
ingo@587:
ingo@587: long ttl = -1;
ingo@587: try {
ingo@587: ttl = Long.valueOf(ttlStr);
ingo@587: }
ingo@587: catch (NumberFormatException nfe) {
ingo@587: // do nothing
ingo@587: }
ingo@587:
ingo@524: Map themeList = parseThemeLists(description);
ingo@524:
sascha@581: Collection c = !themeList.isEmpty()
ingo@587: ? new DefaultCollection(uuid, ttl, themeList)
ingo@587: : new DefaultCollection(uuid, ttl);
ingo@99:
ingo@99: NodeList items = (NodeList) XMLUtils.xpath(
ingo@99: description,
ingo@99: "art:artifact-collection/art:artifacts/art:artifact",
ingo@99: XPathConstants.NODESET,
ingo@99: ArtifactNamespaceContext.INSTANCE);
ingo@99:
ingo@99: if (items == null || items.getLength() == 0) {
ingo@99: System.out.println("No collection item found for this collection.");
ingo@99:
ingo@99: return c;
ingo@99: }
ingo@99:
ingo@99: int size = items.getLength();
ingo@99:
ingo@99: for (int i = 0; i < size; i++) {
sascha@581: CollectionItem item = parseCollectionItem((Element)items.item(i));
ingo@99:
ingo@99: if (item != null) {
ingo@99: c.addItem(item);
ingo@99: }
ingo@99: }
ingo@99:
ingo@99: System.out.println(
ingo@99: "Found " + c.getItemLength() + " collection items " +
ingo@99: "for the Collection '" + c.identifier() + "'.");
ingo@99:
ingo@99: return c;
ingo@99: }
ingo@99:
ingo@99:
ingo@524: protected Map parseThemeLists(Document description) {
ingo@524: System.out.println("DescribeCollectionServiceImpl.parseThemeLists");
ingo@524:
ingo@524: NodeList lists = (NodeList) XMLUtils.xpath(
ingo@524: description,
ingo@524: "/art:artifact-collection/art:attribute/art:outputs/art:output",
ingo@524: XPathConstants.NODESET,
ingo@524: ArtifactNamespaceContext.INSTANCE);
ingo@524:
ingo@524: int num = lists != null ? lists.getLength() : 0;
ingo@524:
ingo@524: Map themeList = new HashMap(num);
ingo@524:
sascha@581: String uri = ArtifactNamespaceContext.NAMESPACE_URI;
ingo@524:
sascha@581: for (int i = 0; i < num; i++) {
sascha@581: Element node = (Element)lists.item(i);
ingo@524:
sascha@581: String outName = node.getAttribute("name");
ingo@524:
sascha@581: if (outName.length() > 0) {
sascha@581: ThemeList list = parseThemeList(node);
sascha@581: if (list.getThemeCount() > 0) {
sascha@581: themeList.put(outName, list);
sascha@581: }
ingo@524: }
ingo@524: }
ingo@524:
ingo@524: return themeList;
ingo@524: }
ingo@524:
ingo@524:
sascha@581: protected ThemeList parseThemeList(Element node) {
ingo@524: System.out.println("DescribeCollectionServiceImpl.parseThemeList");
ingo@524:
sascha@581: NodeList themes = node.getElementsByTagNameNS(
sascha@581: ArtifactNamespaceContext.NAMESPACE_URI,
sascha@581: "theme");
ingo@524:
ingo@524: int num = themes != null ? themes.getLength() : 0;
ingo@524:
ingo@524: List themeList = new ArrayList(num);
ingo@524:
ingo@524: for (int i = 0; i < num; i++) {
sascha@581: Theme theme = parseTheme((Element)themes.item(i));
ingo@524:
ingo@524: if (theme != null) {
ingo@524: themeList.add(theme);
ingo@524: }
ingo@524: }
ingo@524:
ingo@524: return new ThemeList(themeList);
ingo@524: }
ingo@524:
ingo@524:
ingo@575: protected Theme parseTheme(Element ele) {
ingo@524: System.out.println("DescribeCollectionServiceImpl.parseTheme");
ingo@524:
ingo@575: String uri = ArtifactNamespaceContext.NAMESPACE_URI;
ingo@524:
ingo@575: String strAct = ele.getAttributeNS(uri, "active");
ingo@575: String art = ele.getAttributeNS(uri, "artifact");
ingo@575: String fac = ele.getAttributeNS(uri, "facet");
ingo@575: String strPos = ele.getAttributeNS(uri, "pos");
ingo@575: String desc = ele.getAttributeNS(uri, "description");
ingo@575: String strIdx = ele.getAttributeNS(uri, "index");
ingo@524:
sascha@581: if (strAct.length() > 0 && art.length() > 0 && fac.length() > 0
sascha@581: && strPos.length() > 0 && strIdx.length() > 0)
ingo@575: {
ingo@524: try {
ingo@524: int pos = Integer.valueOf(strPos);
ingo@524: int active = Integer.valueOf(strAct);
ingo@575: int idx = Integer.valueOf(strIdx);
ingo@524:
ingo@575: return new DefaultTheme(pos, idx, active > 0, art, fac, desc);
ingo@524: }
ingo@524: catch (NumberFormatException nfe) {
ingo@524: nfe.printStackTrace();
ingo@524: }
ingo@524: }
ingo@524:
ingo@524: return null;
ingo@524: }
ingo@524:
ingo@524:
ingo@99: /**
ingo@99: * This method extracts the CollectionItem from node with its output
ingo@99: * modes. The output modes are parsed using the parseOutputModes() method.
ingo@99: *
ingo@99: * @param node A node that contains information about a CollectionItem.
ingo@99: *
ingo@99: * @return a CollectionItem.
ingo@99: */
sascha@581: protected CollectionItem parseCollectionItem(Element node) {
ingo@99: System.out.println("AddArtifactServiceImpl.parseCollectionItem");
ingo@99:
ingo@99: if (node == null) {
ingo@99: System.err.println("The node for parsing CollectionItem is null!");
ingo@99: return null;
ingo@99: }
ingo@99:
sascha@581: String uri = ArtifactNamespaceContext.NAMESPACE_URI;
ingo@99:
sascha@581: String uuid = node.getAttributeNS(uri, "uuid");
sascha@581: String hash = node.getAttributeNS(uri, "hash");
ingo@99:
ingo@587: if (uuid == null || uuid.length() == 0) {
ingo@99: System.err.println("Found an invalid CollectionItem!");
sascha@581: return null;
ingo@99: }
ingo@99:
sascha@581: NodeList outputmodes = node.getElementsByTagNameNS(uri, "outputmodes");
ingo@99:
sascha@581: if (outputmodes.getLength() < 1) {
sascha@581: return null;
sascha@581: }
sascha@581:
sascha@581: Element om = (Element)outputmodes.item(0);
sascha@581:
sascha@581: List modes = parseOutputModes(om);
ingo@99:
ingo@99: return new DefaultCollectionItem(uuid, hash, modes);
ingo@99: }
ingo@99:
ingo@99:
ingo@99: /**
ingo@99: * This method extracts the OutputModes available for a specific
ingo@99: * CollectionItem and returns them as list.
ingo@99: *
ingo@99: * @param node The root node of the outputmodes list.
ingo@99: *
ingo@99: * @return a list of OutputModes.
ingo@99: */
sascha@581: protected List parseOutputModes(Element node) {
ingo@99: System.out.println("AddArtifactServiceImpl.parseOutputModes");
ingo@99:
ingo@99: if (node == null) {
ingo@99: System.err.println("The node for parsing OutputModes is null!");
ingo@99: return null;
ingo@99: }
ingo@99:
sascha@581: String uri = ArtifactNamespaceContext.NAMESPACE_URI;
ingo@99:
sascha@581: NodeList list = node.getElementsByTagNameNS(uri, "output");
sascha@581:
sascha@581: int size = list.getLength();
sascha@581:
sascha@581: if (size == 0) {
ingo@99: System.err.println("No outputmode nodes found!");
ingo@99: return null;
ingo@99: }
ingo@99:
ingo@99: List modes = new ArrayList(size);
ingo@99:
ingo@99: for (int i = 0; i < size; i++) {
sascha@581: Element tmp = (Element)list.item(i);
ingo@99:
sascha@581: String name = tmp.getAttributeNS(uri, "name");
sascha@581: String desc = tmp.getAttributeNS(uri, "description");
sascha@581: String mime = tmp.getAttributeNS(uri, "mime-type");
sascha@581:
sascha@581: if (name.length() == 0) {
ingo@99: System.err.println("Found an invalid output mode.");
ingo@99: continue;
ingo@99: }
ingo@99:
ingo@270: OutputMode outmode = null;
ingo@270: List fs = extractFacets(tmp);
ingo@99:
ingo@270: if (name.indexOf("export") > -1) {
ingo@270: outmode = new ExportMode(name, desc, mime, fs);
ingo@270: }
sascha@589: else if (name.indexOf("report") > -1) {
sascha@589: outmode = new ReportMode(name, desc, mime, fs);
sascha@589: }
ingo@270: else {
ingo@270: outmode = new DefaultOutputMode(name, desc, mime, fs);
ingo@270: }
ingo@270:
ingo@270: modes.add(outmode);
ingo@99: }
ingo@99:
ingo@99: return modes;
ingo@99: }
ingo@270:
ingo@270:
sascha@581: protected static List extractFacets(Element outmode) {
ingo@270: System.out.println("ArtifactDescriptionFactory - extractFacets()");
ingo@270:
ingo@270: NodeList facetList = (NodeList) XMLUtils.xpath(
ingo@270: outmode,
ingo@270: XPATH_FACETS,
ingo@270: XPathConstants.NODESET,
ingo@270: ArtifactNamespaceContext.INSTANCE);
ingo@270:
ingo@270: int num = facetList != null ? facetList.getLength() : 0;
ingo@270:
ingo@270: List facets = new ArrayList(num);
ingo@270:
ingo@575: String uri = ArtifactNamespaceContext.NAMESPACE_URI;
ingo@270:
ingo@575: for (int i = 0; i < num; i++) {
ingo@575: Element facetEl = (Element) facetList.item(i);
ingo@270:
ingo@575: String name = facetEl.getAttributeNS(uri, "name");
ingo@575: String desc = facetEl.getAttributeNS(uri, "description");
ingo@575: String index = facetEl.getAttributeNS(uri, "index");
ingo@575:
ingo@575: if (name != null && name.length() > 0 && index != null) {
ingo@575: facets.add(new DefaultFacet(name, Integer.valueOf(index),desc));
ingo@270: }
ingo@270: }
ingo@270:
ingo@270: return facets;
ingo@270: }
ingo@99: }
ingo@99: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :