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