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