/*---------------- FILE HEADER ------------------------------------------
This file is part of deegree.
Copyright (C) 2001-2006 by:
EXSE, Department of Geography, University of Bonn
http://www.giub.uni-bonn.de/deegree/
lat/lon GmbH
http://www.lat-lon.de
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:
Andreas Poth
lat/lon GmbH
Aennchenstr. 19
53115 Bonn
Germany
E-Mail: poth@lat-lon.de
Prof. Dr. Klaus Greve
Department of Geography
University of Bonn
Meckenheimer Allee 166
53115 Bonn
Germany
E-Mail: greve@giub.uni-bonn.de
---------------------------------------------------------------------------*/
package org.deegree.graphics.sld;
import java.io.IOException;
import java.io.StringReader;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import org.deegree.datatypes.QualifiedName;
import org.deegree.framework.log.ILogger;
import org.deegree.framework.log.LoggerFactory;
import org.deegree.framework.xml.ElementList;
import org.deegree.framework.xml.NamespaceContext;
import org.deegree.framework.xml.XMLFragment;
import org.deegree.framework.xml.XMLParsingException;
import org.deegree.framework.xml.XMLTools;
import org.deegree.model.filterencoding.AbstractFilter;
import org.deegree.model.filterencoding.ComplexFilter;
import org.deegree.model.filterencoding.Expression;
import org.deegree.model.filterencoding.FalseFilter;
import org.deegree.model.filterencoding.Filter;
import org.deegree.model.filterencoding.LogicalOperation;
import org.deegree.model.filterencoding.OperationDefines;
import org.deegree.ogcbase.CommonNamespaces;
import org.deegree.ogcbase.OGCDocument;
import org.deegree.ogcbase.PropertyPath;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.xml.sax.SAXException;
/**
* Factory class for all mapped SLD-elements.
* <p>
* TODO: Default values for omitted elements (such as fill color) should better not be used in the
* construction of the corresponding objects (Fill), but marked as left out (to make it possible to
* differentiate between explicitly given values and default values).
* <p>
*
* @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
* @author <a href="mailto:mschneider@lat-lon.de">Markus Schneider</a>
* @version $Revision: 1.26 $ $Date: 2006/11/30 08:40:34 $
*/
public class SLDFactory {
private static final ILogger LOG = LoggerFactory.getLogger( SLDFactory.class );
private static URI ogcNS = CommonNamespaces.OGCNS;
private static URI xlnNS = CommonNamespaces.XLNNS;
private static NamespaceContext nsContext = CommonNamespaces.getNamespaceContext();
private static XMLFragment sldDoc = null;
/**
* Creates a <tt>StyledLayerDescriptor</tt>-instance from the given XML-representation.
* <p>
*
* @param s
* contains the XML document
* @throws XMLParsingException
* if a syntactic or semantic error in the XML document is encountered
* @return the constructed <tt>StyledLayerDescriptor</tt>-instance
*/
public static synchronized StyledLayerDescriptor createSLD( String s )
throws XMLParsingException {
StyledLayerDescriptor sld = null;
try {
sldDoc = new XMLFragment();
sldDoc.load( new StringReader( s ), XMLFragment.DEFAULT_URL );
sld = createSLD( sldDoc );
} catch ( IOException e ) {
LOG.logDebug( e.getMessage(), e );
throw new XMLParsingException( "IOException encountered while parsing SLD-Document" );
} catch ( SAXException e ) {
LOG.logDebug( e.getMessage(), e );
throw new XMLParsingException( "SAXException encountered while parsing SLD-Document" );
}
return sld;
}
public static StyledLayerDescriptor createSLD( URL url )
throws XMLParsingException {
StyledLayerDescriptor sld = null;
try {
sldDoc = new XMLFragment();
sldDoc.load( url );
sld = createSLD( sldDoc );
} catch ( IOException e ) {
LOG.logError( e.getMessage(), e );
throw new XMLParsingException( "IOException encountered while parsing SLD-Document" );
} catch ( SAXException e ) {
LOG.logError( e.getMessage(), e );
throw new XMLParsingException( "SAXException encountered while parsing SLD-Document" );
}
return sld;
}
/**
* Creates a <tt>StyledLayerDescriptor</tt>-instance according to the contents of the
* DOM-subtree starting at the given 'StyledLayerDescriptor'-<tt>Element</tt>.
* <p>
*
* @param element
* the 'StyledLayerDescriptor'-<tt>Element</tt>
* @throws XMLParsingException
* if a syntactic or semantic error in the DOM-subtree is encountered
* @return the constructed <tt>StyledLayerDescriptor</tt>-instance
*/
public static StyledLayerDescriptor createSLD( XMLFragment sldDoc )
throws XMLParsingException {
Element element = sldDoc.getRootElement();
// optional: <Name>
String name = XMLTools.getStringValue( "Name", CommonNamespaces.SLDNS, element, null );
// optional: <Title>
String title = XMLTools.getStringValue( "Title", CommonNamespaces.SLDNS, element, null );
// optional: <Abstract>
String abstract_ = XMLTools.getStringValue( "Abstract", CommonNamespaces.SLDNS, element,
null );
// required: version-Attribute
String version = XMLTools.getRequiredAttrValue( "version", null, element );
// optional: <NamedLayer>(s) / <UserLayer>(s)
NodeList nodelist = element.getChildNodes();
ArrayList layerList = new ArrayList( 100 );
for ( int i = 0; i < nodelist.getLength(); i++ ) {
if ( nodelist.item( i ) instanceof Element ) {
Element child = (Element) nodelist.item( i );
String namespace = child.getNamespaceURI();
if ( !CommonNamespaces.SLDNS.toASCIIString().equals( namespace ) ) {
continue;
}
String childName = child.getLocalName();
if ( childName.equals( "NamedLayer" ) ) {
layerList.add( createNamedLayer( child ) );
} else if ( childName.equals( "UserLayer" ) ) {
layerList.add( createUserLayer( child ) );
}
}
}
AbstractLayer[] al = new AbstractLayer[layerList.size()];
AbstractLayer[] layers = (AbstractLayer[]) layerList.toArray( al );
return new StyledLayerDescriptor( name, title, version, abstract_, layers );
}
/**
*
* @param element
* @param min
* @param max
* @return
*/
private static RasterSymbolizer createRasterSymbolizer( Element element, double min, double max ) {
throw new UnsupportedOperationException(
"method createRasterSymbolizer is not implemented yet" );
}
/**
* Creates a <tt>TextSymbolizer</tt>-instance according to the contents of the DOM-subtree
* starting at the given 'TextSymbolizer'-<tt>Element</tt>.
* <p>
*
* @param element
* the 'TextSymbolizer'-<tt>Element</tt>
* @param min
* scale-constraint to be used
* @param max
* scale-constraint to be used
* @throws XMLParsingException
* if a syntactic or semantic error in the DOM-subtree is encountered
* @return the constructed <tt>TextSymbolizer</tt>-instance
*/
private static TextSymbolizer createTextSymbolizer( Element element, double min, double max )
throws XMLParsingException {
// optional: <Geometry>
Geometry geometry = null;
Element geometryElement = XMLTools.getChildElement( "Geometry", CommonNamespaces.SLDNS,
element );
if ( geometryElement != null ) {
geometry = createGeometry( geometryElement );
}
// optional: <Label>
ParameterValueType label = null;
Element labelElement = XMLTools.getChildElement( "Label", CommonNamespaces.SLDNS, element );
if ( labelElement != null ) {
label = createParameterValueType( labelElement );
}
// optional: <Font>
Font font = null;
Element fontElement = XMLTools.getChildElement( "Font", CommonNamespaces.SLDNS, element );
if ( fontElement != null ) {
font = createFont( fontElement );
}
// optional: <LabelPlacement>
LabelPlacement labelPlacement = null;
Element lpElement = XMLTools.getChildElement( "LabelPlacement", CommonNamespaces.SLDNS,
element );
if ( lpElement != null ) {
labelPlacement = createLabelPlacement( lpElement );
} else {
PointPlacement pp = StyleFactory.createPointPlacement();
labelPlacement = StyleFactory.createLabelPlacement( pp );
}
// optional: <Halo>
Halo halo = null;
Element haloElement = XMLTools.getChildElement( "Halo", CommonNamespaces.SLDNS, element );
if ( haloElement != null ) {
halo = createHalo( haloElement );
}
// optional: <Fill>
Fill fill = null;
TextSymbolizer ps = null;
String respClass = XMLTools.getAttrValue( element, "responsibleClass" );
if ( respClass == null ) {
ps = new TextSymbolizer( geometry, label, font, labelPlacement, halo, fill, min, max );
} else {
ps = new TextSymbolizer( geometry, respClass, label, font, labelPlacement, halo, fill,
min, max );
}
return ps;
}
/**
* Creates a <tt>Halo</tt>-instance according to the contents of the DOM-subtree starting at
* the given 'Halo'-<tt>Element</tt>.
* <p>
*
* @param element
* the 'Halo'-<tt>Element</tt>
* @throws XMLParsingException
* if a syntactic or semantic error in the DOM-subtree is encountered
* @return the constructed <tt>Halo</tt>-instance
*/
private static Halo createHalo( Element element )
throws XMLParsingException {
// optional: <Radius>
ParameterValueType radius = null;
Element radiusElement = XMLTools.getChildElement( "Radius", CommonNamespaces.SLDNS, element );
if ( radiusElement != null ) {
radius = createParameterValueType( radiusElement );
}
// optional: <Fill>
Fill fill = null;
Element fillElement = XMLTools.getChildElement( "Fill", CommonNamespaces.SLDNS, element );
if ( fillElement != null ) {
fill = createFill( fillElement );
}
// optional: <Stroke>
Stroke stroke = null;
Element strokeElement = XMLTools.getChildElement( "Stroke", CommonNamespaces.SLDNS, element );
if ( strokeElement != null ) {
stroke = createStroke( strokeElement );
}
return new Halo( radius, fill, stroke );
}
/**
* Creates a <tt>LabelPlacement</tt>-instance according to the contents of the DOM-subtree
* starting at the given 'LabelPlacement'-<tt>Element</tt>.
* <p>
*
* @param element
* the 'LabelPlacement'-<tt>Element</tt>
* @throws XMLParsingException
* if a syntactic or semantic error in the DOM-subtree is encountered
* @return the constructed <tt>LabelPlacement</tt>-instance
*/
private static LabelPlacement createLabelPlacement( Element element )
throws XMLParsingException {
LabelPlacement labelPlacement = null;
// required: <PointPlacement> / <LinePlacement>
NodeList nodelist = element.getChildNodes();
PointPlacement pPlacement = null;
LinePlacement lPlacement = null;
for ( int i = 0; i < nodelist.getLength(); i++ ) {
if ( nodelist.item( i ) instanceof Element ) {
Element child = (Element) nodelist.item( i );
String namespace = child.getNamespaceURI();
if ( !CommonNamespaces.SLDNS.toASCIIString().equals( namespace ) ) {
continue;
}
String childName = child.getLocalName();
if ( childName.equals( "PointPlacement" ) ) {
pPlacement = createPointPlacement( child );
} else if ( childName.equals( "LinePlacement" ) ) {
lPlacement = createLinePlacement( child );
}
}
}
if ( ( pPlacement != null ) && ( lPlacement == null ) ) {
labelPlacement = new LabelPlacement( pPlacement );
} else if ( ( pPlacement == null ) && ( lPlacement != null ) ) {
labelPlacement = new LabelPlacement( lPlacement );
} else {
throw new XMLParsingException( "Element 'LabelPlacement' must contain exactly one "
+ "'PointPlacement'- or one 'LinePlacement'-element!" );
}
return labelPlacement;
}
/**
* Creates a <tt>PointPlacement</tt>-instance according to the contents of the DOM-subtree
* starting at the given 'PointPlacement'-<tt>Element</tt>.
* <p>
*
* @param element
* the 'PointPlacement'-<tt>Element</tt>
* @throws XMLParsingException
* if a syntactic or semantic error in the DOM-subtree is encountered
* @return the constructed <tt>PointPlacement</tt>-instance
*/
private static PointPlacement createPointPlacement( Element element )
throws XMLParsingException {
// optional: auto-Attribute (this is deegree-specific)
boolean auto = false;
String autoStr = XMLTools.getAttrValue( element, "auto" );
if ( autoStr != null && autoStr.equals( "true" ) ) {
auto = true;
}
// optional: <AnchorPoint>
ParameterValueType[] anchorPoint = null;
Element apElement = XMLTools.getChildElement( "AnchorPoint", CommonNamespaces.SLDNS,
element );
if ( apElement != null ) {
anchorPoint = new ParameterValueType[2];
Element apXElement = XMLTools.getChildElement( "AnchorPointX", CommonNamespaces.SLDNS,
apElement );
Element apYElement = XMLTools.getChildElement( "AnchorPointY", CommonNamespaces.SLDNS,
apElement );
if ( ( apXElement == null ) || ( apYElement == null ) ) {
throw new XMLParsingException( "Element 'AnchorPoint' must contain exactly one "
+ "'AnchorPointX'- and one 'AnchorPointY'-element!" );
}
anchorPoint[0] = createParameterValueType( apXElement );
anchorPoint[1] = createParameterValueType( apYElement );
}
// optional: <Displacement>
ParameterValueType[] displacement = null;
Element dElement = XMLTools.getChildElement( "Displacement", CommonNamespaces.SLDNS,
element );
if ( dElement != null ) {
displacement = new ParameterValueType[2];
Element dXElement = XMLTools.getChildElement( "DisplacementX", CommonNamespaces.SLDNS,
dElement );
Element dYElement = XMLTools.getChildElement( "DisplacementY", CommonNamespaces.SLDNS,
dElement );
if ( ( dXElement == null ) || ( dYElement == null ) ) {
throw new XMLParsingException(
"Element 'Displacement' must contain exactly one "
+ "'DisplacementX'- and one 'DisplacementY'-element!" );
}
displacement[0] = createParameterValueType( dXElement );
displacement[1] = createParameterValueType( dYElement );
}
// optional: <Rotation>
ParameterValueType rotation = null;
Element rElement = XMLTools.getChildElement( "Rotation", CommonNamespaces.SLDNS, element );
if ( rElement != null ) {
rotation = createParameterValueType( rElement );
}
return new PointPlacement( anchorPoint, displacement, rotation, auto );
}
/**
* Creates a <tt>LinePlacement</tt>-instance according to the contents of the DOM-subtree
* starting at the given 'LinePlacement'-<tt>Element</tt>.
* <p>
*
* @param element
* the 'LinePlacement'-<tt>Element</tt>
* @throws XMLParsingException
* if a syntactic or semantic error in the DOM-subtree is encountered
* @return the constructed <tt>LinePlacement</tt>-instance
*/
private static LinePlacement createLinePlacement( Element element )
throws XMLParsingException {
// optional: <PerpendicularOffset>
ParameterValueType pOffset = null;
Element pOffsetElement = XMLTools.getChildElement( "PerpendicularOffset",
CommonNamespaces.SLDNS, element );
if ( pOffsetElement != null ) {
pOffset = createParameterValueType( pOffsetElement );
}
// optional: <Gap> (this is deegree-specific)
ParameterValueType gap = null;
Element gapElement = XMLTools.getChildElement( "Gap", CommonNamespaces.SLDNS, element );
if ( gapElement != null ) {
gap = createParameterValueType( gapElement );
}
// optional: <LineWidth> (this is deegree-specific)
ParameterValueType lineWidth = null;
Element lineWidthElement = XMLTools.getChildElement( "LineWidth", CommonNamespaces.SLDNS,
element );
if ( lineWidthElement != null ) {
lineWidth = createParameterValueType( lineWidthElement );
}
return new LinePlacement( pOffset, lineWidth, gap );
}
/**
* Creates a <tt>Font</tt>-instance according to the contents of the DOM-subtree starting at
* the given 'Font'-<tt>Element</tt>.
* <p>
*
* @param element
* the 'Font'-<tt>Element</tt>
* @throws XMLParsingException
* if a syntactic or semantic error in the DOM-subtree is encountered
* @return the constructed <tt>Font</tt>-instance
*/
private static Font createFont( Element element )
throws XMLParsingException {
// optional: <CssParameter>s
ElementList nl = XMLTools.getChildElements( "CssParameter", CommonNamespaces.SLDNS, element );
HashMap cssParams = new HashMap( nl.getLength() );
for ( int i = 0; i < nl.getLength(); i++ ) {
CssParameter cssParam = createCssParameter( nl.item( i ) );
cssParams.put( cssParam.getName(), cssParam );
}
return new Font( cssParams );
}
/**
* Creates a <tt>ParameterValueType</tt>-instance according to the contents of the
* DOM-subtree starting at the given <tt>Element</tt>.
* <p>
*
* @param element
* the <tt>Element</tt> (must be of the type sld:ParameterValueType)
* @throws XMLParsingException
* if a syntactic or semantic error in the DOM-subtree is encountered
* @return the constructed <tt>ParameterValueType</tt>-instance
*/
private static ParameterValueType createParameterValueType( Element element )
throws XMLParsingException {
// mix of text nodes and <wfs:Expression>-elements
ArrayList componentList = new ArrayList();
NodeList nl = element.getChildNodes();
for ( int i = 0; i < nl.getLength(); i++ ) {
Node node = nl.item( i );
switch ( node.getNodeType() ) {
case Node.TEXT_NODE: {
componentList.add( node.getNodeValue() );
break;
}
case Node.ELEMENT_NODE: {
Expression expression = Expression.buildFromDOM( (Element) node );
componentList.add( expression );
break;
}
default:
throw new XMLParsingException( "Elements of type 'ParameterValueType' may only "
+ "consist of CDATA and 'ogc:Expression'-elements!" );
}
}
Object[] components = componentList.toArray( new Object[componentList.size()] );
return new ParameterValueType( components );
}
/**
* Creates a <tt>NamedStyle</tt>-instance according to the contents of the DOM-subtree
* starting at the given 'NamedStyle'-<tt>Element</tt>.
* <p>
*
* @param element
* the 'NamedStyle'-<tt>Element</tt>
* @throws XMLParsingException
* if a syntactic or semantic error in the DOM-subtree is encountered
* @return the constructed <tt>NamedStyle</tt>-instance
*/
private static NamedStyle createNamedStyle( Element element )
throws XMLParsingException {
// required: <Name>
String name = XMLTools.getRequiredStringValue( "Name", CommonNamespaces.SLDNS, element );
return new NamedStyle( name );
}
/**
*
*/
public static NamedStyle createNamedStyle( String name ) {
return new NamedStyle( name );
}
/**
* Creates a <tt>RemoteOWS</tt>-instance according to the contents of the DOM-subtree
* starting at the given 'RemoteOWS'-<tt>Element</tt>.
* <p>
*
* @param element
* the 'RemoteOWS'-<tt>Element</tt>
* @throws XMLParsingException
* if a syntactic or semantic error in the DOM-subtree is encountered
* @return the constructed <tt>RemoteOWS</tt>-instance
*/
private static RemoteOWS createRemoteOWS( Element element )
throws XMLParsingException {
// required: <Service>
String service = XMLTools.getRequiredStringValue( "Service", CommonNamespaces.SLDNS,
element );
if ( !( service.equals( "WFS" ) || service.equals( "WCS" ) ) ) {
throw new XMLParsingException( "Value ('" + service
+ "') of element 'service' is invalid. "
+ "Allowed values are: 'WFS' and 'WCS'." );
}
// required: <OnlineResource>
Element onlineResourceElement = XMLTools.getRequiredChildElement( "OnlineResource",
CommonNamespaces.SLDNS,
element );
String href = XMLTools.getRequiredAttrValue( "xlink:href", null, onlineResourceElement );
URL url = null;
try {
url = new URL( href );
} catch ( MalformedURLException e ) {
LOG.logDebug( e.getMessage(), e );
throw new XMLParsingException( "Value ('" + href + "') of attribute 'href' of "
+ "element 'OnlineResoure' does not denote a valid URL" );
}
return new RemoteOWS( service, url );
}
/**
* Creates a <tt>NamedLayer</tt>-instance according to the contents of the DOM-subtree
* starting at the given 'UserLayer'-<tt>Element</tt>.
* <p>
*
* @param element
* the 'NamedLayer'-<tt>Element</tt>
* @throws XMLParsingException
* if a syntactic or semantic error in the DOM-subtree is encountered
* @return the constructed <tt>NamedLayer</tt>-instance
*/
private static NamedLayer createNamedLayer( Element element )
throws XMLParsingException {
// required: <Name>
String name = XMLTools.getRequiredStringValue( "Name", CommonNamespaces.SLDNS, element );
// optional: <LayerFeatureConstraints>
LayerFeatureConstraints lfc = null;
Element lfcElement = XMLTools.getChildElement( "LayerFeatureConstraints",
CommonNamespaces.SLDNS, element );
if ( lfcElement != null ) {
lfc = createLayerFeatureConstraints( lfcElement );
}
// optional: <NamedStyle>(s) / <UserStyle>(s)
NodeList nodelist = element.getChildNodes();
ArrayList styleList = new ArrayList();
for ( int i = 0; i < nodelist.getLength(); i++ ) {
if ( nodelist.item( i ) instanceof Element ) {
Element child = (Element) nodelist.item( i );
String namespace = child.getNamespaceURI();
if ( !CommonNamespaces.SLDNS.toASCIIString().equals( namespace ) ) {
continue;
}
String childName = child.getLocalName();
if ( childName.equals( "NamedStyle" ) ) {
styleList.add( createNamedStyle( child ) );
} else if ( childName.equals( "UserStyle" ) ) {
styleList.add( createUserStyle( child ) );
}
}
}
AbstractStyle[] styles = (AbstractStyle[]) styleList.toArray( new AbstractStyle[styleList.size()] );
return new NamedLayer( name, lfc, styles );
}
/**
*
*/
public static NamedLayer createNamedLayer( String name,
LayerFeatureConstraints layerFeatureConstraints,
AbstractStyle[] styles ) {
return new NamedLayer( name, layerFeatureConstraints, styles );
}
/**
* Creates a <tt>UserLayer</tt>-instance according to the contents of the DOM-subtree
* starting at the given 'UserLayer'-<tt>Element</tt>.
* <p>
*
* @param element
* the 'UserLayer'-<tt>Element</tt>
* @throws XMLParsingException
* if a syntactic or semantic error in the DOM-subtree is encountered
* @return the constructed <tt>UserLayer</tt>-instance
*/
private static UserLayer createUserLayer( Element element )
throws XMLParsingException {
// optional: <Name>
String name = XMLTools.getStringValue( "Name", CommonNamespaces.SLDNS, element, null );
// optional: <RemoteOWS>
RemoteOWS remoteOWS = null;
Element remoteOWSElement = XMLTools.getChildElement( "RemoteOWS", CommonNamespaces.SLDNS,
element );
if ( remoteOWSElement != null ) {
remoteOWS = createRemoteOWS( remoteOWSElement );
}
// required: <LayerFeatureConstraints>
LayerFeatureConstraints lfc = null;
Element lfcElement = XMLTools.getRequiredChildElement( "LayerFeatureConstraints",
CommonNamespaces.SLDNS, element );
lfc = createLayerFeatureConstraints( lfcElement );
// optional: <UserStyle>(s)
ElementList nodelist = XMLTools.getChildElements( "UserStyle", CommonNamespaces.SLDNS,
element );
UserStyle[] styles = new UserStyle[nodelist.getLength()];
for ( int i = 0; i < nodelist.getLength(); i++ ) {
styles[i] = createUserStyle( nodelist.item( i ) );
}
return new UserLayer( name, lfc, styles, remoteOWS );
}
/**
* Creates a <tt>FeatureTypeConstraint</tt>-instance according to the contents of the
* DOM-subtree starting at the given 'FeatureTypeConstraint'-<tt>Element</tt>.
* <p>
*
* @param element
* the 'FeatureTypeConstraint'-<tt>Element</tt>
* @throws XMLParsingException
* if a syntactic or semantic error in the DOM-subtree is encountered
* @return the constructed <tt>FeatureTypeConstraint</tt>-instance
*/
private static FeatureTypeConstraint createFeatureTypeConstraint( Element element )
throws XMLParsingException {
// optional: <Name>
Node node = XMLTools.getRequiredNode( element, "sld:FeatureTypeName/text()",
CommonNamespaces.getNamespaceContext() );
QualifiedName name = XMLTools.getQualifiedNameValue( node );
// optional: <Filter>
Filter filter = null;
Element filterElement = XMLTools.getChildElement( "Filter", ogcNS, element );
if ( filterElement != null ) {
filter = AbstractFilter.buildFromDOM( filterElement );
}
// optional: <Extent>(s)
ElementList nodelist = XMLTools.getChildElements( "Extent", CommonNamespaces.SLDNS, element );
Extent[] extents = new Extent[nodelist.getLength()];
for ( int i = 0; i < nodelist.getLength(); i++ ) {
extents[i] = createExtent( nodelist.item( i ) );
}
return new FeatureTypeConstraint( name, filter, extents );
}
/**
* Creates an <tt>Extent</tt>-instance according to the contents of the DOM-subtree starting
* at the given 'Extent'-<tt>Element</tt>.
* <p>
*
* @param element
* the 'Extent'-<tt>Element</tt>
* @throws XMLParsingException
* if a syntactic or semantic error in the DOM-subtree is encountered
* @return the constructed <tt>Extent</tt>-instance
*/
private static Extent createExtent( Element element )
throws XMLParsingException {
// required: <Name>
String name = XMLTools.getRequiredStringValue( "Name", CommonNamespaces.SLDNS, element );
// required: <Value>
String value = XMLTools.getRequiredStringValue( "Value", CommonNamespaces.SLDNS, element );
return new Extent( name, value );
}
/**
* Creates a <tt>LayerFeatureConstraints</tt>-instance according to the contents of the
* DOM-subtree starting at the given 'LayerFeatureConstraints'-<tt>Element</tt>.
* <p>
*
* @param element
* the 'LayerFeatureConstraints'-<tt>Element</tt>
* @throws XMLParsingException
* if a syntactic or semantic error in the DOM-subtree is encountered
* @return the constructed <tt>LayerFeatureConstraints</tt>-instance
*/
public static LayerFeatureConstraints createLayerFeatureConstraints( Element element )
throws XMLParsingException {
// required: <FeatureTypeConstraint>(s)
ElementList nodelist = XMLTools.getChildElements( "FeatureTypeConstraint",
CommonNamespaces.SLDNS, element );
FeatureTypeConstraint[] ftcs = new FeatureTypeConstraint[nodelist.getLength()];
for ( int i = 0; i < nodelist.getLength(); i++ ) {
ftcs[i] = createFeatureTypeConstraint( nodelist.item( i ) );
}
return new LayerFeatureConstraints( ftcs );
}
/**
* Creates a <tt>UserStyle</tt>-instance according to the contents of the DOM-subtree
* starting at the given 'UserStyle'-<tt>Element</tt>.
* <p>
*
* @param element
* the 'UserStyle'-<tt>Element</tt>
* @throws XMLParsingException
* if a syntactic or semantic error in the DOM-subtree is encountered
* @return the constructed <tt>UserStyle</tt>-instance
*/
private static UserStyle createUserStyle( Element element )
throws XMLParsingException {
// optional: <Name>
String name = XMLTools.getStringValue( "Name", CommonNamespaces.SLDNS, element, null );
// optional: <Title>
String title = XMLTools.getStringValue( "Title", CommonNamespaces.SLDNS, element, null );
// optional: <Abstract>
String abstract_ = XMLTools.getStringValue( "Abstract", CommonNamespaces.SLDNS, element,
null );
// optional: <IsDefault>
String defaultString = XMLTools.getStringValue( "IsDefault", CommonNamespaces.SLDNS,
element, null );
boolean isDefault = false;
if ( defaultString != null ) {
if ( defaultString.equals( "1" ) ) {
isDefault = true;
}
}
// required: <FeatureTypeStyle> (s)
ElementList nl = XMLTools.getChildElements( "FeatureTypeStyle", CommonNamespaces.SLDNS,
element );
FeatureTypeStyle[] styles = new FeatureTypeStyle[nl.getLength()];
if ( styles.length == 0 ) {
throw new XMLParsingException( "Required child-element 'FeatureTypeStyle' of element "
+ "'UserStyle' is missing!" );
}
for ( int i = 0; i < nl.getLength(); i++ ) {
styles[i] = createFeatureTypeStyle( nl.item( i ) );
}
return new UserStyle( name, title, abstract_, isDefault, styles );
}
/**
* Creates a <tt>FeatureTypeStyle</tt>-instance according to the contents of the DOM-subtree
* starting at the given 'FeatureTypeStyle'-<tt>Element</tt>.
* <p>
* TODO: The ElseFilter currently does not work correctly with FeatureFilters.
* <p>
*
* @param element
* the 'FeatureTypeStyle'-<tt>Element</tt>
* @throws XMLParsingException
* if a syntactic or semantic error in the DOM-subtree is encountered
* @return the constructed <tt>FeatureTypeStyle</tt>-instance
*/
public static FeatureTypeStyle createFeatureTypeStyle( Element element )
throws XMLParsingException {
// optional: <Name>
String name = XMLTools.getStringValue( "Name", CommonNamespaces.SLDNS, element, null );
// optional: <Title>
String title = XMLTools.getStringValue( "Title", CommonNamespaces.SLDNS, element, null );
// optional: <Abstract>
String abstract_ = XMLTools.getStringValue( "Abstract", CommonNamespaces.SLDNS, element,
null );
// optional: <FeatureTypeName>
String featureTypeName = XMLTools.getStringValue( "FeatureTypeName",
CommonNamespaces.SLDNS, element, null );
// optional: several <Rule> / <SemanticTypeIdentifier>
NodeList nodelist = element.getChildNodes();
ArrayList ruleList = new ArrayList();
ArrayList typeIdentifierList = new ArrayList();
// collect Filters of all Rules
ArrayList filters = new ArrayList();
// collect all Rules that have an ElseFilter
ArrayList elseRules = new ArrayList();
for ( int i = 0; i < nodelist.getLength(); i++ ) {
if ( nodelist.item( i ) instanceof Element ) {
Element child = (Element) nodelist.item( i );
String namespace = child.getNamespaceURI();
if ( !CommonNamespaces.SLDNS.toString().equals( namespace ) ) {
continue;
}
String childName = child.getLocalName();
if ( childName.equals( "Rule" ) ) {
Rule rule = createRule( child );
if ( rule.hasElseFilter() ) {
elseRules.add( rule );
} else if ( rule.getFilter() == null
|| rule.getFilter() instanceof ComplexFilter ) {
filters.add( rule.getFilter() );
}
ruleList.add( rule );
} else if ( childName.equals( "SemanticTypeIdentifier" ) ) {
typeIdentifierList.add( XMLTools.getStringValue( child ) );
}
}
}
// compute and set the ElseFilter for all ElseFilter-Rules
Filter elseFilter = null;
// a Rule exists with no Filter at all -> elseFilter = false
if ( filters.contains( null ) ) {
elseFilter = new FalseFilter();
// one Rule with a Filter exists -> elseFilter = NOT Filter
} else if ( filters.size() == 1 ) {
elseFilter = new ComplexFilter( OperationDefines.NOT );
List arguments = ( (LogicalOperation) ( (ComplexFilter) elseFilter ).getOperation() ).getArguments();
ComplexFilter complexFilter = (ComplexFilter) filters.get( 0 );
arguments.add( complexFilter.getOperation() );
// several Rules with Filters exist -> elseFilter = NOT (Filter1 OR Filter2 OR...)
} else if ( filters.size() > 1 ) {
ComplexFilter innerFilter = new ComplexFilter( OperationDefines.OR );
elseFilter = new ComplexFilter( innerFilter, null, OperationDefines.NOT );
List arguments = ( (LogicalOperation) innerFilter.getOperation() ).getArguments();
Iterator it = filters.iterator();
while ( it.hasNext() ) {
ComplexFilter complexFilter = (ComplexFilter) it.next();
arguments.add( complexFilter.getOperation() );
}
}
Iterator it = elseRules.iterator();
while ( it.hasNext() ) {
( (Rule) it.next() ).setFilter( elseFilter );
}
Rule[] rules = (Rule[]) ruleList.toArray( new Rule[ruleList.size()] );
String[] typeIdentifiers = (String[]) typeIdentifierList.toArray( new String[typeIdentifierList.size()] );
return new FeatureTypeStyle( name, title, abstract_, featureTypeName, typeIdentifiers,
rules );
}
/**
* Creates a <tt>Rule</tt>-instance according to the contents of the DOM-subtree starting at
* the given 'Rule'-<tt>Element</tt>.
* <p>
*
* @param element
* the 'Rule'-<tt>Element</tt>
* @throws XMLParsingException
* if a syntactic or semantic error in the DOM-subtree is encountered
* @return the constructed <tt>Rule</tt>-instance
*/
private static Rule createRule( Element element )
throws XMLParsingException {
// optional: <Name>
String name = XMLTools.getStringValue( "Name", CommonNamespaces.SLDNS, element, null );
// optional: <Title>
String title = XMLTools.getStringValue( "Title", CommonNamespaces.SLDNS, element, null );
// optional: <Abstract>
String abstract_ = XMLTools.getStringValue( "Abstract", CommonNamespaces.SLDNS, element,
null );
// optional: <LegendGraphic>
LegendGraphic legendGraphic = null;
Element legendGraphicElement = XMLTools.getChildElement( "LegendGraphic",
CommonNamespaces.SLDNS, element );
if ( legendGraphicElement != null ) {
legendGraphic = createLegendGraphic( legendGraphicElement );
}
// optional: <Filter>
boolean isAnElseFilter = false;
Filter filter = null;
Element filterElement = XMLTools.getChildElement( "Filter", ogcNS, element );
if ( filterElement != null ) {
filter = AbstractFilter.buildFromDOM( filterElement );
}
// optional: <ElseFilter>
Element elseFilterElement = XMLTools.getChildElement( "ElseFilter", CommonNamespaces.SLDNS,
element );
if ( elseFilterElement != null ) {
isAnElseFilter = true;
}
if ( ( filterElement != null ) && ( elseFilterElement != null ) ) {
throw new XMLParsingException( "Element 'Rule' may contain a 'Filter'- or "
+ "an 'ElseFilter'-element, but not both!" );
}
// optional: <MinScaleDenominator>
double min = XMLTools.getNodeAsDouble( element, "sld:MinScaleDenominator", nsContext, 0.0 );
// optional: <MaxScaleDenominator>
double max = XMLTools.getNodeAsDouble( element, "sld:MaxScaleDenominator", nsContext, 9E99 );
// optional: different Symbolizer-elements
NodeList symbolizerNL = element.getChildNodes();
ArrayList symbolizerList = new ArrayList();
for ( int i = 0; i < symbolizerNL.getLength(); i++ ) {
if ( symbolizerNL.item( i ) instanceof Element ) {
Element symbolizerElement = (Element) symbolizerNL.item( i );
String namespace = symbolizerElement.getNamespaceURI();
if ( !CommonNamespaces.SLDNS.toString().equals( namespace ) ) {
continue;
}
String symbolizerName = symbolizerElement.getLocalName();
if ( symbolizerName.equals( "LineSymbolizer" ) ) {
symbolizerList.add( createLineSymbolizer( symbolizerElement, min, max ) );
} else if ( symbolizerName.equals( "PointSymbolizer" ) ) {
symbolizerList.add( createPointSymbolizer( symbolizerElement, min, max ) );
} else if ( symbolizerName.equals( "PolygonSymbolizer" ) ) {
symbolizerList.add( createPolygonSymbolizer( symbolizerElement, min, max ) );
} else if ( symbolizerName.equals( "TextSymbolizer" ) ) {
symbolizerList.add( createTextSymbolizer( symbolizerElement, min, max ) );
} else if ( symbolizerName.equals( "RasterSymbolizer" ) ) {
symbolizerList.add( createRasterSymbolizer( symbolizerElement, min, max ) );
}
}
}
Symbolizer[] symbolizers = (Symbolizer[]) symbolizerList.toArray( new Symbolizer[symbolizerList.size()] );
return new Rule( symbolizers, name, title, abstract_, legendGraphic, filter,
isAnElseFilter, min, max );
}
/**
* Creates a <tt>PointSymbolizer</tt>-instance according to the contents of the DOM-subtree
* starting at the given 'PointSymbolizer'-<tt>Element</tt>.
* <p>
*
* @param element
* the 'PointSymbolizer'-<tt>Element</tt>
* @param min
* scale-constraint to be used
* @param max
* scale-constraint to be used
* @throws XMLParsingException
* if a syntactic or semantic error in the DOM-subtree is encountered
* @return the constructed <tt>PointSymbolizer</tt>-instance
*/
private static PointSymbolizer createPointSymbolizer( Element element, double min, double max )
throws XMLParsingException {
// optional: <Geometry>
Geometry geometry = null;
Element geometryElement = XMLTools.getChildElement( "Geometry", CommonNamespaces.SLDNS,
element );
if ( geometryElement != null ) {
geometry = createGeometry( geometryElement );
}
// optional: <Graphic>
Graphic graphic = null;
Element graphicElement = XMLTools.getChildElement( "Graphic", CommonNamespaces.SLDNS,
element );
if ( graphicElement != null ) {
graphic = createGraphic( graphicElement );
}
PointSymbolizer ps = null;
String respClass = XMLTools.getAttrValue( element, "responsibleClass" );
if ( respClass == null ) {
ps = new PointSymbolizer( graphic, geometry, min, max );
} else {
ps = new PointSymbolizer( graphic, geometry, respClass, min, max );
}
return ps;
}
/**
* Creates a <tt>LineSymbolizer</tt>-instance according to the contents of the DOM-subtree
* starting at the given 'LineSymbolizer'-<tt>Element</tt>.
* <p>
*
* @param element
* the 'LineSymbolizer'-<tt>Element</tt>
* @param min
* scale-constraint to be used
* @param max
* scale-constraint to be used
* @throws XMLParsingException
* if a syntactic or semantic error in the DOM-subtree is encountered
* @return the constructed <tt>LineSymbolizer</tt>-instance
*/
private static LineSymbolizer createLineSymbolizer( Element element, double min, double max )
throws XMLParsingException {
// optional: <Geometry>
Geometry geometry = null;
Element geometryElement = XMLTools.getChildElement( "Geometry", CommonNamespaces.SLDNS,
element );
if ( geometryElement != null ) {
geometry = createGeometry( geometryElement );
}
// optional: <Stroke>
Stroke stroke = null;
Element strokeElement = XMLTools.getChildElement( "Stroke", CommonNamespaces.SLDNS, element );
if ( strokeElement != null ) {
stroke = createStroke( strokeElement );
}
LineSymbolizer ls = null;
String respClass = XMLTools.getAttrValue( element, "responsibleClass" );
if ( respClass == null ) {
ls = new LineSymbolizer( stroke, geometry, min, max );
} else {
ls = new LineSymbolizer( stroke, geometry, respClass, min, max );
}
return ls;
}
/**
* Creates a <tt>PolygonSymbolizer</tt>-instance according to the contents of the DOM-subtree
* starting at the given 'PolygonSymbolizer'-<tt>Element</tt>.
* <p>
*
* @param element
* the 'PolygonSymbolizer'-<tt>Element</tt>
* @param min
* scale-constraint to be used
* @param max
* scale-constraint to be used
* @throws XMLParsingException
* if a syntactic or semantic error in the DOM-subtree is encountered
* @return the constructed <tt>PolygonSymbolizer</tt>-instance
*/
private static PolygonSymbolizer createPolygonSymbolizer( Element element, double min,
double max )
throws XMLParsingException {
// optional: <Geometry>
Geometry geometry = null;
Element geometryElement = XMLTools.getChildElement( "Geometry", CommonNamespaces.SLDNS,
element );
if ( geometryElement != null ) {
geometry = createGeometry( geometryElement );
}
// optional: <Fill>
Fill fill = null;
Element fillElement = XMLTools.getChildElement( "Fill", CommonNamespaces.SLDNS, element );
if ( fillElement != null ) {
fill = createFill( fillElement );
}
// optional: <Stroke>
Stroke stroke = null;
Element strokeElement = XMLTools.getChildElement( "Stroke", CommonNamespaces.SLDNS, element );
if ( strokeElement != null ) {
stroke = createStroke( strokeElement );
}
PolygonSymbolizer ps = null;
String respClass = XMLTools.getAttrValue( element, "responsibleClass" );
if ( respClass == null ) {
ps = new PolygonSymbolizer( fill, stroke, geometry, min, max );
} else {
ps = new PolygonSymbolizer( fill, stroke, geometry, respClass, min, max );
}
return ps;
}
/**
* Creates a <tt>Geometry</tt>-instance according to the contents of the DOM-subtree starting
* at the given 'Geometry'-<tt>Element</tt>.
* <p>
* FIXME: Add support for 'Function'-Elements.
* <p>
*
* @param element
* the 'Geometry'-<tt>Element</tt>
* @throws XMLParsingException
* if a syntactic or semantic error in the DOM-subtree is encountered
* @return the constructed <tt>Geometry</tt>-instance
*/
private static Geometry createGeometry( Element element )
throws XMLParsingException {
Geometry geometry = null;
// required: <PropertyName>
Element propertyNameElement = XMLTools.getRequiredChildElement( "PropertyName", ogcNS,
element );
// optional: <Function>
Element functionElement = XMLTools.getChildElement( "Function", ogcNS, propertyNameElement );
// just a property name exists
if ( functionElement == null ) {
Node node = XMLTools.getNode( propertyNameElement, "/text()", nsContext );
PropertyPath pp = OGCDocument.parsePropertyPath( (Text) node );
geometry = new Geometry( pp, null );
} else {
// FIXME:
// the property probably contains a wfs:Function expression
}
return geometry;
}
/**
* Creates a <tt>Fill</tt>-instance according to the contents of the DOM-subtree starting at
* the given 'Fill'-<tt>Element</tt>.
* <p>
*
* @param element
* the 'Fill'-<tt>Element</tt>
* @throws XMLParsingException
* if a syntactic or semantic error in the DOM-subtree is encountered
* @return the constructed <tt>Fill</tt>-instance
*/
private static Fill createFill( Element element )
throws XMLParsingException {
// optional: <GraphicFill>
GraphicFill graphicFill = null;
Element graphicFillElement = XMLTools.getChildElement( "GraphicFill",
CommonNamespaces.SLDNS, element );
if ( graphicFillElement != null ) {
graphicFill = createGraphicFill( graphicFillElement );
}
// optional: <CssParameter>s
ElementList nl = XMLTools.getChildElements( "CssParameter", CommonNamespaces.SLDNS, element );
HashMap cssParams = new HashMap( nl.getLength() );
for ( int i = 0; i < nl.getLength(); i++ ) {
CssParameter cssParam = createCssParameter( nl.item( i ) );
cssParams.put( cssParam.getName(), cssParam );
}
return new Fill( cssParams, graphicFill );
}
/**
* Creates a <tt>LegendGraphic</tt>-instance according to the contents of the DOM-subtree
* starting at the given 'LegendGraphic'-element.
* <p>
*
* @param element
* the 'LegendGraphic'-<tt>Element</tt>
* @throws XMLParsingException
* if a syntactic or semantic error in the DOM-subtree is encountered
* @return the constructed <tt>Graphic</tt>-instance
*/
private static LegendGraphic createLegendGraphic( Element element )
throws XMLParsingException {
// required: <Graphic>
Element graphicElement = XMLTools.getRequiredChildElement( "Graphic",
CommonNamespaces.SLDNS, element );
Graphic graphic = createGraphic( graphicElement );
return new LegendGraphic( graphic );
}
/**
* Creates an <tt>ExternalGraphic</tt>-instance according to the contents of the DOM-subtree
* starting at the given 'ExternalGraphic'-<tt>Element</tt>.
* <p>
*
* @param element
* the 'ExternalGraphic'-<tt>Element</tt>
* @throws XMLParsingException
* if a syntactic or semantic error in the DOM-subtree is encountered
* @return the constructed <tt>ExternalGraphic</tt>-instance
*/
private static ExternalGraphic createExternalGraphic( Element element )
throws XMLParsingException {
// required: <OnlineResource>
Element onlineResourceElement = XMLTools.getRequiredChildElement( "OnlineResource",
CommonNamespaces.SLDNS,
element );
// required: href-Attribute (in <OnlineResource>)
String href = XMLTools.getRequiredAttrValue( "href", xlnNS, onlineResourceElement );
URL url = null;
try {
url = sldDoc.resolve( href );
} catch ( MalformedURLException e ) {
LOG.logDebug( e.getMessage(), e );
throw new XMLParsingException( "Value ('" + href + "') of attribute 'href' of "
+ "element 'OnlineResoure' does not denote a valid URL" );
}
// required: <Format> (in <OnlineResource>)
String format = XMLTools.getRequiredStringValue( "Format", CommonNamespaces.SLDNS, element );
return new ExternalGraphic( format, url );
}
/**
* Creates a <tt>Mark</tt>-instance according to the contents of the DOM-subtree starting at
* the given 'Mark'-<tt>Element</tt>.
* <p>
*
* @param element
* the 'Mark'-<tt>Element</tt>
* @throws XMLParsingException
* if a syntactic or semantic error in the DOM-subtree is encountered
* @return the constructed <tt>Mark</tt>-instance
*/
private static Mark createMark( Element element )
throws XMLParsingException {
Stroke stroke = null;
Fill fill = null;
// optional: <WellKnownName>
String wkn = XMLTools.getStringValue( "WellKnownName", CommonNamespaces.SLDNS, element,
null );
// optional: <Stroke>
Element strokeElement = XMLTools.getChildElement( "Stroke", CommonNamespaces.SLDNS, element );
if ( strokeElement != null ) {
stroke = createStroke( strokeElement );
}
// optional: <Fill>
Element fillElement = XMLTools.getChildElement( "Fill", CommonNamespaces.SLDNS, element );
if ( fillElement != null ) {
fill = createFill( fillElement );
}
return new Mark( wkn, stroke, fill );
}
/**
* Creates a <tt>Stroke</tt>-instance according to the contents of the DOM-subtree starting
* at the given 'Stroke'-<tt>Element</tt>.
* <p>
*
* @param element
* the 'Stroke'-<tt>Element</tt>
* @throws XMLParsingException
* if a syntactic or semantic error in the DOM-subtree is encountered
* @return the constructed <tt>Stroke</tt>-instance
*/
private static Stroke createStroke( Element element )
throws XMLParsingException {
GraphicFill gf = null;
GraphicStroke gs = null;
// optional: <GraphicFill>
Element gfElement = XMLTools.getChildElement( "GraphicFill", CommonNamespaces.SLDNS,
element );
if ( gfElement != null ) {
gf = createGraphicFill( gfElement );
}
// optional: <GraphicStroke>
Element gsElement = XMLTools.getChildElement( "GraphicStroke", CommonNamespaces.SLDNS,
element );
if ( gsElement != null ) {
gs = createGraphicStroke( gsElement );
}
// optional: <CssParameter>s
ElementList nl = XMLTools.getChildElements( "CssParameter", CommonNamespaces.SLDNS, element );
HashMap cssParams = new HashMap( nl.getLength() );
for ( int i = 0; i < nl.getLength(); i++ ) {
CssParameter cssParam = createCssParameter( nl.item( i ) );
cssParams.put( cssParam.getName(), cssParam );
}
return new Stroke( cssParams, gs, gf );
}
/**
* Creates a <tt>GraphicFill</tt>-instance according to the contents of the DOM-subtree
* starting at the given 'GraphicFill'-<tt>Element</tt>.
* <p>
*
* @param element
* the 'GraphicFill'-<tt>Element</tt>
* @throws XMLParsingException
* if a syntactic or semantic error in the DOM-subtree is encountered
* @return the constructed <tt>GraphicFill</tt>-instance
*/
private static GraphicFill createGraphicFill( Element element )
throws XMLParsingException {
// required: <Graphic>
Element graphicElement = XMLTools.getRequiredChildElement( "Graphic",
CommonNamespaces.SLDNS, element );
Graphic graphic = createGraphic( graphicElement );
return new GraphicFill( graphic );
}
/**
* Creates a <tt>GraphicStroke</tt>-instance according to the contents of the DOM-subtree
* starting at the given 'GraphicStroke'-<tt>Element</tt>.
* <p>
*
* @param element
* the 'GraphicStroke'-<tt>Element</tt>
* @throws XMLParsingException
* if a syntactic or semantic error in the DOM-subtree is encountered
* @return the constructed <tt>GraphicStroke</tt>-instance
*/
private static GraphicStroke createGraphicStroke( Element element )
throws XMLParsingException {
// required: <Graphic>
Element graphicElement = XMLTools.getRequiredChildElement( "Graphic",
CommonNamespaces.SLDNS, element );
Graphic graphic = createGraphic( graphicElement );
return new GraphicStroke( graphic );
}
/**
* Creates a <tt>Graphic</tt>-instance according to the contents of the DOM-subtree starting
* at the given 'Graphic'-element.
* <p>
*
* @param element
* the 'Graphic'-<tt>Element</tt>
* @throws XMLParsingException
* if a syntactic or semantic error in the DOM-subtree is encountered
* @return the constructed <tt>Graphic</tt>-instance
*/
private static Graphic createGraphic( Element element )
throws XMLParsingException {
// optional: <Opacity>
ParameterValueType opacity = null;
// optional: <Size>
ParameterValueType size = null;
// optional: <Rotation>
ParameterValueType rotation = null;
// optional: <ExternalGraphic>s / <Mark>s
NodeList nodelist = element.getChildNodes();
ArrayList marksAndExtGraphicsList = new ArrayList();
for ( int i = 0; i < nodelist.getLength(); i++ ) {
if ( nodelist.item( i ) instanceof Element ) {
Element child = (Element) nodelist.item( i );
String namespace = child.getNamespaceURI();
if ( !CommonNamespaces.SLDNS.toString().equals( namespace ) ) {
continue;
}
String childName = child.getLocalName();
if ( childName.equals( "ExternalGraphic" ) ) {
marksAndExtGraphicsList.add( createExternalGraphic( child ) );
} else if ( childName.equals( "Mark" ) ) {
marksAndExtGraphicsList.add( createMark( child ) );
} else if ( childName.equals( "Opacity" ) ) {
opacity = createParameterValueType( child );
} else if ( childName.equals( "Size" ) ) {
size = createParameterValueType( child );
} else if ( childName.equals( "Rotation" ) ) {
rotation = createParameterValueType( child );
}
}
}
Object[] marksAndExtGraphics =
marksAndExtGraphicsList.toArray( new Object[marksAndExtGraphicsList.size()] );
return new Graphic( marksAndExtGraphics, opacity, size, rotation );
}
/**
* Creates a <tt>CssParameter</tt>-instance according to the contents of the DOM-subtree
* starting at the given 'CssParameter'-<tt>Element</tt>.
* <p>
*
* @param element
* the 'CssParamter'-<tt>Element</tt>
* @throws XMLParsingException
* if a syntactic or semantic error in the DOM-subtree is encountered
* @return the constructed <tt>CssParameter</tt>-instance
*/
private static CssParameter createCssParameter( Element element )
throws XMLParsingException {
// required: name-Attribute
String name = XMLTools.getRequiredAttrValue( "name", null, element );
ParameterValueType pvt = createParameterValueType( element );
return ( new CssParameter( name, pvt ) );
}
}
/* ********************************************************************
Changes to this class. What the people have been up to:
$Log: SLDFactory.java,v $
Revision 1.26 2006/11/30 08:40:34 poth
refactoring (renaming of a method)
Revision 1.25 2006/11/29 21:28:30 poth
bug fixing - SLD GetMap requests containing user layers with featuretypeconstraints
Revision 1.24 2006/10/02 10:02:37 poth
debug statements changed from logDebug to logError in parsing method
Revision 1.23 2006/09/28 12:49:28 poth
code formating
Revision 1.22 2006/09/08 08:42:02 schmitz
Updated the WMS to be 1.1.1 conformant once again.
Cleaned up the WMS code.
Added cite WMS test data.
Revision 1.21 2006/08/06 20:26:00 poth
UnsupportedOperationException exception will be thrown if a not implemented method will be called
Revision 1.20 2006/07/29 08:51:12 poth
references to deprecated classes removed
Revision 1.19 2006/07/12 14:46:14 poth
comment footer added
********************************************************************** */