001    //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_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 classes/interfaces that
057     * 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: apoth $
061     * 
062     * @version $Revision: 25989 $, $Date: 2010-08-20 14:18:18 +0200 (Fr, 20 Aug 2010) $
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 without parents and
232         * 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> otherwise
238         * @param properties
239         *            properties containing the <code>FeatureType</code>s content
240         * @return instance of a <code>FeatureType</code>
241         */
242        public static FeatureType createFeatureType( QualifiedName name, boolean isAbstract, PropertyType[] properties ) {
243            return new DefaultFeatureType( name, isAbstract, properties );
244        }
245    
246        /**
247         * creates an instance of a FeatureType from an array of FeatureTypeProperties, and its name but without parents and
248         * childs
249         * 
250         * @param name
251         *            name of the <code>FeatureType</code>
252         * @param isAbstract
253         *            <code>true</code> if the feature type to create is abstract, <code>false</code> otherwise
254         * @param properties
255         *            properties containing the <code>FeatureType</code>s content
256         * @return instance of a <code>FeatureType</code>
257         */
258        public static FeatureType createFeatureType( String name, boolean isAbstract, PropertyType[] properties ) {
259            return new DefaultFeatureType( new QualifiedName( name ), isAbstract, properties );
260        }
261    
262        /**
263         * creates an instance of a FeatureType from an array of FeatureTypeProperties, and its name but without parents and
264         * childs
265         * 
266         * @param name
267         *            name of the <code>FeatureType</code>
268         * @param isAbstract
269         *            <code>true</code> if the feature type to create is abstract, <code>false</code> otherwise
270         * @param schemaLocation
271         * @param properties
272         *            properties containing the <code>FeatureType</code>s content
273         * @return instance of a <code>FeatureType</code>
274         */
275        public static FeatureType createFeatureType( QualifiedName name, boolean isAbstract, URI schemaLocation,
276                                                     PropertyType[] properties ) {
277            return new DefaultFeatureType( name, isAbstract, schemaLocation, properties );
278        }
279    
280        /**
281         * creates an instance of a FeatureType from an array of FeatureTypeProperties, and its name but without parents and
282         * childs
283         * 
284         * @param name
285         *            name of the <code>FeatureType</code>
286         * @param isAbstract
287         *            <code>true</code> if the feature type to create is abstract, <code>false</code> otherwise
288         * @param schemaLocation
289         * @param properties
290         *            properties containing the <code>FeatureType</code>s content
291         * @return instance of a <code>FeatureType</code>
292         */
293        public static FeatureType createFeatureType( String name, boolean isAbstract, URI schemaLocation,
294                                                     PropertyType[] properties ) {
295            QualifiedName gName = new QualifiedName( name );
296            return new DefaultFeatureType( gName, isAbstract, schemaLocation, properties );
297        }
298    
299        /**
300         * creates an instance of a FeatureProperty from its name and the data (value) it contains
301         * 
302         * @param name
303         *            name of the <code>FeatureProperty</code>
304         * @return an instance of a <code>FeatureProperty</code>
305         * @param value
306         *            value of the <code>FeatureProperty</code>
307         */
308        public static FeatureProperty createFeatureProperty( QualifiedName name, Object value ) {
309            return new DefaultFeatureProperty( name, value );
310        }
311    
312        /**
313         * creates an instance of a FeatureProperty from its name and the data (value) it contains
314         * 
315         * @param name
316         *            name of the <code>FeatureProperty</code>
317         * @return an instance of a <code>FeatureProperty</code>
318         * @param value
319         *            value of the <code>FeatureProperty</code>
320         * @deprecated use {@link #createFeatureProperty (QualifiedName, Object)} instead
321         */
322        @Deprecated
323        public static FeatureProperty createFeatureProperty( String name, Object value ) {
324            QualifiedName qn = new QualifiedName( name );
325            return new DefaultFeatureProperty( qn, value );
326        }
327    
328        /**
329         * creates an instance of a @see {@link FeatureProperty} from its name. The created @see {@link FeatureProperty}
330         * does takes a value generator instead of a value.
331         * 
332         * @param name
333         *            name of the <code>FeatureProperty</code>
334         * @return an instance of a <code>FeatureProperty</code>
335         * @param value
336         *            value of the <code>FeatureProperty</code>
337         */
338        public static FeatureProperty createGeneratedValueFeatureProperty( QualifiedName name, ValueGenerator valueGenerator ) {
339            return new GeneratedValueFeatureProperty( name, valueGenerator );
340        }
341    
342        /**
343         * creates an instance of a Feature from its FeatureType and an array of Objects that represents it properties. It
344         * is assumed that the order of the properties is identical to the order of the FeatureTypeProperties of the the
345         * 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 it properties. It
361         * is assumed that the order of the properties is identical to the order of the FeatureTypeProperties of the the
362         * 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 FeatureCollection doesn't have
379         * a FeatureType nor properties. It is just a collection of Features.
380         * 
381         * @param id
382         *            unique id of the <code>FeatureCollection</code>
383         * @param initialCapacity
384         *            initial capacity of the <code>FeatureCollection</code>
385         * @return instance of an empty <code>FeatureCollection</code>
386         */
387        public static FeatureCollection createFeatureCollection( String id, int initialCapacity ) {
388            return new DefaultFeatureCollection( id, initialCapacity );
389        }
390    
391        /**
392         * creates an instance of a FeatureCollection from an array of Features. The returned FeatureCollection doesn't have
393         * a FeatureType nor properties. It is just a collection of Features.
394         * 
395         * @param id
396         *            unique id of the <code>FeatureCollection</code> instance
397         * @param features
398         *            <code>Feature</code>s to fill in into the <code>FeatureCollection</code>
399         * @return instance of a <code>FeatureCollection</code> containing the submitted features
400         */
401        public static FeatureCollection createFeatureCollection( String id, Feature[] features ) {
402            return new DefaultFeatureCollection( id, features );
403        }
404    
405        /**
406         * creates an instance of a FeatureCollection from an array of Features. The returned FeatureCollection doesn't have
407         * a FeatureType nor properties. It is just a collection of Features. With it's name set to the given qualifiedName
408         * 
409         * @param id
410         *            unique id of the <code>FeatureCollection</code> instance
411         * @param features
412         *            <code>Feature</code>s to fill in into the <code>FeatureCollection</code>
413         * @param qName
414         *            name of the featureCollection
415         * @return instance of a <code>FeatureCollection</code> containing the submitted features
416         */
417        public static FeatureCollection createFeatureCollection( String id, Feature[] features, QualifiedName qName ) {
418            return new DefaultFeatureCollection( id, features, qName );
419        }
420    
421        /**
422         * Creates a {@link FeatureTupleCollection} for the given feature tuples.
423         * 
424         * @param id
425         *            id for the <code>FeatureCollection</code> instance
426         * @param featureTuples
427         *            list of feature tuples (array length must match tupleLength parameter)
428         * @param tupleLength
429         *            number of features per tuple
430         * @return <code>FeatureTupleCollection</code> containing the given feature tuples
431         */
432        public static FeatureTupleCollection createFeatureCollection( String id, List<Feature[]> featureTuples,
433                                                                      int tupleLength ) {
434            return new FeatureTupleCollection( id, featureTuples, tupleLength );
435        }
436    }