001: //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/trunk/src/org/deegree/ogcwebservices/wms/GetMapServiceInvokerForUL.java $
002: /*---------------- FILE HEADER ------------------------------------------
003:
004: This file is part of deegree.
005: Copyright (C) 2001-2008 by:
006: EXSE, Department of Geography, University of Bonn
007: http://www.giub.uni-bonn.de/deegree/
008: lat/lon GmbH
009: http://www.lat-lon.de
010:
011: This library is free software; you can redistribute it and/or
012: modify it under the terms of the GNU Lesser General Public
013: License as published by the Free Software Foundation; either
014: version 2.1 of the License, or (at your option) any later version.
015:
016: This library is distributed in the hope that it will be useful,
017: but WITHOUT ANY WARRANTY; without even the implied warranty of
018: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
019: Lesser General Public License for more details.
020:
021: You should have received a copy of the GNU Lesser General Public
022: License along with this library; if not, write to the Free Software
023: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
024:
025: Contact:
026:
027: Andreas Poth
028: lat/lon GmbH
029: Aennchenstr. 19
030: 53177 Bonn
031: Germany
032: E-Mail: poth@lat-lon.de
033:
034: Prof. Dr. Klaus Greve
035: Department of Geography
036: University of Bonn
037: Meckenheimer Allee 166
038: 53115 Bonn
039: Germany
040: E-Mail: greve@giub.uni-bonn.de
041:
042: ---------------------------------------------------------------------------*/
043: package org.deegree.ogcwebservices.wms;
044:
045: import static java.lang.Boolean.FALSE;
046:
047: import java.io.ByteArrayOutputStream;
048: import java.io.InputStreamReader;
049: import java.io.StringReader;
050: import java.net.URI;
051: import java.net.URL;
052: import java.util.Arrays;
053: import java.util.Iterator;
054: import java.util.List;
055: import java.util.Map;
056: import java.util.concurrent.Callable;
057:
058: import org.deegree.datatypes.QualifiedName;
059: import org.deegree.framework.log.ILogger;
060: import org.deegree.framework.log.LoggerFactory;
061: import org.deegree.framework.util.CharsetUtils;
062: import org.deegree.framework.util.IDGenerator;
063: import org.deegree.framework.util.NetWorker;
064: import org.deegree.framework.xml.XMLFragment;
065: import org.deegree.graphics.MapFactory;
066: import org.deegree.graphics.sld.AbstractStyle;
067: import org.deegree.graphics.sld.FeatureTypeConstraint;
068: import org.deegree.graphics.sld.LayerFeatureConstraints;
069: import org.deegree.graphics.sld.RemoteOWS;
070: import org.deegree.graphics.sld.StyleUtils;
071: import org.deegree.graphics.sld.UserLayer;
072: import org.deegree.graphics.sld.UserStyle;
073: import org.deegree.model.feature.FeatureCollection;
074: import org.deegree.model.feature.GMLFeatureCollectionDocument;
075: import org.deegree.model.filterencoding.Filter;
076: import org.deegree.ogcbase.PropertyPath;
077: import org.deegree.ogcwebservices.OGCWebServiceException;
078: import org.deegree.ogcwebservices.wfs.WFService;
079: import org.deegree.ogcwebservices.wfs.operation.FeatureResult;
080: import org.deegree.ogcwebservices.wfs.operation.GetFeature;
081: import org.w3c.dom.Element;
082:
083: /**
084: * class for accessing the data of one user layer and creating <tt>DisplayElement</tt>s and a
085: * <tt>Thrme</tt> from it. The class extends <tt>Thread</tt> and implements the run method, so
086: * that a parallel data accessing from several layers is possible.
087: *
088: * @version $Revision: 9345 $
089: * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
090: * @author last edited by: $Author: apoth $
091: *
092: * @version 1.0. $Revision: 9345 $, $Date: 2007-12-27 08:22:25 -0800 (Thu, 27 Dec 2007) $
093: *
094: * @since 2.0
095: */
096: class GetMapServiceInvokerForUL extends GetMapServiceInvoker implements
097: Callable<Object> {
098:
099: private static final ILogger LOG = LoggerFactory
100: .getLogger(GetMapServiceInvokerForUL.class);
101:
102: private UserLayer layer = null;
103:
104: private UserStyle[] styles = null;
105:
106: /**
107: *
108: * @param handler
109: * @param layer
110: * @param scale
111: * current mapscale denominator
112: * @param index
113: */
114: GetMapServiceInvokerForUL(DefaultGetMapHandler handler,
115: UserLayer layer, double scale) {
116: super (handler, scale);
117:
118: this .layer = layer;
119: AbstractStyle[] tmp = layer.getStyles();
120: styles = new UserStyle[tmp.length];
121: for (int i = 0; i < tmp.length; i++) {
122: styles[i] = (UserStyle) tmp[i];
123: }
124:
125: }
126:
127: public Object call() {
128:
129: try {
130: if (layer.getRemoteOWS() == null
131: || layer.getRemoteOWS().getService().equals(
132: RemoteOWS.WFS)) {
133: return handleWFS();
134: } else if (layer.getRemoteOWS().getService().equals(
135: RemoteOWS.WCS)) {
136: return handleWCS();
137: }
138:
139: } catch (Exception e) {
140: LOG.logError(e.getMessage(), e);
141: OGCWebServiceException exce = new OGCWebServiceException(
142: "ServiceInvokerForUL: " + layer.getName(),
143: "Couldn't perform query!");
144: return exce;
145: }
146:
147: return null;
148: }
149:
150: /**
151: * handles requests against a WFS
152: */
153: private Object handleWFS() throws Exception {
154:
155: FeatureCollection fc = null;
156: String request = createGetFeatureRequest();
157: LOG.logDebug(request);
158: if (layer.getRemoteOWS() != null) {
159: // handle request against a remote WFS
160: RemoteOWS remoteOWS = layer.getRemoteOWS();
161: URL url = remoteOWS.getOnlineResource();
162:
163: NetWorker nw = new NetWorker(CharsetUtils
164: .getSystemCharset(), url, request);
165: InputStreamReader isr = new InputStreamReader(nw
166: .getInputStream(), CharsetUtils.getSystemCharset());
167: GMLFeatureCollectionDocument doc = new GMLFeatureCollectionDocument();
168: doc.load(isr, url.toString());
169: Element root = doc.getRootElement();
170:
171: if (root.getNodeName().indexOf("Exception") > -1) {
172: ByteArrayOutputStream bos = new ByteArrayOutputStream(
173: 1000);
174: doc.write(bos);
175: throw new Exception(new String(bos.toByteArray()));
176: }
177: fc = doc.parse();
178: } else {
179: // handle request agaist a local WFS; this is bit problematic
180: // because deegree WMS is able to handle more than one
181: // local WFS. At the moment the WFS will be used that will
182: // returned by the WFServiceFactory as default
183: XMLFragment xml = new XMLFragment(
184: new StringReader(request), XMLFragment.DEFAULT_URL);
185: Element root = xml.getRootElement();
186: // create OGCWebServiceEvent object
187: IDGenerator idg = IDGenerator.getInstance();
188: GetFeature gfr = GetFeature.create(""
189: + idg.generateUniqueID(), root);
190:
191: // returns the WFS responsible for handling current feature type
192: WFService wfs = getResponsibleService(layer);
193: FeatureResult fr = (FeatureResult) wfs.doService(gfr);
194: fc = (FeatureCollection) fr.getResponse();
195: }
196: org.deegree.graphics.Layer fl = MapFactory.createFeatureLayer(
197: layer.getName(), this .handler.getRequestCRS(), fc);
198: return MapFactory.createTheme(layer.getName(), fl, styles);
199: }
200:
201: /**
202: * creates a GetFeature request related to the UserLayer encapsulated in this object
203: */
204: private String createGetFeatureRequest() throws Exception {
205:
206: LayerFeatureConstraints lfc = layer
207: .getLayerFeatureConstraints();
208: FeatureTypeConstraint[] ftc = lfc.getFeatureTypeConstraint();
209:
210: List<UserStyle> styleList = Arrays.asList(styles);
211: List<PropertyPath> pp = StyleUtils.extractRequiredProperties(
212: styleList, scaleDen);
213: LOG.logDebug("required properties: ", pp);
214: pp = findGeoProperties(layer, ftc, pp);
215: Map<String, URI> namesp = extractNameSpaceDef(pp);
216: for (int i = 0; i < ftc.length; i++) {
217: QualifiedName qn = ftc[i].getFeatureTypeName();
218: namesp.put(qn.getPrefix(), qn.getNamespace());
219: }
220:
221: StringBuffer sb = new StringBuffer(5000);
222: sb.append("<?xml version='1.0' encoding='"
223: + CharsetUtils.getSystemCharset() + "'?>");
224: sb.append("<GetFeature xmlns='http://www.opengis.net/wfs' ");
225: sb.append("xmlns:ogc='http://www.opengis.net/ogc' ");
226: sb.append("xmlns:gml='http://www.opengis.net/gml' ");
227:
228: Iterator<String> iter = namesp.keySet().iterator();
229: while (iter.hasNext()) {
230: String pre = iter.next();
231: URI nsp = namesp.get(pre);
232: if (!pre.equals("xmlns")) {
233: sb.append("xmlns:").append(pre).append("='");
234: sb.append(nsp.toASCIIString()).append("' ");
235: }
236: }
237:
238: sb.append("service='WFS' version='1.1.0' ");
239: sb.append("outputFormat='text/xml; subtype=gml/3.1.1'>");
240: for (int i = 0; i < ftc.length; i++) {
241: QualifiedName qn = ftc[i].getFeatureTypeName();
242: sb.append("<Query typeName='").append(qn.getPrefixedName())
243: .append("'>");
244:
245: for (int j = 0; j < pp.size(); j++) {
246: if (!pp.get(j).getAsString().endsWith("$SCALE")) {
247: // $SCALE is a dynamicly created property of each feature
248: // and can not be requested
249: sb.append("<PropertyName>").append(
250: pp.get(j).getAsString());
251: sb.append("</PropertyName>");
252: }
253: }
254:
255: Filter filter = ftc[i].getFilter();
256: if (filter != null) {
257: sb.append(filter.toXML());
258: }
259: sb.append("</Query>");
260: }
261: sb.append("</GetFeature>");
262:
263: LOG.logDebug(sb.toString());
264:
265: return sb.toString();
266: }
267:
268: /**
269: * handles requests against a WCS
270: */
271: private Object handleWCS() throws Exception {
272: return FALSE;
273: /*
274: * TODO RemoteOWS remoteOWS = layer.getRemoteOWS(); URL url = remoteOWS.getOnlineResource();
275: *
276: * NetWorker nw = new NetWorker( url ); MemoryCacheSeekableStream mcss = new
277: * MemoryCacheSeekableStream( nw.getInputStream() );
278: *
279: * RenderedOp rop = JAI.create("stream", mcss);
280: *
281: * GC_GridCoverage gc = new ImageGridCoverage(rop.getAsBufferedImage(),
282: * request.getBoundingBox(), reqCRS, false); mcss.close();
283: *
284: * org.deegree.graphics.Layer rl = MapFactory.createRasterLayer(layer.getName(), gc);
285: *
286: * putTheme(index, MapFactory.createTheme(layer.getName(), rl)); mcss.close();
287: * increaseCounter();
288: */
289:
290: }
291:
292: }
|