001: // $HeadURL: https://svn.wald.intevation.org/svn/deegree/base/trunk/src/org/deegree/ogcwebservices/wms/GetLegendGraphicHandler.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: ---------------------------------------------------------------------------*/
044: package org.deegree.ogcwebservices.wms;
045:
046: import java.awt.image.BufferedImage;
047: import java.net.URL;
048: import java.util.List;
049:
050: import org.deegree.datatypes.QualifiedName;
051: import org.deegree.framework.log.ILogger;
052: import org.deegree.framework.log.LoggerFactory;
053: import org.deegree.framework.util.ImageUtils;
054: import org.deegree.framework.util.StringTools;
055: import org.deegree.graphics.legend.LegendElement;
056: import org.deegree.graphics.legend.LegendFactory;
057: import org.deegree.graphics.sld.SLDFactory;
058: import org.deegree.graphics.sld.StyledLayerDescriptor;
059: import org.deegree.graphics.sld.UserStyle;
060: import org.deegree.i18n.Messages;
061: import org.deegree.ogcwebservices.OGCWebServiceException;
062: import org.deegree.ogcwebservices.wms.capabilities.Layer;
063: import org.deegree.ogcwebservices.wms.capabilities.LegendURL;
064: import org.deegree.ogcwebservices.wms.configuration.WMSConfigurationType;
065: import org.deegree.ogcwebservices.wms.operation.GetLegendGraphic;
066: import org.deegree.ogcwebservices.wms.operation.GetLegendGraphicResult;
067: import org.deegree.ogcwebservices.wms.operation.WMSProtocolFactory;
068: import org.deegree.owscommon_new.DCP;
069: import org.deegree.owscommon_new.HTTP;
070: import org.deegree.owscommon_new.Operation;
071: import org.deegree.owscommon_new.OperationsMetadata;
072:
073: /**
074: * performs a GetLegendGraphic request. The capability of the deegree implementation is limited to
075: * handle requests containing a named style or using the (named) styles defined in a passed or
076: * referenced SLD. featuretype and rule are not supported yet.
077: *
078: * @version $Revision: 9345 $
079: * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
080: * @author last edited by: $Author: apoth $
081: *
082: * @version 1.0. $Revision: 9345 $, $Date: 2007-12-27 08:22:25 -0800 (Thu, 27 Dec 2007) $
083: *
084: * @since 1.1
085: */
086: class GetLegendGraphicHandler {
087:
088: private static final ILogger LOG = LoggerFactory
089: .getLogger(GetLegendGraphicHandler.class);
090:
091: private WMSConfigurationType configuration = null;
092:
093: private StyledLayerDescriptor sld = null;
094:
095: private GetLegendGraphic request = null;
096:
097: /**
098: * Creates a new GetMapHandler object.
099: *
100: * @param capabilities
101: * @param request
102: * request to perform
103: */
104: public GetLegendGraphicHandler(WMSConfigurationType capabilities,
105: GetLegendGraphic request) {
106: this .configuration = capabilities;
107: this .request = request;
108: }
109:
110: /**
111: * performs the request and returns the result of it.
112: *
113: * @return the result object
114: * @throws OGCWebServiceException
115: */
116: public GetLegendGraphicResult performGetLegendGraphic()
117: throws OGCWebServiceException {
118:
119: validate(request);
120: LegendElement lege = getSymbol(request);
121: BufferedImage bi = null;
122: try {
123: bi = lege.exportAsImage(request.getFormat());
124: } catch (Exception e) {
125: LOG.logError(e.getMessage(), e);
126: throw new OGCWebServiceException(getClass().getName(), e
127: .getMessage());
128: }
129:
130: GetLegendGraphicResult res = WMSProtocolFactory
131: .createGetLegendGraphicResponse(request, bi);
132:
133: return res;
134: }
135:
136: /**
137: * validates if the passed request is valid against the WMS it was sent to and the SLD maybe
138: * contained or referenced in/by the request.
139: *
140: * @param request
141: * request to validate
142: */
143: private void validate(GetLegendGraphic request)
144: throws OGCWebServiceException {
145:
146: String layerName = request.getLayer();
147: String style = request.getStyle();
148:
149: if (request.getSLD() == null && request.getSLD_Body() == null) {
150: Layer layer = configuration.getLayer(layerName);
151: if (layer == null) {
152: String s = Messages.getMessage("WMS_UNKNOWNLAYER",
153: layerName);
154: throw new LayerNotDefinedException(s);
155: }
156: if (getNamedStyle(style) == null) {
157: String s = Messages.getMessage("WMS_STYLENOTKNOWN",
158: style);
159: throw new StyleNotDefinedException(s);
160: }
161: } else {
162: try {
163: if (request.getSLD() != null) {
164: sld = SLDFactory.createSLD(request.getSLD());
165: } else {
166: sld = SLDFactory.createSLD(request.getSLD_Body());
167: }
168: // check if layer and style are present
169: org.deegree.graphics.sld.AbstractLayer[] sldLayers = sld
170: .getLayers();
171: boolean found = false;
172: for (int i = 0; i < sldLayers.length; i++) {
173: if (layerName.equals(sldLayers[i].getName())) {
174: org.deegree.graphics.sld.AbstractStyle[] sldStyles = sldLayers[i]
175: .getStyles();
176: for (int k = 0; k < sldStyles.length; k++) {
177: if (sldStyles[k].getName().equals(style)) {
178: found = true;
179: break;
180: }
181: }
182: if (found)
183: break;
184: }
185: }
186: if (!found) {
187: String s = Messages.getMessage("WMS_LAYERNOTKNOWN",
188: layerName);
189: throw new OGCWebServiceException(getClass()
190: .getName(), s);
191: }
192:
193: } catch (Exception e) {
194: LOG.logError(e.getMessage(), e);
195: String s = Messages.getMessage("WMS_INVALIDSLDREF");
196: throw new OGCWebServiceException(getClass().getName(),
197: s);
198: }
199:
200: }
201:
202: }
203:
204: private org.deegree.ogcwebservices.wms.capabilities.Style getNamedStyle(
205: String name) {
206: String layerName = request.getLayer();
207: Layer layer = configuration.getLayer(layerName);
208: org.deegree.ogcwebservices.wms.capabilities.Style[] styles = layer
209: .getStyles();
210: for (int i = 0; i < styles.length; i++) {
211: if (styles[i].getName().equals(name)) {
212: return styles[i];
213: }
214: }
215: return null;
216: }
217:
218: /**
219: * @param request
220: * @return the symbol
221: * @throws WebServiceException
222: */
223: private LegendElement getSymbol(GetLegendGraphic request)
224: throws OGCWebServiceException {
225:
226: LegendElement le = null;
227: try {
228: if (request.getSLD() == null
229: && request.getSLD_Body() == null) {
230: le = getFromWellKnownStyle();
231: } else {
232: le = getFromSLDStyle();
233: }
234: } catch (Exception e) {
235: LOG.logError(e.getMessage(), e);
236: String s = Messages.getMessage("WMS_LEGENDELEM");
237: throw new OGCWebServiceException(getClass().getName(), s);
238: }
239:
240: return le;
241: }
242:
243: /**
244: * creates a LegendElement from a style known by the WMS
245: */
246: private LegendElement getFromWellKnownStyle()
247: throws OGCWebServiceException {
248:
249: String layerName = request.getLayer();
250: String styleName = request.getStyle();
251: LegendElement le = null;
252: LegendFactory lf = new LegendFactory();
253:
254: try {
255: // get Layer object from the WMS capabilities
256: Layer layer = configuration.getLayer(layerName);
257: // get the Style section from the matching the requested style
258: org.deegree.ogcwebservices.wms.capabilities.Style nStyle = getNamedStyle(styleName);
259: LegendURL[] lURLs = nStyle.getLegendURL();
260: OperationsMetadata om = configuration
261: .getOperationMetadata();
262: Operation op = om.getOperation(new QualifiedName(
263: "GetLegendGraphic"));
264: URL url = null;
265: if (op != null) {
266: // TODO
267: // should check if really HTTP
268: List<DCP> dcpList = op.getDCP();
269: HTTP http = (HTTP) dcpList.get(0);
270: url = http.getLinks().get(0).getLinkage().getHref();
271: if (lURLs[0].getOnlineResource().getHost().equals(
272: url.getHost())) {
273: String s = StringTools
274: .concat(
275: 200,
276: "GetLegendGraphic request ",
277: "to the WMS itself has been set has defined ",
278: "as LegendURL for layer: ",
279: layerName);
280: LOG.logInfo(s);
281: // avoid cyclic calling of WMS
282: UserStyle style = layer.getStyle(styleName);
283: if (style != null) {
284: // drawing legend symbol
285: String title = configuration
286: .getLayer(layerName).getTitle();
287: le = lf
288: .createLegendElement(style, request
289: .getWidth(), request
290: .getHeight(), title);
291: } else {
292: s = Messages.getMessage(
293: "WMS_GENERALSTYLEERROR", styleName);
294: throw new OGCWebServiceException(getClass()
295: .getName(), s);
296: }
297: } else {
298: // if a legend url is defined will be used for creating the legend
299: // symbol; otherwise it will be tried to create the legend symbol
300: // dynamicly
301: try {
302: BufferedImage bi = ImageUtils
303: .loadImage(lURLs[0].getOnlineResource());
304: le = lf.createLegendElement(bi);
305: } catch (Exception e) {
306: String s = StringTools.concat(200,
307: "can not open legen URL: ", lURLs[0]
308: .getOnlineResource(),
309: "; try to create ",
310: "legend symbol dynamicly.");
311: LOG.logInfo(s);
312: UserStyle style = layer.getStyle(styleName);
313: if (style != null) {
314: // drawing legend symbol
315: String title = configuration.getLayer(
316: layerName).getTitle();
317: le = lf.createLegendElement(style, request
318: .getWidth(), request.getHeight(),
319: title);
320: } else {
321: s = Messages.getMessage(
322: "WMS_GENERALSTYLEERROR", styleName);
323: throw new OGCWebServiceException(getClass()
324: .getName(), s);
325: }
326: }
327:
328: }
329: }
330:
331: } catch (Exception e) {
332: LOG.logError(e.getMessage(), e);
333: throw new OGCWebServiceException(e.getMessage());
334: }
335: return le;
336: }
337:
338: /**
339: * creates a LegendElement from a style defined in the SLD document passed/referenced by/in the
340: * request
341: */
342: private LegendElement getFromSLDStyle()
343: throws OGCWebServiceException {
344:
345: String layerName = request.getLayer();
346: String styleName = request.getStyle();
347: LegendElement le = null;
348: LegendFactory lf = new LegendFactory();
349:
350: try {
351: org.deegree.graphics.sld.AbstractLayer[] sldLayers = sld
352: .getLayers();
353: for (int i = 0; i < sldLayers.length; i++) {
354: if (layerName.equals(sldLayers[i].getName())) {
355: org.deegree.graphics.sld.AbstractStyle[] sldStyles = sldLayers[i]
356: .getStyles();
357: org.deegree.graphics.sld.AbstractStyle style = null;
358: if (styleName == null) {
359: style = sldStyles[0];
360: } else {
361: for (int k = 0; k < sldStyles.length; k++) {
362: if (sldStyles[k].getName()
363: .equals(styleName)) {
364: style = sldStyles[k];
365: break;
366: }
367: }
368: }
369: String title = configuration.getLayer(layerName)
370: .getTitle();
371: le = lf.createLegendElement(style, request
372: .getWidth(), request.getHeight(), title);
373: }
374: }
375: } catch (Exception e) {
376: LOG.logError(e.getMessage(), e);
377: throw new OGCWebServiceException(StringTools
378: .stackTraceToString(e.getStackTrace()));
379: }
380:
381: return le;
382: }
383:
384: }
|