001    //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/io/sdeapi/SDEAdapter.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.io.sdeapi;
037    
038    import java.util.ArrayList;
039    
040    import org.deegree.framework.util.TimeTools;
041    import org.deegree.model.crs.CoordinateSystem;
042    import org.deegree.model.spatialschema.Curve;
043    import org.deegree.model.spatialschema.Geometry;
044    import org.deegree.model.spatialschema.GeometryException;
045    import org.deegree.model.spatialschema.GeometryFactory;
046    import org.deegree.model.spatialschema.MultiCurve;
047    import org.deegree.model.spatialschema.MultiPoint;
048    import org.deegree.model.spatialschema.MultiSurface;
049    import org.deegree.model.spatialschema.Point;
050    import org.deegree.model.spatialschema.Position;
051    import org.deegree.model.spatialschema.Ring;
052    import org.deegree.model.spatialschema.Surface;
053    import org.deegree.model.spatialschema.SurfaceBoundary;
054    import org.deegree.model.spatialschema.SurfaceInterpolationImpl;
055    
056    import com.esri.sde.sdk.client.SDEPoint;
057    import com.esri.sde.sdk.client.SeColumnDefinition;
058    import com.esri.sde.sdk.client.SeCoordinateReference;
059    import com.esri.sde.sdk.client.SeException;
060    import com.esri.sde.sdk.client.SeRasterAttr;
061    import com.esri.sde.sdk.client.SeRow;
062    import com.esri.sde.sdk.client.SeShape;
063    import com.esri.sde.sdk.client.SeXmlDoc;
064    
065    /**
066     * Adapter class for exporting deegree geometries to WKT and to wrap WKT code geometries to deegree
067     * geometries.
068     *
069     * @version $Revision: 23718 $
070     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
071     */
072    public class SDEAdapter {
073    
074        // private static final ILogger LOG = LoggerFactory.getLogger( SDEAdapter.class );
075    
076        /**
077         *
078         * @param shape
079         * @param coordinateSystem 
080         * @return the corresponding <tt>Geometry</tt>
081         * @throws GeometryException
082         *             if type unsupported or conversion failed
083         * @throws SeException
084         */
085        public static Geometry wrap( SeShape shape, CoordinateSystem coordinateSystem )
086                                throws GeometryException, SeException {
087    
088            Geometry geo = null;
089    
090            if ( shape == null ) {
091                return null;
092            }
093    
094            switch ( shape.getType() ) {
095            case SeShape.TYPE_POINT: {
096                geo = wrapPoint( shape, coordinateSystem );
097                break;
098            }
099            case SeShape.TYPE_SIMPLE_LINE:
100            case SeShape.TYPE_LINE: {
101                geo = wrapCurve( shape, coordinateSystem );
102                break;
103            }
104            case SeShape.TYPE_POLYGON: {
105                geo = wrapSurface( shape, coordinateSystem );
106                break;
107            }
108            case SeShape.TYPE_MULTI_POINT: {
109                geo = wrapMultiPoint( shape, coordinateSystem );
110                break;
111            }
112            case SeShape.TYPE_MULTI_SIMPLE_LINE:
113            case SeShape.TYPE_MULTI_LINE: {
114                geo = wrapMultiCurve( shape, coordinateSystem );
115                break;
116            }
117            case SeShape.TYPE_MULTI_POLYGON: {
118                geo = wrapMultiSurface( shape, coordinateSystem );
119                break;
120            }
121            }
122    
123            return geo;
124        }
125    
126        /**
127         * @param geom
128         *            geometry
129         * @param crs
130         *
131         * @return the shape
132         * @throws GeometryException
133         * @throws SeException
134         */
135        public static SeShape export( Geometry geom, SeCoordinateReference crs )
136                                throws GeometryException, SeException {
137    
138            SeShape sb = null;
139    
140            if ( geom instanceof Point ) {
141                sb = export( (Point) geom, crs );
142            } else if ( geom instanceof Curve ) {
143                sb = export( (Curve) geom, crs );
144            } else if ( geom instanceof Surface ) {
145                sb = export( (Surface) geom, crs );
146            } else if ( geom instanceof MultiPoint ) {
147                sb = export( (MultiPoint) geom, crs );
148            } else if ( geom instanceof MultiCurve ) {
149                sb = export( (MultiCurve) geom, crs );
150            } else if ( geom instanceof MultiSurface ) {
151                sb = export( (MultiSurface) geom, crs );
152            }
153    
154            return sb;
155        }
156    
157        /**
158         * @param point
159         *            point geometry
160         *
161         */
162        private static SeShape export( Point point, SeCoordinateReference crs )
163                                throws SeException {
164    
165            SDEPoint pt = new SDEPoint( point.getX(), point.getY() );
166            SeShape shp = new SeShape( crs );
167            shp.generatePoint( 1, new SDEPoint[] { pt } );
168    
169            return shp;
170        }
171    
172        /**
173         *
174         * @param cur
175         *            curve geometry
176         *
177         *
178         * @throws GeometryException
179         */
180        private static SeShape export( Curve cur, SeCoordinateReference crs )
181                                throws GeometryException, SeException {
182    
183            Position[] pos = cur.getAsLineString().getPositions();
184            SDEPoint[] ptArray = new SDEPoint[pos.length];
185    
186            for ( int i = 0; i < pos.length; i++ ) {
187                ptArray[i] = new SDEPoint( pos[i].getX(), pos[i].getY() );
188            }
189            int numParts = 1;
190            int[] partOffSets = new int[numParts];
191            partOffSets[0] = 0;
192    
193            SeShape line = new SeShape( crs );
194            line.generateSimpleLine( pos.length, numParts, partOffSets, ptArray );
195    
196            return line;
197        }
198    
199        /**
200         *
201         *
202         * @param sur
203         *
204         *
205         * @throws SeException
206         */
207        private static SeShape export( Surface sur, SeCoordinateReference crs )
208                                throws SeException {
209    
210            int numParts = 1;
211            SurfaceBoundary sbo = sur.getSurfaceBoundary();
212            Ring ex = sbo.getExteriorRing();
213            Ring[] rings = sbo.getInteriorRings();
214    
215            int[] partOffsets = new int[numParts];
216            partOffsets[0] = 0;
217            int numPts = sbo.getExteriorRing().getPositions().length;
218            if ( rings != null ) {
219                for ( int i = 0; i < rings.length; i++ ) {
220                    numPts += rings[i].getPositions().length;
221                    numParts++;
222                }
223            }
224    
225            SDEPoint[] ptArray = new SDEPoint[numPts];
226    
227            int cnt = 0;
228            for ( int i = 0; i < ex.getPositions().length; i++ ) {
229                ptArray[cnt++] = new SDEPoint( ex.getPositions()[i].getX(), ex.getPositions()[i].getY() );
230            }
231    
232            if ( rings != null ) {
233                for ( int k = 0; k < rings.length; k++ ) {
234                    for ( int i = 0; i < rings[k].getPositions().length; i++ ) {
235                        ptArray[cnt++] = new SDEPoint( rings[k].getPositions()[i].getX(), rings[k].getPositions()[i].getY() );
236                    }
237                }
238            }
239    
240            SeShape polygon = new SeShape( crs );
241            polygon.generatePolygon( numPts, numParts, partOffsets, ptArray );
242    
243            return polygon;
244        }
245    
246        /**
247         * @param mp
248         * @param crs
249         * @throws SeException
250         */
251        private static SeShape export( MultiPoint mp, SeCoordinateReference crs )
252                                throws SeException {
253    
254            SDEPoint[] pt = new SDEPoint[mp.getSize()];
255    
256            for ( int i = 0; i < pt.length; i++ ) {
257                pt[i] = new SDEPoint( mp.getPointAt( i ).getX(), mp.getPointAt( i ).getY() );
258            }
259            SeShape shp = new SeShape( crs );
260            shp.generatePoint( pt.length, pt );
261    
262            return shp;
263        }
264    
265        /**
266         *
267         *
268         * @param mc
269         *
270         *
271         * @throws GeometryException
272         */
273        private static SeShape export( MultiCurve mc, SeCoordinateReference crs )
274                                throws GeometryException, SeException {
275    
276            int numParts = mc.getSize();
277            int[] partOffSets = new int[numParts];
278            int numPts = 0;
279            for ( int i = 0; i < numParts; i++ ) {
280                partOffSets[i] = numPts;
281                numPts += mc.getCurveAt( i ).getAsLineString().getNumberOfPoints();
282            }
283            SDEPoint[] ptArray = new SDEPoint[numPts];
284            int cnt = 0;
285            for ( int k = 0; k < numParts; k++ ) {
286                Position[] pos = mc.getCurveAt( k ).getAsLineString().getPositions();
287                for ( int i = 0; i < pos.length; i++ ) {
288                    ptArray[cnt++] = new SDEPoint( pos[i].getX(), pos[i].getY() );
289                }
290            }
291    
292            SeShape line = new SeShape( crs );
293            line.generateSimpleLine( numPts, numParts, partOffSets, ptArray );
294    
295            return line;
296        }
297    
298        /**
299         *
300         *
301         * @param ms
302         *
303         *
304         * @throws SeException
305         */
306        private static SeShape export( MultiSurface ms, SeCoordinateReference crs )
307                                throws SeException {
308    
309            int numParts = ms.getSize();
310            int[] partOffSets = new int[numParts];
311            int numPts = 0;
312            for ( int i = 0; i < numParts; i++ ) {
313                partOffSets[i] = numPts;
314                SurfaceBoundary sbo = ms.getSurfaceAt( i ).getSurfaceBoundary();
315                Ring ex = sbo.getExteriorRing();
316                Ring[] inner = sbo.getInteriorRings();
317                numPts += ex.getPositions().length;
318                if ( inner != null ) {
319                    for ( int j = 0; j < inner.length; j++ ) {
320                        numPts += inner[j].getPositions().length;
321                    }
322                }
323            }
324            SDEPoint[] ptArray = new SDEPoint[numPts];
325            int cnt = 0;
326            for ( int k = 0; k < numParts; k++ ) {
327                SurfaceBoundary sbo = ms.getSurfaceAt( k ).getSurfaceBoundary();
328                Ring ex = sbo.getExteriorRing();
329                Ring[] inner = sbo.getInteriorRings();
330                Position[] pos = ex.getPositions();
331                for ( int i = 0; i < pos.length; i++ ) {
332                    ptArray[cnt++] = new SDEPoint( pos[i].getX(), pos[i].getY() );
333                }
334                if ( inner != null ) {
335                    for ( int j = 0; j < inner.length; j++ ) {
336                        pos = inner[j].getPositions();
337                        for ( int i = 0; i < pos.length; i++ ) {
338                            ptArray[cnt++] = new SDEPoint( pos[i].getX(), pos[i].getY() );
339                        }
340                    }
341                }
342            }
343    
344            SeShape polygon = new SeShape( crs );
345            polygon.generatePolygon( numPts, numParts, partOffSets, ptArray );
346    
347            return polygon;
348        }
349    
350        /**
351         * creates a Point from a SeShape
352         *
353         * @param shape
354         * @param coordinateSystem 
355         */
356        private static Point wrapPoint( SeShape shape, CoordinateSystem coordinateSystem )
357                                throws SeException {
358    
359            /*
360             * ArrayList al = shape.getAllPoints( SeShape.TURN_DEFAULT, true ); // Retrieve the array of
361             * SDEPoints SDEPoint[] points = (SDEPoint[])al.get( 0 );
362             *
363             * Point point = GeometryFactory.createPoint( points[0].getX(), points[0].getY(), null );
364             */
365            double[][][] xyz = shape.getAllCoords( SeShape.TURN_DEFAULT );
366            Point point = GeometryFactory.createPoint( xyz[0][0][0], xyz[0][0][1], coordinateSystem );
367    
368            return point;
369        }
370    
371        /**
372         * creates a Curve from a SeShape
373         *
374         * @param shape
375         * @param coordinateSystem 
376         */
377        private static Curve wrapCurve( SeShape shape, CoordinateSystem coordinateSystem )
378                                throws GeometryException, SeException {
379    
380            ArrayList<?> al = shape.getAllPoints( SeShape.TURN_DEFAULT, true );
381            // Retrieve the array of SDEPoints
382            SDEPoint[] points = (SDEPoint[]) al.get( 0 );
383            // // Retrieve the part offsets array.
384            // int[] partOffset = (int[])al.get( 1 );
385            // // Retrieve the sub-part offsets array.
386            // int[] subPartOffset = (int[])al.get( 2 );
387    
388            int numPoints = shape.getNumOfPoints();
389    
390            Position[] gmSimpleLinePosition = new Position[numPoints];
391    
392            for ( int pt = 0; pt < numPoints; pt++ ) {
393                gmSimpleLinePosition[pt] = GeometryFactory.createPosition( points[pt].getX(), points[pt].getY() );
394            }
395    
396            Curve curve = GeometryFactory.createCurve( gmSimpleLinePosition, coordinateSystem );
397    
398            return curve;
399        }
400    
401        /**
402         * creates a Surface
403         *
404         * @param shape
405         * @param coordinateSystem 
406         */
407        private static Surface wrapSurface( SeShape shape, CoordinateSystem coordinateSystem )
408                                throws GeometryException, SeException {
409    
410            ArrayList<?> al = shape.getAllPoints( SeShape.TURN_DEFAULT, true );
411            // Retrieve the array of SDEPoints
412            SDEPoint[] points = (SDEPoint[]) al.get( 0 );
413            // Retrieve the part offsets array.
414            // int[] partOffset = (int[])al.get( 1 );
415            // Retrieve the sub-part offsets array.
416            int[] subPartOffset = (int[]) al.get( 2 );
417    
418            int numSubParts = shape.getNumSubParts( 1 );
419    
420            Position[] gmPolygonExteriorRing = new Position[shape.getNumPoints( 1, 1 )];
421    
422            for ( int pt = 0; pt < shape.getNumPoints( 1, 1 ); pt++ ) {
423                gmPolygonExteriorRing[pt] = GeometryFactory.createPosition( points[pt].getX(), points[pt].getY() );
424            }
425    
426            Position[][] gmPolygonInteriorRings = null;
427    
428            // if it is a donut create inner rings
429            if ( numSubParts > 1 ) {
430                gmPolygonInteriorRings = new Position[numSubParts - 1][];
431    
432                int j = 0;
433    
434                for ( int subPartNo = 1; subPartNo < numSubParts; subPartNo++ ) {
435                    int lastPoint = shape.getNumPoints( 1, subPartNo + 1 ) + subPartOffset[subPartNo];
436                    Position[] gmPolygonPosition = new Position[shape.getNumPoints( 1, subPartNo + 1 )];
437                    int i = 0;
438    
439                    for ( int pt = subPartOffset[subPartNo]; pt < lastPoint; pt++ ) {
440                        gmPolygonPosition[i] = GeometryFactory.createPosition( points[pt].getX(), points[pt].getY() );
441                        i++;
442                    }
443    
444                    gmPolygonInteriorRings[j] = gmPolygonPosition;
445                    j++;
446                }
447            }
448    
449            Surface sur = GeometryFactory.createSurface( gmPolygonExteriorRing, gmPolygonInteriorRings,
450                                                         new SurfaceInterpolationImpl(), coordinateSystem );
451    
452            return sur;
453        }
454    
455        /**
456         * creates a MultiPoint from a WKT
457         *
458         * @param shape
459         * @param coordinateSystem 
460         */
461        private static MultiPoint wrapMultiPoint( SeShape shape, CoordinateSystem coordinateSystem )
462                                throws SeException {
463    
464            ArrayList<?> al = shape.getAllPoints( SeShape.TURN_DEFAULT, true );
465            // Retrieve the array of SDEPoints
466            SDEPoint[] points = (SDEPoint[]) al.get( 0 );
467    
468            int numPoints = shape.getNumOfPoints();
469    
470            Point[] gmPoints = new Point[numPoints];
471    
472            for ( int pt = 0; pt < numPoints; pt++ ) {
473                gmPoints[pt] = GeometryFactory.createPoint( points[pt].getX(), points[pt].getY(), coordinateSystem );
474            }
475    
476            MultiPoint gmMultiPoint = GeometryFactory.createMultiPoint( gmPoints );
477    
478            return gmMultiPoint;
479        }
480    
481        /**
482         * creates a MultiCurve from a WKT
483         *
484         * @param shape
485         * @param coordinateSystem 
486         */
487        private static MultiCurve wrapMultiCurve( SeShape shape, CoordinateSystem coordinateSystem )
488                                throws GeometryException, SeException {
489    
490            ArrayList<?> al = shape.getAllPoints( SeShape.TURN_DEFAULT, true );
491            // Retrieve the array of SDEPoints
492            SDEPoint[] points = (SDEPoint[]) al.get( 0 );
493    
494            // Retrieve the part offsets array.
495            int[] partOffset = (int[]) al.get( 1 );
496    
497            int numParts = shape.getNumParts();
498    
499            Curve[] gmCurves = new Curve[numParts];
500    
501            for ( int partNo = 0; partNo < numParts; partNo++ ) {
502                int lastPoint = shape.getNumPoints( partNo + 1, 1 ) + partOffset[partNo];
503                Position[] gmMultiSimpleLinePosition = new Position[shape.getNumPoints( partNo + 1, 1 )];
504                int i = 0;
505    
506                for ( int pt = partOffset[partNo]; pt < lastPoint; pt++ ) {
507                    gmMultiSimpleLinePosition[i] = GeometryFactory.createPosition( points[pt].getX(), points[pt].getY() );
508                    i++;
509                }
510    
511                gmCurves[partNo] = GeometryFactory.createCurve( gmMultiSimpleLinePosition, coordinateSystem );
512            }
513    
514            MultiCurve gmMultiCurve = GeometryFactory.createMultiCurve( gmCurves );
515    
516            return gmMultiCurve;
517        }
518    
519        /**
520         * creates a MultiSurface from a WKT
521         *
522         * @param shape
523         * @param coordinateSystem 
524         */
525        private static MultiSurface wrapMultiSurface( SeShape shape, CoordinateSystem coordinateSystem )
526                                throws GeometryException, SeException {
527    
528            ArrayList<?> al = shape.getAllPoints( SeShape.TURN_DEFAULT, true );
529            // Retrieve the array of SDEPoints
530            SDEPoint[] points = (SDEPoint[]) al.get( 0 );
531            // Retrieve the part offsets array.
532            int[] partOffset = (int[]) al.get( 1 );
533            // Retrieve the sub-part offsets array.
534            int[] subPartOffset = (int[]) al.get( 2 );
535    
536            int numParts = shape.getNumParts();
537    
538            Surface[] gmMultiPolygonSurface = new Surface[numParts];
539            boolean subParts = false;
540    
541            if ( partOffset.length < subPartOffset.length ) {
542                subParts = true;
543            }
544    
545            for ( int partNo = 0, partEnd = 0; partNo < partOffset.length; partNo++ ) {
546                Position[] gmMultiPolygonExteriorRing = new Position[shape.getNumPoints( partNo + 1, 1 )];
547                Position[][] gmMultiPolygonInteriorRings = null;
548                int nSubParts = shape.getNumSubParts( partNo + 1 );
549    
550                if ( nSubParts > 1 ) {
551                    gmMultiPolygonInteriorRings = new Position[( nSubParts - 1 )][];
552                }
553    
554                if ( ( partOffset.length - partNo ) == 1 ) {
555                    partEnd = points.length; // If this is the last part, scan through to
556                    // points.length
557                } else {
558                    partEnd = subPartOffset[partOffset[partNo + 1]]; // Otherwise scan to the offset
559                    // of next part
560                }
561    
562                int subPartNo = partOffset[partNo];
563                int pointNo = subPartOffset[partOffset[partNo]];
564                boolean exterior = true;
565                int i = 0;
566                int subPartIndex = -1;
567    
568                for ( ; ( pointNo < points.length ) && ( pointNo < partEnd ); pointNo++ ) {
569                    if ( subParts ) {
570                        if ( ( subPartNo < subPartOffset.length ) && ( pointNo == subPartOffset[subPartNo] ) ) {
571                            subPartNo++;
572                            i = 0;
573                        }
574                    }
575    
576                    if ( exterior ) {
577                        gmMultiPolygonExteriorRing[i] = GeometryFactory.createPosition( points[pointNo].getX(),
578                                                                                        points[pointNo].getY() );
579    
580                        i++;
581    
582                        if ( ( subPartNo < subPartOffset.length ) && ( pointNo == ( subPartOffset[subPartNo] - 1 ) ) ) {
583                            exterior = false;
584                        }
585                    } else {
586                        // When i=0 we are starting a new subPart. I compute
587                        // and assign the size of the second dimension of gmMultiPolygonInteriorRings
588                        if ( i == 0 ) {
589                            subPartIndex++; // Used to address each interior ring
590    
591                            gmMultiPolygonInteriorRings[subPartIndex] = new Position[subPartOffset[subPartNo]
592                                                                                     - subPartOffset[subPartNo - 1]];
593                        }
594    
595                        gmMultiPolygonInteriorRings[subPartIndex][i] = GeometryFactory.createPosition(
596                                                                                                       points[pointNo].getX(),
597                                                                                                       points[pointNo].getY() );
598    
599                        i++;
600                    }
601                } // End for
602    
603                gmMultiPolygonSurface[partNo] = GeometryFactory.createSurface( gmMultiPolygonExteriorRing,
604                                                                               gmMultiPolygonInteriorRings,
605                                                                               new SurfaceInterpolationImpl(), null );
606            } // End for
607    
608            MultiSurface gmMultiSurface = GeometryFactory.createMultiSurface( gmMultiPolygonSurface );
609    
610            return gmMultiSurface;
611        }
612    
613        /**
614         * Set a row value with the appropriate setting method. If the datatype is unknown it will be
615         * assigned by following rules:<br> - first, check the dataype of the given value and choose an
616         * appropriate setter method<br> - or, if it isn't assignable this way, take the setString
617         * method
618         *
619         * @param row
620         * @param pos -
621         *            the column position (0 - n)
622         * @param value -
623         *            the column value
624         * @param sdetype -
625         *            the datatype, expressed as SeColumnDefinition constant or -1, if unknown
626         * @throws SeException
627         */
628        public static void setRowValue( SeRow row, int pos, Object value, int sdetype )
629                                throws SeException {
630            if ( -1 == sdetype )
631                sdetype = findSDEType( value );
632            switch ( sdetype ) {
633            case SeColumnDefinition.TYPE_BLOB: {
634                row.setBlob( pos, (java.io.ByteArrayInputStream) value );
635                break;
636            }
637            case SeColumnDefinition.TYPE_CLOB: {
638                row.setClob( pos, (java.io.ByteArrayInputStream) value );
639                break;
640            }
641            case SeColumnDefinition.TYPE_DATE: {
642                if ( null != value && value instanceof String )
643                    value = TimeTools.createCalendar( (String) value ).getTime();
644                if ( value instanceof java.util.Date )
645                    row.setDate( pos, (java.util.Date) value );
646                else if ( value instanceof java.util.Calendar )
647                    row.setTime( pos, (java.util.Calendar) value );
648                break;
649            }
650            case SeColumnDefinition.TYPE_FLOAT64: {
651                if ( null != value && value instanceof String )
652                    value = new Double( (String) value );
653                row.setDouble( pos, (java.lang.Double) value );
654                break;
655            }
656            case SeColumnDefinition.TYPE_FLOAT32: {
657                if ( null != value && value instanceof String )
658                    value = new Float( (String) value );
659                row.setFloat( pos, (java.lang.Float) value );
660                break;
661            }
662            case SeColumnDefinition.TYPE_INT16: {
663                if ( null != value && value instanceof String )
664                    value = new Short( (String) value );
665                row.setShort( pos, (java.lang.Short) value );
666                break;
667            }
668            case SeColumnDefinition.TYPE_INT32: {
669                if ( null != value && value instanceof String )
670                    value = new Integer( (String) value );
671                row.setInteger( pos, (java.lang.Integer) value );
672                break;
673            }
674            case SeColumnDefinition.TYPE_INT64: {
675                if ( null != value && value instanceof String )
676                    value = new Long( (String) value );
677                row.setLong( pos, (java.lang.Long) value );
678                break;
679            }
680            case SeColumnDefinition.TYPE_NCLOB: {
681                row.setNClob( pos, (java.io.ByteArrayInputStream) value );
682                break;
683            }
684            case SeColumnDefinition.TYPE_NSTRING: {
685                row.setNString( pos, (String) value );
686                break;
687            }
688            case SeColumnDefinition.TYPE_RASTER: {
689                row.setRaster( pos, (SeRasterAttr) value );
690                break;
691            }
692            case SeColumnDefinition.TYPE_SHAPE: {
693                row.setShape( pos, (SeShape) value );
694                break;
695            }
696            case SeColumnDefinition.TYPE_STRING: {
697                row.setString( pos, (String) value );
698                break;
699            }
700            case SeColumnDefinition.TYPE_UUID: {
701                row.setUuid( pos, (String) value );
702                break;
703            }
704            case SeColumnDefinition.TYPE_XML: {
705                row.setXml( pos, (SeXmlDoc) value );
706                break;
707            }
708            default: {
709                row.setString( pos, value.toString() );
710                break;
711            }
712            }
713        }
714    
715        /**
716         * Find an appropriate ArcSDE datataype for the given object value
717         *
718         * @param value
719         * @return sdetype
720         */
721        public static int findSDEType( Object value ) {
722            if ( null == value )
723                return -1;
724            else if ( value instanceof java.lang.Integer )
725                return SeColumnDefinition.TYPE_INT16;
726            else if ( value instanceof java.lang.Double )
727                return SeColumnDefinition.TYPE_FLOAT64;
728            else if ( value instanceof java.lang.Float )
729                return SeColumnDefinition.TYPE_FLOAT32;
730            else if ( value instanceof java.util.Calendar )
731                return SeColumnDefinition.TYPE_DATE;
732            else if ( value instanceof java.util.Date )
733                return SeColumnDefinition.TYPE_DATE;
734            else if ( value instanceof java.sql.Date )
735                return SeColumnDefinition.TYPE_DATE;
736            else if ( value instanceof SeRasterAttr )
737                return SeColumnDefinition.TYPE_RASTER;
738            else if ( value instanceof SeShape )
739                return SeColumnDefinition.TYPE_SHAPE;
740            else if ( value instanceof java.lang.String )
741                return SeColumnDefinition.TYPE_STRING;
742            else if ( value instanceof SeXmlDoc )
743                return SeColumnDefinition.TYPE_XML;
744            else
745                return -1;
746        }
747    
748        /**
749         * Map SQL datatypes to appropriate ArcSDE datataypes.
750         *
751         * @param sqltype
752         * @return sdetype
753         */
754        public static int mapSQL2SDE( int sqltype ) {
755            switch ( sqltype ) {
756            case java.sql.Types.ARRAY:
757                return -1;
758            case java.sql.Types.BIGINT:
759                return SeColumnDefinition.TYPE_INT64;
760            case java.sql.Types.BINARY:
761                return SeColumnDefinition.TYPE_STRING;
762            case java.sql.Types.BIT:
763                return -1;
764            case java.sql.Types.BLOB:
765                return SeColumnDefinition.TYPE_BLOB;
766            case java.sql.Types.BOOLEAN:
767                return -1;
768            case java.sql.Types.CHAR:
769                return SeColumnDefinition.TYPE_STRING;
770            case java.sql.Types.CLOB:
771                return SeColumnDefinition.TYPE_CLOB;
772            case java.sql.Types.DATALINK:
773                return -1;
774            case java.sql.Types.DATE:
775                return SeColumnDefinition.TYPE_DATE;
776            case java.sql.Types.DECIMAL:
777                return SeColumnDefinition.TYPE_FLOAT64;
778            case java.sql.Types.DISTINCT:
779                return -1;
780            case java.sql.Types.DOUBLE:
781                return SeColumnDefinition.TYPE_FLOAT64;
782            case java.sql.Types.FLOAT:
783                return SeColumnDefinition.TYPE_FLOAT32;
784            case java.sql.Types.INTEGER:
785                return SeColumnDefinition.TYPE_INT32;
786            case java.sql.Types.JAVA_OBJECT:
787                return -1;
788            case java.sql.Types.LONGVARBINARY:
789                return -1;
790            case java.sql.Types.LONGVARCHAR:
791                return -1;
792            case java.sql.Types.NULL:
793                return -1;
794            case java.sql.Types.NUMERIC:
795                return SeColumnDefinition.TYPE_FLOAT64;
796            case java.sql.Types.OTHER:
797                return -1;
798            case java.sql.Types.REAL:
799                return SeColumnDefinition.TYPE_FLOAT32;
800            case java.sql.Types.REF:
801                return -1;
802            case java.sql.Types.SMALLINT:
803                return SeColumnDefinition.TYPE_INT16;
804            case java.sql.Types.STRUCT:
805                return SeColumnDefinition.TYPE_SHAPE;
806            case java.sql.Types.TIME:
807                return SeColumnDefinition.TYPE_DATE;
808            case java.sql.Types.TIMESTAMP:
809                return SeColumnDefinition.TYPE_DATE;
810            case java.sql.Types.TINYINT:
811                return SeColumnDefinition.TYPE_INT16;
812            case java.sql.Types.VARBINARY:
813                return SeColumnDefinition.TYPE_STRING;
814            case java.sql.Types.VARCHAR:
815                return SeColumnDefinition.TYPE_STRING;
816            default:
817                return -1;
818            }
819        }
820    
821        /**
822         * Map ArcSDE datatypes to appropriate SQL datataypes.
823         *
824         * @param sdetype
825         * @return sqltype
826         */
827        public static int mapSDE2SQL( int sdetype ) {
828            switch ( sdetype ) {
829            case SeColumnDefinition.TYPE_BLOB:
830                return java.sql.Types.BLOB;
831            case SeColumnDefinition.TYPE_CLOB:
832                return java.sql.Types.CLOB;
833            case SeColumnDefinition.TYPE_DATE:
834                return java.sql.Types.DATE;
835            case SeColumnDefinition.TYPE_FLOAT64:
836                return java.sql.Types.DOUBLE;
837            case SeColumnDefinition.TYPE_FLOAT32:
838                return java.sql.Types.FLOAT;
839            case SeColumnDefinition.TYPE_INT64: // Since ArcSDE v9.0
840                return java.sql.Types.INTEGER;
841            case SeColumnDefinition.TYPE_INT32:
842                return java.sql.Types.INTEGER;
843            case SeColumnDefinition.TYPE_NCLOB:
844                return java.sql.Types.CLOB;
845            case SeColumnDefinition.TYPE_NSTRING:
846                return java.sql.Types.VARCHAR;
847            case SeColumnDefinition.TYPE_RASTER:
848                return -1;
849            case SeColumnDefinition.TYPE_SHAPE:
850                return java.sql.Types.STRUCT;
851            case SeColumnDefinition.TYPE_INT16:
852                return java.sql.Types.SMALLINT;
853            case SeColumnDefinition.TYPE_STRING:
854                return java.sql.Types.VARCHAR;
855            case SeColumnDefinition.TYPE_UUID:
856                return java.sql.Types.VARCHAR;
857            case SeColumnDefinition.TYPE_XML:
858                return java.sql.Types.VARCHAR;
859            default:
860                return -1;
861            }
862        }
863    }