001    //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/datatypes/Types.java $
002    /*----------------    FILE HEADER  ------------------------------------------
003    
004     This file is part of deegree.
005     Copyright (C) 2001-2008 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    package org.deegree.datatypes;
044    
045    import java.lang.reflect.Field;
046    import java.net.URI;
047    import java.util.HashMap;
048    import java.util.Map;
049    
050    import org.deegree.framework.log.ILogger;
051    import org.deegree.framework.log.LoggerFactory;
052    import org.deegree.framework.util.BootLogger;
053    import org.deegree.ogcbase.CommonNamespaces;
054    
055    /**
056     * General data type constants definition. the type values are the same as in
057     * <code>java.sql.Types<code>. Except for several geometry types, 
058     * <code>UNKNOWN</code>, <code>FEATURE</code>, <code>FEATURES</code> and 
059     * <code>FEATURECOLLECTION</code> that are not known by 
060     * <code>java.sql.Types</code>.
061     * <p>
062     * NOTE: Generally, it would be feasible to extend <code>java.sql.Types</code>,
063     * but unfortunately, this is not possible, as it's default constructor is not visible. 
064     * </p> 
065     * 
066     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth </a>
067     * @author last edited by: $Author: apoth $
068     * 
069     * @version $Revision: 9337 $, $Date: 2007-12-27 13:31:11 +0100 (Do, 27 Dez 2007) $
070     * 
071     * @see java.sql.Types
072     */
073    public final class Types {
074    
075        private static ILogger LOG = LoggerFactory.getLogger( Types.class );
076    
077        private static URI GMLNS = CommonNamespaces.GMLNS;
078    
079        // generic sql types
080    
081        public final static int ARRAY = java.sql.Types.ARRAY;
082    
083        public final static int BIGINT = java.sql.Types.BIGINT;
084    
085        public final static int BINARY = java.sql.Types.BINARY;
086    
087        public final static int BIT = java.sql.Types.BIT;
088    
089        public final static int BLOB = java.sql.Types.BLOB;
090    
091        public final static int BOOLEAN = java.sql.Types.BOOLEAN;
092    
093        public final static int CHAR = java.sql.Types.CHAR;
094    
095        public final static int CLOB = java.sql.Types.CLOB;
096    
097        public final static int DATALINK = java.sql.Types.DATALINK;
098    
099        public final static int DATE = java.sql.Types.DATE;
100    
101        public final static int DECIMAL = java.sql.Types.DECIMAL;
102    
103        public final static int DISTINCT = java.sql.Types.DISTINCT;
104    
105        public final static int DOUBLE = java.sql.Types.DOUBLE;
106    
107        public final static int FLOAT = java.sql.Types.FLOAT;
108    
109        public final static int INTEGER = java.sql.Types.INTEGER;
110    
111        public final static int JAVA_OBJECT = java.sql.Types.JAVA_OBJECT;
112    
113        public final static int LONGVARBINARY = java.sql.Types.LONGVARBINARY;
114    
115        public final static int LONGVARCHAR = java.sql.Types.LONGVARCHAR;
116    
117        public final static int NULL = java.sql.Types.NULL;
118    
119        public final static int NUMERIC = java.sql.Types.NUMERIC;
120    
121        public final static int OTHER = java.sql.Types.OTHER;
122    
123        public final static int REAL = java.sql.Types.REAL;
124    
125        public final static int REF = java.sql.Types.REF;
126    
127        public final static int SMALLINT = java.sql.Types.SMALLINT;
128    
129        public final static int STRUCT = java.sql.Types.STRUCT;
130    
131        public final static int TIME = java.sql.Types.TIME;
132    
133        public final static int TIMESTAMP = java.sql.Types.TIMESTAMP;
134    
135        public final static int TINYINT = java.sql.Types.TINYINT;
136    
137        public final static int VARBINARY = java.sql.Types.VARBINARY;
138    
139        public final static int VARCHAR = java.sql.Types.VARCHAR;
140    
141        // geometry + gml types
142    
143        public static final int GEOMETRY = java.sql.Types.VARCHAR + 10000;
144    
145        public static final int MULTIGEOMETRY = java.sql.Types.VARCHAR + 10001;
146    
147        public static final int FEATURE = java.sql.Types.VARCHAR + 10002;
148    
149        public static final int FEATURECOLLECTION = java.sql.Types.VARCHAR + 10004;
150    
151        public static final int POINT = java.sql.Types.VARCHAR + 11000;
152    
153        public static final int CURVE = java.sql.Types.VARCHAR + 11001;
154    
155        public static final int SURFACE = java.sql.Types.VARCHAR + 11002;
156    
157        public static final int MULTIPOINT = java.sql.Types.VARCHAR + 11003;
158    
159        public static final int MULTICURVE = java.sql.Types.VARCHAR + 11004;
160    
161        public static final int MULTISURFACE = java.sql.Types.VARCHAR + 11005;
162    
163        public static final int ENVELOPE = java.sql.Types.VARCHAR + 11006;
164    
165        public static final int ANYTYPE = java.sql.Types.VARCHAR + 11007;
166    
167        public static final QualifiedName GEOMETRY_PROPERTY_NAME = new QualifiedName( "GeometryPropertyType", GMLNS );
168    
169        public static final QualifiedName MULTI_GEOMETRY_PROPERTY_NAME = new QualifiedName( "MultiGeometryPropertyType",
170                                                                                            GMLNS );
171    
172        public static final QualifiedName FEATURE_PROPERTY_NAME = new QualifiedName( "FeaturePropertyType", GMLNS );
173    
174        // TODO check if this is really needed
175        public static final QualifiedName FEATURE_ARRAY_PROPERTY_NAME = new QualifiedName( "FeatureArrayPropertyType",
176                                                                                           GMLNS );
177    
178        // key instances: Integer, value instances: String
179        private static Map<Integer, String> typeNameMap = new HashMap<Integer, String>();
180    
181        // key instances: String, value instances: Integer
182        private static Map<String, Integer> typeCodeMap = new HashMap<String, Integer>();
183    
184        static {
185            try {
186                Field[] fields = java.sql.Types.class.getFields();
187                for ( int i = 0; i < fields.length; i++ ) {
188                    String typeName = fields[i].getName();
189                    Integer typeCode = (Integer) fields[i].get( null );
190                    typeNameMap.put( typeCode, typeName );
191                    typeCodeMap.put( typeName, typeCode );
192                }
193            } catch ( Exception e ) {
194                BootLogger.logError( "Error populating sql type code maps: " + e.getMessage(), e );
195            }
196        }
197    
198        /**
199         * Returns the generic sql type code for the given type name.
200         * 
201         * @param typeName
202         * @return the generic sql type code for the given type name.
203         * @throws UnknownTypeException
204         *             if the type name is not an sql type name
205         * @see java.sql.Types
206         */
207        public static int getTypeCodeForSQLType( String typeName )
208                                throws UnknownTypeException {
209            Integer typeCode = typeCodeMap.get( typeName );
210            if ( typeCode == null ) {
211                throw new UnknownTypeException( "Type name '" + typeName + "' does not denote an sql type." );
212            }
213            return typeCode.intValue();
214        }
215    
216        /**
217         * Returns the generic sql type name for the given type code.
218         * 
219         * @param typeCode
220         * @return the generic sql type name for the given type code.
221         * @throws UnknownTypeException
222         *             if the type code is not an sql type code
223         * @see java.sql.Types
224         */
225        public static String getTypeNameForSQLTypeCode( int typeCode )
226                                throws UnknownTypeException {
227            String typeName = typeNameMap.get( new Integer( typeCode ) );
228            if ( typeName == null ) {
229                throw new UnknownTypeException( "Type code '" + typeCode + "' does not denote an sql type." );
230            }
231            return typeName;
232        }
233    
234        /**
235         * mapping between GML-typenames and java-classnames for GML-geometry types
236         * 
237         * @param gmlTypeName
238         *            the name of the GML type name
239         * @return the internal type
240         * @throws UnknownTypeException
241         *             if the given name cannot be mapped to a known type.
242         */
243        public static int getJavaTypeForGMLType( String gmlTypeName )
244                                throws UnknownTypeException {
245            if ( "GeometryPropertyType".equals( gmlTypeName ) )
246                return Types.GEOMETRY;
247    
248            if ( "PointPropertyType".equals( gmlTypeName ) )
249                // return Types.POINT;
250                return Types.GEOMETRY;
251    
252            if ( "MultiPointPropertyType".equals( gmlTypeName ) )
253                // return Types.MULTIPOINT;
254                return Types.GEOMETRY;
255    
256            if ( "PolygonPropertyType".equals( gmlTypeName ) )
257                // return Types.SURFACE;
258                return Types.GEOMETRY;
259    
260            if ( "MultiPolygonPropertyType".equals( gmlTypeName ) )
261                // return Types.MULTISURFACE;
262                return Types.GEOMETRY;
263    
264            if ( "LineStringPropertyType".equals( gmlTypeName ) )
265                // return Types.CURVE;
266                return Types.GEOMETRY;
267    
268            if ( "MultiLineStringPropertyType".equals( gmlTypeName ) )
269                // return Types.MULTICURVE;
270                return Types.GEOMETRY;
271    
272            if ( "CurvePropertyType".equals( gmlTypeName ) )
273                // return Types.POINT;
274                return Types.GEOMETRY;
275    
276            if ( "MultiCurvePropertyType".equals( gmlTypeName ) )
277                // return Types.POINT;
278                return Types.GEOMETRY;
279    
280            if ( "SurfacePropertyType".equals( gmlTypeName ) )
281                // return Types.POINT;
282                return Types.GEOMETRY;
283    
284            if ( "MultiSurfacePropertyType".equals( gmlTypeName ) )
285                // return Types.POINT;
286                return Types.GEOMETRY;
287    
288            throw new UnknownTypeException( "Unsupported Type: '" + gmlTypeName + "'" );
289        }
290    
291        /**
292         * mapping between xml-typenames and java-classnames for XMLSCHEMA-simple types
293         * 
294         * @param schemaTypeName
295         *            of the XML schema type
296         * @return the internal type
297         * @throws UnknownTypeException
298         *             if the given name cannot be mapped to a known type.
299         * @todo TODO map them all over registry
300         */
301        public static int getJavaTypeForXSDType( String schemaTypeName )
302                                throws UnknownTypeException {
303    
304            if ( "integer".equals( schemaTypeName ) || "int".equals( schemaTypeName ) || "long".equals( schemaTypeName ) )
305                return Types.INTEGER;
306    
307            if ( "string".equals( schemaTypeName ) )
308                return Types.VARCHAR;
309    
310            if ( "date".equals( schemaTypeName ) )
311                return Types.DATE;
312    
313            if ( "boolean".equals( schemaTypeName ) )
314                return Types.BOOLEAN;
315    
316            if ( "float".equals( schemaTypeName ) )
317                return Types.FLOAT;
318    
319            if ( "double".equals( schemaTypeName ) )
320                return Types.DOUBLE;
321    
322            if ( "decimal".equals( schemaTypeName ) )
323                return Types.DECIMAL;
324    
325            if ( "dateTime".equals( schemaTypeName ) )
326                return Types.TIMESTAMP;
327    
328            if ( "time".equals( schemaTypeName ) )
329                return Types.TIME;
330    
331            if ( "date".equals( schemaTypeName ) )
332                return Types.DATE;
333    
334            if ( "anyURI".equals( schemaTypeName ) )
335                return Types.VARCHAR;
336    
337            if ( "anyType".equals( schemaTypeName ) )
338                return Types.ANYTYPE;
339    
340            throw new UnknownTypeException( "Unsupported Type:" + schemaTypeName );
341        }
342    
343        /**
344         * 
345         * @param type
346         *            SQL datatype code
347         * @param precision
348         *            precision (just used for type NUMERIC)
349         * @return typename
350         */
351        public static String getXSDTypeForSQLType( int type, int precision ) {
352            String s = null;
353    
354            switch ( type ) {
355            case Types.VARCHAR:
356            case Types.CHAR:
357                s = "string";
358                break;
359            case Types.NUMERIC: {
360                if ( precision <= 1 ) {
361                    s = "integer";
362                    break;
363                }
364                s = "double";
365                break;
366            }
367            case Types.DECIMAL:
368                s = "decimal";
369                break;
370            case Types.DOUBLE:
371            case Types.REAL:
372                s = "double";
373                break;
374            case Types.FLOAT:
375                s = "float";
376                break;
377            case Types.INTEGER:
378            case Types.SMALLINT:
379            case Types.BIGINT:
380                s = "integer";
381                break;
382            case Types.TIMESTAMP:
383            case Types.TIME:
384            case Types.DATE:
385                s = "dateTime";
386                break;
387            case Types.CLOB:
388                s = "string";
389                break;
390            case Types.BIT:
391            case Types.BOOLEAN:
392                s = "boolean";
393                break;
394            case Types.GEOMETRY:
395            case Types.OTHER:
396            case Types.STRUCT:
397                s = "gml:GeometryPropertyType";
398                break;
399            case Types.FEATURE:
400                s = "gml:FeaturePropertyType";
401                break;
402            default:
403                LOG.logWarning( "could not determine XSDType for SQLType; using 'XXX': " + type );
404                s = "code: " + type;
405            }
406            return s;
407        }
408    
409    }