001    //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/datatypes/Types.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.datatypes;
037    
038    import java.lang.reflect.Field;
039    import java.net.URI;
040    import java.util.HashMap;
041    import java.util.Map;
042    
043    import org.deegree.framework.log.ILogger;
044    import org.deegree.framework.log.LoggerFactory;
045    import org.deegree.framework.util.BootLogger;
046    import org.deegree.ogcbase.CommonNamespaces;
047    
048    /**
049     * General data type constants definition. the type values are the same as in
050     * <code>java.sql.Types<code>. Except for several geometry types,
051     * <code>UNKNOWN</code>, <code>FEATURE</code>, <code>FEATURES</code> and <code>FEATURECOLLECTION</code> that are not
052     * known by <code>java.sql.Types</code>.
053     * <p>
054     * NOTE: Generally, it would be feasible to extend <code>java.sql.Types</code>, but unfortunately, this is not possible,
055     * as it's default constructor is not visible.
056     * </p>
057     * 
058     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth </a>
059     * @author last edited by: $Author: aschmitz $
060     * 
061     * @version $Revision: 26926 $, $Date: 2010-09-22 17:23:56 +0200 (Mi, 22 Sep 2010) $
062     * 
063     * @see java.sql.Types
064     */
065    public final class Types {
066    
067        private static ILogger LOG = LoggerFactory.getLogger( Types.class );
068    
069        private static URI GMLNS = CommonNamespaces.GMLNS;
070    
071        // generic sql types
072    
073        /**
074         * maps to java.sql.Types.ARRAY (why not use directly?)
075         */
076        public final static int ARRAY = java.sql.Types.ARRAY;
077    
078        /**
079         * maps to java.sql.Types.BIGINT (why not use directly?)
080         */
081        public final static int BIGINT = java.sql.Types.BIGINT;
082    
083        /**
084         * maps to java.sql.Types.BINARY (why not use directly?)
085         */
086        public final static int BINARY = java.sql.Types.BINARY;
087    
088        /**
089         * maps to java.sql.Types.BIT (why not use directly?)
090         */
091        public final static int BIT = java.sql.Types.BIT;
092    
093        /**
094         * maps to java.sql.Types.BLOB (why not use directly?)
095         */
096        public final static int BLOB = java.sql.Types.BLOB;
097    
098        /**
099         * maps to java.sql.Types.BOOLEAN (why not use directly?)
100         */
101        public final static int BOOLEAN = java.sql.Types.BOOLEAN;
102    
103        /**
104         * maps to java.sql.Types.CHAR (why not use directly?)
105         */
106        public final static int CHAR = java.sql.Types.CHAR;
107    
108        /**
109         * maps to java.sql.Types.CLOB (why not use directly?)
110         */
111        public final static int CLOB = java.sql.Types.CLOB;
112    
113        /**
114         * maps to java.sql.Types.DATALINK (why not use directly?)
115         */
116        public final static int DATALINK = java.sql.Types.DATALINK;
117    
118        /**
119         * maps to java.sql.Types.DATE (why not use directly?)
120         */
121        public final static int DATE = java.sql.Types.DATE;
122    
123        /**
124         * maps to java.sql.Types.DECIMAL (why not use directly?)
125         */
126        public final static int DECIMAL = java.sql.Types.DECIMAL;
127    
128        /**
129         * maps to java.sql.Types.DISTINCT (why not use directly?)
130         */
131        public final static int DISTINCT = java.sql.Types.DISTINCT;
132    
133        /**
134         * maps to java.sql.Types.DOUBLE (why not use directly?)
135         */
136        public final static int DOUBLE = java.sql.Types.DOUBLE;
137    
138        /**
139         * maps to java.sql.Types.FLOAT (why not use directly?)
140         */
141        public final static int FLOAT = java.sql.Types.FLOAT;
142    
143        /**
144         * maps to java.sql.Types.INTEGER (why not use directly?)
145         */
146        public final static int INTEGER = java.sql.Types.INTEGER;
147    
148        /**
149         * maps to java.sql.Types.JAVA_OBJECT (why not use directly?)
150         */
151        public final static int JAVA_OBJECT = java.sql.Types.JAVA_OBJECT;
152    
153        /**
154         * maps to java.sql.Types.LONGVARBINARY (why not use directly?)
155         */
156        public final static int LONGVARBINARY = java.sql.Types.LONGVARBINARY;
157    
158        /**
159         * maps to java.sql.Types.LONGVARCHAR (why not use directly?)
160         */
161        public final static int LONGVARCHAR = java.sql.Types.LONGVARCHAR;
162    
163        /**
164         * maps to java.sql.Types.NULL (why not use directly?)
165         */
166        public final static int NULL = java.sql.Types.NULL;
167    
168        /**
169         * maps to java.sql.Types.NUMERIC (why not use directly?)
170         */
171        public final static int NUMERIC = java.sql.Types.NUMERIC;
172    
173        /**
174         * maps to java.sql.Types.OTHER (why not use directly?)
175         */
176        public final static int OTHER = java.sql.Types.OTHER;
177    
178        /**
179         * maps to java.sql.Types.REAL (why not use directly?)
180         */
181        public final static int REAL = java.sql.Types.REAL;
182    
183        /**
184         * maps to java.sql.Types.REF (why not use directly?)
185         */
186        public final static int REF = java.sql.Types.REF;
187    
188        /**
189         * maps to java.sql.Types.SMALLINT (why not use directly?)
190         */
191        public final static int SMALLINT = java.sql.Types.SMALLINT;
192    
193        /**
194         * maps to java.sql.Types.STRUCT (why not use directly?)
195         */
196        public final static int STRUCT = java.sql.Types.STRUCT;
197    
198        /**
199         * maps to java.sql.Types.TIME (why not use directly?)
200         */
201        public final static int TIME = java.sql.Types.TIME;
202    
203        /**
204         * maps to java.sql.Types.TIMESTAMP (why not use directly?)
205         */
206        public final static int TIMESTAMP = java.sql.Types.TIMESTAMP;
207    
208        /**
209         * maps to java.sql.Types.TINYINT (why not use directly?)
210         */
211        public final static int TINYINT = java.sql.Types.TINYINT;
212    
213        /**
214         * maps to java.sql.Types.VARBINARY (why not use directly?)
215         */
216        public final static int VARBINARY = java.sql.Types.VARBINARY;
217    
218        /**
219         * maps to java.sql.Types.VARCHAR (why not use directly?)
220         */
221        public final static int VARCHAR = java.sql.Types.VARCHAR;
222    
223        // geometry + gml types
224    
225        /**
226         * redefinition of java.sql.Types.VARCHAR
227         */
228        public static final int GEOMETRY = java.sql.Types.VARCHAR + 10000;
229    
230        /**
231         * redefinition of java.sql.Types.VARCHAR
232         */
233        public static final int MULTIGEOMETRY = java.sql.Types.VARCHAR + 10001;
234    
235        /**
236         * redefinition of java.sql.Types.VARCHAR
237         */
238        public static final int FEATURE = java.sql.Types.VARCHAR + 10002;
239    
240        /**
241         * redefinition of java.sql.Types.VARCHAR
242         */
243        public static final int FEATURECOLLECTION = java.sql.Types.VARCHAR + 10004;
244    
245        /**
246         * redefinition of java.sql.Types.VARCHAR
247         */
248        public static final int POINT = java.sql.Types.VARCHAR + 11000;
249    
250        /**
251         * redefinition of java.sql.Types.VARCHAR
252         */
253        public static final int CURVE = java.sql.Types.VARCHAR + 11001;
254    
255        /**
256         * redefinition of java.sql.Types.VARCHAR
257         */
258        public static final int SURFACE = java.sql.Types.VARCHAR + 11002;
259    
260        /**
261         * redefinition of java.sql.Types.VARCHAR
262         */
263        public static final int MULTIPOINT = java.sql.Types.VARCHAR + 11003;
264    
265        /**
266         * redefinition of java.sql.Types.VARCHAR
267         */
268        public static final int MULTICURVE = java.sql.Types.VARCHAR + 11004;
269    
270        /**
271         * redefinition of java.sql.Types.VARCHAR
272         */
273        public static final int MULTISURFACE = java.sql.Types.VARCHAR + 11005;
274    
275        /**
276         * redefinition of java.sql.Types.VARCHAR
277         */
278        public static final int ENVELOPE = java.sql.Types.VARCHAR + 11006;
279    
280        /**
281         * redefinition of java.sql.Types.VARCHAR
282         */
283        public static final int ANYTYPE = java.sql.Types.VARCHAR + 11007;
284    
285        /**
286         * {http://www.opengis.net/gml}:GeGeometryPropertyType
287         */
288        public static final QualifiedName GEOMETRY_PROPERTY_NAME = new QualifiedName( "GeometryPropertyType", GMLNS );
289    
290        /**
291         * {http://www.opengis.net/gml}:MultiGeometryPropertyType
292         */
293        public static final QualifiedName MULTI_GEOMETRY_PROPERTY_NAME = new QualifiedName( "MultiGeometryPropertyType",
294                                                                                            GMLNS );
295    
296        /**
297         * {http://www.opengis.net/gml}:FeaturePropertyType
298         */
299        public static final QualifiedName FEATURE_PROPERTY_NAME = new QualifiedName( "FeaturePropertyType", GMLNS );
300    
301        //
302        /**
303         * TODO check if this is really needed {http://www.opengis.net/gml}:FeatureArrayPropertyType
304         */
305        public static final QualifiedName FEATURE_ARRAY_PROPERTY_NAME = new QualifiedName( "FeatureArrayPropertyType",
306                                                                                           GMLNS );
307    
308        // key instances: Integer, value instances: String
309        private static Map<Integer, String> typeNameMap = new HashMap<Integer, String>();
310    
311        // key instances: String, value instances: Integer
312        private static Map<String, Integer> typeCodeMap = new HashMap<String, Integer>();
313    
314        static {
315            try {
316                Field[] fields = java.sql.Types.class.getFields();
317                for ( int i = 0; i < fields.length; i++ ) {
318                    String typeName = fields[i].getName();
319                    Integer typeCode = (Integer) fields[i].get( null );
320                    typeNameMap.put( typeCode, typeName );
321                    typeCodeMap.put( typeName, typeCode );
322                }
323            } catch ( Exception e ) {
324                BootLogger.logError( "Error populating sql type code maps: " + e.getMessage(), e );
325            }
326        }
327    
328        /**
329         * Returns the generic sql type code for the given type name.
330         * 
331         * @param typeName
332         * @return the generic sql type code for the given type name.
333         * @throws UnknownTypeException
334         *             if the type name is not an sql type name
335         * @see java.sql.Types
336         */
337        public static int getTypeCodeForSQLType( String typeName )
338                                throws UnknownTypeException {
339            Integer typeCode = typeCodeMap.get( typeName );
340            if ( typeCode == null ) {
341                throw new UnknownTypeException( "Type name '" + typeName + "' does not denote an sql type." );
342            }
343            return typeCode.intValue();
344        }
345    
346        /**
347         * Returns the generic sql type name for the given type code.
348         * 
349         * @param typeCode
350         * @return the generic sql type name for the given type code.
351         * @throws UnknownTypeException
352         *             if the type code is not an sql type code
353         * @see java.sql.Types
354         */
355        public static String getTypeNameForSQLTypeCode( int typeCode )
356                                throws UnknownTypeException {
357            String typeName = typeNameMap.get( new Integer( typeCode ) );
358            if ( typeName == null ) {
359                throw new UnknownTypeException( "Type code '" + typeCode + "' does not denote an sql type." );
360            }
361            return typeName;
362        }
363    
364        /**
365         * mapping between GML-typenames and java-classnames for GML-geometry types
366         * 
367         * @param gmlTypeName
368         *            the name of the GML type name
369         * @return the internal type
370         * @throws UnknownTypeException
371         *             if the given name cannot be mapped to a known type.
372         */
373        public static int getJavaTypeForGMLType( String gmlTypeName )
374                                throws UnknownTypeException {
375            if ( "GeometryPropertyType".equals( gmlTypeName ) )
376                return Types.GEOMETRY;
377    
378            if ( "PointPropertyType".equals( gmlTypeName ) )
379                // return Types.POINT;
380                return Types.GEOMETRY;
381    
382            if ( "MultiPointPropertyType".equals( gmlTypeName ) )
383                // return Types.MULTIPOINT;
384                return Types.GEOMETRY;
385    
386            if ( "PolygonPropertyType".equals( gmlTypeName ) )
387                // return Types.SURFACE;
388                return Types.GEOMETRY;
389    
390            if ( "MultiPolygonPropertyType".equals( gmlTypeName ) )
391                // return Types.MULTISURFACE;
392                return Types.GEOMETRY;
393    
394            if ( "LineStringPropertyType".equals( gmlTypeName ) )
395                // return Types.CURVE;
396                return Types.GEOMETRY;
397    
398            if ( "MultiLineStringPropertyType".equals( gmlTypeName ) )
399                // return Types.MULTICURVE;
400                return Types.GEOMETRY;
401    
402            if ( "CurvePropertyType".equals( gmlTypeName ) )
403                // return Types.POINT;
404                return Types.GEOMETRY;
405    
406            if ( "MultiCurvePropertyType".equals( gmlTypeName ) )
407                // return Types.POINT;
408                return Types.GEOMETRY;
409    
410            if ( "SurfacePropertyType".equals( gmlTypeName ) )
411                // return Types.POINT;
412                return Types.GEOMETRY;
413    
414            if ( "MultiSurfacePropertyType".equals( gmlTypeName ) )
415                // return Types.POINT;
416                return Types.GEOMETRY;
417    
418            throw new UnknownTypeException( "Unsupported Type: '" + gmlTypeName + "'" );
419        }
420    
421        /**
422         * mapping between xml-typenames and java-classnames for XMLSCHEMA-simple types
423         * 
424         * @param schemaTypeName
425         *            of the XML schema type
426         * @return the internal type
427         * @throws UnknownTypeException
428         *             if the given name cannot be mapped to a known type.
429         * @todo TODO map them all over registry
430         */
431        public static int getJavaTypeForXSDType( String schemaTypeName )
432                                throws UnknownTypeException {
433    
434            if ( "integer".equals( schemaTypeName ) || "int".equals( schemaTypeName ) || "long".equals( schemaTypeName ) )
435                return Types.INTEGER;
436    
437            if ( "string".equals( schemaTypeName ) )
438                return Types.VARCHAR;
439    
440            if ( "date".equals( schemaTypeName ) )
441                return Types.DATE;
442    
443            if ( "boolean".equals( schemaTypeName ) )
444                return Types.BOOLEAN;
445    
446            if ( "float".equals( schemaTypeName ) )
447                return Types.FLOAT;
448    
449            if ( "double".equals( schemaTypeName ) )
450                return Types.DOUBLE;
451    
452            if ( "decimal".equals( schemaTypeName ) )
453                return Types.DECIMAL;
454    
455            if ( "dateTime".equals( schemaTypeName ) )
456                return Types.TIMESTAMP;
457    
458            if ( "time".equals( schemaTypeName ) )
459                return Types.TIME;
460    
461            if ( "date".equals( schemaTypeName ) )
462                return Types.DATE;
463    
464            if ( "anyURI".equals( schemaTypeName ) )
465                return Types.VARCHAR;
466    
467            if ( "anyType".equals( schemaTypeName ) )
468                return Types.ANYTYPE;
469    
470            throw new UnknownTypeException( "Unsupported Type:" + schemaTypeName );
471        }
472    
473        /**
474         * Scale is set to 0.
475         * 
476         * @param type
477         *            SQL datatype code
478         * @param precision
479         *            precision (just used for type NUMERIC)
480         * @return typename
481         */
482        public static String getXSDTypeForSQLType( int type, int precision ) {
483            return getXSDTypeForSQLType( type, precision, 0 );
484        }
485    
486        /**
487         * 
488         * @param type
489         *            SQL datatype code
490         * @param precision
491         *            precision (just used for type NUMERIC)
492         * @param scale
493         *            scale (just used for type NUMERIC)
494         * @return typename
495         */
496        public static String getXSDTypeForSQLType( int type, int precision, int scale ) {
497            String s = null;
498    
499            switch ( type ) {
500            case Types.VARCHAR:
501            case Types.CHAR:
502                s = "string";
503                break;
504            case Types.NUMERIC: {
505                if ( precision == 0 || scale > 0 ) {
506                    s = "double";
507                    break;
508                }
509                s = "integer";
510                break;
511            }
512            case Types.DECIMAL:
513                s = "decimal";
514                break;
515            case Types.DOUBLE:
516            case Types.REAL:
517                s = "double";
518                break;
519            case Types.FLOAT:
520                s = "float";
521                break;
522            case Types.INTEGER:
523            case Types.SMALLINT:
524            case Types.BIGINT:
525                s = "integer";
526                break;
527            case Types.TIMESTAMP:
528                s = "dateTime";
529                break;
530            case Types.TIME:
531                s = "time";
532                break;
533            case Types.DATE:
534                s = "date";
535                break;
536            case Types.CLOB:
537                s = "string";
538                break;
539            case Types.BIT:
540            case Types.BOOLEAN:
541                s = "boolean";
542                break;
543            case Types.GEOMETRY:
544            case Types.OTHER:
545            case Types.STRUCT:
546                s = "gml:GeometryPropertyType";
547                break;
548            case Types.FEATURE:
549                s = "gml:FeaturePropertyType";
550                break;
551            default:
552                LOG.logWarning( "could not determine XSDType for SQLType; using 'XXX': " + type );
553                s = "code: " + type;
554            }
555            return s;
556        }
557    
558    }