001    // $HeadURL:
002    // /deegreerepository/deegree/src/org/deegree/model/filterencoding/capabilities/FilterCapabilities100Factory.java,v
003    // 1.3 2005/03/09 11:55:46 mschneider Exp $
004    /*----------------------------------------------------------------------------
005     This file is part of deegree, http://deegree.org/
006     Copyright (C) 2001-2009 by:
007       Department of Geography, University of Bonn
008     and
009       lat/lon GmbH
010    
011     This library is free software; you can redistribute it and/or modify it under
012     the terms of the GNU Lesser General Public License as published by the Free
013     Software Foundation; either version 2.1 of the License, or (at your option)
014     any later version.
015     This library is distributed in the hope that it will be useful, but WITHOUT
016     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
017     FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
018     details.
019     You should have received a copy of the GNU Lesser General Public License
020     along with this library; if not, write to the Free Software Foundation, Inc.,
021     59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
022    
023     Contact information:
024    
025     lat/lon GmbH
026     Aennchenstr. 19, 53177 Bonn
027     Germany
028     http://lat-lon.de/
029    
030     Department of Geography, University of Bonn
031     Prof. Dr. Klaus Greve
032     Postfach 1147, 53001 Bonn
033     Germany
034     http://www.geographie.uni-bonn.de/deegree/
035    
036     e-mail: info@deegree.org
037    ----------------------------------------------------------------------------*/
038    package org.deegree.model.filterencoding.capabilities;
039    
040    import java.net.URI;
041    import java.net.URL;
042    import java.util.ArrayList;
043    import java.util.HashMap;
044    import java.util.Iterator;
045    import java.util.List;
046    import java.util.Map;
047    
048    import org.deegree.framework.log.ILogger;
049    import org.deegree.framework.log.LoggerFactory;
050    import org.deegree.framework.xml.ElementList;
051    import org.deegree.framework.xml.NamespaceContext;
052    import org.deegree.framework.xml.XMLFragment;
053    import org.deegree.framework.xml.XMLParsingException;
054    import org.deegree.framework.xml.XMLTools;
055    import org.deegree.ogcbase.CommonNamespaces;
056    import org.deegree.ogcwebservices.getcapabilities.UnknownOperatorNameException;
057    import org.w3c.dom.Element;
058    
059    /**
060     *
061     *
062     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
063     * @author last edited by: $Author: mschneider $
064     *
065     * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $
066     */
067    public class FilterCapabilities100Fragment extends XMLFragment {
068    
069        private static final long serialVersionUID = 2430362135205814360L;
070    
071        private static final URI OGCNS = CommonNamespaces.OGCNS;
072    
073        private static final ILogger LOG = LoggerFactory.getLogger( FilterCapabilities100Fragment.class );
074    
075        private static NamespaceContext nsContext = CommonNamespaces.getNamespaceContext();
076    
077        /**
078         * Creates a new <code>FilterCapabilities100Fragment</code> from the given parameters.
079         *
080         * @param element
081         * @param systemId
082         */
083        public FilterCapabilities100Fragment( Element element, URL systemId ) {
084            super( element );
085            setSystemId( systemId );
086        }
087    
088        /**
089         * Returns the object representation for the <code>ogc:Filter_Capabilities</code> root element.
090         *
091         * @return object representation for the given <code>ogc:Filter_Capabilities</code> element
092         * @throws XMLParsingException
093         */
094        public FilterCapabilities parseFilterCapabilities()
095                                throws XMLParsingException {
096            Element e1 = (Element) XMLTools.getRequiredNode( getRootElement(), "ogc:Scalar_Capabilities", nsContext );
097            Element e2 = (Element) XMLTools.getRequiredNode( getRootElement(), "ogc:Spatial_Capabilities", nsContext );
098            return new FilterCapabilities( parseScalarCapabilities( e1 ), parseSpatialCapabilities( e2 ) );
099        }
100    
101        /**
102         * Returns the object representation for an <code>ogc:Spatial_Capabilities</code> element.
103         *
104         * @return object representation for the given <code>ogc:Spatial_Capabilities</code> element
105         * @throws XMLParsingException
106         */
107        private SpatialCapabilities parseSpatialCapabilities( Element spatialElement )
108                                throws XMLParsingException {
109            Map<String, Element> operatorMap = parseOperators( (Element) XMLTools.getRequiredNode( spatialElement,
110                                                                                                   "ogc:Spatial_Operators",
111                                                                                                   nsContext ) );
112            ArrayList<SpatialOperator> operators = new ArrayList<SpatialOperator>();
113            Iterator<String> it = operatorMap.keySet().iterator();
114            while ( it.hasNext() ) {
115                String next = it.next();
116                try {
117                    operators.add( OperatorFactory100.createSpatialOperator( next ) );
118                } catch ( UnknownOperatorNameException e ) {
119                    LOG.logWarning( "Operator name not found. Trying again with filter encoding 1.1.0 names..." );
120                    try {
121                        operators.add( OperatorFactory110.createSpatialOperator( next ) );
122                    } catch ( UnknownOperatorNameException e2 ) {
123                        LOG.logError( "Still not found. Here's two stack traces:" );
124                        LOG.logError( e.getMessage(), e );
125                        LOG.logError( e2.getMessage(), e2 );
126                    }
127                }
128            }
129            return new SpatialCapabilities( operators.toArray( new SpatialOperator[operators.size()] ) );
130        }
131    
132        /**
133         * Returns the object representation for an <code>ogc:Scalar_Capabilities</code> element.
134         *
135         * @return object representation for the given <code>ogc:Scalar_Capabilities</code> element
136         * @throws XMLParsingException
137         */
138        private ScalarCapabilities parseScalarCapabilities( Element scalarElement )
139                                throws XMLParsingException {
140    
141            // "Logical_Operators"-element
142            boolean supportsLogicalOperators = false;
143            if ( XMLTools.getChildElement( "Logical_Operators", OGCNS, scalarElement ) != null ) {
144                supportsLogicalOperators = true;
145            }
146    
147            // "Comparison_Operators"-element
148            Element elem = XMLTools.getChildElement( "Comparison_Operators", OGCNS, scalarElement );
149            ArrayList<Operator> operators = new ArrayList<Operator>();
150            Map<String, Element> operatorMap = null;
151            if ( elem != null ) {
152                operatorMap = parseOperators( elem );
153                Iterator<String> it = operatorMap.keySet().iterator();
154                while ( it.hasNext() ) {
155                    String next = it.next();
156                    try {
157                        operators.add( OperatorFactory100.createComparisonOperator( next ) );
158                    } catch ( UnknownOperatorNameException e ) {
159                        LOG.logWarning( "Operator name not found. Trying again with filter encoding 1.1.0 names..." );
160                        try {
161                            operators.add( OperatorFactory110.createComparisonOperator( next ) );
162                        } catch ( UnknownOperatorNameException e2 ) {
163                            LOG.logError( "Still not found. Here's two stack traces:" );
164                            LOG.logError( e.getMessage(), e );
165                            LOG.logError( e2.getMessage(), e2 );
166                        }
167                    }
168                }
169            }
170            Operator[] comparionsOperators = operators.toArray( new Operator[operators.size()] );
171            operators = null;
172    
173            // "Arithmetic_Operators"-element
174            elem = XMLTools.getChildElement( "Arithmetic_Operators", OGCNS, scalarElement );
175            if ( elem != null ) {
176                operatorMap = parseOperators( elem );
177                operators = new ArrayList<Operator>();
178                Iterator<String> it = operatorMap.keySet().iterator();
179                while ( it.hasNext() ) {
180                    String operatorName = it.next();
181                    try {
182                        if ( operatorName.equals( OperatorFactory100.OPERATOR_FUNCTIONS ) ) {
183                            // functions definition
184                            Element functionsElement = operatorMap.get( operatorName );
185                            Element functionNamesElement = XMLTools.getRequiredChildElement( "Function_Names", OGCNS,
186                                                                                             functionsElement );
187                            List<Element> functionNameList = XMLTools.getRequiredElements( functionNamesElement,
188                                                                                           "ogc:Function_Name", nsContext );
189                            for ( int i = 0; i < functionNameList.size(); i++ ) {
190                                Element functionNameElement = functionNameList.get( i );
191                                String name = XMLTools.getStringValue( functionNameElement );
192                                String argumentCount = XMLTools.getRequiredAttrValue( "nArgs", null, functionNameElement );
193                                if ( name == null || name.length() == 0 ) {
194                                    throw new XMLParsingException( "Error parsing a 'Function_Name' (namespace: '" + OGCNS
195                                                                   + "') element: text node is empty." );
196                                }
197                                try {
198                                    operators.add( OperatorFactory100.createArithmeticFunction(
199                                                                                                name,
200                                                                                                Integer.parseInt( argumentCount ) ) );
201                                } catch ( NumberFormatException e ) {
202                                    throw new XMLParsingException( "Error parsing 'Function_Name' (namespace: '" + OGCNS
203                                                                   + "') element: attribute 'nArgs'"
204                                                                   + " does not contain a valid integer value." );
205                                }
206                            }
207    
208                        } else {
209                            // simple operator
210                            operators.add( OperatorFactory100.createArithmeticOperator( operatorName ) );
211                        }
212                    } catch ( UnknownOperatorNameException e ) {
213                        LOG.logWarning( "Operator name not found. Trying again with filter encoding 1.1.0 names..." );
214                        try {
215                            operators.add( OperatorFactory110.createComparisonOperator( operatorName ) );
216                        } catch ( UnknownOperatorNameException e2 ) {
217                            LOG.logError( "Still not found. Here's two stack traces:" );
218                            LOG.logError( e.getMessage(), e );
219                            LOG.logError( e2.getMessage(), e2 );
220                        }
221                    }
222                }
223            }
224            Operator[] arithmeticOperators = operators != null ? operators.toArray( new Operator[operators.size()] )
225                                                              : new Operator[0];
226            return new ScalarCapabilities( supportsLogicalOperators, comparionsOperators, arithmeticOperators );
227        }
228    
229        private Map<String, Element> parseOperators( Element operatorsElement ) {
230            HashMap<String, Element> operators = new HashMap<String, Element>();
231            ElementList operatorList = XMLTools.getChildElements( operatorsElement );
232            for ( int i = 0; i < operatorList.getLength(); i++ ) {
233                String namespaceURI = operatorList.item( i ).getNamespaceURI();
234                if ( namespaceURI != null && namespaceURI.equals( OGCNS.toASCIIString() ) ) {
235                    operators.put( operatorList.item( i ).getLocalName(), operatorList.item( i ) );
236                }
237            }
238            return operators;
239        }
240    }