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