teichmann@5835: package org.dive4elements.river.client.server; ingo@219: ingo@219: import java.util.ArrayList; ingo@219: import java.util.List; ingo@219: ingo@219: import org.w3c.dom.Document; ingo@219: import org.w3c.dom.Element; ingo@219: import org.w3c.dom.NodeList; ingo@219: ingo@1367: import org.apache.log4j.Logger; ingo@1367: ingo@219: import com.google.gwt.user.server.rpc.RemoteServiceServlet; ingo@219: teichmann@5835: import org.dive4elements.artifacts.common.ArtifactNamespaceContext; teichmann@5835: import org.dive4elements.artifacts.common.utils.XMLUtils; ingo@219: teichmann@5835: import org.dive4elements.artifacts.httpclient.exceptions.ConnectionException; teichmann@5835: import org.dive4elements.artifacts.httpclient.http.HttpClient; teichmann@5835: import org.dive4elements.artifacts.httpclient.http.HttpClientImpl; ingo@219: teichmann@5835: import org.dive4elements.river.client.shared.exceptions.ServerException; teichmann@5835: import org.dive4elements.river.client.client.services.DistanceInfoService; teichmann@5835: import org.dive4elements.river.client.shared.model.DistanceInfoObject; teichmann@5835: import org.dive4elements.river.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@1367: private static final Logger logger = ingo@1367: Logger.getLogger(DistanceInfoServiceImpl.class); ingo@1367: 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 locale, ingo@229: String river) ingo@219: throws ServerException ingo@219: { ingo@1367: logger.info("DistanceInfoServiceImpl.getDistanceInfo"); ingo@219: raimund@1425: String url = getServletContext().getInitParameter("server-url"); raimund@1425: 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@1367: logger.debug("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@1367: logger.error(ce, ce); 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: { sascha@569: NodeList list = result.getElementsByTagName("distance"); ingo@219: ingo@219: if (list == null || list.getLength() == 0) { ingo@1367: logger.warn("No distance info found."); ingo@219: throw new ServerException(ERROR_NO_DISTANCEINFO_FOUND); ingo@219: } ingo@219: ingo@219: int num = list.getLength(); ingo@1367: logger.debug("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++) { sascha@569: DistanceInfoObject obj = buildDistanceInfoObject( sascha@569: (Element)list.item(i)); ingo@219: ingo@219: if (obj != null) { ingo@219: objects.add(obj); ingo@219: } ingo@219: } ingo@219: ingo@1367: logger.debug("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: */ sascha@569: protected DistanceInfoObject buildDistanceInfoObject(Element node) { ingo@219: sascha@569: String desc = node.getAttribute("description").trim(); sascha@569: String from = node.getAttribute("from").trim(); sascha@569: String to = node.getAttribute("to").trim(); sascha@569: String riverside = node.getAttribute("riverside").trim(); sascha@569: String bottom = node.getAttribute("bottom").trim(); sascha@569: String top = node.getAttribute("top").trim(); sascha@567: sascha@569: if (desc.length() > 0 && from.length() > 0) { sascha@569: try { sascha@569: Double f = new Double(from); sascha@569: Double t = to .length() > 0 ? new Double(to) : null; sascha@569: Double b = bottom.length() > 0 ? new Double(bottom) : null; sascha@569: Double tp = top .length() > 0 ? new Double(top) : null; sascha@567: sascha@567: return new DistanceInfoObjectImpl(desc, f, t, riverside, b, tp); ingo@219: } ingo@219: catch (NumberFormatException nfe) { ingo@1367: logger.warn(nfe.getLocalizedMessage()); ingo@219: } ingo@219: } ingo@219: ingo@1367: logger.warn("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 :