ingo@219: package de.intevation.flys.client.server;
ingo@219:
ingo@219: import java.util.ArrayList;
ingo@219: import java.util.List;
ingo@219:
ingo@219: import javax.xml.xpath.XPathConstants;
ingo@219:
ingo@219: import org.w3c.dom.Document;
ingo@219: import org.w3c.dom.Element;
ingo@219: import org.w3c.dom.Node;
ingo@219: import org.w3c.dom.NodeList;
ingo@219:
ingo@219: import com.google.gwt.user.server.rpc.RemoteServiceServlet;
ingo@219:
ingo@219: import de.intevation.artifacts.common.ArtifactNamespaceContext;
ingo@219: import de.intevation.artifacts.common.utils.XMLUtils;
ingo@219:
ingo@219: import de.intevation.artifacts.httpclient.exceptions.ConnectionException;
ingo@219: import de.intevation.artifacts.httpclient.http.HttpClient;
ingo@219: import de.intevation.artifacts.httpclient.http.HttpClientImpl;
ingo@219:
ingo@219: import de.intevation.flys.client.shared.exceptions.ServerException;
ingo@219: import de.intevation.flys.client.client.services.DistanceInfoService;
ingo@219: import de.intevation.flys.client.shared.model.DistanceInfoObject;
ingo@219: import de.intevation.flys.client.shared.model.DistanceInfoObjectImpl;
ingo@219:
ingo@219:
ingo@219: /**
ingo@219: * @author Ingo Weinzierl
ingo@219: */
ingo@219: public class DistanceInfoServiceImpl
ingo@219: extends RemoteServiceServlet
ingo@219: implements DistanceInfoService
ingo@219: {
ingo@219: public static final String ERROR_NO_DISTANCEINFO_FOUND =
ingo@219: "error_no_distanceinfo_found";
ingo@219:
ingo@219: public static final String XPATH_DISTANCES = "art:distances/art:distance";
ingo@219:
ingo@219:
ingo@229: public DistanceInfoObject[] getDistanceInfo(
ingo@229: String url,
ingo@229: String locale,
ingo@229: String river)
ingo@219: throws ServerException
ingo@219: {
ingo@219: System.out.println("DistanceInfoServiceImpl.getDistanceInfo");
ingo@219:
ingo@219: Document doc = XMLUtils.newDocument();
ingo@219:
ingo@219: XMLUtils.ElementCreator ec = new XMLUtils.ElementCreator(
ingo@219: doc,
ingo@219: ArtifactNamespaceContext.NAMESPACE_URI,
ingo@219: ArtifactNamespaceContext.NAMESPACE_PREFIX);
ingo@219:
ingo@219: Element riverEl = ec.create("river");
ingo@219:
ingo@219: riverEl.setTextContent(river);
ingo@219:
ingo@219: doc.appendChild(riverEl);
ingo@219:
ingo@229: HttpClient client = new HttpClientImpl(url, locale);
ingo@219:
ingo@219: try {
ingo@219: Document result = client.callService(url, "distanceinfo", doc);
ingo@219:
ingo@219: System.out.println("Extract distance info objects now.");
ingo@219: DistanceInfoObject[] objects = extractDistanceInfoObjects(result);
ingo@219:
ingo@219: if (objects != null && objects.length > 0) {
ingo@219: return objects;
ingo@219: }
ingo@219: }
ingo@219: catch (ConnectionException ce) {
ingo@219: System.err.println(ce.getLocalizedMessage());
ingo@219: }
ingo@219:
ingo@219: throw new ServerException(ERROR_NO_DISTANCEINFO_FOUND);
ingo@219: }
ingo@219:
ingo@219:
ingo@219: /**
ingo@219: * Extracts all distance info objects from result document.
ingo@219: *
ingo@219: * @param result The document retrieved by the server.
ingo@219: *
ingo@219: * @return a list of DistanceInfoObjects.
ingo@219: */
ingo@219: protected DistanceInfoObject[] extractDistanceInfoObjects(Document result)
ingo@219: throws ServerException
ingo@219: {
ingo@219: NodeList list = (NodeList) XMLUtils.xpath(
ingo@219: result,
ingo@219: XPATH_DISTANCES,
ingo@219: XPathConstants.NODESET,
ingo@219: ArtifactNamespaceContext.INSTANCE);
ingo@219:
ingo@219: if (list == null || list.getLength() == 0) {
ingo@219: System.err.println("No distance info found.");
ingo@219:
ingo@219: throw new ServerException(ERROR_NO_DISTANCEINFO_FOUND);
ingo@219: }
ingo@219:
ingo@219: int num = list.getLength();
ingo@219: System.out.println("Response contains " + num + " objects.");
ingo@219:
ingo@219: List objects =
ingo@219: new ArrayList(num);
ingo@219:
ingo@219: for (int i = 0; i < num; i++) {
ingo@219: DistanceInfoObject obj = buildDistanceInfoObject(list.item(i));
ingo@219:
ingo@219: if (obj != null) {
ingo@219: objects.add(obj);
ingo@219: }
ingo@219: }
ingo@219:
ingo@219: System.out.println("Retrieved " + objects.size() + " distances.");
ingo@219:
ingo@219: return (DistanceInfoObject[])
ingo@219: objects.toArray(new DistanceInfoObject[num]);
ingo@219: }
ingo@219:
ingo@219:
ingo@219: /**
ingo@219: * Extracts information for a single distance info object and intializes an
ingo@219: * DistanceInfoObject with them.
ingo@219: *
ingo@219: * @param node The node that contains the information.
ingo@219: *
ingo@219: * @return a valid DistanceInfoObject.
ingo@219: */
ingo@219: protected DistanceInfoObject buildDistanceInfoObject(Node node) {
ingo@219: String desc = XMLUtils.xpathString(
ingo@219: node, "@art:description", ArtifactNamespaceContext.INSTANCE);
ingo@219:
ingo@219: String from = XMLUtils.xpathString(
ingo@219: node, "@art:from", ArtifactNamespaceContext.INSTANCE);
ingo@219:
ingo@219: String to = XMLUtils.xpathString(
ingo@219: node, "@art:to", ArtifactNamespaceContext.INSTANCE);
ingo@219:
ingo@219: String riverside = XMLUtils.xpathString(
ingo@219: node, "@art:riverside", ArtifactNamespaceContext.INSTANCE);
ingo@219:
ingo@219: if (desc != null && from != null) {
ingo@219: try {
ingo@219: return new DistanceInfoObjectImpl(
ingo@219: desc,
ingo@219: new Double(from),
ingo@219: to != null && to.trim().length() > 0 ? new Double(to) : null,
ingo@219: riverside);
ingo@219: }
ingo@219: catch (NumberFormatException nfe) {
ingo@219: System.err.println(nfe.getLocalizedMessage());
ingo@219: }
ingo@219: }
ingo@219:
ingo@219: System.err.println("Invalid distance info object found.");
ingo@219:
ingo@219: return null;
ingo@219: }
ingo@219: }
ingo@219: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :