diff --git a/deegree-core/deegree-core-commons/src/main/java/org/deegree/commons/xml/CommonNamespaces.java b/deegree-core/deegree-core-commons/src/main/java/org/deegree/commons/xml/CommonNamespaces.java index f483fc4302..401d4d6649 100644 --- a/deegree-core/deegree-core-commons/src/main/java/org/deegree/commons/xml/CommonNamespaces.java +++ b/deegree-core/deegree-core-commons/src/main/java/org/deegree/commons/xml/CommonNamespaces.java @@ -90,6 +90,11 @@ public class CommonNamespaces { */ public static final String OWS_11_NS = "http://www.opengis.net/ows/1.1"; + /** + * The OWS_11_NS namespace is bound to: "http://www.opengis.net/ows/2.0" + */ + public static final String OWS_20_NS = "http://www.opengis.net/ows/2.0"; + /** * The ISO19115NS namespace is bound to: "http://schemas.opengis.net/iso19115full" */ diff --git a/deegree-core/deegree-core-commons/src/main/java/org/deegree/commons/xml/stax/XMLStreamUtils.java b/deegree-core/deegree-core-commons/src/main/java/org/deegree/commons/xml/stax/XMLStreamUtils.java index 1bf2d8a598..bc9a32a9c2 100644 --- a/deegree-core/deegree-core-commons/src/main/java/org/deegree/commons/xml/stax/XMLStreamUtils.java +++ b/deegree-core/deegree-core-commons/src/main/java/org/deegree/commons/xml/stax/XMLStreamUtils.java @@ -748,6 +748,29 @@ public static double getRequiredElementTextAsDouble( XMLStreamReader reader, QNa return result; } + /** + * Returns the text in the required element as a inz. If the name of the reader does not match the given qName, an + * exception will be thrown. If the value is not a double, an exception will be thrown. Post: reader will be + * unchanged or at {@link XMLStreamConstants #END_ELEMENT} of the matching element or at + * {@link XMLStreamConstants #START_ELEMENT} of the next element if requested. + * + * @param reader + * @param elementName + * @param nextElemOnSucces + * if true the reader will be move to the next element if the operation was successful. + * @return the double value of the required element. + * @throws XMLStreamException + */ + public static int getRequiredElementTextAsInteger( XMLStreamReader reader, QName elementName, + boolean nextElemOnSucces ) + throws XMLStreamException { + if ( !elementName.equals( reader.getName() ) ) { + throw new XMLParsingException( reader, "The current element: " + reader.getName() + " is not expected: " + + elementName ); + } + return getElementTextAsInteger( reader ); + } + /** * Move the reader to the first element which matches the given name. The reader will be positioned on the * {@link XMLStreamConstants#START_ELEMENT} event or after the {@link XMLStreamConstants#END_DOCUMENT} which ever diff --git a/deegree-core/deegree-core-protocol/deegree-protocol-commons/src/main/java/org/deegree/protocol/ows/OWSCommonXMLAdapter.java b/deegree-core/deegree-core-protocol/deegree-protocol-commons/src/main/java/org/deegree/protocol/ows/OWSCommonXMLAdapter.java index 9ea72a2380..cc7edf6ea2 100644 --- a/deegree-core/deegree-core-protocol/deegree-protocol-commons/src/main/java/org/deegree/protocol/ows/OWSCommonXMLAdapter.java +++ b/deegree-core/deegree-core-protocol/deegree-protocol-commons/src/main/java/org/deegree/protocol/ows/OWSCommonXMLAdapter.java @@ -72,6 +72,11 @@ public class OWSCommonXMLAdapter extends XMLAdapter { */ public static final String OWS110_NS = "http://www.opengis.net/ows/1.1"; + /** + * ows 2.0 version + */ + public static final String OWS200_NS = "http://www.opengis.net/ows/2.0"; + /** * normal xml namespace */ @@ -87,6 +92,11 @@ public class OWSCommonXMLAdapter extends XMLAdapter { */ public static final String OWS110_PREFIX = "ows110"; + /** + * the ows 2.0.0 prefix + */ + public static final String OWS200_PREFIX = "ows200"; + /** * the xml prefix */ @@ -98,9 +108,10 @@ public class OWSCommonXMLAdapter extends XMLAdapter { // add to common namespaces from xml adapter nsContext.addNamespace( OWS_PREFIX, OWS_NS ); nsContext.addNamespace( OWS110_PREFIX, OWS110_NS ); + nsContext.addNamespace( OWS200_PREFIX, OWS200_NS ); nsContext.addNamespace( XML_PREFIX, XML_NS ); } - + /** * Parses the given element of type ows:BoundingBoxType. * @@ -282,5 +293,5 @@ public static void exportPositionType( XMLStreamWriter writer, Point pos ) writer.writeCharacters( "" + coord ); needsDelim = true; } - } + } } diff --git a/deegree-core/deegree-core-protocol/deegree-protocol-commons/src/main/java/org/deegree/protocol/ows/getcapabilities/GetCapabilitiesXMLParser.java b/deegree-core/deegree-core-protocol/deegree-protocol-commons/src/main/java/org/deegree/protocol/ows/getcapabilities/GetCapabilitiesXMLParser.java index ed159a58e9..13f9fad474 100644 --- a/deegree-core/deegree-core-protocol/deegree-protocol-commons/src/main/java/org/deegree/protocol/ows/getcapabilities/GetCapabilitiesXMLParser.java +++ b/deegree-core/deegree-core-protocol/deegree-protocol-commons/src/main/java/org/deegree/protocol/ows/getcapabilities/GetCapabilitiesXMLParser.java @@ -160,6 +160,29 @@ public GetCapabilities parse110() return new GetCapabilities( null, Arrays.asList( versions ), sections, formats, updateSequence, languages ); } + /** + * Parses an OWS 2.0.0 GetCapabilitiesType into a {@link GetCapabilities} object. + * + * @return GetCapabilities object corresponding to the input document + * @throws XMLParsingException + * if the document contains syntactic or semantic errors + */ + public GetCapabilities parse200() + throws XMLParsingException { + // @updateSequence (optional) + String updateSequence = rootElement.getAttributeValue( new QName( "updateSequence" ) ); + // ows200:AcceptVersions (optional) + String[] versions = getNodesAsStrings( rootElement, new XPath( "ows200:AcceptVersions/ows200:Version/text()", + nsContext ) ); + // ows200:Sections (optional) + List sections = parseSections( OWS200_PREFIX ); + // ows200:AcceptFormats (optional) + List formats = parse200Formats(); + // ows200:AcceptLanguages (optional) + List languages = parse200Languages(); + return new GetCapabilities( null, Arrays.asList( versions ), sections, formats, updateSequence, languages ); + } + /** * @return all parsed Sections */ @@ -180,4 +203,26 @@ private List parseSections( String nsPrefix ) { } return sections; } -} + + private List parse200Formats() { + List formatElements = getElements( rootElement, + new XPath( "ows200:AcceptFormats/ows200:OutputFormat", nsContext ) ); + List formats = new ArrayList( formatElements.size() ); + for ( OMElement formatElement : formatElements ) { + formats.add( formatElement.getText() ); + } + return formats; + } + + private List parse200Languages() { + List languageElements = getElements( rootElement, + new XPath( "ows200:AcceptLanguages/ows200:Language", nsContext ) ); + List languages = new ArrayList(); + for ( OMElement languageElement : languageElements ) { + String language = languageElement.getText(); + languages.add( language ); + } + return languages; + } + +} \ No newline at end of file diff --git a/deegree-core/deegree-core-protocol/deegree-protocol-commons/src/test/java/org/deegree/protocol/ows/capabilities/GetCapabilitiesXMLParserTest.java b/deegree-core/deegree-core-protocol/deegree-protocol-commons/src/test/java/org/deegree/protocol/ows/getcapabilities/GetCapabilitiesXMLParserTest.java similarity index 68% rename from deegree-core/deegree-core-protocol/deegree-protocol-commons/src/test/java/org/deegree/protocol/ows/capabilities/GetCapabilitiesXMLParserTest.java rename to deegree-core/deegree-core-protocol/deegree-protocol-commons/src/test/java/org/deegree/protocol/ows/getcapabilities/GetCapabilitiesXMLParserTest.java index dd0a215d98..f7b59753ed 100644 --- a/deegree-core/deegree-core-protocol/deegree-protocol-commons/src/test/java/org/deegree/protocol/ows/capabilities/GetCapabilitiesXMLParserTest.java +++ b/deegree-core/deegree-core-protocol/deegree-protocol-commons/src/test/java/org/deegree/protocol/ows/getcapabilities/GetCapabilitiesXMLParserTest.java @@ -2,9 +2,9 @@ /*---------------------------------------------------------------------------- This file is part of deegree, http://deegree.org/ Copyright (C) 2001-2009 by: - Department of Geography, University of Bonn + Department of Geography, University of Bonn and - lat/lon GmbH + lat/lon GmbH This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free @@ -32,27 +32,30 @@ http://www.geographie.uni-bonn.de/deegree/ e-mail: info@deegree.org -----------------------------------------------------------------------------*/ -package org.deegree.protocol.ows.capabilities; + ----------------------------------------------------------------------------*/ +package org.deegree.protocol.ows.getcapabilities; +import static org.hamcrest.CoreMatchers.hasItems; +import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import java.net.URL; +import java.util.List; +import java.util.Set; import org.deegree.commons.tom.ows.Version; -import org.deegree.protocol.ows.getcapabilities.GetCapabilities; -import org.deegree.protocol.ows.getcapabilities.GetCapabilitiesXMLParser; import org.junit.Test; /** * Test cases for {@link GetCapabilitiesXMLParser}. - * + * * @author Markus Schneider * @author last edited by: $Author:$ - * + * * @version $Revision:$, $Date:$ */ public class GetCapabilitiesXMLParserTest { @@ -62,7 +65,7 @@ public class GetCapabilitiesXMLParserTest { */ @Test public void testParsing100() { - URL docURL = GetCapabilitiesXMLParserTest.class.getResource( "GetCapabilitiesOWS100.xml" ); + URL docURL = GetCapabilitiesXMLParserTest.class.getResource( "../capabilities/GetCapabilitiesOWS100.xml" ); GetCapabilitiesXMLParser parser = new GetCapabilitiesXMLParser(); parser.load( docURL ); GetCapabilities request = parser.parse100(); @@ -71,8 +74,8 @@ public void testParsing100() { // check accept versions assertNotNull( request.getAcceptVersions() ); assertEquals( 2, request.getAcceptVersions().size() ); - assertEquals( Version.parseVersion( "1.0.0" ), request.getAcceptVersionsAsVersions().get(1) ); - assertEquals( Version.parseVersion( "1.1.0" ), request.getAcceptVersionsAsVersions().get(0) ); + assertEquals( Version.parseVersion( "1.0.0" ), request.getAcceptVersionsAsVersions().get( 1 ) ); + assertEquals( Version.parseVersion( "1.1.0" ), request.getAcceptVersionsAsVersions().get( 0 ) ); // check sections assertNotNull( request.getSections() ); @@ -94,7 +97,7 @@ public void testParsing100() { */ @Test public void testParsing110() { - URL docURL = GetCapabilitiesXMLParserTest.class.getResource( "GetCapabilitiesOWS110.xml" ); + URL docURL = GetCapabilitiesXMLParserTest.class.getResource( "../capabilities/GetCapabilitiesOWS110.xml" ); GetCapabilitiesXMLParser parser = new GetCapabilitiesXMLParser(); parser.load( docURL ); GetCapabilities request = parser.parse110(); @@ -103,8 +106,8 @@ public void testParsing110() { // check accept versions assertNotNull( request.getAcceptVersions() ); assertEquals( 3, request.getAcceptVersions().size() ); - assertEquals( Version.parseVersion( "1.0.0" ), request.getAcceptVersionsAsVersions().get(0) ); - assertEquals( Version.parseVersion( "2.0.0" ), request.getAcceptVersionsAsVersions().get(1) ); + assertEquals( Version.parseVersion( "1.0.0" ), request.getAcceptVersionsAsVersions().get( 0 ) ); + assertEquals( Version.parseVersion( "2.0.0" ), request.getAcceptVersionsAsVersions().get( 1 ) ); // check sections assertNotNull( request.getSections() ); @@ -120,4 +123,38 @@ public void testParsing110() { assertNull( request.getUpdateSequence() ); } -} + + /** + * Tests the parsing of an OWS 2.0.0 GetCapabilities document. + */ + @Test + public void testParsing200() { + URL docURL = GetCapabilitiesXMLParserTest.class.getResource( "../capabilities/GetCapabilitiesOWS200.xml" ); + GetCapabilitiesXMLParser parser = new GetCapabilitiesXMLParser(); + parser.load( docURL ); + GetCapabilities request = parser.parse200(); + + // check accept versions + List acceptVersions = request.getAcceptVersions(); + assertThat( acceptVersions.size(), is( 3 ) ); + assertThat( acceptVersions, hasItems( "1.0.0", "2.0.0", "1.1.0" ) ); + + // check sections + Set sections = request.getSections(); + assertThat( sections.size(), is( 3 ) ); + assertThat( sections, hasItems( "ServiceIdentification", "ServiceProvider", "OperationsMetadata" ) ); + + // check accept formats + Set acceptFormats = request.getAcceptFormats(); + assertThat( acceptFormats.size(), is( 1 ) ); + assertThat( acceptFormats, hasItems( "text/xml" ) ); + + // check accept formats + List acceptLanguages = request.getAcceptLanguages(); + assertThat( acceptLanguages.size(), is( 2 ) ); + assertThat( acceptLanguages, hasItems( "en", "de" ) ); + + assertThat( request.getUpdateSequence(), is( "2" ) ); + } + +} \ No newline at end of file diff --git a/deegree-core/deegree-core-protocol/deegree-protocol-commons/src/test/resources/org/deegree/protocol/ows/capabilities/GetCapabilitiesOWS200.xml b/deegree-core/deegree-core-protocol/deegree-protocol-commons/src/test/resources/org/deegree/protocol/ows/capabilities/GetCapabilitiesOWS200.xml new file mode 100644 index 0000000000..6109561c27 --- /dev/null +++ b/deegree-core/deegree-core-protocol/deegree-protocol-commons/src/test/resources/org/deegree/protocol/ows/capabilities/GetCapabilitiesOWS200.xml @@ -0,0 +1,22 @@ + + + + 1.0.0 + 2.0.0 + 1.1.0 + + +
ServiceIdentification
+
ServiceProvider
+
OperationsMetadata
+
+ + text/xml + + + en + de + +
diff --git a/deegree-core/deegree-core-protocol/deegree-protocol-wms/pom.xml b/deegree-core/deegree-core-protocol/deegree-protocol-wms/pom.xml index bf16b5059c..b779d05366 100644 --- a/deegree-core/deegree-core-protocol/deegree-protocol-wms/pom.xml +++ b/deegree-core/deegree-core-protocol/deegree-protocol-wms/pom.xml @@ -57,5 +57,9 @@ junit junit + + org.mockito + mockito-core + diff --git a/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/AbstractWmsParser.java b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/AbstractWmsParser.java new file mode 100644 index 0000000000..03776a860e --- /dev/null +++ b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/AbstractWmsParser.java @@ -0,0 +1,77 @@ +//$HeadURL$ +/*---------------------------------------------------------------------------- + This file is part of deegree, http://deegree.org/ + Copyright (C) 2001-2015 by: + - Department of Geography, University of Bonn - + and + - lat/lon GmbH - + + This library is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at your option) + any later version. + This library is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + details. + You should have received a copy of the GNU Lesser General Public License + along with this library; if not, write to the Free Software Foundation, Inc., + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Contact information: + + lat/lon GmbH + Aennchenstr. 19, 53177 Bonn + Germany + http://lat-lon.de/ + + Department of Geography, University of Bonn + Prof. Dr. Klaus Greve + Postfach 1147, 53001 Bonn + Germany + http://www.geographie.uni-bonn.de/deegree/ + + e-mail: info@deegree.org + ----------------------------------------------------------------------------*/ +package org.deegree.protocol.wms; + +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.deegree.commons.tom.ows.Version; +import org.deegree.commons.utils.kvp.InvalidParameterValueException; +import org.deegree.commons.xml.CommonNamespaces; +import org.deegree.commons.xml.stax.XMLStreamUtils; + +/** + * Contains common methods for WMS Parsers. + * + * @author Lyn Goltz + */ +public class AbstractWmsParser { + + private static final String VERSION_130 = "1.3.0"; + + /** + * Skips to the start elment of the documents and checks the version attribute. + * + * @param request + * WMS request, never null + * @return the version from the document, if version is null the namespace is evaluated, never null + * @throws XMLStreamException + * if an exeption occured during parsing + * @throw {@link InvalidParameterValueException} if the version could not be parsed + */ + protected Version forwardToStartAndDetermineVersion( XMLStreamReader request ) + throws XMLStreamException { + XMLStreamUtils.skipStartDocument( request ); + String versionAttributeValue = request.getAttributeValue( null, "version" ); + if ( CommonNamespaces.WMSNS.equals( request.getNamespaceURI() ) ) { + if ( versionAttributeValue.isEmpty() ) { + versionAttributeValue = VERSION_130; + } + } + return Version.parseVersion( versionAttributeValue ); + } + +} \ No newline at end of file diff --git a/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/capabilities/GetCapabilitiesXMLAdapter.java b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/capabilities/GetCapabilitiesXMLAdapter.java new file mode 100644 index 0000000000..4e63d88fd7 --- /dev/null +++ b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/capabilities/GetCapabilitiesXMLAdapter.java @@ -0,0 +1,82 @@ +//$HeadURL$ +/*---------------------------------------------------------------------------- + This file is part of deegree, http://deegree.org/ + Copyright (C) 2001-2009 by: + Department of Geography, University of Bonn + and + lat/lon GmbH + + This library is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at your option) + any later version. + This library is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + details. + You should have received a copy of the GNU Lesser General Public License + along with this library; if not, write to the Free Software Foundation, Inc., + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Contact information: + + lat/lon GmbH + Aennchenstr. 19, 53177 Bonn + Germany + http://lat-lon.de/ + + Department of Geography, University of Bonn + Prof. Dr. Klaus Greve + Postfach 1147, 53001 Bonn + Germany + http://www.geographie.uni-bonn.de/deegree/ + + e-mail: info@deegree.org + ----------------------------------------------------------------------------*/ +package org.deegree.protocol.wms.capabilities; + +import static org.deegree.protocol.wms.WMSConstants.VERSION_130; + +import org.deegree.commons.tom.ows.Version; +import org.deegree.commons.xml.CommonNamespaces; +import org.deegree.protocol.ows.getcapabilities.GetCapabilities; +import org.deegree.protocol.ows.getcapabilities.GetCapabilitiesXMLParser; + +/** + * Adapter between XML encoded GetCapabilities requests (WMS) and {@link GetCapabilities} objects. + * + * @author Lyn Goltz + */ +public class GetCapabilitiesXMLAdapter extends GetCapabilitiesXMLParser { + + /** + * Parses a WMS GetCapabilities document into a {@link GetCapabilities} request. + *

+ * Supported versions: + *

    + *
  • 1.3.0 (OWS 2.0.0)
  • + *
+ * + * @param version + * specifies the request version, may be null (version attribute is evaluated then) + * @return parsed {@link GetCapabilities} request, never null + * @throws IllegalArgumentException + * if version is not supported + */ + public GetCapabilities parse( Version version ) { + Version wmsVersion = detectVersion( version ); + if ( VERSION_130.equals( wmsVersion ) ) + return parse200(); + throw new IllegalArgumentException( "Cannot parse Caapbilities request: Unsupported Version" ); + + } + + private Version detectVersion( Version version ) { + if ( version != null ) + return version; + else if ( CommonNamespaces.OWS_20_NS.equals( getRootElement().getNamespace().getNamespaceURI() ) ) + return VERSION_130; + return null; + } + +} \ No newline at end of file diff --git a/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/featureinfo/GetFeatureInfoParser.java b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/featureinfo/GetFeatureInfoParser.java new file mode 100644 index 0000000000..e54cbe7cb1 --- /dev/null +++ b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/featureinfo/GetFeatureInfoParser.java @@ -0,0 +1,202 @@ +//$HeadURL$ +/*---------------------------------------------------------------------------- + This file is part of deegree, http://deegree.org/ + Copyright (C) 2001-2015 by: + - Department of Geography, University of Bonn - + and + - lat/lon GmbH - + + This library is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at your option) + any later version. + This library is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + details. + You should have received a copy of the GNU Lesser General Public License + along with this library; if not, write to the Free Software Foundation, Inc., + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Contact information: + + lat/lon GmbH + Aennchenstr. 19, 53177 Bonn + Germany + http://lat-lon.de/ + + Department of Geography, University of Bonn + Prof. Dr. Klaus Greve + Postfach 1147, 53001 Bonn + Germany + http://www.geographie.uni-bonn.de/deegree/ + + e-mail: info@deegree.org + ----------------------------------------------------------------------------*/ +package org.deegree.protocol.wms.featureinfo; + +import static org.deegree.commons.xml.CommonNamespaces.OWS_NS; +import static org.deegree.commons.xml.CommonNamespaces.SLDNS; +import static org.deegree.commons.xml.stax.XMLStreamUtils.getText; +import static org.deegree.commons.xml.stax.XMLStreamUtils.nextElement; +import static org.deegree.commons.xml.stax.XMLStreamUtils.skipElement; +import static org.deegree.commons.xml.stax.XMLStreamUtils.skipToRequiredElement; + +import java.security.InvalidParameterException; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.deegree.commons.ows.exception.OWSException; +import org.deegree.commons.tom.ows.Version; +import org.deegree.commons.xml.stax.XMLStreamUtils; +import org.deegree.cs.exceptions.UnknownCRSException; +import org.deegree.protocol.wms.AbstractWmsParser; +import org.deegree.protocol.wms.WMSConstants; +import org.deegree.protocol.wms.map.GetMapParser; +import org.deegree.protocol.wms.ops.GetFeatureInfo; +import org.deegree.protocol.wms.ops.GetMap; + +/** + * Adapter between XML GetFeatureInfo requests and {@link GetFeatureInfo} objects. + *

+ * Supported WMS versions: + *

    + *
  • 1.3.0
  • + *
+ *

+ * + * @author Lyn Goltz + */ +public class GetFeatureInfoParser extends AbstractWmsParser { + + private static final QName QUERYLAYER_ELEMENT = new QName( OWS_NS, "QueryLayer" ); + + private static final QName I_ELEMENT = new QName( OWS_NS, "I" ); + + private static final QName J_ELEMENT = new QName( OWS_NS, "J" ); + + private static final QName Output_ELEMENT = new QName( OWS_NS, "Output" ); + + private static final QName InfoFormat_ELEMENT = new QName( OWS_NS, "InfoFormat" ); + + private static final QName FeatureCount_ELEMENT = new QName( OWS_NS, "FeatureCount" ); + + private static final QName Exceptions_ELEMENT = new QName( OWS_NS, "Exceptions" ); + + /** + * Parses a WMS GetFeatureInfo document into a {@link GetFeatureInfo} object. + * + *

+ * Supported WMS versions: + *

    + *
  • 1.3.0
  • + *
+ *

+ * + * @return parsed {@link GetFeatureInfo} request, never null + * @throws XMLStreamException + * if an error occurs during parsing the xml + * @throws InvalidParameterException + * if the request version is not supported + * @throws OWSException + * if the CRS is not supported or an error occurred during parsing a value + */ + public GetFeatureInfo parse( XMLStreamReader getMap ) + throws OWSException, XMLStreamException { + Version version = forwardToStartAndDetermineVersion( getMap ); + if ( !WMSConstants.VERSION_130.equals( version ) ) + throw new InvalidParameterException( "Version " + version + " is not supported (yet)." ); + try { + return parse130( getMap ); + } catch ( UnknownCRSException e ) { + throw new OWSException( e.getMessage(), OWSException.NO_APPLICABLE_CODE ); + } catch ( ParseException e ) { + throw new OWSException( e.getMessage(), OWSException.NO_APPLICABLE_CODE ); + } + } + + private GetFeatureInfo parse130( XMLStreamReader in ) + throws UnknownCRSException, XMLStreamException, OWSException, ParseException { + skipToRequiredElement( in, new QName( SLDNS, "GetMap" ) ); + + GetMapParser getMapParser = new GetMapParser(); + GetMap parsedGetMap = getMapParser.parse( in ); + + skipToRequiredElement( in, QUERYLAYER_ELEMENT ); + List queryLayers = parseQueryLayers( in ); + + skipToRequiredElement( in, I_ELEMENT ); + int i = XMLStreamUtils.getRequiredElementTextAsInteger( in, I_ELEMENT, true ); + + skipToRequiredElement( in, J_ELEMENT ); + int j = XMLStreamUtils.getRequiredElementTextAsInteger( in, J_ELEMENT, true ); + + skipToRequiredElement( in, Output_ELEMENT ); + Output output = parseOutput( in ); + String exceptions = parseExceptions( in ); + + return createGetFeatureInfo( parsedGetMap, queryLayers, i, j, output, exceptions ); + } + + private GetFeatureInfo createGetFeatureInfo( GetMap getMap, List queryLayers, int i, int j, Output output, + String exceptions ) + throws OWSException { + HashMap parameterMap = new HashMap(); + if ( exceptions != null ) + parameterMap.put( "EXCEPTIONS", exceptions ); + return new GetFeatureInfo( getMap.getLayers(), getMap.getStyles(), queryLayers, getMap.getWidth(), + getMap.getHeight(), i, j, getMap.getBoundingBox(), getMap.getCoordinateSystem(), + output.featureCount, output.infoFormat, parameterMap, getMap.getDimensions() ); + } + + private List parseQueryLayers( XMLStreamReader in ) + throws XMLStreamException { + List queryLayers = new ArrayList(); + while ( QUERYLAYER_ELEMENT.equals( in.getName() ) ) { + String queryLayer = getText( in, QUERYLAYER_ELEMENT, null, true ); + if ( queryLayer != null ) + queryLayers.add( queryLayer ); + } + return queryLayers; + } + + private Output parseOutput( XMLStreamReader in ) + throws XMLStreamException { + skipToRequiredElement( in, InfoFormat_ELEMENT ); + String infoFormat = getText( in, InfoFormat_ELEMENT, null, true ); + int featureCount = 1; + if ( FeatureCount_ELEMENT.equals( in.getName() ) ) { + featureCount = XMLStreamUtils.getElementTextAsInteger( in ); + nextElement( in ); + } + skipElement( in ); + nextElement( in ); + return new Output( infoFormat, featureCount ); + } + + private String parseExceptions( XMLStreamReader in ) + throws XMLStreamException { + if ( Exceptions_ELEMENT.equals( in.getName() ) ) + return getText( in, Exceptions_ELEMENT, null, true ); + return null; + } + + private class Output { + + String infoFormat; + + int featureCount; + + public Output( String infoFormat, int featureCount ) { + this.infoFormat = infoFormat; + this.featureCount = featureCount; + } + + } +} \ No newline at end of file diff --git a/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/map/GetMapParser.java b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/map/GetMapParser.java new file mode 100644 index 0000000000..e441c54885 --- /dev/null +++ b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/map/GetMapParser.java @@ -0,0 +1,334 @@ +//$HeadURL$ +/*---------------------------------------------------------------------------- + This file is part of deegree, http://deegree.org/ + Copyright (C) 2001-2015 by: + - Department of Geography, University of Bonn - + and + - lat/lon GmbH - + + This library is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at your option) + any later version. + This library is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + details. + You should have received a copy of the GNU Lesser General Public License + along with this library; if not, write to the Free Software Foundation, Inc., + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Contact information: + + lat/lon GmbH + Aennchenstr. 19, 53177 Bonn + Germany + http://lat-lon.de/ + + Department of Geography, University of Bonn + Prof. Dr. Klaus Greve + Postfach 1147, 53001 Bonn + Germany + http://www.geographie.uni-bonn.de/deegree/ + + e-mail: info@deegree.org + ----------------------------------------------------------------------------*/ +package org.deegree.protocol.wms.map; + +import static java.awt.Color.WHITE; +import static org.deegree.commons.xml.CommonNamespaces.OWS_NS; +import static org.deegree.commons.xml.CommonNamespaces.SLDNS; +import static org.deegree.commons.xml.CommonNamespaces.WMSNS; +import static org.deegree.commons.xml.stax.XMLStreamUtils.getElementTextAsDouble; +import static org.deegree.commons.xml.stax.XMLStreamUtils.getRequiredElementTextAsDouble; +import static org.deegree.commons.xml.stax.XMLStreamUtils.getRequiredElementTextAsInteger; +import static org.deegree.commons.xml.stax.XMLStreamUtils.getRequiredText; +import static org.deegree.commons.xml.stax.XMLStreamUtils.getText; +import static org.deegree.commons.xml.stax.XMLStreamUtils.nextElement; +import static org.deegree.commons.xml.stax.XMLStreamUtils.skipElement; +import static org.deegree.commons.xml.stax.XMLStreamUtils.skipToRequiredElement; + +import java.awt.Color; +import java.security.InvalidParameterException; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.deegree.commons.ows.exception.OWSException; +import org.deegree.commons.tom.datetime.DateTime; +import org.deegree.commons.tom.datetime.ISO8601Converter; +import org.deegree.commons.tom.ows.Version; +import org.deegree.commons.xml.stax.XMLStreamUtils; +import org.deegree.cs.coordinatesystems.ICRS; +import org.deegree.cs.exceptions.UnknownCRSException; +import org.deegree.cs.persistence.CRSManager; +import org.deegree.geometry.Envelope; +import org.deegree.geometry.SimpleGeometryFactory; +import org.deegree.layer.LayerRef; +import org.deegree.layer.dims.DimensionInterval; +import org.deegree.protocol.wms.AbstractWmsParser; +import org.deegree.protocol.wms.WMSConstants; +import org.deegree.protocol.wms.ops.GetMap; +import org.deegree.protocol.wms.ops.SLDParser; +import org.deegree.protocol.wms.sld.StyleContainer; +import org.deegree.protocol.wms.sld.StylesContainer; +import org.deegree.style.StyleRef; + +/** + * Adapter between XML GetMap requests and {@link GetMap} objects. + *

+ * Supported WMS versions: + *

    + *
  • 1.3.0
  • + *
+ *

+ * + * @author Lyn Goltz + */ +public class GetMapParser extends AbstractWmsParser { + + private static final SimpleGeometryFactory GEOMETRY_FACTORY = new SimpleGeometryFactory(); + + /** + * Parses a WMS GetMap document into a {@link GetMap} object. + * + *

+ * Supported WMS versions: + *

    + *
  • 1.3.0
  • + *
+ *

+ * + * @return parsed {@link GetMap} request, never null + * @throws XMLStreamException + * if an error occurs during parsing the xml + * @throws InvalidParameterException + * if the request version is not supported + * @throws OWSException + * if the CRS is not supported or an error occurred during parsing a value + */ + public GetMap parse( XMLStreamReader getMap ) + throws OWSException, XMLStreamException { + Version version = forwardToStartAndDetermineVersion( getMap ); + if ( !WMSConstants.VERSION_130.equals( version ) ) + throw new InvalidParameterException( "Version " + version + " is not supported (yet)." ); + try { + return parse130( getMap ); + } catch ( UnknownCRSException e ) { + throw new OWSException( e.getMessage(), OWSException.NO_APPLICABLE_CODE ); + } catch ( ParseException e ) { + throw new OWSException( e.getMessage(), OWSException.NO_APPLICABLE_CODE ); + } + } + + private GetMap parse130( XMLStreamReader in ) + throws UnknownCRSException, XMLStreamException, OWSException, ParseException { + skipToRequiredElement( in, new QName( SLDNS, "StyledLayerDescriptor" ) ); + StylesContainer parsedStyles = SLDParser.parse( in ); + List layers = new ArrayList(); + List styles = new ArrayList(); + for ( StyleContainer style : parsedStyles.getStyles() ) { + layers.add( style.getLayerRef() ); + styles.add( style.getStyleRef() ); + } + + skipToRequiredElement( in, new QName( SLDNS, "CRS" ) ); + ICRS crs = parseCRS( in ); + + skipToRequiredElement( in, new QName( SLDNS, "BoundingBox" ) ); + Envelope envelope = parseBoundingBox( in ); + + skipToRequiredElement( in, new QName( SLDNS, "Output" ) ); + Output output = parseOutput( in ); + + Map parameterMap = new HashMap(); + parameterMap.put( "EXCEPTIONS", parseExceptions( in ) ); + + Map> dimensions = parseDimensions( in ); + + return createGetMap( layers, styles, crs, envelope, output, parameterMap, dimensions ); + } + + private GetMap createGetMap( List layers, List styles, ICRS crs, Envelope envelope, + Output output, Map parameterMap, Map> dimensions ) { + int width = output.width; + int height = output.height; + String format = output.format; + boolean transparent = output.transparent; + Color color = output.bgcolor; + return new GetMap( layers, styles, width, height, envelope, crs, format, transparent, color, parameterMap, + dimensions ); + } + + private Output parseOutput( XMLStreamReader in ) + throws XMLStreamException, OWSException { + skipToRequiredElement( in, new QName( SLDNS, "Size" ) ); + skipToRequiredElement( in, new QName( SLDNS, "Width" ) ); + int width = getRequiredElementTextAsInteger( in, new QName( SLDNS, "Width" ), true ); + skipToRequiredElement( in, new QName( SLDNS, "Height" ) ); + int height = getRequiredElementTextAsInteger( in, new QName( SLDNS, "Height" ), true ); + skipToRequiredElement( in, new QName( WMSNS, "Format" ) ); + String format = getRequiredText( in, new QName( WMSNS, "Format" ), true ); + + boolean transparent = false; + if ( in.getName().equals( new QName( SLDNS, "Transparent" ) ) ) + transparent = XMLStreamUtils.getElementTextAsBoolean( in, new QName( SLDNS, "Transparent" ), false, true ); + + Color bgcolor = Color.WHITE; + if ( in.getName().equals( new QName( SLDNS, "BGcolor" ) ) ) + bgcolor = parseColor( in ); + + skipElement( in ); + nextElement( in ); + return new Output( width, height, format, transparent, bgcolor ); + } + + private Color parseColor( XMLStreamReader in ) + throws XMLStreamException, OWSException { + String bgcolor = XMLStreamUtils.getText( in, new QName( SLDNS, "BGcolor" ), null, true ); + if ( bgcolor == null ) + return WHITE; + try { + return Color.decode( bgcolor ); + } catch ( NumberFormatException e ) { + throw new OWSException( "Could not parse BGcolor '" + bgcolor + "' as color.", + OWSException.NO_APPLICABLE_CODE ); + } + } + + private String parseExceptions( XMLStreamReader in ) + throws XMLStreamException { + QName exceptions = new QName( SLDNS, "Exceptions" ); + if ( in.getName().equals( exceptions ) ) { + return XMLStreamUtils.getText( in, exceptions, "XML", true ); + } + return "XML"; + } + + private Map> parseDimensions( XMLStreamReader in ) + throws XMLStreamException { + Map> dimensions = new HashMap>(); + parseAndAddTime( in, dimensions ); + + QName elevation = new QName( SLDNS, "Elevation" ); + if ( in.getName().equals( elevation ) ) { + nextElement( in ); + parseAndAddValues( in, dimensions ); + parseAndAddInterval( in, dimensions ); + } + return dimensions; + } + + private void parseAndAddValues( XMLStreamReader in, Map> dimensions ) + throws XMLStreamException { + QName value = new QName( SLDNS, "Value" ); + List values = new ArrayList(); + while ( in.isStartElement() && in.getName().equals( value ) ) { + double valueValue = getElementTextAsDouble( in, value, Double.NaN, true ); + if ( !Double.isNaN( valueValue ) ) + values.add( valueValue ); + } + if ( !values.isEmpty() ) { + dimensions.put( "elevation", values ); + } + } + + @SuppressWarnings("unchecked") + private void parseAndAddInterval( XMLStreamReader in, Map> dimensions ) + throws XMLStreamException { + QName interval = new QName( SLDNS, "Interval" ); + if ( in.getName().equals( interval ) ) { + QName min = new QName( SLDNS, "Min" ); + skipToRequiredElement( in, min ); + double minValue = getRequiredElementTextAsDouble( in, min, true ); + + QName max = new QName( SLDNS, "Max" ); + skipToRequiredElement( in, max ); + double maxValue = getRequiredElementTextAsDouble( in, max, true ); + DimensionInterval dimensionInterval = new DimensionInterval( + minValue, + maxValue, + 0d ); + dimensions.put( "elevation", Arrays.asList( dimensionInterval ) ); + } + } + + private void parseAndAddTime( XMLStreamReader in, Map> dimensions ) + throws XMLStreamException { + QName time = new QName( SLDNS, "Time" ); + if ( in.getName().equals( time ) ) { + String timeValue = getText( in, time, null, true ); + if ( timeValue != null ) { + DateTime parsedDateTime = ISO8601Converter.parseDateTime( timeValue ); + dimensions.put( "time", Arrays.asList( parsedDateTime ) ); + } + } + } + + private ICRS parseCRS( XMLStreamReader in ) + throws UnknownCRSException, XMLStreamException { + String crs = XMLStreamUtils.getRequiredText( in, new QName( SLDNS, "CRS" ), true ); + return CRSManager.lookup( crs ); + } + + private Envelope parseBoundingBox( XMLStreamReader in ) + throws UnknownCRSException, OWSException, XMLStreamException { + String crsValue = XMLStreamUtils.getAttributeValue( in, "crs" ); + ICRS crs = CRSManager.lookup( crsValue ); + + QName lowerCorner = new QName( OWS_NS, "LowerCorner" ); + skipToRequiredElement( in, lowerCorner ); + double[] min = parseCorner( in, lowerCorner ); + + QName upperCorner = new QName( OWS_NS, "UpperCorner" ); + skipToRequiredElement( in, upperCorner ); + double[] max = parseCorner( in, upperCorner ); + + return GEOMETRY_FACTORY.createEnvelope( min, max, crs ); + } + + private double[] parseCorner( XMLStreamReader in, QName expectedElement ) + throws OWSException, XMLStreamException { + String corner = getRequiredText( in, expectedElement, true ); + String[] coords = corner.split( " " ); + if ( coords.length != 2 ) + throw new OWSException( "Could not parse element " + expectedElement, OWSException.NO_APPLICABLE_CODE ); + try { + double coord1 = Double.parseDouble( coords[0] ); + double coord2 = Double.parseDouble( coords[1] ); + return new double[] { coord1, coord2 }; + } catch ( NumberFormatException e ) { + String msg = "Invalid element " + expectedElement + + ". Expected are two double values, seperated by an white space."; + throw new OWSException( msg, OWSException.NO_APPLICABLE_CODE ); + } + } + + private class Output { + int width; + + int height; + + String format; + + boolean transparent; + + Color bgcolor; + + public Output( int width, int height, String format, boolean transparent, Color bgcolor ) { + this.width = width; + this.height = height; + this.format = format; + this.transparent = transparent; + this.bgcolor = bgcolor; + } + } + +} \ No newline at end of file diff --git a/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/ops/GetFeatureInfo.java b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/ops/GetFeatureInfo.java index 0c510ff1f0..907068d2bc 100644 --- a/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/ops/GetFeatureInfo.java +++ b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/ops/GetFeatureInfo.java @@ -133,6 +133,25 @@ public GetFeatureInfo( List layers, int width, int height, int x, int y, scale = RenderHelper.calcScaleWMS130( width, height, bbox, crs, DEFAULT_PIXEL_SIZE ); } + public GetFeatureInfo( List layers, List styles, List queryLayers, int width, + int height, int x, int y, Envelope envelope, ICRS crs, int featureCount, String infoFormat, + HashMap parameterMap, Map> dimensions ) throws OWSException { + this.layers.addAll( layers ); + this.styles.addAll( styles ); + cleanUpLayers( queryLayers ); + this.width = width; + this.height = height; + this.x = x; + this.y = y; + this.bbox = envelope; + this.crs = crs; + this.featureCount = featureCount; + this.infoFormat = infoFormat; + this.dimensions.putAll( dimensions ); + this.parameterMap.putAll( parameterMap ); + this.scale = RenderHelper.calcScaleWMS130( width, height, bbox, crs, DEFAULT_PIXEL_SIZE ); + } + private void parse111( Map map ) throws OWSException { double[] vals = handleCommon( map ); @@ -254,22 +273,7 @@ private double[] handleCommon( Map map ) handleSLD( sld, sldBody ); } - ListIterator lays = this.layers.listIterator(); - ListIterator stys = this.styles.listIterator(); - - while ( lays.hasNext() ) { - String name = lays.next().getName(); - stys.next(); - if ( !qlayers.contains( name ) ) { - lays.remove(); - stys.remove(); - } - } - - if ( layers.isEmpty() ) { - throw new OWSException( "An invalid combination of LAYERS and QUERY_LAYERS was specified.", - "LayerNotDefined" ); - } + cleanUpLayers( qlayers ); String format = map.get( "INFO_FORMAT" ); if ( format != null ) { @@ -418,4 +422,27 @@ public List getLayers() { return layers; } + /* + * Styles and Layers must be set before! + */ + private void cleanUpLayers( List qlayers ) + throws OWSException { + ListIterator lays = this.layers.listIterator(); + ListIterator stys = this.styles.listIterator(); + + while ( lays.hasNext() ) { + String name = lays.next().getName(); + stys.next(); + if ( !qlayers.contains( name ) ) { + lays.remove(); + stys.remove(); + } + } + + if ( layers.isEmpty() ) { + throw new OWSException( "An invalid combination of LAYERS and QUERY_LAYERS was specified.", + "LayerNotDefined" ); + } + } + } diff --git a/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/ops/GetMap.java b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/ops/GetMap.java index ad3f2dd327..ed3e3b6bfe 100644 --- a/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/ops/GetMap.java +++ b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/ops/GetMap.java @@ -77,7 +77,6 @@ import org.deegree.commons.utils.Pair; import org.deegree.cs.CRSUtils; import org.deegree.cs.coordinatesystems.ICRS; -import org.deegree.cs.exceptions.UnknownCRSException; import org.deegree.cs.persistence.CRSManager; import org.deegree.geometry.Envelope; import org.deegree.geometry.GeometryFactory; @@ -126,7 +125,7 @@ public class GetMap extends RequestBase { private double resolution; - private MapOptionsMaps extensions; + private MapOptionsMaps extensions = new MapOptionsMaps(); private double queryBoxSize = -1; @@ -204,6 +203,22 @@ public GetMap( List layers, int width, int height, Envelope envelope, IC this.transparent = transparent; } + public GetMap( List layers, List styles, int width, int height, Envelope envelope, ICRS crs, + String format, boolean transparent, Color bgcolor, Map parameterMap, + Map> dimensions ) { + this.layers.addAll( layers ); + this.styles.addAll( styles ); + this.width = width; + this.height = height; + this.bbox = envelope; + this.crs = crs; + this.format = format; + this.transparent = transparent; + this.bgcolor = bgcolor; + this.parameterMap.putAll( parameterMap ); + this.dimensions.putAll( dimensions ); + } + public GetMap( List layers, List styles, int width, int height, Envelope envelope, ICRS crs, String format, boolean transparent, Map overriddenParameters ) { this( layers, width, height, envelope, crs, format, transparent ); @@ -403,7 +418,6 @@ private void handleVSPs( Map map, MapOptionsMaps defaults ) { if ( defaults == null ) { defaults = new MapOptionsMaps(); } - extensions = new MapOptionsMaps(); handleEnumVSP( Quality.class, getQualitySetter( extensions ), NORMAL, map.get( "QUALITY" ), getQualityGetter( defaults ) ); handleEnumVSP( Interpolation.class, getInterpolationSetter( extensions ), NEARESTNEIGHBOR, diff --git a/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/ops/SLDParser.java b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/ops/SLDParser.java index 5bdda31a4e..2b30d6d296 100644 --- a/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/ops/SLDParser.java +++ b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/ops/SLDParser.java @@ -69,6 +69,8 @@ import org.deegree.filter.logical.Or; import org.deegree.filter.xml.Filter110XMLDecoder; import org.deegree.layer.LayerRef; +import org.deegree.protocol.wms.sld.StyleContainer; +import org.deegree.protocol.wms.sld.StylesContainer; import org.deegree.style.StyleRef; import org.deegree.style.se.parser.SymbologyParser; import org.deegree.style.se.unevaluated.Style; @@ -97,17 +99,49 @@ public class SLDParser { * @throws OWSException * @throws ParseException */ + @Deprecated public static Triple, LinkedList, LinkedList> parse( XMLStreamReader in, RequestBase gm ) throws XMLStreamException, OWSException, ParseException { + StylesContainer styleInformations = parse( in ); + + for ( Pair> dimension : styleInformations.getDimensions() ) { + gm.addDimensionValue( dimension.first, dimension.second ); + } + + LinkedList layerRefs = new LinkedList(); + LinkedList styleRefs = new LinkedList(); + LinkedList filters = new LinkedList(); + + List styles = styleInformations.getStyles(); + for ( StyleContainer styleInformation : styles ) { + layerRefs.add( styleInformation.getLayerRef() ); + styleRefs.add( styleInformation.getStyleRef() ); + filters.add( styleInformation.getFilter() ); + } + return new Triple, LinkedList, LinkedList>( layerRefs, + styleRefs, filters ); + } + + /** + * @param in + * the StyledLayerDescriptor to parse, never null + * @return the parsed SLD, never null + * @throws XMLStreamException + * if an error occurred during parsing + * @throws OWSException + * if an error occurred during parsing + * @throws ParseException + * if an error occurred during parsing + */ + public static StylesContainer parse( XMLStreamReader in ) + throws XMLStreamException, OWSException, ParseException { while ( !in.isStartElement() || in.getLocalName() == null || !( in.getLocalName().equals( "NamedLayer" ) || in.getLocalName().equals( "UserLayer" ) ) ) { in.nextTag(); } - LinkedList layers = new LinkedList(); - LinkedList styles = new LinkedList(); - LinkedList filters = new LinkedList(); + StylesContainer stylesContainer = new StylesContainer(); while ( in.getLocalName().equals( "NamedLayer" ) || in.getLocalName().equals( "UserLayer" ) ) { if ( in.getLocalName().equals( "NamedLayer" ) ) { @@ -183,10 +217,10 @@ public static Triple, LinkedList, LinkedList list = parseDimensionValues( value, name.toLowerCase() ); if ( name.toUpperCase().equals( "TIME" ) ) { - gm.addDimensionValue( "time", (List) parseTyped( list, true ) ); + stylesContainer.addDimensionValue( "time", (List) parseTyped( list, true ) ); } else { List values = (List) parseTyped( list, false ); - gm.addDimensionValue( name, values ); + stylesContainer.addDimensionValue( name, values ); } } @@ -200,9 +234,10 @@ public static Triple, LinkedList, LinkedList, LinkedList, LinkedList, LinkedList, LinkedList, LinkedList, LinkedList>( layers, styles, - filters ); + return stylesContainer; } /** diff --git a/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/sld/StyleContainer.java b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/sld/StyleContainer.java new file mode 100644 index 0000000000..dd3b677dcb --- /dev/null +++ b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/sld/StyleContainer.java @@ -0,0 +1,90 @@ +//$HeadURL$ +/*---------------------------------------------------------------------------- + This file is part of deegree, http://deegree.org/ + Copyright (C) 2001-2014 by: + - Department of Geography, University of Bonn - + and + - lat/lon GmbH - + + This library is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at your option) + any later version. + This library is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + details. + You should have received a copy of the GNU Lesser General Public License + along with this library; if not, write to the Free Software Foundation, Inc., + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Contact information: + + lat/lon GmbH + Aennchenstr. 19, 53177 Bonn + Germany + http://lat-lon.de/ + + Department of Geography, University of Bonn + Prof. Dr. Klaus Greve + Postfach 1147, 53001 Bonn + Germany + http://www.geographie.uni-bonn.de/deegree/ + + e-mail: info@deegree.org + ----------------------------------------------------------------------------*/ +package org.deegree.protocol.wms.sld; + +import org.deegree.filter.OperatorFilter; +import org.deegree.layer.LayerRef; +import org.deegree.style.StyleRef; + +/** + * Encapsulates a style parsed from SLD. + * + * @author Lyn Goltz + */ +public class StyleContainer { + + private final LayerRef layerRef; + + private final StyleRef styleRef; + + private final OperatorFilter filter; + + /** + * @param layerRef + * the parsed layer, never null + * @param styleRef + * the parsed style, never null + * @param filter + * the parsed filter, may be null + */ + public StyleContainer( LayerRef layerRef, StyleRef styleRef, OperatorFilter filter ) { + this.layerRef = layerRef; + this.styleRef = styleRef; + this.filter = filter; + } + + /** + * @return the parsed layer, never null + */ + public LayerRef getLayerRef() { + return layerRef; + } + + /** + * @return the parsed style, never null + */ + public StyleRef getStyleRef() { + return styleRef; + } + + /** + * @return the parsed filter, may be null + */ + public OperatorFilter getFilter() { + return filter; + } + +} \ No newline at end of file diff --git a/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/sld/StylesContainer.java b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/sld/StylesContainer.java new file mode 100644 index 0000000000..ba84700402 --- /dev/null +++ b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/sld/StylesContainer.java @@ -0,0 +1,90 @@ +//$HeadURL$ +/*---------------------------------------------------------------------------- + This file is part of deegree, http://deegree.org/ + Copyright (C) 2001-2014 by: + - Department of Geography, University of Bonn - + and + - lat/lon GmbH - + + This library is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at your option) + any later version. + This library is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + details. + You should have received a copy of the GNU Lesser General Public License + along with this library; if not, write to the Free Software Foundation, Inc., + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Contact information: + + lat/lon GmbH + Aennchenstr. 19, 53177 Bonn + Germany + http://lat-lon.de/ + + Department of Geography, University of Bonn + Prof. Dr. Klaus Greve + Postfach 1147, 53001 Bonn + Germany + http://www.geographie.uni-bonn.de/deegree/ + + e-mail: info@deegree.org + ----------------------------------------------------------------------------*/ +package org.deegree.protocol.wms.sld; + +import java.util.ArrayList; +import java.util.List; + +import org.deegree.commons.utils.Pair; + +/** + * Encapsulates styles parsed from SLD. + * + * @author Lyn Goltz + */ +public class StylesContainer { + + private final List styles = new ArrayList(); + + private final List>> dimensions = new ArrayList>>(); + + /** + * Add a new {@link StyleContainer}. + * + * @param style + * to add, never null + */ + public void addStyle( StyleContainer style ) { + styles.add( style ); + } + + /** + * Adds a new dimension. + * + * @param name + * the name of the dimension, never null + * @param values + * the values of the dimension, never null + */ + public void addDimensionValue( String name, List values ) { + dimensions.add( new Pair>( name, values ) ); + } + + /** + * @return the dimensions parsed from SLD, never null (but may be empty) + */ + public List>> getDimensions() { + return dimensions; + } + + /** + * @return the styles parsed from SLD, never null + */ + public List getStyles() { + return styles; + } + +} \ No newline at end of file diff --git a/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/test/java/org/deegree/protocol/wms/featureinfo/GetFeatureInfoParserTest.java b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/test/java/org/deegree/protocol/wms/featureinfo/GetFeatureInfoParserTest.java new file mode 100644 index 0000000000..767e8047ed --- /dev/null +++ b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/test/java/org/deegree/protocol/wms/featureinfo/GetFeatureInfoParserTest.java @@ -0,0 +1,143 @@ +//$HeadURL$ +/*---------------------------------------------------------------------------- + This file is part of deegree, http://deegree.org/ + Copyright (C) 2001-2015 by: + - Department of Geography, University of Bonn - + and + - lat/lon GmbH - + + This library is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at your option) + any later version. + This library is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + details. + You should have received a copy of the GNU Lesser General Public License + along with this library; if not, write to the Free Software Foundation, Inc., + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Contact information: + + lat/lon GmbH + Aennchenstr. 19, 53177 Bonn + Germany + http://lat-lon.de/ + + Department of Geography, University of Bonn + Prof. Dr. Klaus Greve + Postfach 1147, 53001 Bonn + Germany + http://www.geographie.uni-bonn.de/deegree/ + + e-mail: info@deegree.org + ----------------------------------------------------------------------------*/ +package org.deegree.protocol.wms.featureinfo; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.io.InputStream; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.xml.stream.FactoryConfigurationError; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.deegree.cs.persistence.CRSManager; +import org.deegree.geometry.Envelope; +import org.deegree.layer.LayerRef; +import org.deegree.protocol.wms.ops.GetFeatureInfo; +import org.hamcrest.BaseMatcher; +import org.hamcrest.Description; +import org.hamcrest.Matcher; +import org.junit.Test; + +/** + * @author Lyn Goltz + */ +public class GetFeatureInfoParserTest { + + @Test + public void testParse() + throws Exception { + GetFeatureInfoParser parser = new GetFeatureInfoParser(); + XMLStreamReader xmlStreamReader = createXmlStreamReader( "wms-1.3.0-GetFeatureInfo.xml" ); + GetFeatureInfo getFeatureInfo = parser.parse( xmlStreamReader ); + + assertThat( getFeatureInfo.getWidth(), is( 1024 ) ); + assertThat( getFeatureInfo.getHeight(), is( 512 ) ); + + assertThat( getFeatureInfo.getCoordinateSystem(), is( CRSManager.lookup( "EPSG:4326" ) ) ); + Envelope boundingBox = getFeatureInfo.getEnvelope(); + assertThat( boundingBox.getMin().get0(), is( -115.4 ) ); + assertThat( boundingBox.getMin().get1(), is( 35.0 ) ); + assertThat( boundingBox.getMax().get0(), is( -108.0 ) ); + assertThat( boundingBox.getMax().get1(), is( 44.0 ) ); + + HashMap> dimensions = getFeatureInfo.getDimensions(); + assertThat( dimensions.size(), is( 0 ) ); + + Map parameterMap = getFeatureInfo.getParameterMap(); + assertThat( parameterMap.size(), is( 1 ) ); + assertThat( parameterMap.get( "EXCEPTIONS" ), is( "XML" ) ); + + assertThat( getFeatureInfo.getX(), is( 5 ) ); + assertThat( getFeatureInfo.getY(), is( 10 ) ); + assertThat( getFeatureInfo.getFeatureCount(), is( 42 ) ); + assertThat( getFeatureInfo.getInfoFormat(), is( "text/html" ) ); + assertThat( getFeatureInfo.getQueryLayers().size(), is( 2 ) ); + assertThat( getFeatureInfo.getQueryLayers(), hasLayerRef( "counties" ) ); + assertThat( getFeatureInfo.getQueryLayers(), hasLayerRef( "municipalities" ) ); + } + + @Test + public void testParse_defaultValues() + throws Exception { + GetFeatureInfoParser parser = new GetFeatureInfoParser(); + XMLStreamReader xmlStreamReader = createXmlStreamReader( "wms-1.3.0-GetFeatureInfo_simple.xml" ); + GetFeatureInfo getFeatureInfo = parser.parse( xmlStreamReader ); + + Map parameterMap = getFeatureInfo.getParameterMap(); + assertThat( parameterMap.size(), is( 0 ) ); + + assertThat( getFeatureInfo.getX(), is( 50 ) ); + assertThat( getFeatureInfo.getY(), is( 15 ) ); + assertThat( getFeatureInfo.getFeatureCount(), is( 1 ) ); + assertThat( getFeatureInfo.getInfoFormat(), is( "text/xml" ) ); + assertThat( getFeatureInfo.getQueryLayers().size(), is( 1 ) ); + assertThat( getFeatureInfo.getQueryLayers(), hasLayerRef( "counties" ) ); + } + + private XMLStreamReader createXmlStreamReader( String resource ) + throws XMLStreamException, FactoryConfigurationError { + InputStream getMapResource = GetFeatureInfoParserTest.class.getResourceAsStream( resource ); + return XMLInputFactory.newInstance().createXMLStreamReader( getMapResource ); + } + + @SuppressWarnings("unchecked") + private Matcher> hasLayerRef( final String layer ) { + return new BaseMatcher>() { + + @Override + public boolean matches( Object item ) { + List layers = (List) item; + for ( LayerRef layerRef : layers ) { + if ( layer.equals( layerRef.getName() ) ) + return true; + } + return false; + } + + @Override + public void describeTo( Description description ) { + description.appendText( "List should contain a layer with name " + layer ); + } + }; + } + +} diff --git a/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/test/java/org/deegree/protocol/wms/map/GetMapParserTest.java b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/test/java/org/deegree/protocol/wms/map/GetMapParserTest.java new file mode 100644 index 0000000000..fd2ae5c0c8 --- /dev/null +++ b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/test/java/org/deegree/protocol/wms/map/GetMapParserTest.java @@ -0,0 +1,250 @@ +//$HeadURL$ +/*---------------------------------------------------------------------------- + This file is part of deegree, http://deegree.org/ + Copyright (C) 2001-2015 by: + - Department of Geography, University of Bonn - + and + - lat/lon GmbH - + + This library is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at your option) + any later version. + This library is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + details. + You should have received a copy of the GNU Lesser General Public License + along with this library; if not, write to the Free Software Foundation, Inc., + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Contact information: + + lat/lon GmbH + Aennchenstr. 19, 53177 Bonn + Germany + http://lat-lon.de/ + + Department of Geography, University of Bonn + Prof. Dr. Klaus Greve + Postfach 1147, 53001 Bonn + Germany + http://www.geographie.uni-bonn.de/deegree/ + + e-mail: info@deegree.org + ----------------------------------------------------------------------------*/ +package org.deegree.protocol.wms.map; + +import static java.awt.Color.BLACK; +import static java.awt.Color.WHITE; +import static org.hamcrest.CoreMatchers.hasItems; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.io.InputStream; +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.TimeZone; + +import javax.xml.stream.FactoryConfigurationError; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.deegree.commons.tom.datetime.DateTime; +import org.deegree.cs.persistence.CRSManager; +import org.deegree.geometry.Envelope; +import org.deegree.layer.LayerRef; +import org.deegree.layer.dims.DimensionInterval; +import org.deegree.protocol.wms.ops.GetMap; +import org.deegree.style.StyleRef; +import org.hamcrest.BaseMatcher; +import org.hamcrest.Description; +import org.hamcrest.Matcher; +import org.junit.Test; + +/** + * @author Lyn Goltz + */ +public class GetMapParserTest { + + @SuppressWarnings("unchecked") + @Test + public void testParse() + throws Exception { + GetMapParser getMapXMLAdapter = new GetMapParser(); + XMLStreamReader xmlStreamReader = createXmlStreamReader( "wms-1.3.0-GetMap.xml" ); + GetMap getMap = getMapXMLAdapter.parse( xmlStreamReader ); + + LinkedList layers = getMap.getLayers(); + assertThat( layers.size(), is( 3 ) ); + assertThat( layers, hasLayerRef( "municipalities" ) ); + assertThat( layers, hasLayerRef( "counties" ) ); + assertThat( layers, hasLayerRef( "zipcodes" ) ); + + LinkedList styles = getMap.getStyles(); + assertThat( styles.size(), is( 3 ) ); + assertThat( styles, hasStyleRef( "Municipalities" ) ); + assertThat( styles, hasStyleRef( "CountyBoundary" ) ); + assertThat( styles, hasStyleRef( "default" ) ); + + assertThat( getMap.getWidth(), is( 1024 ) ); + assertThat( getMap.getHeight(), is( 512 ) ); + assertThat( getMap.getFormat(), is( "image/png" ) ); + assertThat( getMap.getTransparent(), is( true ) ); + assertThat( getMap.getBgColor(), is( BLACK ) ); + + assertThat( getMap.getCoordinateSystem(), is( CRSManager.lookup( "EPSG:4326" ) ) ); + Envelope boundingBox = getMap.getBoundingBox(); + assertThat( boundingBox.getMin().get0(), is( -115.4 ) ); + assertThat( boundingBox.getMin().get1(), is( 35.0 ) ); + assertThat( boundingBox.getMax().get0(), is( -108.0 ) ); + assertThat( boundingBox.getMax().get1(), is( 44.0 ) ); + + Map parameterMap = getMap.getParameterMap(); + assertThat( parameterMap.size(), is( 1 ) ); + assertThat( parameterMap.get( "EXCEPTIONS" ), is( "INIMAGE" ) ); + + HashMap> dimensions = getMap.getDimensions(); + assertThat( dimensions.size(), is( 2 ) ); + + assertThat( ( (List) dimensions.get( "time" ) ).size(), is( 1 ) ); + assertThat( ( (List) dimensions.get( "time" ) ).get( 0 ).getDate(), is( expectedDateTime() ) ); + + assertThat( ( (List) dimensions.get( "elevation" ) ).size(), is( 1 ) ); + assertThat( ( (List) dimensions.get( "elevation" ) ).get( 0 ), is( 5d ) ); + } + + @Test + public void testParse_defaultValues() + throws Exception { + GetMapParser getMapXMLAdapter = new GetMapParser(); + XMLStreamReader xmlStreamReader = createXmlStreamReader( "wms-1.3.0-GetMap_simple.xml" ); + GetMap getMap = getMapXMLAdapter.parse( xmlStreamReader ); + + LinkedList layers = getMap.getLayers(); + assertThat( layers.size(), is( 1 ) ); + assertThat( layers, hasLayerRef( "municipalities" ) ); + + LinkedList styles = getMap.getStyles(); + assertThat( styles.size(), is( 1 ) ); + assertThat( styles, hasStyleRef( "Municipalities" ) ); + + assertThat( getMap.getWidth(), is( 10 ) ); + assertThat( getMap.getHeight(), is( 50 ) ); + assertThat( getMap.getFormat(), is( "image/jpeg" ) ); + assertThat( getMap.getTransparent(), is( false ) ); + assertThat( getMap.getBgColor(), is( WHITE ) ); + + assertThat( getMap.getCoordinateSystem(), is( CRSManager.lookup( "EPSG:4326" ) ) ); + Envelope boundingBox = getMap.getBoundingBox(); + assertThat( boundingBox.getMin().get0(), is( -115.4 ) ); + assertThat( boundingBox.getMin().get1(), is( 35.0 ) ); + assertThat( boundingBox.getMax().get0(), is( -108.0 ) ); + assertThat( boundingBox.getMax().get1(), is( 44.0 ) ); + + Map parameterMap = getMap.getParameterMap(); + assertThat( parameterMap.size(), is( 1 ) ); + assertThat( parameterMap.get( "EXCEPTIONS" ), is( "XML" ) ); + } + + @SuppressWarnings("unchecked") + @Test + public void testParse_elevationValues() + throws Exception { + GetMapParser getMapXMLAdapter = new GetMapParser(); + XMLStreamReader xmlStreamReader = createXmlStreamReader( "wms-1.3.0-GetMap_elevationValues.xml" ); + GetMap getMap = getMapXMLAdapter.parse( xmlStreamReader ); + + HashMap> dimensions = getMap.getDimensions(); + assertThat( dimensions.size(), is( 1 ) ); + + List elevationValues = (List) dimensions.get( "elevation" ); + assertThat( elevationValues.size(), is( 5 ) ); + assertThat( elevationValues, hasItems( -1.5, -0.5, 0d, 0.5, 1.5 ) ); + } + + @SuppressWarnings("unchecked") + @Test + public void testParse_elevationInterval() + throws Exception { + GetMapParser getMapXMLAdapter = new GetMapParser(); + XMLStreamReader xmlStreamReader = createXmlStreamReader( "wms-1.3.0-GetMap_elevationInterval.xml" ); + GetMap getMap = getMapXMLAdapter.parse( xmlStreamReader ); + + HashMap> dimensions = getMap.getDimensions(); + assertThat( dimensions.size(), is( 1 ) ); + + List> elevationValues = (List>) dimensions.get( "elevation" ); + assertThat( elevationValues.size(), is( 1 ) ); + assertThat( elevationValues.get( 0 ).min, is( -5d ) ); + assertThat( elevationValues.get( 0 ).max, is( 5d ) ); + assertThat( elevationValues.get( 0 ).res, is( 0d ) ); + } + + private XMLStreamReader createXmlStreamReader( String resource ) + throws XMLStreamException, FactoryConfigurationError { + InputStream getMapResource = GetMapParserTest.class.getResourceAsStream( resource ); + return XMLInputFactory.newInstance().createXMLStreamReader( getMapResource ); + } + + private Date expectedDateTime() { + Calendar expectedCalendar = Calendar.getInstance(); + expectedCalendar.set( Calendar.YEAR, 2015 ); + expectedCalendar.set( Calendar.MONTH, 7 ); + expectedCalendar.set( Calendar.DAY_OF_MONTH, 24 ); + expectedCalendar.set( Calendar.HOUR_OF_DAY, 9 ); + expectedCalendar.set( Calendar.MINUTE, 30 ); + expectedCalendar.set( Calendar.SECOND, 0 ); + expectedCalendar.set( Calendar.MILLISECOND, 0 ); + expectedCalendar.setTimeZone( TimeZone.getTimeZone( "UTC" ) ); + return expectedCalendar.getTime(); + } + + @SuppressWarnings("unchecked") + private Matcher> hasLayerRef( final String layer ) { + return new BaseMatcher>() { + + @Override + public boolean matches( Object item ) { + LinkedList layers = (LinkedList) item; + for ( LayerRef layerRef : layers ) { + if ( layer.equals( layerRef.getName() ) ) + return true; + } + return false; + } + + @Override + public void describeTo( Description description ) { + description.appendText( "List should contain a layer with name " + layer ); + } + }; + } + + @SuppressWarnings("unchecked") + private Matcher> hasStyleRef( final String style ) { + return new BaseMatcher>() { + + @Override + public boolean matches( Object item ) { + LinkedList styles = (LinkedList) item; + for ( StyleRef styleRef : styles ) { + if ( style.equals( styleRef.getName() ) ) + return true; + } + return false; + } + + @Override + public void describeTo( Description description ) { + description.appendText( "List should contain a style with name " + style ); + } + }; + } + +} \ No newline at end of file diff --git a/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/test/java/org/deegree/protocol/wms/ops/SLDParserTest.java b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/test/java/org/deegree/protocol/wms/ops/SLDParserTest.java new file mode 100644 index 0000000000..c71d8d6a4d --- /dev/null +++ b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/test/java/org/deegree/protocol/wms/ops/SLDParserTest.java @@ -0,0 +1,124 @@ +//$HeadURL$ +/*---------------------------------------------------------------------------- + This file is part of deegree, http://deegree.org/ + Copyright (C) 2001-2015 by: + - Department of Geography, University of Bonn - + and + - lat/lon GmbH - + + This library is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at your option) + any later version. + This library is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + details. + You should have received a copy of the GNU Lesser General Public License + along with this library; if not, write to the Free Software Foundation, Inc., + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Contact information: + + lat/lon GmbH + Aennchenstr. 19, 53177 Bonn + Germany + http://lat-lon.de/ + + Department of Geography, University of Bonn + Prof. Dr. Klaus Greve + Postfach 1147, 53001 Bonn + Germany + http://www.geographie.uni-bonn.de/deegree/ + + e-mail: info@deegree.org + ----------------------------------------------------------------------------*/ +package org.deegree.protocol.wms.ops; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.mock; + +import java.io.InputStream; +import java.util.LinkedList; +import java.util.List; + +import javax.xml.namespace.QName; +import javax.xml.stream.FactoryConfigurationError; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.deegree.commons.utils.Pair; +import org.deegree.commons.utils.Triple; +import org.deegree.filter.OperatorFilter; +import org.deegree.layer.LayerRef; +import org.deegree.protocol.wms.sld.StyleContainer; +import org.deegree.protocol.wms.sld.StylesContainer; +import org.deegree.style.StyleRef; +import org.junit.Test; + +/** + * TODO add class documentation here + * + * @author Lyn Goltz + */ +public class SLDParserTest { + + @Test + public void testParse() + throws Exception { + XMLStreamReader in = retrieveSldAsStream( "example-sld.xml" ); + RequestBase gm = mockRequestBase(); + Triple, LinkedList, LinkedList> sld = SLDParser.parse( in, gm ); + + LinkedList layerRefs = sld.first; + assertThat( layerRefs.size(), is( 1 ) ); + assertThat( layerRefs.get( 0 ).getName(), is( "OCEANSEA_1M:Foundation" ) ); + + LinkedList styleRefs = sld.second; + assertThat( styleRefs.size(), is( 1 ) ); + assertThat( styleRefs.get( 0 ).getStyle().getFeatureType(), is( new QName( "Foundation" ) ) ); + assertThat( styleRefs.get( 0 ).getStyle().getRules().size(), is( 1 ) ); + + LinkedList operatorFilters = sld.third; + assertThat( operatorFilters.size(), is( 1 ) ); + assertThat( operatorFilters.get( 0 ), is( nullValue() ) ); + } + + @Test + public void testParse_StyleInformations() + throws Exception { + XMLStreamReader in = retrieveSldAsStream( "example-sld.xml" ); + StylesContainer sld = SLDParser.parse( in ); + List>> dimensions = sld.getDimensions(); + assertThat( dimensions.size(), is( 0 ) ); + + List styles = sld.getStyles(); + assertThat( styles.size(), is( 1 ) ); + + StyleContainer styleInformation = styles.get( 0 ); + + LayerRef layerRefs = styleInformation.getLayerRef(); + assertThat( layerRefs.getName(), is( "OCEANSEA_1M:Foundation" ) ); + + StyleRef layerRef = styleInformation.getStyleRef(); + assertThat( layerRef.getStyle().getFeatureType(), is( new QName( "Foundation" ) ) ); + assertThat( layerRef.getStyle().getRules().size(), is( 1 ) ); + + OperatorFilter filter = styleInformation.getFilter(); + assertThat( filter, is( nullValue() ) ); + } + + private XMLStreamReader retrieveSldAsStream( String resource ) + throws XMLStreamException, FactoryConfigurationError { + InputStream resourceAsStream = SLDParserTest.class.getResourceAsStream( resource ); + return XMLInputFactory.newInstance().createXMLStreamReader( resourceAsStream ); + } + + private RequestBase mockRequestBase() { + return mock( RequestBase.class ); + } + +} diff --git a/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/test/resources/org/deegree/protocol/wms/featureinfo/wms-1.3.0-GetFeatureInfo.xml b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/test/resources/org/deegree/protocol/wms/featureinfo/wms-1.3.0-GetFeatureInfo.xml new file mode 100644 index 0000000000..5d9a9b578e --- /dev/null +++ b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/test/resources/org/deegree/protocol/wms/featureinfo/wms-1.3.0-GetFeatureInfo.xml @@ -0,0 +1,52 @@ + + + + + + municipalities + + Municipalities + + + + counties + + CountyBoundary + + + + zipcodes + + default + + + + EPSG:4326 + + -115.4 35.0 + -108.0 44.0 + + + + 1024 + 512 + + image/png + true + 0x000000 + + INIMAGE + + counties + municipalities + 5 + 10 + + text/html + 42 + + XML + \ No newline at end of file diff --git a/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/test/resources/org/deegree/protocol/wms/featureinfo/wms-1.3.0-GetFeatureInfo_simple.xml b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/test/resources/org/deegree/protocol/wms/featureinfo/wms-1.3.0-GetFeatureInfo_simple.xml new file mode 100644 index 0000000000..d216c2df27 --- /dev/null +++ b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/test/resources/org/deegree/protocol/wms/featureinfo/wms-1.3.0-GetFeatureInfo_simple.xml @@ -0,0 +1,46 @@ + + + + + + municipalities + + Municipalities + + + + counties + + CountyBoundary + + + + zipcodes + + default + + + + EPSG:4326 + + -115.4 35.0 + -108.0 44.0 + + + + 1024 + 512 + + image/png + + + counties + 50 + 15 + + text/xml + + \ No newline at end of file diff --git a/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/test/resources/org/deegree/protocol/wms/map/wms-1.3.0-GetMap.xml b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/test/resources/org/deegree/protocol/wms/map/wms-1.3.0-GetMap.xml new file mode 100644 index 0000000000..f06820f1a8 --- /dev/null +++ b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/test/resources/org/deegree/protocol/wms/map/wms-1.3.0-GetMap.xml @@ -0,0 +1,45 @@ + + + + + municipalities + + Municipalities + + + + counties + + CountyBoundary + + + + zipcodes + + default + + + + EPSG:4326 + + -115.4 35.0 + -108.0 44.0 + + + + 1024 + 512 + + image/png + true + 0x000000 + + INIMAGE + + + 5 + + \ No newline at end of file diff --git a/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/test/resources/org/deegree/protocol/wms/map/wms-1.3.0-GetMap_elevationInterval.xml b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/test/resources/org/deegree/protocol/wms/map/wms-1.3.0-GetMap_elevationInterval.xml new file mode 100644 index 0000000000..870a489bc0 --- /dev/null +++ b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/test/resources/org/deegree/protocol/wms/map/wms-1.3.0-GetMap_elevationInterval.xml @@ -0,0 +1,32 @@ + + + + + municipalities + + Municipalities + + + + EPSG:4326 + + -115.4 35.0 + -108.0 44.0 + + + + 10 + 50 + + image/jpeg + + + + -5 + 5 + + + \ No newline at end of file diff --git a/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/test/resources/org/deegree/protocol/wms/map/wms-1.3.0-GetMap_elevationValues.xml b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/test/resources/org/deegree/protocol/wms/map/wms-1.3.0-GetMap_elevationValues.xml new file mode 100644 index 0000000000..cc36c44308 --- /dev/null +++ b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/test/resources/org/deegree/protocol/wms/map/wms-1.3.0-GetMap_elevationValues.xml @@ -0,0 +1,33 @@ + + + + + municipalities + + Municipalities + + + + EPSG:4326 + + -115.4 35.0 + -108.0 44.0 + + + + 10 + 50 + + image/jpeg + + + -1.5 + -0.5 + 0 + 0.5 + 1.5 + + \ No newline at end of file diff --git a/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/test/resources/org/deegree/protocol/wms/map/wms-1.3.0-GetMap_simple.xml b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/test/resources/org/deegree/protocol/wms/map/wms-1.3.0-GetMap_simple.xml new file mode 100644 index 0000000000..67649483cf --- /dev/null +++ b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/test/resources/org/deegree/protocol/wms/map/wms-1.3.0-GetMap_simple.xml @@ -0,0 +1,26 @@ + + + + + municipalities + + Municipalities + + + + EPSG:4326 + + -115.4 35.0 + -108.0 44.0 + + + + 10 + 50 + + image/jpeg + + \ No newline at end of file diff --git a/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/test/resources/org/deegree/protocol/wms/ops/example-sld.xml b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/test/resources/org/deegree/protocol/wms/ops/example-sld.xml new file mode 100644 index 0000000000..ae806332af --- /dev/null +++ b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/test/resources/org/deegree/protocol/wms/ops/example-sld.xml @@ -0,0 +1,32 @@ + + + + + OCEANSEA_1M:Foundation + + GEOSYM + 1 + + Foundation + + main + + MySymbol + + Example Symbol + This is just a simple example. + + + GEOMETRY + + + #96C3F5 + + + + + + + \ No newline at end of file diff --git a/deegree-services/deegree-services-wms/pom.xml b/deegree-services/deegree-services-wms/pom.xml index e3abba275e..431713af67 100644 --- a/deegree-services/deegree-services-wms/pom.xml +++ b/deegree-services/deegree-services-wms/pom.xml @@ -103,7 +103,11 @@ org.mockito mockito-core - + + + org.xmlmatchers + xml-matchers + diff --git a/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/WMSController.java b/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/WMSController.java index 4373e8931c..78746dbb82 100644 --- a/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/WMSController.java +++ b/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/WMSController.java @@ -38,11 +38,11 @@ import static javax.imageio.ImageIO.write; import static org.deegree.commons.ows.exception.OWSException.OPERATION_NOT_SUPPORTED; -import static org.deegree.commons.tom.ows.Version.parseVersion; import static org.deegree.commons.utils.ArrayUtils.join; import static org.deegree.commons.utils.CollectionUtils.getStringJoiner; import static org.deegree.commons.utils.CollectionUtils.map; import static org.deegree.commons.utils.CollectionUtils.reduce; +import static org.deegree.commons.xml.stax.XMLStreamUtils.nextElement; import static org.deegree.protocol.wms.WMSConstants.VERSION_111; import static org.deegree.protocol.wms.WMSConstants.VERSION_130; import static org.deegree.services.controller.OGCFrontController.getHttpGetURL; @@ -51,6 +51,7 @@ import static org.slf4j.LoggerFactory.getLogger; import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -62,16 +63,32 @@ import java.util.List; import java.util.Map; import java.util.TreeMap; +import java.util.UUID; +import javax.activation.DataHandler; +import javax.activation.DataSource; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; +import javax.xml.soap.AttachmentPart; +import javax.xml.soap.MessageFactory; +import javax.xml.soap.Name; +import javax.xml.soap.SOAPBody; +import javax.xml.soap.SOAPBodyElement; +import javax.xml.soap.SOAPConstants; +import javax.xml.soap.SOAPEnvelope; +import javax.xml.soap.SOAPException; +import javax.xml.soap.SOAPMessage; +import javax.xml.soap.SOAPPart; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import javax.xml.stream.XMLStreamWriter; import javax.xml.transform.dom.DOMSource; +import org.apache.axiom.attachments.ByteArrayDataSource; import org.apache.axiom.om.OMElement; +import org.apache.axiom.soap.SOAP11Version; +import org.apache.axiom.soap.SOAPVersion; import org.apache.commons.fileupload.FileItem; import org.deegree.commons.annotations.LoggingNotes; import org.deegree.commons.ows.exception.OWSException; @@ -81,8 +98,11 @@ import org.deegree.commons.tom.ows.Version; import org.deegree.commons.utils.CollectionUtils; import org.deegree.commons.utils.Pair; +import org.deegree.commons.utils.kvp.InvalidParameterValueException; +import org.deegree.commons.xml.CommonNamespaces; import org.deegree.commons.xml.NamespaceBindings; import org.deegree.commons.xml.XMLAdapter; +import org.deegree.commons.xml.stax.XMLStreamUtils; import org.deegree.cs.coordinatesystems.ICRS; import org.deegree.cs.refs.coordinatesystem.CRSRef; import org.deegree.feature.FeatureCollection; @@ -97,8 +117,13 @@ import org.deegree.protocol.wms.WMSConstants.WMSRequestType; import org.deegree.protocol.wms.WMSException.InvalidDimensionValue; import org.deegree.protocol.wms.WMSException.MissingDimensionValue; +import org.deegree.protocol.wms.capabilities.GetCapabilitiesXMLAdapter; +import org.deegree.protocol.wms.featureinfo.GetFeatureInfoParser; +import org.deegree.protocol.wms.map.GetMapParser; +import org.deegree.protocol.wms.ops.GetFeatureInfo; import org.deegree.protocol.wms.ops.GetFeatureInfoSchema; import org.deegree.protocol.wms.ops.GetLegendGraphic; +import org.deegree.protocol.wms.ops.GetMap; import org.deegree.rendering.r2d.context.RenderContext; import org.deegree.rendering.r2d.context.RenderingInfo; import org.deegree.services.OWS; @@ -107,18 +132,20 @@ import org.deegree.services.controller.AbstractOWS; import org.deegree.services.controller.ImplementationMetadata; import org.deegree.services.controller.OGCFrontController; +import org.deegree.services.controller.exception.serializer.ExceptionSerializer; import org.deegree.services.controller.exception.serializer.XMLExceptionSerializer; import org.deegree.services.controller.utils.HttpResponseBuffer; import org.deegree.services.controller.utils.StandardFeatureInfoContext; import org.deegree.services.jaxb.controller.DeegreeServiceControllerType; import org.deegree.services.jaxb.metadata.DeegreeServicesMetadataType; import org.deegree.services.jaxb.wms.DeegreeWMS; -import org.deegree.services.jaxb.wms.GetMapFormatsType; import org.deegree.services.jaxb.wms.DeegreeWMS.ExtendedCapabilities; +import org.deegree.services.jaxb.wms.DeegreeWMS.SupportedVersions; import org.deegree.services.jaxb.wms.FeatureInfoFormatsType; import org.deegree.services.jaxb.wms.FeatureInfoFormatsType.GetFeatureInfoFormat; import org.deegree.services.jaxb.wms.FeatureInfoFormatsType.GetFeatureInfoFormat.Serializer; import org.deegree.services.jaxb.wms.FeatureInfoFormatsType.GetFeatureInfoFormat.XSLTFile; +import org.deegree.services.jaxb.wms.GetMapFormatsType; import org.deegree.services.jaxb.wms.ServiceConfigurationType; import org.deegree.services.metadata.OWSMetadataProvider; import org.deegree.services.metadata.provider.OWSMetadataProviderProvider; @@ -167,7 +194,7 @@ public class WMSController extends AbstractOWS { private String metadataURLTemplate; private FeatureInfoManager featureInfoManager; - + private OutputFormatProvider ouputFormatProvider; private OWSMetadataProvider metadataProvider; @@ -189,10 +216,10 @@ public WMSController( ResourceMetadata metadata, Workspace workspace, Deegr } featureInfoManager = new FeatureInfoManager( addDefaultFormats ); - ouputFormatProvider = new DefaultOutputFormatProvider(); + initOfferedVersions( jaxbConfig.getSupportedVersions() ); } - + public Collection getSupportedImageFormats() { return supportedImageFormats; } @@ -220,7 +247,6 @@ private void handleMetadata( String metadataURLTemplate, String storeid ) { @Override public void init( DeegreeServicesMetadataType serviceMetadata, DeegreeServiceControllerType mainConfig, Object controllerConf ) { - identification = convertFromJAXB( serviceMetadata.getServiceIdentification() ); provider = convertFromJAXB( serviceMetadata.getServiceProvider() ); @@ -247,7 +273,7 @@ public void init( DeegreeServicesMetadataType serviceMetadata, DeegreeServiceCon try { addSupportedImageFormats( conf ); - + if ( conf.getFeatureInfoFormats() != null ) { for ( GetFeatureInfoFormat t : conf.getFeatureInfoFormats().getGetFeatureInfoFormat() ) { if ( t.getFile() != null ) { @@ -333,11 +359,11 @@ public void doKVP( Map map, HttpServletRequest request, HttpResp if ( v == null ) { v = map.get( "WMTVER" ); } - Version version = v == null ? highestVersion : parseVersion( v ); + Version version = v == null ? highestVersion : Version.parseVersion( v ); WMSRequestType req; try { - req = (WMSRequestType) ( (ImplementationMetadata) ( (OWSProvider) getMetadata().getProvider() ).getImplementationMetadata() ).getRequestTypeByName( map.get( "REQUEST" ) ); + req = (WMSRequestType) ( (ImplementationMetadata) ( (OWSProvider) getMetadata().getProvider() ).getImplementationMetadata() ).getRequestTypeByName( map.get( "REQUEST" ) ); } catch ( IllegalArgumentException e ) { controllers.get( version ).sendException( new OWSException( get( "WMS.OPERATION_NOT_KNOWN", map.get( "REQUEST" ) ), @@ -451,57 +477,8 @@ private void getLegendGraphic( Map map, HttpResponseBuffer respo private void getFeatureInfo( Map map, final HttpResponseBuffer response, Version version ) throws OWSException, IOException, MissingDimensionValue, InvalidDimensionValue { - - Pair> pair; - String format; - List queryLayers; - boolean geometries; - FeatureType type = null; - ICRS crs; - Map nsBindings = new HashMap(); - - LinkedList headers = new LinkedList(); org.deegree.protocol.wms.ops.GetFeatureInfo fi = new org.deegree.protocol.wms.ops.GetFeatureInfo( map, version ); - checkGetFeatureInfo( version, fi ); - crs = fi.getCoordinateSystem(); - geometries = fi.returnGeometries(); - queryLayers = map( fi.getQueryLayers(), CollectionUtils. getToStringMapper() ); - - RenderingInfo info = new RenderingInfo( fi.getInfoFormat(), fi.getWidth(), fi.getHeight(), false, null, - fi.getEnvelope(), 0.28, map ); - format = fi.getInfoFormat(); - info.setFormat( format ); - info.setFeatureCount( fi.getFeatureCount() ); - info.setX( fi.getX() ); - info.setY( fi.getY() ); - pair = new Pair>( service.getFeatures( fi, headers ), headers ); - - FeatureCollection col = pair.first; - addHeaders( response, pair.second ); - format = format == null ? "application/vnd.ogc.gml" : format; - response.setContentType( format ); - response.setCharacterEncoding( "UTF-8" ); - - Map fismap = new HashMap(); - fismap.put( "LAYERS", reduce( "", queryLayers, getStringJoiner( "," ) ) ); - GetFeatureInfoSchema fis = new GetFeatureInfoSchema( fismap ); - List schema = service.getSchema( fis ); - for ( FeatureType ft : schema ) { - type = ft; - if ( ft.getSchema() != null ) { - nsBindings.putAll( ft.getSchema().getNamespaceBindings() ); - } - } - - String loc = getHttpGetURL() + "request=GetFeatureInfoSchema&layers=" + join( ",", queryLayers ); - - try { - FeatureInfoParams params = new FeatureInfoParams( nsBindings, col, format, geometries, loc, type, crs ); - featureInfoManager.serializeFeatureInfo( params, new StandardFeatureInfoContext( response ) ); - response.flushBuffer(); - } catch ( XMLStreamException e ) { - throw new IOException( e.getLocalizedMessage(), e ); - } + doGetFeatureInfo( map, response, version, fi ); } private void getFeatureInfoSchema( Map map, HttpResponseBuffer response ) @@ -540,16 +517,7 @@ protected void getMap( Map map, HttpResponseBuffer response, Ver org.deegree.protocol.wms.ops.GetMap gm2 = new org.deegree.protocol.wms.ops.GetMap( map, version, service.getExtensions() ); - checkGetMap( version, gm2 ); - - RenderingInfo info = new RenderingInfo( gm2.getFormat(), gm2.getWidth(), gm2.getHeight(), gm2.getTransparent(), - gm2.getBgColor(), gm2.getBoundingBox(), gm2.getPixelSize(), map ); - RenderContext ctx = ouputFormatProvider.getRenderers( info, response.getOutputStream() ); - LinkedList headers = new LinkedList(); - service.getMap( gm2, headers, ctx ); - response.setContentType( gm2.getFormat() ); - ctx.close(); - addHeaders( response, headers ); + doGetMap( map, response, version, gm2 ); } private void checkGetFeatureInfo( Version version, org.deegree.protocol.wms.ops.GetFeatureInfo gfi ) @@ -617,7 +585,6 @@ private void checkGetMap( Version version, org.deegree.protocol.wms.ops.GetMap g protected void getCapabilities( Map map, HttpResponseBuffer response ) throws OWSException, IOException { - String version = map.get( "VERSION" ); // not putting it into the bean, why should I? It's used just a few lines below... @@ -626,30 +593,108 @@ protected void getCapabilities( Map map, HttpResponseBuffer resp version = map.get( "WMTVER" ); } GetCapabilities req = new GetCapabilities( version ); - - Version myVersion = negotiateVersion( req ); - - String getUrl = OGCFrontController.getHttpGetURL(); - String postUrl = OGCFrontController.getHttpPostURL(); - - if ( metadataProvider != null ) { - controllers.get( myVersion ).getCapabilities( getUrl, postUrl, updateSequence, service, response, - metadataProvider.getServiceIdentification(), - metadataProvider.getServiceProvider(), map, this, - metadataProvider ); - } else { - controllers.get( myVersion ).getCapabilities( getUrl, postUrl, updateSequence, service, response, - identification, provider, map, this, null ); - } - - response.flushBuffer(); // TODO remove this to enable validation, enable validation on a DTD basis... + doGetCapabilities( map, response, updateSequence, req ); } @Override public void doXML( XMLStreamReader xmlStream, HttpServletRequest request, HttpResponseBuffer response, List multiParts ) throws ServletException, IOException { - throw new UnsupportedOperationException( "XML request handling is currently not supported for the wms" ); + Version requestVersion = null; + try { + String requestName = xmlStream.getLocalName(); + WMSRequestType requestType = detectWmsRequestType( requestName ); + requestVersion = parseAndCheckVersion( xmlStream ); + + switch ( requestType ) { + case GetCapabilities: + GetCapabilitiesXMLAdapter getCapabilitiesXMLAdapter = new GetCapabilitiesXMLAdapter(); + getCapabilitiesXMLAdapter.setRootElement( new XMLAdapter( xmlStream ).getRootElement() ); + GetCapabilities getCapabilities = getCapabilitiesXMLAdapter.parse( requestVersion ); + String updateSequence = getCapabilities.getUpdateSequence(); + doGetCapabilities( new HashMap(), response, updateSequence, getCapabilities ); + break; + case GetMap: + GetMapParser getMapParser = new GetMapParser(); + GetMap getMap = getMapParser.parse( xmlStream ); + Map map = new HashMap(); + doGetMap( map, response, VERSION_130, getMap ); + break; + case GetFeatureInfo: + GetFeatureInfoParser getFeatureInfoParser = new GetFeatureInfoParser(); + GetFeatureInfo getFeatureInfo = getFeatureInfoParser.parse( xmlStream ); + Map gfiMap = new HashMap(); + doGetFeatureInfo( gfiMap, response, VERSION_130, getFeatureInfo ); + break; + default: + String msg = "XML request handling is currently not supported for operation " + requestName; + throw new UnsupportedOperationException( msg ); + } + } catch ( OWSException e ) { + LOG.debug( e.getMessage(), e ); + sendServiceException( response, requestVersion, e ); + } catch ( XMLStreamException e ) { + LOG.debug( e.getMessage(), e ); + OWSException owsException = new OWSException( e.getMessage(), OWSException.NO_APPLICABLE_CODE ); + sendServiceException( response, requestVersion, owsException ); + } + } + + @Override + public void doSOAP( org.apache.axiom.soap.SOAPEnvelope soapDoc, HttpServletRequest request, + HttpResponseBuffer response, java.util.List multiParts, + org.apache.axiom.soap.SOAPFactory factory ) + throws ServletException, IOException, org.deegree.services.authentication.SecurityException { + Version requestVersion = null; + try { + + OMElement body = soapDoc.getBody().getFirstElement().cloneOMElement(); + XMLStreamReader xmlStream = body.getXMLStreamReaderWithoutCaching(); + nextElement( xmlStream ); + + String requestName = xmlStream.getLocalName(); + WMSRequestType requestType = detectWmsRequestType( requestName ); + requestVersion = parseAndCheckVersion( xmlStream ); + + if ( WMSRequestType.GetMap.equals( requestType ) ) { + doSoapGetMap( soapDoc.getVersion(), response, xmlStream ); + } else { + beginSoapResponse( soapDoc, response ); + switch ( requestType ) { + case GetCapabilities: + GetCapabilitiesXMLAdapter getCapabilitiesXMLAdapter = new GetCapabilitiesXMLAdapter(); + getCapabilitiesXMLAdapter.setRootElement( body ); + GetCapabilities getCapabilities = getCapabilitiesXMLAdapter.parse( requestVersion ); + String updateSequence = getCapabilities.getUpdateSequence(); + doGetCapabilities( new HashMap(), response, updateSequence, getCapabilities ); + break; + case GetFeatureInfo: + GetFeatureInfoParser getFeatureInfoParser = new GetFeatureInfoParser(); + GetFeatureInfo getFeatureInfo = getFeatureInfoParser.parse( xmlStream ); + Map gfiMap = new HashMap(); + doGetFeatureInfo( gfiMap, response, VERSION_130, getFeatureInfo ); + break; + default: + String msg = "SOAP request handling is currently not supported for operation " + requestName; + throw new UnsupportedOperationException( msg ); + } + endSOAPResponse( response ); + } + + } catch ( OWSException e ) { + LOG.debug( e.getMessage(), e ); + sendSOAPException( soapDoc.getHeader(), factory, response, e, null, null, null, request.getServerName(), + request.getCharacterEncoding() ); + sendServiceException( response, requestVersion, e ); + } catch ( XMLStreamException e ) { + LOG.debug( e.getMessage(), e ); + OWSException owsException = new OWSException( e.getMessage(), OWSException.NO_APPLICABLE_CODE ); + sendSOAPException( soapDoc.getHeader(), factory, response, owsException, null, null, null, + request.getServerName(), request.getCharacterEncoding() ); + } catch ( SOAPException e ) { + // TODO Auto-generated catch block + e.printStackTrace(); + } } /** @@ -734,7 +779,123 @@ public String getMetadataURLTemplate() { public FeatureInfoManager getFeatureInfoManager() { return featureInfoManager; } - + + private void initOfferedVersions( SupportedVersions supportedVersions ) { + List versions = null; + if ( supportedVersions != null ) { + versions = supportedVersions.getVersion(); + } + if ( versions == null || versions.isEmpty() ) { + LOG.info( "No protocol versions specified. Activating all implemented versions." ); + ImplementationMetadata md = ( (OWSProvider) getMetadata().getProvider() ).getImplementationMetadata(); + versions = new ArrayList( md.getImplementedVersions().size() ); + for ( Version version : md.getImplementedVersions() ) { + versions.add( version.toString() ); + } + } + validateAndSetOfferedVersions( versions ); + } + + private void doGetCapabilities( Map map, HttpResponseBuffer response, String updateSequence, + GetCapabilities req ) + throws OWSException, IOException { + Version myVersion = negotiateVersion( req ); + + String getUrl = OGCFrontController.getHttpGetURL(); + String postUrl = OGCFrontController.getHttpPostURL(); + + if ( metadataProvider != null ) { + controllers.get( myVersion ).getCapabilities( getUrl, postUrl, updateSequence, service, response, + metadataProvider.getServiceIdentification(), + metadataProvider.getServiceProvider(), map, this, + metadataProvider ); + } else { + controllers.get( myVersion ).getCapabilities( getUrl, postUrl, updateSequence, service, response, + identification, provider, map, this, null ); + } + + response.flushBuffer(); // TODO remove this to enable validation, enable validation on a DTD basis... + } + + private void doGetMap( Map map, HttpResponseBuffer response, Version version, GetMap gm ) + throws OWSException, IOException { + LinkedList headers = doGetMap( gm, map, version, response.getOutputStream() ); + response.setContentType( gm.getFormat() ); + addHeaders( response, headers ); + } + + private LinkedList doGetMap( GetMap getMap, Map map, Version version, OutputStream stream ) + throws OWSException, IOException { + checkGetMap( version, getMap ); + + RenderingInfo info = new RenderingInfo( getMap.getFormat(), getMap.getWidth(), getMap.getHeight(), + getMap.getTransparent(), getMap.getBgColor(), getMap.getBoundingBox(), + getMap.getPixelSize(), map ); + RenderContext ctx = ouputFormatProvider.getRenderers( info, stream ); + LinkedList headers = new LinkedList(); + service.getMap( getMap, headers, ctx ); + ctx.close(); + return headers; + } + + private void doGetFeatureInfo( Map map, final HttpResponseBuffer response, Version version, + org.deegree.protocol.wms.ops.GetFeatureInfo fi ) + throws OWSException, IOException { + checkGetFeatureInfo( version, fi ); + ICRS crs = fi.getCoordinateSystem(); + boolean geometries = fi.returnGeometries(); + List queryLayers = map( fi.getQueryLayers(), CollectionUtils. getToStringMapper() ); + + RenderingInfo info = new RenderingInfo( fi.getInfoFormat(), fi.getWidth(), fi.getHeight(), false, null, + fi.getEnvelope(), 0.28, map ); + String format = fi.getInfoFormat(); + info.setFormat( format ); + info.setFeatureCount( fi.getFeatureCount() ); + info.setX( fi.getX() ); + info.setY( fi.getY() ); + LinkedList headers = new LinkedList(); + Pair> pair = new Pair>( + service.getFeatures( fi, + headers ), + headers ); + + FeatureCollection col = pair.first; + addHeaders( response, pair.second ); + format = format == null ? "application/vnd.ogc.gml" : format; + response.setContentType( format ); + response.setCharacterEncoding( "UTF-8" ); + + Map fismap = new HashMap(); + fismap.put( "LAYERS", reduce( "", queryLayers, getStringJoiner( "," ) ) ); + GetFeatureInfoSchema fis = new GetFeatureInfoSchema( fismap ); + + FeatureType type = null; + Map nsBindings = new HashMap(); + List schema = service.getSchema( fis ); + for ( FeatureType ft : schema ) { + type = ft; + if ( ft.getSchema() != null ) { + nsBindings.putAll( ft.getSchema().getNamespaceBindings() ); + } + } + + String loc = getHttpGetURL() + "request=GetFeatureInfoSchema&layers=" + join( ",", queryLayers ); + + try { + FeatureInfoParams params = new FeatureInfoParams( nsBindings, col, format, geometries, loc, type, crs ); + featureInfoManager.serializeFeatureInfo( params, new StandardFeatureInfoContext( response ) ); + response.flushBuffer(); + } catch ( XMLStreamException e ) { + throw new IOException( e.getLocalizedMessage(), e ); + } + } + + private void sendServiceException( HttpResponseBuffer response, Version requestVersion, OWSException e ) + throws ServletException { + ExceptionSerializer serializer = getExceptionSerializer( requestVersion ); + sendException( null, serializer, e, response ); + } + private void addSupportedImageFormats( DeegreeWMS conf ) { if ( conf.getGetMapFormats() != null ) { GetMapFormatsType getMapFormats = conf.getGetMapFormats(); @@ -748,6 +909,112 @@ private void addSupportedImageFormats( DeegreeWMS conf ) { } } + private WMSRequestType detectWmsRequestType( String requestName ) + throws OWSException { + for ( WMSRequestType wmsRequestType : WMSRequestType.values() ) { + if ( wmsRequestType.name().equals( requestName ) ) + return wmsRequestType; + } + String msg = "Request type '" + requestName + "' is not supported."; + throw new OWSException( msg, OWSException.OPERATION_NOT_SUPPORTED, "request" ); + } + + private Version parseAndCheckVersion( XMLStreamReader xmlStream ) + throws OWSException { + String version = XMLStreamUtils.getAttributeValue( xmlStream, "version" ); + Version parsedVersion = parseVersion( version ); + return checkVersion( parsedVersion ); + } + + private Version parseVersion( String versionString ) + throws OWSException { + if ( versionString != null && !"".equals( versionString ) ) { + try { + return Version.parseVersion( versionString ); + } catch ( InvalidParameterValueException e ) { + throw new OWSException( e.getMessage(), OWSException.INVALID_PARAMETER_VALUE, "version" ); + } + } + return null; + } + + private void doSoapGetMap( SOAPVersion soapVersion, HttpResponseBuffer response, XMLStreamReader xmlStream ) + throws OWSException, XMLStreamException, IOException, SOAPException { + response.setContentType( "application/xop+xml" ); + + GetMapParser getMapParser = new GetMapParser(); + GetMap getMap = getMapParser.parse( xmlStream ); + Map map = new HashMap(); + + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + doGetMap( getMap, map, VERSION_130, stream ); + + String contentId = UUID.randomUUID().toString(); + + SOAPMessage message = createSoapMessage( soapVersion, contentId ); + + AttachmentPart attachmentPart = createAttachment( getMap, stream, message, contentId ); + message.addAttachmentPart( attachmentPart ); + message.writeTo( response.getOutputStream() ); + } + + private SOAPMessage createSoapMessage( SOAPVersion soapVersion, String contentId ) + throws SOAPException { + String soapProtocol = SOAPConstants.SOAP_1_2_PROTOCOL; + if ( isSoap11( soapVersion ) ) + soapProtocol = SOAPConstants.SOAP_1_1_PROTOCOL; + MessageFactory messageFactory = MessageFactory.newInstance( soapProtocol ); + + SOAPMessage message = messageFactory.createMessage(); + SOAPPart soapPart = message.getSOAPPart(); + SOAPEnvelope envelope = soapPart.getEnvelope(); + SOAPBody body = envelope.getBody(); + + envelope.createName( "response", CommonNamespaces.WMS_PREFIX, CommonNamespaces.WMSNS ); + Name name = envelope.createName( "response", CommonNamespaces.WMS_PREFIX, CommonNamespaces.WMSNS ); + + SOAPBodyElement bodyElement = body.addBodyElement( name ); + bodyElement.setTextContent( contentId ); + return message; + } + + private AttachmentPart createAttachment( GetMap getMap, ByteArrayOutputStream stream, SOAPMessage message, + String contentId ) { + DataSource ds = new ByteArrayDataSource( stream.toByteArray() ); + DataHandler dataHandler = new DataHandler( ds ); + AttachmentPart attachmentPart = message.createAttachmentPart( dataHandler ); + attachmentPart.setContentId( contentId ); + attachmentPart.setContentType( getMap.getFormat() ); + return attachmentPart; + } + + private void beginSoapResponse( org.apache.axiom.soap.SOAPEnvelope soapDoc, HttpResponseBuffer response ) + throws IOException, XMLStreamException { + if ( isSoap11( soapDoc.getVersion() ) ) { + beginSoap11Response( response ); + } else { + beginSOAPResponse( response ); + } + } + + private boolean isSoap11( SOAPVersion soapVersion ) { + return soapVersion instanceof SOAP11Version; + } + + private void beginSoap11Response( HttpResponseBuffer response ) + throws IOException, XMLStreamException { + response.setContentType( "text/xml" ); + XMLStreamWriter xmlWriter = response.getXMLWriter(); + String soapEnvNS = "http://schemas.xmlsoap.org/soap/envelope/"; + String xsiNS = "http://www.w3.org/2001/XMLSchema-instance"; + xmlWriter.writeStartElement( "soap", "Envelope", soapEnvNS ); + xmlWriter.writeNamespace( "soap", soapEnvNS ); + xmlWriter.writeNamespace( "xsi", xsiNS ); + xmlWriter.writeAttribute( xsiNS, "schemaLocation", + "http://schemas.xmlsoap.org/soap/envelope/ http://schemas.xmlsoap.org/soap/envelope/" ); + xmlWriter.writeStartElement( soapEnvNS, "Body" ); + } + /** * Controller * diff --git a/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/WMSControllerBase.java b/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/WMSControllerBase.java index f802cc8495..b8529e10ec 100644 --- a/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/WMSControllerBase.java +++ b/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/WMSControllerBase.java @@ -182,7 +182,6 @@ public void getCapabilities( String getUrl, String postUrl, String updateSequenc WMSController controller, OWSMetadataProvider metadata ) throws OWSException, IOException { getUrl = getUrl.substring( 0, getUrl.length() - 1 ); - postUrl = postUrl.substring( 0, getUrl.length() - 1 ); if ( updateSequence != null && updateSequence.trim().length() > 0 ) { try { int seq = parseInt( updateSequence ); diff --git a/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/capabilities/Capabilities130XMLAdapter.java b/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/capabilities/Capabilities130XMLAdapter.java index fac922cbb4..7854fff44f 100644 --- a/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/capabilities/Capabilities130XMLAdapter.java +++ b/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/capabilities/Capabilities130XMLAdapter.java @@ -88,13 +88,17 @@ public class Capabilities130XMLAdapter { private final String getUrl; - private MapService service; + private final String postUrl; + + private final MapService service; private final WMSController controller; - private WmsCapabilities130MetadataWriter metadataWriter; + private final WmsCapabilities130MetadataWriter metadataWriter; + + private final WmsCapabilities130ThemeWriter themeWriter; - private WmsCapabilities130ThemeWriter themeWriter; + private final Wms130SoapExtendedCapabilitesWriter soapExtendedCapabilitesWriter = new Wms130SoapExtendedCapabilitesWriter(); /** * @param identification @@ -108,11 +112,13 @@ public Capabilities130XMLAdapter( ServiceIdentification identification, ServiceP OWSMetadataProvider metadata, String getUrl, String postUrl, MapService service, WMSController controller ) { this.getUrl = getUrl; + this.postUrl = postUrl; this.service = service; this.controller = controller; - metadataWriter = new WmsCapabilities130MetadataWriter( identification, provider, getUrl, postUrl, controller ); + this.metadataWriter = new WmsCapabilities130MetadataWriter( identification, provider, getUrl, postUrl, + controller ); final String mdUrlTemplate = getMetadataUrlTemplate( controller, getUrl ); - themeWriter = new WmsCapabilities130ThemeWriter( metadata, this, mdUrlTemplate ); + this.themeWriter = new WmsCapabilities130ThemeWriter( metadata, this, mdUrlTemplate ); } private String getMetadataUrlTemplate( final WMSController controller, final String getUrl ) { @@ -186,6 +192,7 @@ private void writeCapability( XMLStreamWriter writer ) writer.writeEndElement(); writeExtendedCapabilities( writer ); + soapExtendedCapabilitesWriter.writeSoapWmsExtendedCapabilites( writer, postUrl ); writeThemes( writer, service.getThemes() ); @@ -251,7 +258,7 @@ public static void writeDimensions( XMLStreamWriter writer, Map legendSize, - String layerName, Style style ) + String layerName, Style style ) throws XMLStreamException { writer.writeStartElement( WMSNS, "Style" ); writeElement( writer, WMSNS, "Name", name ); @@ -277,4 +284,4 @@ public void writeStyle( XMLStreamWriter writer, String name, String title, Pair< writer.writeEndElement(); } -} +} \ No newline at end of file diff --git a/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/capabilities/Wms130SoapExtendedCapabilitesWriter.java b/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/capabilities/Wms130SoapExtendedCapabilitesWriter.java new file mode 100644 index 0000000000..c6d0cc3edb --- /dev/null +++ b/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/capabilities/Wms130SoapExtendedCapabilitesWriter.java @@ -0,0 +1,131 @@ +//$HeadURL$ +/*---------------------------------------------------------------------------- + This file is part of deegree, http://deegree.org/ + Copyright (C) 2001-2015 by: + - Department of Geography, University of Bonn - + and + - lat/lon GmbH - + + This library is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at your option) + any later version. + This library is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + details. + You should have received a copy of the GNU Lesser General Public License + along with this library; if not, write to the Free Software Foundation, Inc., + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Contact information: + + lat/lon GmbH + Aennchenstr. 19, 53177 Bonn + Germany + http://lat-lon.de/ + + Department of Geography, University of Bonn + Prof. Dr. Klaus Greve + Postfach 1147, 53001 Bonn + Germany + http://www.geographie.uni-bonn.de/deegree/ + + e-mail: info@deegree.org + ----------------------------------------------------------------------------*/ +package org.deegree.services.wms.controller.capabilities; + +import static org.deegree.commons.xml.CommonNamespaces.WMSNS; +import static org.deegree.commons.xml.CommonNamespaces.WMS_PREFIX; +import static org.deegree.commons.xml.CommonNamespaces.XLINK_PREFIX; +import static org.deegree.commons.xml.CommonNamespaces.XLNNS; +import static org.deegree.commons.xml.CommonNamespaces.XSINS; +import static org.deegree.commons.xml.CommonNamespaces.XSI_PREFIX; + +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamWriter; + +/** + * Writes soap wms support as extended capabilities. + * + * @author Lyn Goltz + */ +public class Wms130SoapExtendedCapabilitesWriter { + + private static final String SOAPWMS_XSD_LOCATION = "http://schemas.deegree.org/extensions/services/wms/1.3.0/soapwms.xsd"; + + public static final String SOAPWMS_NS = "http://schemas.deegree.org/extensions/services/wms/1.3.0"; + + public static final String SOAPWMS_PREFIX = "soapwms"; + + /** + * Writes soap support as extended capabilities. + * + * @param writer + * to write in, never null + * @param postUrl + * the url used as endpoint, never null + * @throws XMLStreamException + */ + public void writeSoapWmsExtendedCapabilites( XMLStreamWriter writer, String postUrl ) + throws XMLStreamException { + writer.setPrefix( SOAPWMS_PREFIX, SOAPWMS_NS ); + writer.writeStartElement( SOAPWMS_NS, "ExtendedCapabilities" ); + writer.writeNamespace( SOAPWMS_PREFIX, SOAPWMS_NS ); + writer.writeNamespace( WMS_PREFIX, WMSNS ); + writer.writeNamespace( XSI_PREFIX, XSINS ); + writer.writeNamespace( XLINK_PREFIX, XLNNS ); + + writer.writeAttribute( XSINS, "schemaLocation", SOAPWMS_NS + " " + SOAPWMS_XSD_LOCATION ); + + writer.writeStartElement( SOAPWMS_NS, "SOAP" ); + + writeOnlineResource( writer, postUrl ); + writeSoapVersionConstraint( writer ); + writeSupportedOperations( writer ); + + writer.writeEndElement(); + writer.writeEndElement(); + } + + private void writeOnlineResource( XMLStreamWriter writer, String postUrl ) + throws XMLStreamException { + writer.writeStartElement( WMSNS, "OnlineResource" ); + writer.writeAttribute( XLNNS, "type", "simple" ); + writer.writeAttribute( XLNNS, "href", postUrl ); + writer.writeEndElement(); + } + + private void writeSoapVersionConstraint( XMLStreamWriter writer ) + throws XMLStreamException { + writer.writeStartElement( SOAPWMS_NS, "Constraint" ); + writer.writeAttribute( "name", "SOAPVersion" ); + writeValue( writer, "1.1" ); + writeValue( writer, "1.2" ); + writer.writeEndElement(); + } + + private void writeSupportedOperations( XMLStreamWriter writer ) + throws XMLStreamException { + writer.writeStartElement( SOAPWMS_NS, "SupportedOperations" ); + writeOperation( writer, "GetCapabilities" ); + writeOperation( writer, "GetMap" ); + writeOperation( writer, "GetFeatureInfo" ); + writer.writeEndElement(); + } + + private void writeValue( XMLStreamWriter writer, String value ) + throws XMLStreamException { + writer.writeStartElement( SOAPWMS_NS, "Value" ); + writer.writeCharacters( value ); + writer.writeEndElement(); + } + + private void writeOperation( XMLStreamWriter writer, String operationName ) + throws XMLStreamException { + writer.writeStartElement( SOAPWMS_NS, "Operation" ); + writer.writeAttribute( "name", operationName ); + writer.writeEndElement(); + } + +} \ No newline at end of file diff --git a/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/capabilities/WmsCapabilities130MetadataWriter.java b/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/capabilities/WmsCapabilities130MetadataWriter.java index f84cbd0359..a8e7e66758 100644 --- a/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/capabilities/WmsCapabilities130MetadataWriter.java +++ b/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/capabilities/WmsCapabilities130MetadataWriter.java @@ -44,7 +44,6 @@ Occam Labs UG (haftungsbeschränkt) import static org.deegree.commons.xml.CommonNamespaces.SLDNS; import static org.deegree.commons.xml.CommonNamespaces.WMSNS; import static org.deegree.commons.xml.CommonNamespaces.XLNNS; -import static org.deegree.commons.xml.XMLAdapter.maybeWriteElement; import static org.deegree.commons.xml.XMLAdapter.maybeWriteElementNS; import static org.deegree.commons.xml.XMLAdapter.writeElement; @@ -122,17 +121,17 @@ void writeRequest( XMLStreamWriter writer ) writer.writeStartElement( WMSNS, "GetCapabilities" ); writeElement( writer, WMSNS, "Format", "text/xml" ); - writeDCP( writer, true, false ); + writeDCP( writer, true, true ); writer.writeEndElement(); writer.writeStartElement( WMSNS, "GetMap" ); writeImageFormats( writer ); - writeDCP( writer, true, false ); + writeDCP( writer, true, true ); writer.writeEndElement(); writer.writeStartElement( WMSNS, "GetFeatureInfo" ); writeInfoFormats( writer ); - writeDCP( writer, true, false ); + writeDCP( writer, true, true ); writer.writeEndElement(); writer.writeStartElement( SLDNS, "GetLegendGraphic" ); diff --git a/deegree-services/deegree-services-wms/src/test/java/org/deegree/services/wms/controller/capabilities/Wms130SoapExtendedCapabilitesWriterTest.java b/deegree-services/deegree-services-wms/src/test/java/org/deegree/services/wms/controller/capabilities/Wms130SoapExtendedCapabilitesWriterTest.java new file mode 100644 index 0000000000..8b34417900 --- /dev/null +++ b/deegree-services/deegree-services-wms/src/test/java/org/deegree/services/wms/controller/capabilities/Wms130SoapExtendedCapabilitesWriterTest.java @@ -0,0 +1,113 @@ +//$HeadURL$ +/*---------------------------------------------------------------------------- + This file is part of deegree, http://deegree.org/ + Copyright (C) 2001-2015 by: + - Department of Geography, University of Bonn - + and + - lat/lon GmbH - + + This library is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at your option) + any later version. + This library is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + details. + You should have received a copy of the GNU Lesser General Public License + along with this library; if not, write to the Free Software Foundation, Inc., + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Contact information: + + lat/lon GmbH + Aennchenstr. 19, 53177 Bonn + Germany + http://lat-lon.de/ + + Department of Geography, University of Bonn + Prof. Dr. Klaus Greve + Postfach 1147, 53001 Bonn + Germany + http://www.geographie.uni-bonn.de/deegree/ + + e-mail: info@deegree.org + ----------------------------------------------------------------------------*/ +package org.deegree.services.wms.controller.capabilities; + +import static org.deegree.commons.xml.CommonNamespaces.WMSNS; +import static org.deegree.commons.xml.CommonNamespaces.WMS_PREFIX; +import static org.deegree.commons.xml.CommonNamespaces.XLINK_PREFIX; +import static org.deegree.commons.xml.CommonNamespaces.XLNNS; +import static org.deegree.services.wms.controller.capabilities.Wms130SoapExtendedCapabilitesWriter.SOAPWMS_NS; +import static org.deegree.services.wms.controller.capabilities.Wms130SoapExtendedCapabilitesWriter.SOAPWMS_PREFIX; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.junit.Assert.assertThat; +import static org.xmlmatchers.XmlMatchers.hasXPath; +import static org.xmlmatchers.transform.XmlConverters.xml; + +import java.io.ByteArrayOutputStream; +import java.net.URL; + +import javax.xml.namespace.NamespaceContext; +import javax.xml.stream.XMLOutputFactory; +import javax.xml.stream.XMLStreamWriter; +import javax.xml.validation.Schema; + +import org.junit.Ignore; +import org.junit.Test; +import org.xml.sax.SAXException; +import org.xmlmatchers.XmlMatchers; +import org.xmlmatchers.namespace.SimpleNamespaceContext; +import org.xmlmatchers.validation.SchemaFactory; + +/** + * @author Lyn Goltz + */ +public class Wms130SoapExtendedCapabilitesWriterTest { + + @Test + public void testWriteSoapWmsExtendedCapabilites_ContainsPostUrl() + throws Exception { + Wms130SoapExtendedCapabilitesWriter writer = new Wms130SoapExtendedCapabilitesWriter(); + + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + XMLStreamWriter streamWriter = XMLOutputFactory.newInstance().createXMLStreamWriter( stream ); + String postUrl = "http://post.url/soap"; + writer.writeSoapWmsExtendedCapabilites( streamWriter, postUrl ); + streamWriter.close(); + + assertThat( xml( stream.toString() ), + hasXPath( "//soapwms:ExtendedCapabilities/soapwms:SOAP/wms:OnlineResource/@xlink:href", + nsBindings(), equalTo( postUrl ) ) ); + } + + @Ignore("Requires access to referenced schema") + @Test + public void testWriteSoapWmsExtendedCapabilites_SchemaValid() + throws Exception { + Wms130SoapExtendedCapabilitesWriter writer = new Wms130SoapExtendedCapabilitesWriter(); + + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + XMLStreamWriter streamWriter = XMLOutputFactory.newInstance().createXMLStreamWriter( stream ); + writer.writeSoapWmsExtendedCapabilites( streamWriter, "http://post.url/soap" ); + streamWriter.close(); + + assertThat( xml( stream.toString() ), XmlMatchers.conformsTo( schema() ) ); + } + + private Schema schema() + throws SAXException { + URL schemaResource = Wms130SoapExtendedCapabilitesWriterTest.class.getResource( "soapwms.xsd" ); + return SchemaFactory.w3cXmlSchemaFrom( schemaResource ); + } + + private NamespaceContext nsBindings() { + SimpleNamespaceContext simpleNamespaceContext = new SimpleNamespaceContext(); + simpleNamespaceContext.withBinding( SOAPWMS_PREFIX, SOAPWMS_NS ); + simpleNamespaceContext.withBinding( WMS_PREFIX, WMSNS ); + simpleNamespaceContext.withBinding( XLINK_PREFIX, XLNNS ); + return simpleNamespaceContext; + } + +} \ No newline at end of file diff --git a/deegree-services/deegree-services-wms/src/test/resources/org/deegree/services/wms/controller/capabilities/soapwms.xsd b/deegree-services/deegree-services-wms/src/test/resources/org/deegree/services/wms/controller/capabilities/soapwms.xsd new file mode 100644 index 0000000000..463c1f723c --- /dev/null +++ b/deegree-services/deegree-services-wms/src/test/resources/org/deegree/services/wms/controller/capabilities/soapwms.xsd @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/deegree-services/deegree-webservices-handbook/src/main/sphinx/intro.rst b/deegree-services/deegree-webservices-handbook/src/main/sphinx/intro.rst index 6b2915862b..28202538b7 100644 --- a/deegree-services/deegree-webservices-handbook/src/main/sphinx/intro.rst +++ b/deegree-services/deegree-webservices-handbook/src/main/sphinx/intro.rst @@ -44,6 +44,7 @@ deegree WMS is an implementation of the `OGC Web Map Service specification + + + + + \ No newline at end of file diff --git a/deegree-services/deegree-webservices-handbook/src/main/sphinx/xml/wms_getcapabilities_xml_request_body.xml b/deegree-services/deegree-webservices-handbook/src/main/sphinx/xml/wms_getcapabilities_xml_request_body.xml new file mode 100644 index 0000000000..8ed6f98732 --- /dev/null +++ b/deegree-services/deegree-webservices-handbook/src/main/sphinx/xml/wms_getcapabilities_xml_request_body.xml @@ -0,0 +1,2 @@ + \ No newline at end of file diff --git a/deegree-services/deegree-webservices-handbook/src/main/sphinx/xml/wms_getfeatureinfo_xml_request_body.xml b/deegree-services/deegree-webservices-handbook/src/main/sphinx/xml/wms_getfeatureinfo_xml_request_body.xml new file mode 100644 index 0000000000..a66cd25549 --- /dev/null +++ b/deegree-services/deegree-webservices-handbook/src/main/sphinx/xml/wms_getfeatureinfo_xml_request_body.xml @@ -0,0 +1,45 @@ + + + + + + municipalities + + Municipalities + + + + counties + + CountyBoundary + + + + zipcodes + + default + + + + EPSG:4326 + + -115.4 35.0 + -108.0 44.0 + + + + 1024 + 512 + + image/png + + + counties + 50 + 15 + + text/xml + + \ No newline at end of file diff --git a/deegree-services/deegree-webservices-handbook/src/main/sphinx/xml/wms_getmap_xml_request_body.xml b/deegree-services/deegree-webservices-handbook/src/main/sphinx/xml/wms_getmap_xml_request_body.xml new file mode 100644 index 0000000000..b9d467398a --- /dev/null +++ b/deegree-services/deegree-webservices-handbook/src/main/sphinx/xml/wms_getmap_xml_request_body.xml @@ -0,0 +1,39 @@ + + + + + municipalities + + Municipalities + + + + counties + + CountyBoundary + + + + zipcodes + + default + + + + EPSG:4326 + + -115.4 35.0 + -108.0 44.0 + + + + 1024 + 512 + + image/png + true + + XML + \ No newline at end of file diff --git a/deegree-services/deegree-webservices-handbook/src/main/sphinx/xsd/GFI.xsd b/deegree-services/deegree-webservices-handbook/src/main/sphinx/xsd/GFI.xsd new file mode 100644 index 0000000000..0e4ad0b099 --- /dev/null +++ b/deegree-services/deegree-webservices-handbook/src/main/sphinx/xsd/GFI.xsd @@ -0,0 +1,39 @@ + + + + + + XML Schema for OGC Web Map Service GetFeatureInfo request. + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/deegree-services/deegree-webservices-handbook/src/main/sphinx/xsd/soapwms.xsd b/deegree-services/deegree-webservices-handbook/src/main/sphinx/xsd/soapwms.xsd new file mode 100644 index 0000000000..463c1f723c --- /dev/null +++ b/deegree-services/deegree-webservices-handbook/src/main/sphinx/xsd/soapwms.xsd @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pom.xml b/pom.xml index 24b88a51f3..94b2ea5d01 100644 --- a/pom.xml +++ b/pom.xml @@ -338,6 +338,12 @@ 1.9.5 test + + org.xmlmatchers + xml-matchers + 1.0-RC1 + test + commons-io