0001: //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/trunk/src/org/deegree/ogcwebservices/wmps/operation/PrintMap.java $
0002: /*---------------- FILE HEADER ------------------------------------------
0003:
0004: This file is part of deegree.
0005: Copyright (C) 2001-2008 by:
0006: EXSE, Department of Geography, University of Bonn
0007: http://www.giub.uni-bonn.de/deegree/
0008: lat/lon GmbH
0009: http://www.lat-lon.de
0010:
0011: This library is free software; you can redistribute it and/or
0012: modify it under the terms of the GNU Lesser General Public
0013: License as published by the Free Software Foundation; either
0014: version 2.1 of the License, or (at your option) any later version.
0015:
0016: This library is distributed in the hope that it will be useful,
0017: but WITHOUT ANY WARRANTY; without even the implied warranty of
0018: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0019: Lesser General Public License for more details.
0020:
0021: You should have received a copy of the GNU Lesser General Public
0022: License along with this library; if not, write to the Free Software
0023: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0024:
0025: Contact:
0026:
0027: Andreas Poth
0028: lat/lon GmbH
0029: Aennchenstr. 19
0030: 53115 Bonn
0031: Germany
0032: E-Mail: poth@lat-lon.de
0033:
0034: Prof. Dr. Klaus Greve
0035: Department of Geography
0036: University of Bonn
0037: Meckenheimer Allee 166
0038: 53115 Bonn
0039: Germany
0040: E-Mail: greve@giub.uni-bonn.de
0041:
0042:
0043: ---------------------------------------------------------------------------*/
0044: package org.deegree.ogcwebservices.wmps.operation;
0045:
0046: import java.awt.Color;
0047: import java.io.Serializable;
0048: import java.io.UnsupportedEncodingException;
0049: import java.net.URLDecoder;
0050: import java.sql.Timestamp;
0051: import java.util.ArrayList;
0052: import java.util.Arrays;
0053: import java.util.HashMap;
0054: import java.util.List;
0055: import java.util.Map;
0056: import java.util.StringTokenizer;
0057:
0058: import org.deegree.framework.log.ILogger;
0059: import org.deegree.framework.log.LoggerFactory;
0060: import org.deegree.framework.util.CharsetUtils;
0061: import org.deegree.framework.util.StringTools;
0062: import org.deegree.framework.xml.NamespaceContext;
0063: import org.deegree.framework.xml.XMLParsingException;
0064: import org.deegree.framework.xml.XMLTools;
0065: import org.deegree.model.crs.CRSFactory;
0066: import org.deegree.model.crs.CoordinateSystem;
0067: import org.deegree.model.crs.UnknownCRSException;
0068: import org.deegree.model.spatialschema.Envelope;
0069: import org.deegree.model.spatialschema.GMLGeometryAdapter;
0070: import org.deegree.model.spatialschema.GeometryException;
0071: import org.deegree.model.spatialschema.GeometryFactory;
0072: import org.deegree.model.spatialschema.Point;
0073: import org.deegree.ogcbase.CommonNamespaces;
0074: import org.deegree.ogcbase.InvalidGMLException;
0075: import org.deegree.ogcwebservices.InconsistentRequestException;
0076: import org.deegree.ogcwebservices.wms.InvalidFormatException;
0077: import org.deegree.ogcwebservices.wms.operation.GetMap;
0078: import org.deegree.ogcwebservices.wms.operation.GetMap.Layer;
0079: import org.w3c.dom.Element;
0080: import org.w3c.dom.Node;
0081:
0082: /**
0083: * This interface describes the access to the parameters of a PrintMap request. It is expected that
0084: * there are two kinds of request. The first is the 'normal' HTTP GET request with name-value-pair
0085: * enconding and the second is a HTTP POST request containing a SLD. It is possible to access the
0086: * values of a HTTP GET request throught its bean accessor methods. The request shall be mapped to a
0087: * SLD data structure, accessible using the <code>getSLD()</code> method.
0088: *
0089: * @author <a href="mailto:deshmukh@lat-lon.de">Anup Deshmukh</a>
0090: * @version 2.0
0091: */
0092: public class PrintMap extends WMPSRequestBase implements Serializable {
0093:
0094: private static final long serialVersionUID = 6898492018448337645L;
0095:
0096: private static final ILogger LOG = LoggerFactory
0097: .getLogger(PrintMap.class);
0098:
0099: private static final NamespaceContext nsContext = CommonNamespaces
0100: .getNamespaceContext();
0101:
0102: private List<Layer> layers;
0103:
0104: private String srs;
0105:
0106: private Envelope boundingBox;
0107:
0108: private Point center;
0109:
0110: private int scaleDenominator = -1;
0111:
0112: private boolean transparent;
0113:
0114: private Color bgColor;
0115:
0116: private String title;
0117:
0118: private String copyright;
0119:
0120: private boolean legend;
0121:
0122: private boolean scaleBar;
0123:
0124: private String note;
0125:
0126: private String template;
0127:
0128: private String emailaddress;
0129:
0130: private Timestamp timestamp;
0131:
0132: private TextArea[] textAreas;
0133:
0134: /**
0135: * Create a new PrintMap instance.
0136: *
0137: * @param id
0138: * @param version
0139: * @param layers
0140: * @param srs
0141: * @param boundingBox
0142: * @param center
0143: * @param scaleDenominator
0144: * @param transparent
0145: * @param bgColor
0146: * @param title
0147: * @param copyright
0148: * @param legend
0149: * @param scaleBar
0150: * @param note
0151: * @param template
0152: * @param emailaddress
0153: * @param timestamp
0154: * @param textAreas
0155: * @param vendorSpecificParameter
0156: */
0157: PrintMap(String id, String version, Layer[] layers, String srs,
0158: Envelope boundingBox, Point center, int scaleDenominator,
0159: boolean transparent, Color bgColor, String title,
0160: String copyright, boolean legend, boolean scaleBar,
0161: String note, String template, String emailaddress,
0162: Timestamp timestamp, TextArea[] textAreas,
0163: Map<String, String> vendorSpecificParameter) {
0164:
0165: super (version, id, vendorSpecificParameter);
0166:
0167: setLayers(layers);
0168: this .srs = srs;
0169: this .boundingBox = boundingBox;
0170: this .center = center;
0171: this .scaleDenominator = scaleDenominator;
0172: this .transparent = transparent;
0173: this .bgColor = bgColor;
0174: this .title = title;
0175: this .copyright = copyright;
0176: this .legend = legend;
0177: this .scaleBar = scaleBar;
0178: this .note = note;
0179: this .template = template;
0180: this .emailaddress = emailaddress;
0181: setTimestamp(timestamp);
0182: this .textAreas = textAreas;
0183: }
0184:
0185: /**
0186: * Set the time stamp.
0187: *
0188: * @param timestamp
0189: */
0190: private void setTimestamp(Timestamp timestamp) {
0191:
0192: if (timestamp != null) {
0193: this .timestamp = timestamp;
0194: } else {
0195: this .timestamp = setCurrentTime();
0196: }
0197: }
0198:
0199: /**
0200: * Sets the Current System Time where the request was recieved.
0201: *
0202: * @return Date
0203: */
0204: private static Timestamp setCurrentTime() {
0205: long now = System.currentTimeMillis();
0206: return new Timestamp(now);
0207: }
0208:
0209: /**
0210: * The required LAYERS parameter lists the map layer(s) to be returned by this PrintMapRequest
0211: * request. The value of the LAYERS parameter is a comma-separated list of one or more valid
0212: * layer names. Allowed layer names are the character data content of any <Layer><Name> element
0213: * in the Capabilities XML.
0214: * <p>
0215: * </p>
0216: * A WMS shall render the requested layers by drawing the leftmost in the list bottommost, the
0217: * next one over that, and so on.
0218: * <p>
0219: * </p>
0220: * Each layer is associated to a style. Styles are also is encoded as a comma- seperated list
0221: * within the PrintMapRequest request.
0222: * <p>
0223: * </p>
0224: * The required STYLES parameter lists the style in which each layer is to be rendered. There is
0225: * a one-to-one correspondence between the values in the LAYERS parameter and the values in the
0226: * STYLES parameter. Because of this layer-style combinations are returned coupled within an
0227: * array of Layer- objects. Each map in the list of LAYERS is drawn using the corresponding
0228: * style in the same position in the list of STYLES. Each style Name shall be one that was
0229: * defined in the <Name> element of a <Style> element that is either directly contained within,
0230: * or inherited by, the associated <Layer> element in Capabilities XML.
0231: *
0232: * @return The required LAYERS
0233: */
0234: public Layer[] getLayers() {
0235: return this .layers.toArray(new Layer[this .layers.size()]);
0236: }
0237:
0238: /**
0239: * adds the <Layer>
0240: *
0241: * @param layer
0242: */
0243: protected void addLayers(Layer layer) {
0244: this .layers.add(layer);
0245: }
0246:
0247: /**
0248: * sets the <Layer>
0249: *
0250: * @param layers
0251: * a set of layer
0252: */
0253: private void setLayers(Layer[] layers) {
0254: this .layers = new ArrayList<Layer>(layers.length);
0255: this .layers.clear();
0256: if (layers != null) {
0257: this .layers = Arrays.asList(layers);
0258: }
0259: }
0260:
0261: /**
0262: * creates a <tt>PrintMapRequest</tt> from its XML representation as defined in the
0263: * specification.
0264: *
0265: * @param root
0266: * Element
0267: * @return an instance of <tt>PrintMapRequest</tt>
0268: * @throws InconsistentRequestException
0269: * @throws XMLParsingException
0270: */
0271: public static PrintMap create(Element root)
0272: throws InconsistentRequestException, XMLParsingException {
0273:
0274: LOG.logInfo("Validating PrintMapRequest request.");
0275: // Validation
0276: if (!root.getLocalName().equals("PrintMap")) {
0277: StringBuffer sb = new StringBuffer(50);
0278: sb
0279: .append("Unable to create a 'PrintMapRequest' operation for node '");
0280: sb.append(root.getLocalName()
0281: + "'. Please check the node to be parsed.");
0282: throw new InconsistentRequestException(sb.toString());
0283: }
0284: // VERSION
0285: String version;
0286: try {
0287: version = XMLTools.getRequiredAttrValue("version", null,
0288: root);
0289: } catch (XMLParsingException e) {
0290: throw new XMLParsingException(
0291: "Error parsing required attribute parameter 'Version'. "
0292: + e.getMessage());
0293: }
0294:
0295: // LAYERS & STYLES
0296: List<Layer> layerList = new ArrayList<Layer>();
0297: List layerElements = null;
0298: try {
0299: layerElements = XMLTools.getNodes(root,
0300: "deegreewmps:Layers", nsContext);
0301: } catch (XMLParsingException e) {
0302: throw new XMLParsingException(
0303: "Error parsing required parameter 'Layer(s)'. "
0304: + e.getMessage());
0305: }
0306:
0307: for (int i = 0; i < layerElements.size(); i++) {
0308: Element layer = (Element) layerElements.get(i);
0309: List namedLayers = null;
0310: try {
0311: namedLayers = XMLTools.getNodes(layer,
0312: "sld:NamedLayer", nsContext);
0313: layerList = createLayers(namedLayers, layerList);
0314: } catch (XMLParsingException e) {
0315: throw new XMLParsingException(
0316: "Error parsing parameter 'NamedLayer'.");
0317: }
0318: List userLayers = null;
0319: try {
0320: userLayers = XMLTools.getNodes(layer, "sld:UserLayer",
0321: nsContext);
0322: layerList = createLayers(userLayers, layerList);
0323: } catch (XMLParsingException e) {
0324: throw new XMLParsingException(
0325: "Error parsing parameter 'UserLayer'.");
0326: }
0327: if ((layerList == null) || (layerList.size() == 0)) {
0328: throw new InconsistentRequestException(
0329: "Atleast one 'NamedLayer' or one "
0330: + "'UserLayer' has to be specified.");
0331: }
0332: }
0333: Layer[] layers = layerList.toArray(new Layer[layerList.size()]);
0334:
0335: // BBOX
0336: Element bbox = null;
0337: String srsName = null;
0338: Envelope boundingBox = null;
0339: try {
0340: bbox = (Element) XMLTools.getNode(root, "gml:Envelope",
0341: nsContext);
0342: if (bbox != null) {
0343: try {
0344: srsName = XMLTools.getAttrValue(bbox, null,
0345: "srsName", null);
0346: boundingBox = GMLGeometryAdapter
0347: .wrapBox(bbox, null);
0348: } catch (InvalidGMLException e) {
0349: throw new XMLParsingException(
0350: "Error creating a bounding box for the "
0351: + "'BBOX' parameter.");
0352: } catch (UnknownCRSException e) {
0353: throw new InconsistentRequestException(e
0354: .getMessage());
0355: }
0356: }
0357: } catch (XMLParsingException e) {
0358: throw new XMLParsingException(
0359: "Error parsing optional parameter 'BoundingBox'. "
0360: + e.getMessage());
0361: }
0362:
0363: // Center
0364: Point center = null;
0365: try {
0366: Element centerElement = (Element) XMLTools.getNode(root,
0367: "deegreewmps:Center", nsContext);
0368: if (centerElement != null) {
0369: try {
0370: srsName = XMLTools.getAttrValue(centerElement,
0371: null, "srsName", null);
0372: center = (Point) GMLGeometryAdapter.wrap(
0373: centerElement, null);
0374: } catch (GeometryException e) {
0375: throw new XMLParsingException(
0376: "Error creating a Point for the 'Center' "
0377: + "parameter. " + e.getMessage());
0378: }
0379: }
0380: } catch (XMLParsingException e) {
0381: throw new XMLParsingException(
0382: "Error parsing optional parameter 'Center'. "
0383: + e.getMessage());
0384: }
0385:
0386: // ScaleDenominator
0387: int scaleDenominator = -1;
0388: try {
0389: scaleDenominator = XMLTools.getNodeAsInt(root,
0390: "deegreewmps:ScaleDenominator", nsContext, -1);
0391: } catch (XMLParsingException e) {
0392: throw new XMLParsingException(
0393: "Error parsing optional parameter 'Center'. "
0394: + e.getMessage());
0395: }
0396:
0397: if (boundingBox == null) {
0398: if (center == null) {
0399: throw new InconsistentRequestException(
0400: "Both 'BoundingBox' and 'Center' are not specified. Either of "
0401: + "the two must be set. Both values cannot be null");
0402: }
0403: if (scaleDenominator == -1) {
0404: throw new InconsistentRequestException(
0405: "Scale Denominator must be specified if the Bounding Box has "
0406: + "not been specified. Please check the 'SCALEDENOMINATOR' "
0407: + "parameter.");
0408: }
0409: }
0410:
0411: // TRANSPARENT
0412: boolean transparent = XMLTools.getNodeAsBoolean(root,
0413: "deegreewmps:Transparent", nsContext, false);
0414:
0415: // BGCOLOR
0416: Color bgColor = null;
0417: String colorstring = XMLTools.getNodeAsString(root,
0418: "deegreewmps:BGColor", nsContext, null);
0419: if (colorstring == null) {
0420: bgColor = Color.WHITE;
0421: } else {
0422: try {
0423: bgColor = Color.decode(colorstring);
0424: } catch (Exception e) {
0425: throw new InconsistentRequestException(
0426: "Error parsing 'BGCOLOR' parameter. The color '"
0427: + colorstring
0428: + "' is not a hexadecimal definition of a valid color. "
0429: + e.getMessage());
0430: }
0431: }
0432:
0433: boolean legend = XMLTools.getNodeAsBoolean(root,
0434: "deegreewmps:Legend", nsContext, false);
0435:
0436: boolean scaleBar = XMLTools.getNodeAsBoolean(root,
0437: "deegreewmps:ScaleBar", nsContext, false);
0438:
0439: String template = XMLTools.getNodeAsString(root,
0440: "deegreewmps:Template", nsContext, "default");
0441:
0442: String emailAdd = XMLTools.getNodeAsString(root,
0443: "deegreewmps:EMailAddress", nsContext, null);
0444:
0445: List list = XMLTools
0446: .getNodes(root,
0447: "deegreewmps:TextAreas/deegreewmps:TextArea",
0448: nsContext);
0449:
0450: TextArea[] textAreas = null;
0451: String title = null;
0452: String copyright = null;
0453: String note = null;
0454: if (list != null) {
0455: textAreas = new TextArea[list.size()];
0456: for (int i = 0; i < list.size(); i++) {
0457: Node textArea = (Node) list.get(i);
0458: String name = XMLTools.getRequiredNodeAsString(
0459: textArea, "deegreewmps:Name", nsContext);
0460: String value = XMLTools.getRequiredNodeAsString(
0461: textArea, "deegreewmps:Text", nsContext);
0462: if (name.equalsIgnoreCase("TITLE")) {
0463: title = value;
0464: }
0465: if (name.equalsIgnoreCase("COPYRIGHT")) {
0466: copyright = value;
0467: }
0468: if (name.equalsIgnoreCase("NOTE")) {
0469: note = value;
0470: }
0471: textAreas[i] = new TextArea(name, value);
0472:
0473: }
0474: }
0475: Map<String, String> vendorSpecificParameter = getVendorSpecificParameter(root);
0476:
0477: String id = "" + System.currentTimeMillis();
0478:
0479: LOG.logInfo("Created PrintMap request request with id '" + id
0480: + "'.");
0481:
0482: return new PrintMap(id, version, layers, srsName, boundingBox,
0483: center, scaleDenominator, transparent, bgColor, title,
0484: copyright, legend, scaleBar, note, template, emailAdd,
0485: setCurrentTime(), textAreas, vendorSpecificParameter);
0486:
0487: }
0488:
0489: /**
0490: * Returns the vendorspecific parameters as a map. Currently handles only the 'session id'
0491: *
0492: * @param root
0493: * @return Map
0494: */
0495: private static Map<String, String> getVendorSpecificParameter(
0496: Element root) {
0497:
0498: Map<String, String> vendorspecific = new HashMap<String, String>();
0499:
0500: String sessionID = XMLTools.getAttrValue(root, null,
0501: "sessionID", null);
0502: if (sessionID != null) {
0503: LOG
0504: .logInfo("vendor specific parameter 'sessionid' retrieved");
0505: vendorspecific.put("SESSIONID", sessionID);
0506: }
0507:
0508: return vendorspecific;
0509: }
0510:
0511: /**
0512: * Create Layer objects for each of namedLayer and userLayer.
0513: *
0514: * @param layerNodes
0515: * @param layers
0516: * @return List list of layer objects
0517: * @throws XMLParsingException
0518: */
0519: private static List<Layer> createLayers(List layerNodes,
0520: List<Layer> layers) throws XMLParsingException {
0521:
0522: if (layerNodes != null) {
0523: for (int i = 0; i < layerNodes.size(); i++) {
0524: Node layerNode = (Node) layerNodes.get(i);
0525: try {
0526: String layerName = XMLTools
0527: .getRequiredNodeAsString(layerNode,
0528: "sld:Name", nsContext);
0529: String styleName = XMLTools
0530: .getRequiredNodeAsString(layerNode,
0531: "sld:NamedStyle/sld:Name",
0532: nsContext);
0533: layers.add(new Layer(layerName, styleName));
0534: } catch (XMLParsingException e) {
0535: throw new XMLParsingException(
0536: "Error creating a Layer from the Node '"
0537: + layerNode.getNodeName() + "'. "
0538: + e.getMessage());
0539: }
0540: }
0541: }
0542:
0543: return layers;
0544: }
0545:
0546: /**
0547: * creates a <tt>PrintMapRequest</tt> from a <tt>HashMap</tt> that contains the request
0548: * parameters as key-value-pairs. Keys are expected to be in upper case notation.
0549: *
0550: * @param model
0551: * <tt>HashMap</tt> containing the request parameters
0552: * @return an instance of <tt>PrinttMapRequest</tt>
0553: * @throws InconsistentRequestException
0554: */
0555: public static PrintMap create(Map<String, String> model)
0556: throws InconsistentRequestException {
0557:
0558: retrieveRequestParameter(model);
0559:
0560: String version = retrieveVersionParameter(model);
0561:
0562: Layer[] layers = retrieveLayerAndStyleParameters(model);
0563:
0564: String srs = retrieveSRSParameter(model);
0565:
0566: Envelope boundingBox = null;
0567: Point center = null;
0568: try {
0569: boundingBox = retrieveBBOXParameter(model, srs);
0570: center = retrieveCenterParameter(model, srs);
0571: } catch (UnknownCRSException e) {
0572: throw new InconsistentRequestException(e.getMessage());
0573: }
0574:
0575: int scaleDenominator = retrieveScaleDenominatorParameter(model);
0576:
0577: if (boundingBox == null) {
0578: if (center == null) {
0579: throw new InconsistentRequestException(
0580: "Both 'BoundingBox' and 'Center' are not specified. Either of "
0581: + "the 2 must be set. Both values cannot be null");
0582: }
0583: if (scaleDenominator == -1) {
0584: throw new InconsistentRequestException(
0585: "Scale Denominator must be specified if the Bounding Box has "
0586: + "not been specified. Please check the 'SCALEDENOMINATOR' "
0587: + "parameter.");
0588: }
0589: }
0590:
0591: boolean transparent = retrieveTransparentParameter(model);
0592:
0593: Color bgColor = retrieveBGColorParameter(model);
0594:
0595: String title = retrieveTitleParameter(model);
0596:
0597: String copyRightNote = retrieveCopyrightParameter(model);
0598:
0599: boolean legend = retrieveLegendParameter(model);
0600:
0601: boolean scaleBar = retrieveScaleBarParameter(model);
0602:
0603: String note = retrieveNoteParameter(model);
0604:
0605: String template = retrieveTemplateParameter(model);
0606:
0607: String emailaddress = retrieveEmailParameter(model);
0608:
0609: TextArea[] textAreas = retrieveTextAreas(model);
0610:
0611: Map<String, String> vendorSpecificParameter = model;
0612:
0613: String id = "" + System.currentTimeMillis();
0614:
0615: return new PrintMap(id, version, layers, srs, boundingBox,
0616: center, scaleDenominator, transparent, bgColor, title,
0617: copyRightNote, legend, scaleBar, note, template,
0618: emailaddress, setCurrentTime(), textAreas,
0619: vendorSpecificParameter);
0620:
0621: }
0622:
0623: /**
0624: * Retrieve the Text Areas to be displayed on the PDF output file. Extract the comma seperated
0625: * list of name, value pairs. The name and value should be seperated with a ':'. E.g.->
0626: * name:value,name:value,name:value
0627: *
0628: * @param model
0629: * @return TextArea
0630: */
0631: private static TextArea[] retrieveTextAreas(Map model) {
0632:
0633: List<TextArea> texts = new ArrayList<TextArea>();
0634: if (model.containsKey("TEXTAREAS")) {
0635: String textstring = (String) model.remove("TEXTAREAS");
0636: if (textstring != null) {
0637: String[] nameValue = StringTools.toArray(textstring,
0638: ",", true);
0639: if (nameValue != null) {
0640: for (int i = 0; i < nameValue.length; i++) {
0641: String tmp = nameValue[i].trim();
0642: int idx = tmp.indexOf(":");
0643: if (idx != -1) {
0644: String name = tmp.substring(0, idx);
0645: String value = tmp.substring(idx + 1, tmp
0646: .length());
0647: if ((name != null) && (value != null)) {
0648: TextArea area = new TextArea(name
0649: .toUpperCase(), value);
0650: texts.add(area);
0651: }
0652: }
0653: }
0654: }
0655: }
0656: }
0657:
0658: return texts.toArray(new TextArea[texts.size()]);
0659:
0660: }
0661:
0662: /**
0663: * Parse 'Template' Parameter.
0664: *
0665: * @param model
0666: * @return String
0667: * @throws InconsistentRequestException
0668: */
0669: private static String retrieveTemplateParameter(Map model)
0670: throws InconsistentRequestException {
0671:
0672: String templatestring = null;
0673: if (model.containsKey("TEMPLATE")) {
0674: templatestring = (String) model.remove("TEMPLATE");
0675:
0676: }
0677: if (templatestring == null) {
0678: throw new InconsistentRequestException(
0679: "No Template defined. A Template name has to be specified "
0680: + "along with the 'PrintMap' request.");
0681: }
0682:
0683: return templatestring;
0684: }
0685:
0686: /**
0687: * Retrieve Email parameter
0688: *
0689: * @param model
0690: * @return String
0691: * @throws InconsistentRequestException
0692: */
0693: private static String retrieveEmailParameter(Map model)
0694: throws InconsistentRequestException {
0695:
0696: String email = null;
0697: if (model.containsKey("EMAIL")) {
0698: email = (String) model.remove("EMAIL");
0699: }
0700:
0701: if (email == null) {
0702: throw new InconsistentRequestException(
0703: "EMail parameter must be set.");
0704: }
0705:
0706: return email;
0707: }
0708:
0709: /**
0710: * Parse 'Note' Parameter.
0711: *
0712: * @param model
0713: * @return String
0714: */
0715: private static String retrieveNoteParameter(Map model) {
0716:
0717: String note = null;
0718: if (model.containsKey("NOTE")) {
0719: note = (String) model.remove("NOTE");
0720: }
0721:
0722: return note;
0723: }
0724:
0725: /**
0726: * Parse 'ScaleBar' Parameter.
0727: *
0728: * @param model
0729: * @return boolean
0730: * @throws InconsistentRequestException
0731: */
0732: private static boolean retrieveScaleBarParameter(Map model)
0733: throws InconsistentRequestException {
0734:
0735: boolean showScaleBar = false;
0736: if (model.containsKey("SCALEBAR")) {
0737: String scaleBar = (String) model.remove("SCALEBAR");
0738: if (scaleBar == null) {
0739: showScaleBar = false;
0740: } else if (scaleBar.equalsIgnoreCase("True")) {
0741: showScaleBar = true;
0742: } else if (scaleBar.equalsIgnoreCase("False")) {
0743: showScaleBar = false;
0744: } else {
0745: throw new InconsistentRequestException(
0746: "The 'ScaleBar' parameter can only have 'True', 'False' "
0747: + "values. Here it is '" + scaleBar
0748: + "'.");
0749: }
0750: }
0751:
0752: return showScaleBar;
0753: }
0754:
0755: /**
0756: * Parse 'Legend' Parameter.
0757: *
0758: * @param model
0759: * @return boolean
0760: * @throws InconsistentRequestException
0761: */
0762: private static boolean retrieveLegendParameter(Map model)
0763: throws InconsistentRequestException {
0764:
0765: boolean showLegend = false;
0766: if (model.containsKey("LEGEND")) {
0767: String legend = (String) model.remove("LEGEND");
0768: if (legend == null) {
0769: showLegend = false;
0770: } else if (legend.equalsIgnoreCase("True")) {
0771: showLegend = true;
0772: } else if (legend.equalsIgnoreCase("False")) {
0773: showLegend = false;
0774: } else {
0775: throw new InconsistentRequestException(
0776: "The 'Legend' parameter can only have 'True', 'False' values. "
0777: + "Here it is '" + legend + "'.");
0778: }
0779: }
0780:
0781: return showLegend;
0782:
0783: }
0784:
0785: /**
0786: * Parse 'Copyright' Parameter.
0787: *
0788: * @param model
0789: * @return String
0790: */
0791: private static String retrieveCopyrightParameter(Map model) {
0792:
0793: String copyright = null;
0794: if (model.containsKey("COPYRIGHT")) {
0795: copyright = (String) model.remove("COPYRIGHT");
0796: }
0797:
0798: return copyright;
0799: }
0800:
0801: /**
0802: * Parse 'Title' Parameter.
0803: *
0804: * @param model
0805: * @return String
0806: */
0807: private static String retrieveTitleParameter(Map model) {
0808:
0809: String title = null;
0810: if (model.containsKey("TITLE")) {
0811: title = (String) model.remove("TITLE");
0812: }
0813:
0814: return title;
0815: }
0816:
0817: /**
0818: * Parse 'BGColor' Parameter.
0819: *
0820: * @param model
0821: * @return Color
0822: * @throws InconsistentRequestException
0823: */
0824: private static Color retrieveBGColorParameter(Map model)
0825: throws InconsistentRequestException {
0826:
0827: Color bgColor = Color.WHITE;
0828: if (model.containsKey("BGCOLOR")) {
0829: String colorstring = (String) model.remove("BGCOLOR");
0830: if ((colorstring != null) || (colorstring == "")) {
0831: try {
0832: bgColor = Color.decode(colorstring);
0833: } catch (Exception e) {
0834: throw new InconsistentRequestException(
0835: "Error parsing 'BGCOLOR' parameter. The color '"
0836: + colorstring
0837: + "' is not a hexadecimal "
0838: + "definition of a valid color. "
0839: + e.getMessage());
0840: }
0841: }
0842: }
0843:
0844: return bgColor;
0845: }
0846:
0847: /**
0848: * Parse 'Transparent' Parameter.
0849: *
0850: * @param model
0851: * @return boolean
0852: * @throws InconsistentRequestException
0853: */
0854: private static boolean retrieveTransparentParameter(Map model)
0855: throws InconsistentRequestException {
0856:
0857: boolean isTransparent = false;
0858: if (model.containsKey("TRANSPARENT")) {
0859: String transparent = (String) model.remove("TRANSPARENT");
0860: if (transparent == null) {
0861: isTransparent = false;
0862: } else if (transparent.equalsIgnoreCase("True")) {
0863: isTransparent = true;
0864: } else if (transparent.equalsIgnoreCase("False")) {
0865: isTransparent = false;
0866: } else {
0867: throw new InconsistentRequestException(
0868: "The 'Transparent' parameter can only have "
0869: + "'True', 'False' values. Here it has '"
0870: + transparent + "'.");
0871: }
0872: }
0873:
0874: return isTransparent;
0875: }
0876:
0877: /**
0878: * Parse 'ScaleDenominator' Parameter.
0879: *
0880: * @param model
0881: * @return String
0882: */
0883: private static int retrieveScaleDenominatorParameter(Map model) {
0884:
0885: int scale = -1;
0886: if (model.containsKey("SCALE")) {
0887: String value = (String) model.remove("SCALE");
0888: if (value != null) {
0889: scale = Integer.parseInt(value);
0890: }
0891: }
0892:
0893: return scale;
0894:
0895: }
0896:
0897: /**
0898: * Parse 'Center' Parameter and create a point.
0899: *
0900: * @param model
0901: * @param srs
0902: * @return Point to represent the x,y coordinates.
0903: * @throws InconsistentRequestException
0904: * @throws UnknownCRSException
0905: */
0906: private static Point retrieveCenterParameter(Map model, String srs)
0907: throws InconsistentRequestException, UnknownCRSException {
0908:
0909: Point center = null;
0910: if (model.containsKey("CENTER")) {
0911: String centerstring = (String) model.remove("CENTER");
0912:
0913: String[] values = centerstring.split(",");
0914: if (values.length != 2) {
0915: throw new InconsistentRequestException(
0916: "Centre should be defined as a Point with 'X' and 'Y' "
0917: + "values. The current length is '"
0918: + values.length + "'. It should "
0919: + "be '2'.");
0920: }
0921: double x = -1;
0922: double y = -1;
0923: try {
0924: x = Double.parseDouble(values[0]);
0925: y = Double.parseDouble(values[1]);
0926: } catch (Exception e) {
0927: throw new InconsistentRequestException(
0928: "Error converting 'X','Y' coordinates in the request "
0929: + "parameter 'CENTER' to double. Please check the "
0930: + "values entered.");
0931: }
0932:
0933: CoordinateSystem crs = CRSFactory.create(srs);
0934: center = GeometryFactory.createPoint(x, y, crs);
0935:
0936: }
0937:
0938: return center;
0939: }
0940:
0941: /**
0942: * Parse 'Envelope' Parameter and create an envelope.
0943: *
0944: * @param model
0945: * @param srs
0946: * @return Envelope
0947: * @throws InconsistentRequestException
0948: * @throws InvalidFormatException
0949: * @throws UnknownCRSException
0950: */
0951: private static Envelope retrieveBBOXParameter(Map model, String srs)
0952: throws InconsistentRequestException,
0953: InvalidFormatException, UnknownCRSException {
0954:
0955: Envelope bbox = null;
0956:
0957: if (model.containsKey("BBOX")) {
0958: String boxstring = (String) model.remove("BBOX");
0959: StringTokenizer st = new StringTokenizer(boxstring, ",");
0960: String s = st.nextToken().replace(' ', '+');
0961: double minx = Double.parseDouble(s);
0962: s = st.nextToken().replace(' ', '+');
0963: double miny = Double.parseDouble(s);
0964: s = st.nextToken().replace(' ', '+');
0965: double maxx = Double.parseDouble(s);
0966: s = st.nextToken().replace(' ', '+');
0967: double maxy = Double.parseDouble(s);
0968:
0969: if (minx >= maxx) {
0970: throw new InvalidFormatException(
0971: "minx must be lesser than maxx");
0972: }
0973:
0974: if (miny >= maxy) {
0975: throw new InvalidFormatException(
0976: "miny must be lesser than maxy");
0977: }
0978:
0979: CoordinateSystem crs = CRSFactory.create(srs);
0980: bbox = GeometryFactory.createEnvelope(minx, miny, maxx,
0981: maxy, crs);
0982: }
0983:
0984: return bbox;
0985: }
0986:
0987: /**
0988: * Parse 'SRS' Parameter.
0989: *
0990: * @param model
0991: * @return String
0992: * @throws InconsistentRequestException
0993: */
0994: private static String retrieveSRSParameter(Map model)
0995: throws InconsistentRequestException {
0996:
0997: String srs = null;
0998: if (model.containsKey("SRS")) {
0999: srs = (String) model.remove("SRS");
1000: }
1001: if (srs == null) {
1002: throw new InconsistentRequestException(
1003: "SRS-value must be set");
1004: }
1005:
1006: return srs;
1007: }
1008:
1009: /**
1010: * Parse 'Layer' and 'Style' Parameter.
1011: *
1012: * @param model
1013: * @return Layer[]
1014: * @throws InconsistentRequestException
1015: */
1016: private static Layer[] retrieveLayerAndStyleParameters(Map model)
1017: throws InconsistentRequestException {
1018:
1019: String layersstring = null;
1020: if (model.containsKey("LAYERS")) {
1021: layersstring = (String) model.remove("LAYERS");
1022: }
1023: String stylesstring = null;
1024: if (model.containsKey("STYLES")) {
1025: stylesstring = (String) model.remove("STYLES");
1026: }
1027:
1028: // normalize styles parameter
1029: if ((stylesstring == null) || stylesstring.trim().equals("")) {
1030: stylesstring = "$DEFAULT";
1031: }
1032: if (stylesstring.startsWith(",")) {
1033: stylesstring = "$DEFAULT" + stylesstring;
1034: }
1035: String tmp = ",$DEFAULT,";
1036: stylesstring = StringTools.replace(stylesstring, ",,", tmp,
1037: true);
1038: if (stylesstring.endsWith(",")) {
1039: stylesstring = stylesstring + "$DEFAULT";
1040: }
1041: List<String> layers = new ArrayList<String>();
1042: List<String> styles = new ArrayList<String>();
1043: GetMap.Layer[] ls = null;
1044: if ((layersstring != null) && !layersstring.trim().equals("")) {
1045: StringTokenizer st = new StringTokenizer(layersstring, ",");
1046: int a = 0;
1047: while (st.hasMoreTokens()) {
1048: String s = st.nextToken();
1049: layers.add(s);
1050: }
1051: st = new StringTokenizer(stylesstring, ",");
1052: for (int i = 0; i < layers.size(); i++) {
1053: styles.add("$DEFAULT");
1054: }
1055: a = 0;
1056: while (st.hasMoreTokens()) {
1057: String s = st.nextToken();
1058: styles.set(a++, s);
1059: }
1060:
1061: // At last, build up the Layer object
1062: ls = new GetMap.Layer[layers.size()];
1063:
1064: for (int i = 0; i < layers.size(); i++) {
1065: try {
1066: String l = URLDecoder.decode(layers.get(i),
1067: CharsetUtils.getSystemCharset());
1068: ls[i] = PrintMap.createLayer(l, styles.get(i));
1069: } catch (UnsupportedEncodingException e2) {
1070: e2.printStackTrace();
1071: }
1072: }
1073: }
1074:
1075: if ((ls == null || ls.length == 0)) {
1076: throw new InconsistentRequestException(
1077: "No layers defined in PrintMapRequest request");
1078: }
1079:
1080: return ls;
1081: }
1082:
1083: /**
1084: * Parse the Request parameter to check if the request is actually a 'PrintMapRequest' request
1085: *
1086: * @param model
1087: * @throws InconsistentRequestException
1088: */
1089: private static void retrieveRequestParameter(Map model)
1090: throws InconsistentRequestException {
1091:
1092: String request = null;
1093: if (model.containsKey("REQUEST")) {
1094: request = (String) model.remove("REQUEST");
1095: } else {
1096: throw new InconsistentRequestException(
1097: "Unable to create a PrintMapRequest operation. "
1098: + "The request parameter is missing.");
1099: }
1100: if (request == null || !(request.equals("PrintMap"))) {
1101: throw new InconsistentRequestException(
1102: "Unable to create a PrintMapRequest operation for request '"
1103: + request + "'.");
1104: }
1105:
1106: }
1107:
1108: /**
1109: * Parse 'Version' Parameter.
1110: *
1111: * @param model
1112: * @return String version (default=1.0.0)
1113: */
1114: private static String retrieveVersionParameter(Map model) {
1115:
1116: String version = null;
1117: if (model.containsKey("VERSION")) {
1118: version = (String) model.remove("VERSION");
1119: }
1120: if (version == null) {
1121: /** default value set as per the WMPS draft specifications. */
1122: version = "1.0.0";
1123: }
1124:
1125: return version;
1126: }
1127:
1128: /**
1129: * Get TimeStamp
1130: *
1131: * @return TimeStamp
1132: */
1133: public Timestamp getTimestamp() {
1134: return this .timestamp;
1135: }
1136:
1137: /**
1138: * Get SRS
1139: *
1140: * @return String
1141: */
1142: public String getSRS() {
1143: return this .srs;
1144: }
1145:
1146: /**
1147: * Get bounding box
1148: *
1149: * @return Envelope maybe null
1150: */
1151: public Envelope getBBOX() {
1152: return this .boundingBox;
1153: }
1154:
1155: /**
1156: * Get center
1157: *
1158: * @return Point maybe null
1159: */
1160: public Point getCenter() {
1161: return this .center;
1162: }
1163:
1164: /**
1165: * Get ScaleDenominator
1166: *
1167: * @return String maybe null
1168: */
1169: public int getScaleDenominator() {
1170: return this .scaleDenominator;
1171: }
1172:
1173: /**
1174: * Get Transparency
1175: *
1176: * @return boolean
1177: */
1178: public boolean getTransparent() {
1179: return this .transparent;
1180: }
1181:
1182: /**
1183: * Get BGColor
1184: *
1185: * @return Color default is White.
1186: */
1187: public Color getBGColor() {
1188: return this .bgColor;
1189: }
1190:
1191: /**
1192: * Get Map Title
1193: *
1194: * @return String maybe null
1195: */
1196: public String getTitle() {
1197: return this .title;
1198: }
1199:
1200: /**
1201: * Get Copyright
1202: *
1203: * @return String maybe null
1204: */
1205: public String getCopyright() {
1206: return this .copyright;
1207: }
1208:
1209: /**
1210: * Get Legend
1211: *
1212: * @return boolean
1213: */
1214: public boolean getLegend() {
1215: return this .legend;
1216: }
1217:
1218: /**
1219: * Get Scale Bar
1220: *
1221: * @return boolean
1222: */
1223: public boolean getScaleBar() {
1224: return this .scaleBar;
1225: }
1226:
1227: /**
1228: * Get Note (extra descriptive text)
1229: *
1230: * @return String maybe null
1231: */
1232: public String getNote() {
1233: return this .note;
1234: }
1235:
1236: /**
1237: * Get Template
1238: *
1239: * @return String
1240: */
1241: public String getTemplate() {
1242: return this .template;
1243: }
1244:
1245: /**
1246: * Get Email Address
1247: *
1248: * @return String
1249: */
1250: public String getEmailAddress() {
1251: return this .emailaddress;
1252: }
1253:
1254: /**
1255: * Get Text Areas
1256: *
1257: * @return TextArea[]
1258: */
1259: public TextArea[] getTextAreas() {
1260: return this .textAreas;
1261: }
1262:
1263: /**
1264: * Retrieve ( if available ) the current text area identified by 'name' from the list of text
1265: * areas defined. May return null.
1266: *
1267: * @param name
1268: * @return TextArea
1269: */
1270: public TextArea getTextArea(String name) {
1271:
1272: TextArea textArea = null;
1273: if (this .textAreas != null && this .textAreas.length > 0) {
1274: for (int i = 0; i < this .textAreas.length; i++) {
1275: TextArea tmp = this .textAreas[i];
1276: if (tmp.getName().equalsIgnoreCase(name)) {
1277: textArea = tmp;
1278: break;
1279: }
1280: }
1281: }
1282:
1283: return textArea;
1284: }
1285:
1286: /**
1287: * creates a Layer object beacuse of the inner class construct.
1288: *
1289: * @param name
1290: * the name of the layer
1291: * @param style
1292: * the corresponding style of the layer
1293: * @return Layer a layer object constaining name and style
1294: */
1295: public static Layer createLayer(String name, String style) {
1296: return new Layer(name, style);
1297: }
1298:
1299: /**
1300: * Returns a new PrintMap instance.
1301: *
1302: * @param id
1303: * @param version
1304: * @param layers
1305: * @param srs
1306: * @param bbox
1307: * @param center
1308: * @param scaleDenominator
1309: * @param transparent
1310: * @param bgColor
1311: * @param title
1312: * @param copyright
1313: * @param legend
1314: * @param scaleBar
1315: * @param note
1316: * @param template
1317: * @param emailAddress
1318: * @param timestamp
1319: * @param textAreas
1320: * @param vendorSpecificParameters
1321: * @return PrintMap
1322: */
1323: public static PrintMap create(String id, String version,
1324: Layer[] layers, String srs, Envelope bbox, Point center,
1325: int scaleDenominator, boolean transparent, Color bgColor,
1326: String title, String copyright, boolean legend,
1327: boolean scaleBar, String note, String template,
1328: String emailAddress, Timestamp timestamp,
1329: TextArea[] textAreas,
1330: Map<String, String> vendorSpecificParameters) {
1331:
1332: return new PrintMap(id, version, layers, srs, bbox, center,
1333: scaleDenominator, transparent, bgColor, title,
1334: copyright, legend, scaleBar, note, template,
1335: emailAddress, timestamp, textAreas,
1336: vendorSpecificParameters);
1337: }
1338:
1339: /**
1340: * Overwrite the toString() method to export the current request as a readable statement.
1341: * Currently only the id, version and layer names will be given out. TODO the rest
1342: *
1343: * @return String
1344: */
1345: @Override
1346: public String toString() {
1347:
1348: StringBuffer sb = new StringBuffer(200);
1349: sb.append("id: ");
1350: sb.append(getId());
1351: sb.append("\n");
1352: sb.append("version: ");
1353: sb.append(getVersion());
1354: sb.append("\n");
1355: if (this .layers != null) {
1356: sb.append("layer(s): ");
1357: for (int i = 0; i < this .layers.size(); i++) {
1358: sb.append(this .layers.get(i).getName());
1359: sb.append("\n");
1360: }
1361: }
1362: return sb.toString();
1363: }
1364: }
|