001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.3_testing/src/org/deegree/model/feature/FeatureFactory.java $
002    /*----------------------------------------------------------------------------
003     This file is part of deegree, http://deegree.org/
004     Copyright (C) 2001-2009 by:
005       Department of Geography, University of Bonn
006     and
007       lat/lon GmbH
008    
009     This library is free software; you can redistribute it and/or modify it under
010     the terms of the GNU Lesser General Public License as published by the Free
011     Software Foundation; either version 2.1 of the License, or (at your option)
012     any later version.
013     This library is distributed in the hope that it will be useful, but WITHOUT
014     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
015     FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
016     details.
017     You should have received a copy of the GNU Lesser General Public License
018     along with this library; if not, write to the Free Software Foundation, Inc.,
019     59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020    
021     Contact information:
022    
023     lat/lon GmbH
024     Aennchenstr. 19, 53177 Bonn
025     Germany
026     http://lat-lon.de/
027    
028     Department of Geography, University of Bonn
029     Prof. Dr. Klaus Greve
030     Postfach 1147, 53001 Bonn
031     Germany
032     http://www.geographie.uni-bonn.de/deegree/
033    
034     e-mail: info@deegree.org
035    ----------------------------------------------------------------------------*/
036    package org.deegree.model.feature;
037    
038    import java.net.URI;
039    import java.util.List;
040    
041    import org.deegree.datatypes.QualifiedName;
042    import org.deegree.datatypes.Types;
043    import org.deegree.datatypes.UnknownTypeException;
044    import org.deegree.framework.log.ILogger;
045    import org.deegree.framework.log.LoggerFactory;
046    import org.deegree.model.feature.schema.DefaultFeatureType;
047    import org.deegree.model.feature.schema.FeaturePropertyType;
048    import org.deegree.model.feature.schema.FeatureType;
049    import org.deegree.model.feature.schema.GeometryPropertyType;
050    import org.deegree.model.feature.schema.MultiGeometryPropertyType;
051    import org.deegree.model.feature.schema.PropertyType;
052    import org.deegree.model.feature.schema.SimplePropertyType;
053    import org.deegree.ogcbase.CommonNamespaces;
054    
055    /**
056     * This factory offers methods for creating Features, FeatureCollection and all direct related
057     * classes/interfaces that are part of the org.deegree.model.feature package.
058     *
059     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
060     * @author last edited by: $Author: mschneider $
061     *
062     * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $
063     */
064    public class FeatureFactory {
065    
066        private final static ILogger LOG = LoggerFactory.getLogger( FeatureFactory.class );
067    
068        private static URI GMLNS = CommonNamespaces.GMLNS;
069    
070        /**
071         * Creates an instance of a <code>PropertyType</code> from the given parameters.
072         * <p>
073         * Determines the right type from the given type name.
074         *
075         * @param name
076         *            name of the property type
077         * @param typeName
078         *            type name of the property type
079         * @param nullable
080         *            set to true, if property type may be omitted
081         * @return corresponding PropertyType instance
082         * @throws UnknownTypeException
083         */
084        public static PropertyType createPropertyType( QualifiedName name, QualifiedName typeName, boolean nullable )
085                                throws UnknownTypeException {
086            return createPropertyType( name, typeName, nullable ? 0 : 1, 1 );
087        }
088    
089        /**
090         * Creates an instance of a <code>PropertyType</code> from the given parameters.
091         * <p>
092         * Determines the right type from the given type name.
093         *
094         * @param name
095         *            name of the property type
096         * @param typeName
097         *            type name of the property type
098         * @param minOccurs
099         * @param maxOccurs
100         * @return corresponding PropertyType instance
101         * @throws UnknownTypeException
102         */
103        public static PropertyType createPropertyType( QualifiedName name, QualifiedName typeName, int minOccurs,
104                                                       int maxOccurs )
105                                throws UnknownTypeException {
106    
107            PropertyType type = null;
108    
109            int typeCode = determinePropertyType( typeName );
110            switch ( typeCode ) {
111            case Types.FEATURE: {
112                type = new FeaturePropertyType( name, typeName, typeCode, minOccurs, maxOccurs );
113                break;
114            }
115            case Types.GEOMETRY: {
116                type = new GeometryPropertyType( name, typeName, typeCode, minOccurs, maxOccurs );
117                break;
118            }
119            case Types.MULTIGEOMETRY: {
120                type = new MultiGeometryPropertyType( name, typeName, typeCode, minOccurs, maxOccurs );
121                break;
122            }
123            default: {
124                type = new SimplePropertyType( name, typeCode, minOccurs, maxOccurs );
125            }
126            }
127            return type;
128        }
129    
130        /**
131         * Creates an instance of a <code>SimplePropertyType</code> from the given parameters.
132         *
133         * @param name
134         *            name of the property type
135         * @param typeCode
136         *            type code of the property type
137         * @param nullable
138         *            set to true, if property type may be omitted
139         * @return generated SimplePropertyType instance
140         * @see Types
141         */
142        public static PropertyType createSimplePropertyType( QualifiedName name, int typeCode, boolean nullable ) {
143            return createSimplePropertyType( name, typeCode, nullable ? 0 : 1, 1 );
144        }
145    
146        /**
147         * Creates an instance of a <code>SimplePropertyType</code> from the given parameters.
148         *
149         * @param name
150         *            name of the property type
151         * @param typeCode
152         *            type code of the property type
153         * @param minOccurs
154         * @param maxOccurs
155         * @return generated SimplePropertyType instance
156         * @see Types
157         */
158        public static SimplePropertyType createSimplePropertyType( QualifiedName name, int typeCode, int minOccurs,
159                                                                   int maxOccurs ) {
160            return new SimplePropertyType( name, typeCode, minOccurs, maxOccurs );
161        }
162    
163        /**
164         * Creates an instance of a <code>GeometryPropertyType</code> from the given parameters.
165         *
166         * @param name
167         *            name of the property type
168         * @param typeName
169         *            typeName of the property type
170         * @param minOccurs
171         * @param maxOccurs
172         * @return generated GeometryPropertyType instance
173         * @see Types
174         */
175        public static GeometryPropertyType createGeometryPropertyType( QualifiedName name, QualifiedName typeName,
176                                                                       int minOccurs, int maxOccurs ) {
177            return new GeometryPropertyType( name, typeName, Types.GEOMETRY, minOccurs, maxOccurs );
178        }
179    
180        /**
181         * Creates an instance of a <code>FeaturePropertyType</code> from the given parameters.
182         *
183         * @param name
184         *            name of the property type
185         * @param minOccurs
186         * @param maxOccurs
187         * @return generated FeaturePropertyType instance
188         * @see Types
189         */
190        public static FeaturePropertyType createFeaturePropertyType( QualifiedName name, int minOccurs, int maxOccurs ) {
191            return new FeaturePropertyType( name, Types.FEATURE_PROPERTY_NAME, Types.FEATURE, minOccurs, maxOccurs );
192        }
193    
194        /**
195         * Determines the type code for the given type name.
196         *
197         * @param typeName
198         *            name to determine
199         * @return type code for the given type name
200         * @throws UnknownTypeException
201         *             if the type name cannot be determined
202         * @see Types
203         */
204        public static int determinePropertyType( QualifiedName typeName )
205                                throws UnknownTypeException {
206            LOG.logDebug( "Determining property type code for property type='" + typeName + "'..." );
207            int type = Types.FEATURE;
208            if ( typeName.isInNamespace( CommonNamespaces.XSNS ) ) {
209                LOG.logDebug( "Must be a basic XSD type." );
210                try {
211                    type = Types.getJavaTypeForXSDType( typeName.getLocalName() );
212                } catch ( UnknownTypeException e ) {
213                    throw new UnknownTypeException( e );
214                }
215            } else if ( typeName.isInNamespace( GMLNS ) ) {
216                LOG.logDebug( "Maybe a geometry property type?" );
217                try {
218                    type = Types.getJavaTypeForGMLType( typeName.getLocalName() );
219                    LOG.logDebug( "Yes." );
220                } catch ( UnknownTypeException e ) {
221                    LOG.logDebug( "No. Should be a generic GML feature of some kind." );
222                    // TODO check all possible GML types here, feature array property type
223                }
224            } else {
225                throw new UnknownTypeException( "Cannot determine property type for type '" + typeName + "'." );
226            }
227            return type;
228        }
229    
230        /**
231         * creates an instance of a FeatureType from an array of FeatureTypeProperties, and its name but
232         * without parents and childs
233         *
234         * @param name
235         *            name of the <code>FeatureType</code>
236         * @param isAbstract
237         *            <code>true</code> if the feature type to create is abstract, <code>false</code>
238         *            otherwise
239         * @param properties
240         *            properties containing the <code>FeatureType</code>s content
241         * @return instance of a <code>FeatureType</code>
242         */
243        public static FeatureType createFeatureType( QualifiedName name, boolean isAbstract, PropertyType[] properties ) {
244            return new DefaultFeatureType( name, isAbstract, properties );
245        }
246    
247        /**
248         * creates an instance of a FeatureType from an array of FeatureTypeProperties, and its name but
249         * without parents and childs
250         *
251         * @param name
252         *            name of the <code>FeatureType</code>
253         * @param isAbstract
254         *            <code>true</code> if the feature type to create is abstract, <code>false</code>
255         *            otherwise
256         * @param properties
257         *            properties containing the <code>FeatureType</code>s content
258         * @return instance of a <code>FeatureType</code>
259         */
260        public static FeatureType createFeatureType( String name, boolean isAbstract, PropertyType[] properties ) {
261            return new DefaultFeatureType( new QualifiedName( name ), isAbstract, properties );
262        }
263    
264        /**
265         * creates an instance of a FeatureType from an array of FeatureTypeProperties, and its name but
266         * without parents and childs
267         *
268         * @param name
269         *            name of the <code>FeatureType</code>
270         * @param isAbstract
271         *            <code>true</code> if the feature type to create is abstract, <code>false</code>
272         *            otherwise
273         * @param schemaLocation
274         * @param properties
275         *            properties containing the <code>FeatureType</code>s content
276         * @return instance of a <code>FeatureType</code>
277         */
278        public static FeatureType createFeatureType( QualifiedName name, boolean isAbstract, URI schemaLocation,
279                                                     PropertyType[] properties ) {
280            return new DefaultFeatureType( name, isAbstract, schemaLocation, properties );
281        }
282    
283        /**
284         * creates an instance of a FeatureType from an array of FeatureTypeProperties, and its name but
285         * without parents and childs
286         *
287         * @param name
288         *            name of the <code>FeatureType</code>
289         * @param isAbstract
290         *            <code>true</code> if the feature type to create is abstract, <code>false</code>
291         *            otherwise
292         * @param schemaLocation
293         * @param properties
294         *            properties containing the <code>FeatureType</code>s content
295         * @return instance of a <code>FeatureType</code>
296         */
297        public static FeatureType createFeatureType( String name, boolean isAbstract, URI schemaLocation,
298                                                     PropertyType[] properties ) {
299            QualifiedName gName = new QualifiedName( name );
300            return new DefaultFeatureType( gName, isAbstract, schemaLocation, properties );
301        }
302    
303        /**
304         * creates an instance of a FeatureProperty from its name and the data (value) it contains
305         *
306         * @param name
307         *            name of the <code>FeatureProperty</code>
308         * @return an instance of a <code>FeatureProperty</code>
309         * @param value
310         *            value of the <code>FeatureProperty</code>
311         */
312        public static FeatureProperty createFeatureProperty( QualifiedName name, Object value ) {
313            return new DefaultFeatureProperty( name, value );
314        }
315    
316        /**
317         * creates an instance of a FeatureProperty from its name and the data (value) it contains
318         *
319         * @param name
320         *            name of the <code>FeatureProperty</code>
321         * @return an instance of a <code>FeatureProperty</code>
322         * @param value
323         *            value of the <code>FeatureProperty</code>
324         * @deprecated use {@link #createFeatureProperty (QualifiedName, Object)} instead
325         */
326        @Deprecated
327        public static FeatureProperty createFeatureProperty( String name, Object value ) {
328            QualifiedName qn = new QualifiedName( name );
329            return new DefaultFeatureProperty( qn, value );
330        }
331    
332        /**
333         * creates an instance of a Feature from its FeatureType and an array of Objects that represents
334         * it properties. It is assumed that the order of the properties is identical to the order of
335         * the FeatureTypeProperties of the the FeatureType.
336         *
337         * @param id
338         *            unique id of the <code>Feature</code>
339         * @param featureType
340         *            <code>FeatureType</code> of the <code>Feature</code>
341         * @param properties
342         *            properties (content) of the <code>Feature</code>
343         * @return instance of a <code>Feature</code>
344         */
345        public static Feature createFeature( String id, FeatureType featureType, FeatureProperty[] properties ) {
346            return new DefaultFeature( id, featureType, properties );
347        }
348    
349        /**
350         * creates an instance of a Feature from its FeatureType and an array of Objects that represents
351         * it properties. It is assumed that the order of the properties is identical to the order of
352         * the FeatureTypeProperties of the the FeatureType.
353         *
354         * @param id
355         *            unique id of the <code>Feature</code>
356         * @param featureType
357         *            <code>FeatureType</code> of the <code>Feature</code>
358         * @param properties
359         *            properties (content) of the <code>Feature</code>
360         * @return instance of a <code>Feature</code>
361         */
362        public static Feature createFeature( String id, FeatureType featureType, List<FeatureProperty> properties ) {
363            FeatureProperty[] fps = properties.toArray( new FeatureProperty[properties.size()] );
364            return new DefaultFeature( id, featureType, fps );
365        }
366    
367        /**
368         * creates an instance of a FeatureCollection with an initial capacity. The returned
369         * FeatureCollection doesn't have a FeatureType nor properties. It is just a collection of
370         * Features.
371         *
372         * @param id
373         *            unique id of the <code>FeatureCollection</code>
374         * @param initialCapacity
375         *            initial capacity of the <code>FeatureCollection</code>
376         * @return instance of an empty <code>FeatureCollection</code>
377         */
378        public static FeatureCollection createFeatureCollection( String id, int initialCapacity ) {
379            return new DefaultFeatureCollection( id, initialCapacity );
380        }
381    
382        /**
383         * creates an instance of a FeatureCollection from an array of Features. The returned
384         * FeatureCollection doesn't have a FeatureType nor properties. It is just a collection of
385         * Features.
386         *
387         * @param id
388         *            unique id of the <code>FeatureCollection</code> instance
389         * @param features
390         *            <code>Feature</code>s to fill in into the <code>FeatureCollection</code>
391         * @return instance of a <code>FeatureCollection</code> containing the submitted features
392         */
393        public static FeatureCollection createFeatureCollection( String id, Feature[] features ) {
394            return new DefaultFeatureCollection( id, features );
395        }
396    
397        /**
398         * creates an instance of a FeatureCollection from an array of Features. The returned
399         * FeatureCollection doesn't have a FeatureType nor properties. It is just a collection of
400         * Features. With it's name set to the given qualifiedName
401         *
402         * @param id
403         *            unique id of the <code>FeatureCollection</code> instance
404         * @param features
405         *            <code>Feature</code>s to fill in into the <code>FeatureCollection</code>
406         * @param qName
407         *            name of the featureCollection
408         * @return instance of a <code>FeatureCollection</code> containing the submitted features
409         */
410        public static FeatureCollection createFeatureCollection( String id, Feature[] features, QualifiedName qName ) {
411            return new DefaultFeatureCollection( id, features, qName );
412        }
413    
414        /**
415         * Creates a {@link FeatureTupleCollection} for the given feature tuples.
416         *
417         * @param id
418         *            id for the <code>FeatureCollection</code> instance
419         * @param featureTuples
420         *            list of feature tuples (array length must match tupleLength parameter)
421         * @param tupleLength
422         *            number of features per tuple
423         * @return <code>FeatureTupleCollection</code> containing the given feature tuples
424         */
425        public static FeatureTupleCollection createFeatureCollection( String id, List<Feature[]> featureTuples,
426                                                                      int tupleLength ) {
427            return new FeatureTupleCollection( id, featureTuples, tupleLength );
428        }
429    }