Source Code Cross Referenced for ArcSDEAdapter.java in  » GIS » GeoTools-2.4.1 » org » geotools » arcsde » data » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » GIS » GeoTools 2.4.1 » org.geotools.arcsde.data 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *    Geotools2 - OpenSource mapping toolkit
003:         *    http://geotools.org
004:         *    (C) 2002-2006, Geotools Project Managment Committee (PMC)
005:         *
006:         *    This library is free software; you can redistribute it and/or
007:         *    modify it under the terms of the GNU Lesser General Public
008:         *    License as published by the Free Software Foundation;
009:         *    version 2.1 of the License.
010:         *
011:         *    This library is distributed in the hope that it will be useful,
012:         *    but WITHOUT ANY WARRANTY; without even the implied warranty of
013:         *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014:         *    Lesser General Public License for more details.
015:         *
016:         */
017:        package org.geotools.arcsde.data;
018:
019:        import java.io.IOException;
020:        import java.net.URI;
021:        import java.net.URISyntaxException;
022:        import java.util.ArrayList;
023:        import java.util.Date;
024:        import java.util.HashMap;
025:        import java.util.Iterator;
026:        import java.util.List;
027:        import java.util.Map;
028:        import java.util.NoSuchElementException;
029:        import java.util.Set;
030:        import java.util.logging.Level;
031:        import java.util.logging.Logger;
032:
033:        import org.geotools.arcsde.pool.ArcSDEConnectionPool;
034:        import org.geotools.arcsde.pool.ArcSDEPooledConnection;
035:        import org.geotools.data.DataSourceException;
036:        import org.geotools.feature.AttributeType;
037:        import org.geotools.feature.AttributeTypeFactory;
038:        import org.geotools.feature.DefaultFeatureTypeFactory;
039:        import org.geotools.feature.FeatureType;
040:        import org.geotools.feature.FeatureTypeBuilder;
041:        import org.geotools.feature.GeometryAttributeType;
042:        import org.geotools.feature.SchemaException;
043:
044:        import org.geotools.referencing.ReferencingFactoryFinder;
045:        import org.opengis.filter.identity.FeatureId;
046:        import org.opengis.filter.identity.Identifier;
047:        import org.opengis.referencing.FactoryException;
048:        import org.opengis.referencing.crs.CRSFactory;
049:        import org.opengis.referencing.crs.CoordinateReferenceSystem;
050:
051:        import com.esri.sde.sdk.client.SeColumnDefinition;
052:        import com.esri.sde.sdk.client.SeCoordinateReference;
053:        import com.esri.sde.sdk.client.SeException;
054:        import com.esri.sde.sdk.client.SeLayer;
055:        import com.esri.sde.sdk.client.SeQuery;
056:        import com.esri.sde.sdk.client.SeQueryInfo;
057:        import com.esri.sde.sdk.client.SeRow;
058:        import com.esri.sde.sdk.client.SeShape;
059:        import com.esri.sde.sdk.client.SeTable;
060:        import com.vividsolutions.jts.geom.Geometry;
061:        import com.vividsolutions.jts.geom.GeometryCollection;
062:        import com.vividsolutions.jts.geom.LineString;
063:        import com.vividsolutions.jts.geom.MultiLineString;
064:        import com.vividsolutions.jts.geom.MultiPoint;
065:        import com.vividsolutions.jts.geom.MultiPolygon;
066:        import com.vividsolutions.jts.geom.Point;
067:        import com.vividsolutions.jts.geom.Polygon;
068:
069:        /**
070:         * Utility class to deal with SDE specifics such as creating SeQuery objects
071:         * from geotool's Query's, mapping SDE types to Java ones and JTS Geometries,
072:         * etc.
073:         * 
074:         * @author Gabriel Roldan
075:         * @source $URL:
076:         *         http://svn.geotools.org/geotools/trunk/gt/modules/unsupported/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSDEAdapter.java $
077:         * @version $Id: ArcSDEAdapter.java 28902 2008-01-23 13:50:41Z groldan $
078:         */
079:        public class ArcSDEAdapter {
080:            /** Logger for ths class' package */
081:            private static final Logger LOGGER = org.geotools.util.logging.Logging
082:                    .getLogger(ArcSDEAdapter.class.getPackage().getName());
083:
084:            /** mappings of SDE attribute's types to Java ones */
085:            private static final Map sde2JavaTypes = new HashMap();
086:
087:            /** inverse of sdeTypes, maps Java types to SDE ones */
088:            private static final Map java2SDETypes = new HashMap();
089:
090:            static {
091:                sde2JavaTypes.put(new Integer(SeColumnDefinition.TYPE_NSTRING),
092:                        String.class);
093:                sde2JavaTypes.put(new Integer(SeColumnDefinition.TYPE_STRING),
094:                        String.class);
095:                sde2JavaTypes.put(new Integer(SeColumnDefinition.TYPE_INT16),
096:                        Short.class);
097:                sde2JavaTypes.put(new Integer(SeColumnDefinition.TYPE_INT32),
098:                        Integer.class);
099:                sde2JavaTypes.put(new Integer(SeColumnDefinition.TYPE_INT64),
100:                        Long.class);
101:                sde2JavaTypes.put(new Integer(SeColumnDefinition.TYPE_FLOAT32),
102:                        Float.class);
103:                sde2JavaTypes.put(new Integer(SeColumnDefinition.TYPE_FLOAT64),
104:                        Double.class);
105:                sde2JavaTypes.put(new Integer(SeColumnDefinition.TYPE_DATE),
106:                        Date.class);
107:                // @TODO: not at all, only for capable open table with GeoServer
108:                // sde2JavaTypes.put(new
109:                // Integer(SeColumnDefinition.TYPE_BLOB),byte[].class);
110:                // @TODO sde2JavaTypes.put(new Integer(SeColumnDefinition.TYPE_CLOB),
111:                // String.class);
112:                // @Tested for view
113:                sde2JavaTypes.put(new Integer(SeColumnDefinition.TYPE_UUID),
114:                        String.class);
115:                // @TODO sde2JavaTypes.put(new Integer(SeColumnDefinition.TYPE_XML),
116:                // org.w3c.dom.Document.class);
117:
118:                // deprecated codes as for ArcSDE 9.0+. Adding them to maintain < 9.0
119:                // compatibility
120:                // though the assigned int codes matched their new counterparts, I let
121:                // them here as a reminder
122:                sde2JavaTypes.put(
123:                        new Integer(SeColumnDefinition.TYPE_SMALLINT),
124:                        Short.class);
125:                sde2JavaTypes.put(new Integer(SeColumnDefinition.TYPE_INTEGER),
126:                        Integer.class);
127:                sde2JavaTypes.put(new Integer(SeColumnDefinition.TYPE_FLOAT),
128:                        Float.class);
129:                sde2JavaTypes.put(new Integer(SeColumnDefinition.TYPE_DOUBLE),
130:                        Double.class);
131:
132:                /**
133:                 * By now keep using the deprecated constants (TYPE_INTEGER, etc.),
134:                 * switching directly to the new ones gives problems with ArcSDE
135:                 * instances prior to version 9.0.
136:                 */
137:                // SeColumnDefinition.TYPE_RASTER is not supported...
138:                java2SDETypes.put(String.class, new SdeTypeDef(
139:                        SeColumnDefinition.TYPE_STRING, 255, 0));
140:                java2SDETypes.put(Short.class, new SdeTypeDef(
141:                        SeColumnDefinition.TYPE_SMALLINT, 4, 0));
142:                java2SDETypes.put(Integer.class, new SdeTypeDef(
143:                        SeColumnDefinition.TYPE_INTEGER, 10, 0));
144:                java2SDETypes.put(Float.class, new SdeTypeDef(
145:                        SeColumnDefinition.TYPE_FLOAT, 5, 2));
146:                java2SDETypes.put(Double.class, new SdeTypeDef(
147:                        SeColumnDefinition.TYPE_DOUBLE, 15, 4));
148:                java2SDETypes.put(Date.class, new SdeTypeDef(
149:                        SeColumnDefinition.TYPE_DATE, 1, 0));
150:                java2SDETypes.put(Long.class, new SdeTypeDef(
151:                        SeColumnDefinition.TYPE_INTEGER, 10, 0));
152:                // java2SDETypes.put(byte[].class, new
153:                // SdeTypeDef(SeColumnDefinition.TYPE_BLOB, 1, 0));
154:                java2SDETypes.put(Number.class, new SdeTypeDef(
155:                        SeColumnDefinition.TYPE_DOUBLE, 15, 4));
156:            }
157:
158:            /**
159:             * DOCUMENT ME!
160:             * 
161:             * @param attribute
162:             *            DOCUMENT ME!
163:             * 
164:             * @return DOCUMENT ME!
165:             * 
166:             * @throws NullPointerException
167:             *             DOCUMENT ME!
168:             * @throws IllegalArgumentException
169:             *             DOCUMENT ME!
170:             */
171:            public static int guessShapeTypes(GeometryAttributeType attribute) {
172:                if (attribute == null) {
173:                    throw new NullPointerException(
174:                            "a GeometryAttributeType must be provided, got null");
175:                }
176:
177:                Class geometryClass = attribute.getType();
178:
179:                int shapeTypes = 0;
180:
181:                if (attribute.isNillable()) {
182:                    shapeTypes |= SeLayer.SE_NIL_TYPE_MASK;
183:                }
184:
185:                if (GeometryCollection.class.isAssignableFrom(geometryClass)) {
186:                    shapeTypes |= SeLayer.SE_MULTIPART_TYPE_MASK;
187:
188:                    if (geometryClass == MultiPoint.class) {
189:                        shapeTypes |= SeLayer.SE_POINT_TYPE_MASK;
190:                    } else if (geometryClass == MultiLineString.class) {
191:                        shapeTypes |= SeLayer.SE_LINE_TYPE_MASK;
192:                    } else if (geometryClass == MultiPolygon.class) {
193:                        shapeTypes |= SeLayer.SE_AREA_TYPE_MASK;
194:                    } else {
195:                        throw new IllegalArgumentException(
196:                                "no SDE geometry mapping for " + geometryClass);
197:                    }
198:                } else {
199:                    if (geometryClass == Point.class) {
200:                        shapeTypes |= SeLayer.SE_POINT_TYPE_MASK;
201:                    } else if (geometryClass == LineString.class) {
202:                        shapeTypes |= SeLayer.SE_LINE_TYPE_MASK;
203:                    } else if (geometryClass == Polygon.class) {
204:                        shapeTypes |= SeLayer.SE_AREA_TYPE_MASK;
205:                    } else if (geometryClass == Geometry.class) {
206:                        LOGGER
207:                                .fine("Creating SeShape types for all types of geometries.");
208:                        shapeTypes |= (SeLayer.SE_MULTIPART_TYPE_MASK
209:                                | SeLayer.SE_POINT_TYPE_MASK
210:                                | SeLayer.SE_LINE_TYPE_MASK | SeLayer.SE_AREA_TYPE_MASK);
211:                    } else {
212:                        throw new IllegalArgumentException(
213:                                "no SDE geometry mapping for " + geometryClass);
214:                    }
215:                }
216:
217:                return shapeTypes;
218:            }
219:
220:            /**
221:             * Creates the column definition as used by the ArcSDE Java API, for the
222:             * given AttributeType.
223:             * 
224:             * @param type
225:             *            the source attribute definition.
226:             * 
227:             * @return an <code>SeColumnDefinition</code> object matching the
228:             *         properties of the source AttributeType.
229:             * 
230:             * @throws SeException
231:             *             if the SeColumnDefinition constructor throws it due to some
232:             *             invalid parameter
233:             */
234:            public static SeColumnDefinition createSeColumnDefinition(
235:                    AttributeType type) throws SeException {
236:                SeColumnDefinition colDef = null;
237:                String colName = type.getName();
238:                boolean nillable = type.isNillable();
239:
240:                SdeTypeDef def = getSdeType(type.getType());
241:
242:                int sdeColType = def.colDefType;
243:                int fieldLength = def.size;
244:                int fieldScale = def.scale;
245:
246:                colDef = new SeColumnDefinition(colName, sdeColType,
247:                        fieldLength, fieldScale, nillable);
248:
249:                return colDef;
250:            }
251:
252:            /**
253:             * DOCUMENT ME!
254:             * 
255:             * @param attClass
256:             * 
257:             * @return an SdeTypeDef instance with default values for the given class
258:             * 
259:             * @throws IllegalArgumentException
260:             *             DOCUMENT ME!
261:             */
262:            private static SdeTypeDef getSdeType(Class attClass)
263:                    throws IllegalArgumentException {
264:                SdeTypeDef sdeType = (SdeTypeDef) java2SDETypes.get(attClass);
265:
266:                if (sdeType == null) {
267:                    throw new IllegalArgumentException(
268:                            "No SDE type mapping for " + attClass.getName());
269:                }
270:
271:                return sdeType;
272:            }
273:
274:            /**
275:             * Fetches the schema of a given ArcSDE featureclass and creates its
276:             * corresponding Geotools FeatureType
277:             * 
278:             * @param connPool
279:             *            DOCUMENT ME!
280:             * @param typeName
281:             *            DOCUMENT ME!
282:             * 
283:             * @return DOCUMENT ME!
284:             * 
285:             * @throws IOException
286:             *             DOCUMENT ME!
287:             * @throws DataSourceException
288:             *             DOCUMENT ME!
289:             */
290:            public static FeatureType fetchSchema(
291:                    ArcSDEConnectionPool connPool, String typeName,
292:                    String namespace) throws IOException {
293:                SeLayer sdeLayer = connPool.getSdeLayer(typeName);
294:                SeTable sdeTable = connPool.getSdeTable(typeName);
295:                // List/*<AttributeDescriptor>*/properties =
296:                // createAttributeDescriptors(connPool, sdeLayer, sdeTable, namespace);
297:                List/* <AttributeType> */properties = createAttributeDescriptors(
298:                        connPool, sdeLayer, sdeTable, namespace);
299:                FeatureType type = createSchema(typeName, namespace, properties);
300:                return type;
301:            }
302:
303:            /**
304:             * Fetchs the schema for the "SQL SELECT" like view definition
305:             * 
306:             * @param connPool
307:             * @param typeName
308:             * @param viewDef
309:             * @return
310:             * @throws IOException
311:             */
312:            public static FeatureType fetchSchema(
313:                    ArcSDEConnectionPool connPool, String typeName,
314:                    String namespace, SeQueryInfo queryInfo) throws IOException {
315:
316:                List attributeDescriptors;
317:
318:                ArcSDEPooledConnection conn = connPool.getConnection();
319:
320:                SeQuery testQuery = null;
321:                try {
322:                    // is the first table is a layer, we'll get it to obtain CRS info
323:                    // from
324:                    String mainTable = queryInfo.getConstruct().getTables()[0];
325:                    SeLayer layer = null;
326:                    try {
327:                        layer = connPool.getSdeLayer(conn, mainTable);
328:                    } catch (NoSuchElementException e) {
329:                        LOGGER
330:                                .info(mainTable
331:                                        + " is not an SeLayer, so no CRS info will be parsed");
332:                    }
333:                    LOGGER.fine("testing query");
334:                    testQuery = new SeQuery(conn);
335:                    testQuery.prepareQueryInfo(queryInfo);
336:                    testQuery.execute();
337:                    LOGGER.fine("definition query executed successfully");
338:
339:                    LOGGER.fine("fetching row to obtain view's types");
340:
341:                    SeRow testRow = testQuery.fetch();
342:                    SeColumnDefinition[] colDefs = testRow.getColumns();
343:
344:                    attributeDescriptors = createAttributeDescriptors(layer,
345:                            namespace, colDefs);
346:
347:                } catch (SeException e) {
348:                    throw new DataSourceException(e.getSeError().getErrDesc(),
349:                            e);
350:                } finally {
351:                    if (testQuery != null) {
352:                        try {
353:                            testQuery.close();
354:                        } catch (SeException e) {
355:                        }
356:                    }
357:                    conn.close();
358:                }
359:                FeatureType type = createSchema(typeName, namespace,
360:                        attributeDescriptors);
361:                return type;
362:            }
363:
364:            /**
365:             * Creates the FeatureType content for a given ArcSDE layer in the form of a
366:             * list of AttributeDescriptors
367:             * 
368:             * @param sdeLayer
369:             *            sde layer
370:             * @param table
371:             *            sde business table associated to <code>layer</code>
372:             * 
373:             * @return List&lt;AttributeDescriptor&gt;
374:             * 
375:             * @throws DataSourceException
376:             *             if any problem is found wroking with arcsde to fetch layer
377:             *             metadata
378:             * 
379:             */
380:            private static List createAttributeDescriptors(
381:                    ArcSDEConnectionPool connPool, SeLayer sdeLayer,
382:                    SeTable table, String namespace) throws DataSourceException {
383:                SeColumnDefinition[] seColumns = null;
384:                try {
385:                    seColumns = table.describe();
386:                } catch (SeException e) {
387:                    throw new DataSourceException(e);
388:                }
389:
390:                return createAttributeDescriptors(sdeLayer, namespace,
391:                        seColumns);
392:            }
393:
394:            private static List createAttributeDescriptors(SeLayer sdeLayer,
395:                    String namespace, SeColumnDefinition[] seColumns)
396:                    throws DataSourceException {
397:                String attName;
398:                boolean isNilable;
399:                int fieldLen;
400:                Object defValue;
401:                Object metadata = null;
402:
403:                final int nCols = seColumns.length;
404:                List attDescriptors = new ArrayList(nCols);
405:
406:                AttributeType attributeType = null;
407:                Class typeClass = null;
408:
409:                for (int i = 0; i < nCols; i++) {
410:                    SeColumnDefinition colDef = seColumns[i];
411:
412:                    attName = colDef.getName();
413:                    // didn't found in the ArcSDE Java API the way of knowing
414:                    // if an SeColumnDefinition is nillable. SeColumnDefinition has
415:                    // a nullable argument on its constructor, but no getter method
416:                    isNilable = true;
417:                    defValue = null;
418:                    fieldLen = colDef.getSize();
419:
420:                    final Integer sdeType = new Integer(colDef.getType());
421:
422:                    if (sdeType.intValue() == SeColumnDefinition.TYPE_SHAPE) {
423:                        CoordinateReferenceSystem crs = null;
424:
425:                        crs = parseCRS(sdeLayer);
426:                        metadata = crs;
427:
428:                        int seShapeType = sdeLayer.getShapeTypes();
429:                        typeClass = getGeometryTypeFromLayerMask(seShapeType);
430:                        isNilable = (seShapeType & SeLayer.SE_NIL_TYPE_MASK) == SeLayer.SE_NIL_TYPE_MASK;
431:                        defValue = ArcSDEGeometryBuilder
432:                                .defaultValueFor(typeClass);
433:
434:                    } else {
435:                        typeClass = (Class) sde2JavaTypes.get(sdeType);
436:                        if (typeClass == null) {
437:                            // interesting question: Do we throw an exception here, or
438:                            // do we allow un-handle-able columns
439:                            // to just 'disappear' when serving those tables?
440:                            // GR: just ignore them by now...
441:                            LOGGER.info("Unsupported column type ("
442:                                    + sdeType.intValue() + ") for " + attName
443:                                    + ". Ignoring the column.");
444:                            //do not create the attribute type and add it to the list of descriptors
445:                            continue;
446:                        }
447:                        // @TODO: add restrictions once the Restrictions utility methods
448:                        // are implemented
449:                        // Set restrictions = Restrictions.createLength(name, typeClass,
450:                        // fieldLen);
451:                    }
452:                    attributeType = AttributeTypeFactory.newAttributeType(
453:                            attName, typeClass, isNilable, fieldLen, defValue,
454:                            metadata);
455:                    attDescriptors.add(attributeType);
456:                }
457:
458:                return attDescriptors;
459:            }
460:
461:            private static FeatureType createSchema(String typeName,
462:                    String namespace, List properties) {
463:                // TODO: use factory lookup mechanism once its in place
464:                FeatureTypeBuilder builder = new DefaultFeatureTypeFactory();
465:
466:                builder.setName(typeName);
467:                try {
468:                    builder.setNamespace(new URI(namespace));
469:                } catch (URISyntaxException e) {
470:                    LOGGER.warning("Illegal namespace uri: " + namespace);
471:                }
472:
473:                for (Iterator it = properties.iterator(); it.hasNext();) {
474:                    AttributeType attType = (AttributeType) it.next();
475:                    builder.addType(attType);
476:                }
477:
478:                FeatureType type;
479:                try {
480:                    type = builder.getFeatureType();
481:                } catch (SchemaException e) {
482:                    throw new RuntimeException(e);
483:                }
484:
485:                return type;
486:            }
487:
488:            /**
489:             * Obtains the <code>SeCoordinateReference</code> of the given
490:             * <code>SeLayer</code> and tries to create a
491:             * <code>org.opengis.referencing.crs.CoordinateReferenceSystem</code> from
492:             * its WKT.
493:             * 
494:             * @param sdeLayer
495:             *            the SeLayer from which to query the CRS in ArcSDE form.
496:             * 
497:             * @return the actual CRS or null if <code>sdeLayer</code> does not
498:             *         defines its coordinate system.
499:             * 
500:             * @throws DataSourceException
501:             *             if the WKT can't be parsed to an opengis CRS using the
502:             *             CRSFactory
503:             */
504:            private static CoordinateReferenceSystem parseCRS(SeLayer sdeLayer)
505:                    throws DataSourceException {
506:                CoordinateReferenceSystem crs = null;
507:                SeCoordinateReference seCRS = sdeLayer.getCoordRef();
508:                String WKT = seCRS.getProjectionDescription();
509:                LOGGER.finer("About to parse CRS for layer "
510:                        + sdeLayer.getName() + ": " + WKT);
511:
512:                try {
513:                    LOGGER.fine(sdeLayer.getName() + " has CRS envelope: "
514:                            + seCRS.getXYEnvelope());
515:                } catch (SeException e1) {
516:                    // intentionally blank
517:                }
518:
519:                if ("UNKNOWN".equalsIgnoreCase(WKT)) {
520:                    LOGGER
521:                            .fine("ArcSDE layer "
522:                                    + sdeLayer.getName()
523:                                    + " does not provides a Coordinate Reference System");
524:                } else {
525:                    try {
526:                        CRSFactory crsFactory = ReferencingFactoryFinder
527:                                .getCRSFactory(null);
528:                        crs = crsFactory.createFromWKT(WKT);
529:                        LOGGER.fine("ArcSDE CRS correctly parsed from layer "
530:                                + sdeLayer.getName());
531:                    } catch (FactoryException e) {
532:                        String msg = "CRS factory does not knows how to parse the "
533:                                + "CRS for layer "
534:                                + sdeLayer.getName()
535:                                + ": "
536:                                + WKT;
537:                        LOGGER.log(Level.CONFIG, msg, e);
538:                        // throw new DataSourceException(msg, e);
539:                    }
540:
541:                }
542:
543:                return crs;
544:            }
545:
546:            /**
547:             * Returns the mapping JTS geometry type for the ArcSDE Shape type given by
548:             * the bitmask <code>seShapeType</code>
549:             * 
550:             * <p>
551:             * This bitmask is composed of a combination of the following shape types,
552:             * as defined in the ArcSDE Java API:
553:             * 
554:             * <pre>
555:             * SE_NIL_TYPE_MASK = 1;
556:             * SE_POINT_TYPE_MASK = 2;
557:             * SE_LINE_TYPE_MASK = 4;
558:             * SE_AREA_TYPE_MASK = 16;
559:             * SE_MULTIPART_TYPE_MASK = 262144;
560:             * </pre>
561:             * 
562:             * (Note that the type SE_SIMPLE_LINE_TYPE_MASK is not used)
563:             * </p>
564:             * 
565:             * @param seShapeType
566:             *            DOCUMENT ME!
567:             * 
568:             * @return DOCUMENT ME!
569:             * 
570:             * @throws IllegalArgumentException
571:             *             DOCUMENT ME!
572:             */
573:            public static Class getGeometryTypeFromLayerMask(int seShapeType) {
574:                Class clazz = com.vividsolutions.jts.geom.Geometry.class;
575:                final int MULTIPART_MASK = SeLayer.SE_MULTIPART_TYPE_MASK;
576:                final int POINT_MASK = SeLayer.SE_POINT_TYPE_MASK;
577:                final int SIMPLE_LINE_MASK = SeLayer.SE_SIMPLE_LINE_TYPE_MASK;
578:                final int LINESTRING_MASK = SeLayer.SE_LINE_TYPE_MASK;
579:                final int AREA_MASK = SeLayer.SE_AREA_TYPE_MASK;
580:
581:                // if (seShapeType == SeLayer.TYPE_NIL) {
582:                // // do nothing
583:                // } else if (seShapeType == SeLayer.TYPE_MULTI_MASK) {
584:                // clazz = GeometryCollection.class;
585:                // } else if (seShapeType == SeLayer.TYPE_LINE || seShapeType ==
586:                // SeLayer.TYPE_SIMPLE_LINE) {
587:                // clazz = LineString.class;
588:                // } else if (seShapeType == SeLayer.TYPE_MULTI_LINE
589:                // || seShapeType == SeLayer.TYPE_MULTI_SIMPLE_LINE) {
590:                // clazz = MultiLineString.class;
591:                // } else if (seShapeType == SeLayer.TYPE_MULTI_POINT) {
592:                // clazz = MultiPoint.class;
593:                // } else if (seShapeType == SeLayer.TYPE_MULTI_POLYGON) {
594:                // clazz = MultiPolygon.class;
595:                // } else if (seShapeType == SeLayer.TYPE_POINT) {
596:                // clazz = Point.class;
597:                // } else if (seShapeType == SeLayer.TYPE_POLYGON) {
598:                // clazz = Polygon.class;
599:                // } else {
600:                // in all this assignments, 1 means true and 0 false
601:                final int isCollection = ((seShapeType & MULTIPART_MASK) == MULTIPART_MASK) ? 1
602:                        : 0;
603:
604:                final int isPoint = ((seShapeType & POINT_MASK) == POINT_MASK) ? 1
605:                        : 0;
606:
607:                final int isLineString = (((seShapeType & SIMPLE_LINE_MASK) == SIMPLE_LINE_MASK) || ((seShapeType & LINESTRING_MASK) == LINESTRING_MASK)) ? 1
608:                        : 0;
609:
610:                final int isPolygon = ((seShapeType & AREA_MASK) == AREA_MASK) ? 1
611:                        : 0;
612:
613:                boolean isError = false;
614:
615:                // first check if the shape type supports more than one geometry
616:                // type.
617:                // In that case, it is *highly* recomended that it support all the
618:                // geometry types, so we can safely return Geometry.class. If this
619:                // is
620:                // not
621:                // the case and the shape type supports just a few geometry types,
622:                // then
623:                // we give it a chance and return Geometry.class anyway, but be
624:                // aware
625:                // that transactions over that layer could fail if a Geometry that
626:                // is
627:                // not supported is tried for insertion.
628:                if ((isPoint + isLineString + isPolygon) > 1) {
629:                    clazz = Geometry.class;
630:
631:                    if (4 < (isCollection + isPoint + isLineString + isPolygon)) {
632:                        LOGGER
633:                                .warning("Be careful!! we're mapping an ArcSDE Shape type "
634:                                        + "to the generic Geometry class, but the shape type "
635:                                        + "does not really allows all geometry types!: "
636:                                        + "isCollection="
637:                                        + isCollection
638:                                        + ", isPoint="
639:                                        + isPoint
640:                                        + ", isLineString="
641:                                        + isLineString
642:                                        + ", isPolygon=" + isPolygon);
643:                    } else {
644:                        LOGGER
645:                                .fine("safely mapping SeShapeType to abstract Geometry");
646:                    }
647:                } else if (isCollection == 1) {
648:                    if (isPoint == 1) {
649:                        clazz = MultiPoint.class;
650:                    } else if (isLineString == 1) {
651:                        clazz = MultiLineString.class;
652:                    } else if (isPolygon == 1) {
653:                        clazz = MultiPolygon.class;
654:                    } else {
655:                        isError = true;
656:                    }
657:                } else {
658:                    if (isPoint == 1) {
659:                        clazz = Point.class;
660:                    } else if (isLineString == 1) {
661:                        clazz = LineString.class;
662:                    } else if (isPolygon == 1) {
663:                        clazz = Polygon.class;
664:                    } else {
665:                        isError = true;
666:                    }
667:                }
668:
669:                // }
670:                return clazz;
671:            }
672:
673:            /**
674:             * Returns the most appropriate {@link Geometry} class that matches the
675:             * shape's type.
676:             * 
677:             * @param shape
678:             *            non <code>null</code> SeShape instance for which to infer
679:             *            the matching geometry class
680:             * @return the Geometry subclass corresponding to the shape type
681:             * @throws SeException
682:             *             propagated if thrown by {@link SeShape#getType()}
683:             * @throws IllegalArgumentException
684:             *             if none of the JTS geometry classes can be matched to the
685:             *             shape type (shouldnt happen as for the
686:             *             {@link SeShape#getType() types} defined in the esri arcsde
687:             *             java api 9.0)
688:             */
689:            public static Class getGeometryTypeFromSeShape(SeShape shape)
690:                    throws SeException {
691:                Class clazz = com.vividsolutions.jts.geom.Geometry.class;
692:
693:                int seShapeType = shape.getType();
694:
695:                if (seShapeType == SeShape.TYPE_NIL) {
696:                    // do nothing
697:                } else if (seShapeType == SeShape.TYPE_LINE
698:                        || seShapeType == SeShape.TYPE_SIMPLE_LINE) {
699:                    clazz = LineString.class;
700:                } else if (seShapeType == SeShape.TYPE_MULTI_LINE
701:                        || seShapeType == SeShape.TYPE_MULTI_SIMPLE_LINE) {
702:                    clazz = MultiLineString.class;
703:                } else if (seShapeType == SeShape.TYPE_MULTI_POINT) {
704:                    clazz = MultiPoint.class;
705:                } else if (seShapeType == SeShape.TYPE_MULTI_POLYGON) {
706:                    clazz = MultiPolygon.class;
707:                } else if (seShapeType == SeShape.TYPE_POINT) {
708:                    clazz = Point.class;
709:                } else if (seShapeType == SeShape.TYPE_POLYGON) {
710:                    clazz = Polygon.class;
711:                } else {
712:                    throw new IllegalArgumentException(
713:                            "Cannot map the shape type '" + seShapeType
714:                                    + "' to any known SeShape.TYPE_*");
715:                }
716:                return clazz;
717:            }
718:
719:            /**
720:             * Returns the numeric identifier of a FeatureId, given by the full
721:             * qualified name of the featureclass prepended to the ArcSDE feature id.
722:             * ej: SDE.SDE.SOME_LAYER.1
723:             * 
724:             * @param fid
725:             *            a geotools FeatureID
726:             * 
727:             * @return an ArcSDE feature ID
728:             * 
729:             * @throws IllegalArgumentException
730:             *             If the given string is not properly formatted
731:             *             [anystring].[long value]
732:             */
733:            public static long getNumericFid(Identifier id)
734:                    throws IllegalArgumentException {
735:                if (!(id instanceof  FeatureId))
736:                    throw new IllegalArgumentException(
737:                            "Only FeatureIds are supported when encoding id filters to SDE.  Not "
738:                                    + id.getClass());
739:
740:                String fid = ((FeatureId) id).getID();
741:                int dotIndex = fid.lastIndexOf('.');
742:                try {
743:                    return Long.decode(fid.substring(++dotIndex)).longValue();
744:                } catch (Exception ex) {
745:                    throw new IllegalArgumentException("FeatureID " + fid
746:                            + " does not seems as a valid ArcSDE FID");
747:                }
748:            }
749:
750:            /**
751:             * DOCUMENT ME!
752:             * 
753:             * @param stringFids
754:             *            DOCUMENT ME!
755:             * 
756:             * @return DOCUMENT ME!
757:             * 
758:             * @throws IllegalArgumentException
759:             *             DOCUMENT ME!
760:             */
761:            public static long[] getNumericFids(Set identifiers)
762:                    throws IllegalArgumentException {
763:                int nfids = identifiers.size();
764:                long[] fids = new long[nfids];
765:
766:                Iterator ids = identifiers.iterator();
767:                for (int i = 0; i < nfids; i++) {
768:                    fids[i] = ArcSDEAdapter.getNumericFid((Identifier) ids
769:                            .next());
770:                }
771:
772:                return fids;
773:            }
774:
775:            /**
776:             * Holds default values for the properties (size and scale) of a
777:             * SeColumnDefinition, given by its column type
778:             * (SeColumnDefinition.SE_STRING, etc).
779:             * 
780:             * <p>
781:             * </p>
782:             * 
783:             * @author Gabriel Roldan, Axios Engineering
784:             * @version $Revision: 1.4 $
785:             */
786:            private static class SdeTypeDef {
787:                /** DOCUMENT ME! */
788:                final int colDefType;
789:
790:                /** DOCUMENT ME! */
791:                final int size;
792:
793:                /** DOCUMENT ME! */
794:                final int scale;
795:
796:                /**
797:                 * Creates a new SdeTypeDef object.
798:                 * 
799:                 * @param colDefType
800:                 *            DOCUMENT ME!
801:                 * @param size
802:                 *            DOCUMENT ME!
803:                 * @param scale
804:                 *            DOCUMENT ME!
805:                 */
806:                public SdeTypeDef(int colDefType, int size, int scale) {
807:                    this .colDefType = colDefType;
808:                    this .size = size;
809:                    this .scale = scale;
810:                }
811:
812:                /**
813:                 * DOCUMENT ME!
814:                 * 
815:                 * @return DOCUMENT ME!
816:                 */
817:                public String toString() {
818:                    return "SdeTypeDef[colDefType=" + this .colDefType
819:                            + ", size=" + this .size + ", scale=" + this .scale
820:                            + "]";
821:                }
822:            }
823:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.