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