Source Code Cross Referenced for EmfAppSchemaReader.java in  » GIS » GeoTools-2.4.1 » org » geotools » data » complex » config » 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.data.complex.config 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *    Geotools2 - OpenSource mapping toolkit
003:         *    http://geotools.org
004:         *    (C) 2005-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.data.complex.config;
018:
019:        import java.io.IOException;
020:        import java.io.InputStream;
021:        import java.net.URL;
022:        import java.util.ArrayList;
023:        import java.util.Arrays;
024:        import java.util.Collection;
025:        import java.util.Collections;
026:        import java.util.HashMap;
027:        import java.util.Iterator;
028:        import java.util.List;
029:        import java.util.Map;
030:        import java.util.NoSuchElementException;
031:        import java.util.Set;
032:        import java.util.Stack;
033:        import java.util.Map.Entry;
034:        import java.util.logging.Level;
035:        import java.util.logging.Logger;
036:
037:        import javax.xml.namespace.QName;
038:
039:        import org.apache.xml.resolver.Catalog;
040:        import org.eclipse.xsd.XSDAttributeDeclaration;
041:        import org.eclipse.xsd.XSDAttributeUse;
042:        import org.eclipse.xsd.XSDAttributeUseCategory;
043:        import org.eclipse.xsd.XSDComplexTypeDefinition;
044:        import org.eclipse.xsd.XSDElementDeclaration;
045:        import org.eclipse.xsd.XSDSchema;
046:        import org.eclipse.xsd.XSDSimpleTypeDefinition;
047:        import org.eclipse.xsd.XSDTypeDefinition;
048:        import org.geotools.data.feature.adapter.ISOAttributeTypeAdapter;
049:        import org.geotools.data.feature.adapter.ISOFeatureTypeAdapter;
050:        import org.geotools.feature.iso.Types;
051:        import org.geotools.feature.iso.simple.SimpleTypeFactoryImpl;
052:        import org.geotools.feature.iso.type.TypeFactoryImpl;
053:        import org.geotools.gml3.ApplicationSchemaConfiguration;
054:        import org.geotools.gml3.GMLConfiguration;
055:        import org.geotools.gml3.GMLSchema;
056:        import org.geotools.gml3.bindings.GML;
057:        import org.geotools.gml3.bindings.smil.SMIL20;
058:        import org.geotools.gml3.bindings.smil.SMIL20LANG;
059:        import org.geotools.gml3.smil.SMIL20LANGSchema;
060:        import org.geotools.gml3.smil.SMIL20Schema;
061:        import org.geotools.xlink.bindings.XLINK;
062:        import org.geotools.xml.Binding;
063:        import org.geotools.xml.Configuration;
064:        import org.geotools.xml.SchemaIndex;
065:        import org.geotools.xml.Schemas;
066:        import org.geotools.xs.XSSchema;
067:        import org.geotools.xs.bindings.XS;
068:        import org.opengis.feature.simple.SimpleTypeFactory;
069:        import org.opengis.feature.type.AttributeDescriptor;
070:        import org.opengis.feature.type.AttributeType;
071:        import org.opengis.feature.type.ComplexType;
072:        import org.opengis.feature.type.FeatureType;
073:        import org.opengis.feature.type.Name;
074:        import org.opengis.feature.type.Schema;
075:        import org.opengis.feature.type.TypeFactory;
076:        import org.opengis.referencing.crs.CoordinateReferenceSystem;
077:        import org.opengis.util.InternationalString;
078:        import org.xmlpull.v1.XmlPullParser;
079:        import org.xmlpull.v1.XmlPullParserException;
080:        import org.xmlpull.v1.XmlPullParserFactory;
081:
082:        /**
083:         * Parses an application schema given by a gtxml {@link Configuration} into a
084:         * set of {@link AttributeType}s and {@link AttributeDescriptor}s.
085:         * <p>
086:         * All the XSD schema locations that comprise the application schema are
087:         * obtained from the main {@link Configuration} and its dependencies.
088:         * </p>
089:         * <p>
090:         * Of particular interest might be the {@link ApplicationSchemaConfiguration}
091:         * object, which allows to provide the location of the root xsd schema for a
092:         * given application schema.
093:         * </p>
094:         * 
095:         * @author Gabriel Roldan
096:         * @version $Id: EmfAppSchemaReader.java 28577 2008-01-03 15:44:29Z groldan $
097:         * @source $URL:
098:         *         http://svn.geotools.org/geotools/branches/2.4.x/modules/unsupported/community-schemas/community-schema-ds/src/main/java/org/geotools/data/complex/config/EmfAppSchemaReader.java $
099:         * @since 2.4
100:         */
101:        public class EmfAppSchemaReader {
102:            private static final Logger LOGGER = org.geotools.util.logging.Logging
103:                    .getLogger(EmfAppSchemaReader.class.getPackage().getName());
104:
105:            /**
106:             * Caches the GML 3.1.1 types and its dependencies
107:             */
108:            private static Map FOUNDATION_TYPES = new HashMap();
109:
110:            /**
111:             * Caches the GML 3.1.1 top level descriptors and its dependencies
112:             */
113:            private static Map FOUNDATION_DESCRIPTORS = new HashMap();
114:
115:            /**
116:             * Contains all the AttributeTypes defined in the application schema and its
117:             * imports
118:             */
119:            private Map/* <Name, AttributeType> */typeRegistry;
120:
121:            /**
122:             * Contains all the AttributeDescriptors defined in the application schema
123:             * and its imports
124:             */
125:            private Map/* <Name, AttributeDescriptor> */descriptorRegistry;
126:
127:            /**
128:             * stack of currently being built type names, used by
129:             * {@link #createType(Name, XSDTypeDefinition)} to prevent recursive type
130:             * definitions by proxy'ing a type that appears to be already being
131:             * constructed and thus still not in the type registry.
132:             */
133:            private Stack processingTypes;
134:
135:            private TypeFactory typeFactory;
136:
137:            private Catalog oasisCatalog;
138:
139:            private EmfAppSchemaReader() {
140:                typeFactory = new TypeFactoryImpl();
141:            }
142:
143:            public TypeFactory getTypeFactory() {
144:                return typeFactory;
145:            }
146:
147:            public Map getTypeRegistry() {
148:                return new HashMap(this .typeRegistry);
149:            }
150:
151:            public Map getDescriptorRegistry() {
152:                return new HashMap(this .descriptorRegistry);
153:            }
154:
155:            public Catalog getCatalog() {
156:                return oasisCatalog;
157:            }
158:
159:            public void setCatalog(final Catalog oasisCatalog) {
160:                this .oasisCatalog = oasisCatalog;
161:            }
162:
163:            /**
164:             * Parses the GML schema represented by the <code>configuration</code>'s
165:             * {@link Configuration#getSchemaFileURL() schema location} into a set of
166:             * {@link AttributeDescriptor} and {@link AttributeType} objects.
167:             * <p>
168:             * Upon return of this method, its guaranteed that all the globally defined
169:             * xml elements in the application schema and its dependencies are available
170:             * through {@link #getDescriptorRegistry()}, and all the globally defined
171:             * xml types through {@link #getTypeRegistry()}.
172:             * </p>
173:             * 
174:             * @param configuration
175:             *            configuration object used to access the XSDSchema to parse.
176:             *            This configuration object might contain {@link Binding}s
177:             * @throws IOException
178:             */
179:            public void parse(Configuration configuration) throws IOException {
180:                //if there's an Oasis catalog set, use it to resolve schema locations
181:                final Catalog catalog = getCatalog();
182:                if (catalog != null) {
183:                    configuration = new OasisCatalogConfigurationWrapper(
184:                            catalog, configuration);
185:                }
186:                // find out the schemas involved in the app schema configuration
187:                final SchemaIndex appSchemaIndex = Schemas
188:                        .findSchemas(configuration);
189:
190:                // set up the type registry
191:                typeRegistry = new HashMap();
192:                descriptorRegistry = new HashMap();
193:                processingTypes = new Stack();
194:
195:                // register the "fundation" gml types already bound to geotools
196:                // AttributeTypes
197:                if (EmfAppSchemaReader.FOUNDATION_TYPES.isEmpty()) {
198:                    createFoundationTypes();
199:                }
200:                typeRegistry.putAll(EmfAppSchemaReader.FOUNDATION_TYPES);
201:                descriptorRegistry
202:                        .putAll(EmfAppSchemaReader.FOUNDATION_DESCRIPTORS);
203:
204:                // with the application schemas...
205:                XSDSchema[] appSchemas = appSchemaIndex.getSchemas();
206:                Map schemas = new HashMap();
207:                for (Iterator it = Arrays.asList(appSchemas).iterator(); it
208:                        .hasNext();) {
209:                    XSDSchema schema = (XSDSchema) it.next();
210:                    schemas.put(schema.getTargetNamespace(), schema);
211:                }
212:
213:                // establish a preferred parsing order so there are the less proxies
214:                // possible
215:                String[] preferredOrder = { XS.NAMESPACE, XLINK.NAMESPACE,
216:                        SMIL20.NAMESPACE, SMIL20LANG.NAMESPACE, GML.NAMESPACE };
217:                List schemaList = new ArrayList(appSchemas.length);
218:                for (int i = 0; i < preferredOrder.length; i++) {
219:                    String targetNamespace = preferredOrder[i];
220:                    XSDSchema schema = (XSDSchema) schemas.get(targetNamespace);
221:                    if (schema != null) {
222:                        schemaList.add(schema);
223:                        schemas.remove(targetNamespace);
224:                    }
225:                }
226:                schemaList.addAll(schemas.values());
227:
228:                // and import them all
229:                for (Iterator it = schemaList.iterator(); it.hasNext();) {
230:                    XSDSchema schema = (XSDSchema) it.next();
231:                    importSchema(schema);
232:                }
233:            }
234:
235:            /**
236:             * Parses the gml schema referenced by <code>location</code> into a set of
237:             * {@link AttributeDescriptor} and {@link AttributeType} objects.
238:             * <p>
239:             * Upon return of this method, its guaranteed that all the globally defined
240:             * xml elements in the application schema and its dependencies are available
241:             * through {@link #getDescriptorRegistry()}, and all the globally defined
242:             * xml types through {@link #getTypeRegistry()}.
243:             * </p>
244:             * 
245:             * @param location
246:             *            the phisical location of the root xsd schema that comprises
247:             *            the application schema to parse.
248:             * @throws IOException
249:             *             if any non recoverable problem occurs while parsing the
250:             *             application schema pointed out by <code>location</code> or
251:             *             one of its dependencies.
252:             */
253:            public void parse(final URL location) throws IOException {
254:
255:                final String nameSpace = findSchemaNamespace(location);
256:
257:                final String schemaLocation = location.toExternalForm();
258:
259:                final Configuration configuration = new ApplicationSchemaConfiguration(
260:                        nameSpace, schemaLocation);
261:
262:                parse(configuration);
263:            }
264:
265:            /**
266:             * Finds out the targetNamespace of the xsd schema referenced by
267:             * <code>location</code>
268:             * 
269:             * @param location
270:             * @return
271:             * @throws IOException
272:             */
273:            private String findSchemaNamespace(URL location) throws IOException {
274:                String targetNamespace = null;
275:                // parse some of the instance document to find out the
276:                // schema location
277:                if (getCatalog() != null) {
278:                    String resolvedLocation = getCatalog().resolveSystem(
279:                            location.toExternalForm());
280:                    if (resolvedLocation != null) {
281:                        location = new URL(resolvedLocation);
282:                    }
283:                }
284:                InputStream input = location.openStream();
285:
286:                // create stream parser
287:                XmlPullParser parser = null;
288:
289:                try {
290:                    XmlPullParserFactory factory = XmlPullParserFactory
291:                            .newInstance();
292:                    factory.setNamespaceAware(true);
293:                    factory.setValidating(false);
294:
295:                    // parse root element
296:                    parser = factory.newPullParser();
297:                    parser.setInput(input, "UTF-8");
298:                    parser.nextTag();
299:
300:                    // look for schema location
301:                    for (int i = 0; i < parser.getAttributeCount(); i++) {
302:                        if ("targetNamespace"
303:                                .equals(parser.getAttributeName(i))) {
304:                            targetNamespace = parser.getAttributeValue(i);
305:                            break;
306:                        }
307:                    }
308:                    // reset input stream
309:                    parser.setInput(null);
310:                } catch (XmlPullParserException e) {
311:                    String msg = "Cannot find target namespace for schema document "
312:                            + location;
313:                    throw (RuntimeException) new RuntimeException(msg)
314:                            .initCause(e);
315:                } finally {
316:                    input.close();
317:                }
318:                if (targetNamespace == null) {
319:                    throw new IllegalArgumentException(
320:                            "Input document does not specifies a targetNamespace");
321:                }
322:                return targetNamespace;
323:            }
324:
325:            private void createFoundationTypes() {
326:                synchronized (EmfAppSchemaReader.FOUNDATION_TYPES) {
327:                    if (!EmfAppSchemaReader.FOUNDATION_TYPES.isEmpty()) {
328:                        return;
329:                    }
330:                    Schema schema;
331:                    schema = new XSSchema();
332:                    importSchema(schema);
333:
334:                    schema = new SMIL20Schema();
335:                    importSchema(schema);
336:
337:                    schema = new SMIL20LANGSchema();
338:                    importSchema(schema);
339:
340:                    schema = new GMLSchema();
341:                    importSchema(schema);
342:
343:                    LOGGER
344:                            .info("Creating GMLConfiguration to get the prebuilt gml schemas from");
345:                    GMLConfiguration configuration = new GMLConfiguration();
346:                    LOGGER
347:                            .info("Aquiring prebuilt gml schema and its dependencies");
348:                    SchemaIndex index = Schemas.findSchemas(configuration);
349:                    XSDSchema[] schemas = index.getSchemas();
350:
351:                    LOGGER.info("Importing GML schema and dependencies");
352:                    for (int i = 0; i < schemas.length; i++) {
353:                        XSDSchema xsdSchema = schemas[i];
354:                        String targetNamespace = xsdSchema.getTargetNamespace();
355:                        if (XS.NAMESPACE.equals(targetNamespace)) {
356:                            LOGGER.finest("Ignoring XS schema parsing");
357:                            continue;
358:                        }
359:                        importSchema(xsdSchema);
360:                    }
361:
362:                    EmfAppSchemaReader.FOUNDATION_TYPES.putAll(typeRegistry);
363:                    EmfAppSchemaReader.FOUNDATION_DESCRIPTORS
364:                            .putAll(descriptorRegistry);
365:                    typeRegistry.clear();
366:                    descriptorRegistry.clear();
367:                }
368:            }
369:
370:            /**
371:             * Traverses over the {@link XSDElementDeclaration}s and
372:             * {@link XSDTypeDefinition}s in <code>xsdSchema</code>, parses them to
373:             * the appropriate {@link AttributeDescriptor}s and {@link AttributeType}s,
374:             * and stores the parsed objects into {@link #descriptorRegistry} and
375:             * {@link #typeRegistry}, respectively.
376:             * 
377:             * @param xsdSchema
378:             */
379:            private void importSchema(XSDSchema xsdSchema) {
380:                final String targetNamespace = xsdSchema.getTargetNamespace();
381:                LOGGER.fine("Importing schema " + targetNamespace);
382:
383:                final List xsdTypeDefinitions = xsdSchema.getTypeDefinitions();
384:                LOGGER.finer("Importing " + targetNamespace
385:                        + " type definitions");
386:                importXsdTypeDefinitions(xsdTypeDefinitions);
387:
388:                final List xsdElementDeclarations = xsdSchema
389:                        .getElementDeclarations();
390:                LOGGER.finer("Importing " + targetNamespace
391:                        + " element definitions");
392:                importElementDeclarations(xsdElementDeclarations);
393:            }
394:
395:            private void importElementDeclarations(List elementDeclarations) {
396:                XSDElementDeclaration elemDecl;
397:                for (Iterator it = elementDeclarations.iterator(); it.hasNext();) {
398:                    elemDecl = (XSDElementDeclaration) it.next();
399:                    LOGGER.finest("Creating attribute descriptor for "
400:                            + elemDecl.getQName());
401:                    AttributeDescriptor descriptor;
402:                    try {
403:                        descriptor = createAttributeDescriptor(null, elemDecl);
404:                        LOGGER.finest("Registering attribute descriptor "
405:                                + descriptor.getName());
406:                        register(descriptor);
407:                    } catch (NoSuchElementException e) {
408:                        LOGGER.log(Level.WARNING, e.getMessage());
409:                    }
410:                }
411:            }
412:
413:            private void register(AttributeDescriptor descriptor) {
414:                Name name = descriptor.getName();
415:                descriptorRegistry.put(name, descriptor);
416:            }
417:
418:            private void register(AttributeType type) {
419:                Name name = type.getName();
420:                Object old = typeRegistry.put(name, type);
421:                if (old != null) {
422:                    LOGGER.fine(type.getName() + " replaced by new value.");
423:                }
424:            }
425:
426:            private AttributeDescriptor createAttributeDescriptor(
427:                    final XSDComplexTypeDefinition container,
428:                    final XSDElementDeclaration elemDecl) {
429:                String targetNamespace = elemDecl.getTargetNamespace();
430:                String name = elemDecl.getName();
431:                Name elemName = Types.typeName(targetNamespace, name);
432:
433:                AttributeType type;
434:                try {
435:                    type = getTypeOf(elemDecl);
436:                } catch (NoSuchElementException e) {
437:                    String msg = "Type not found for " + elemName
438:                            + " at type container "
439:                            + container.getTargetNamespace() + "#"
440:                            + container.getName() + " at "
441:                            + container.getSchema().getSchemaLocation();
442:                    NoSuchElementException nse = new NoSuchElementException(msg);
443:                    nse.initCause(e);
444:                    throw nse;
445:                }
446:                int minOccurs = container == null ? 0 : Schemas.getMinOccurs(
447:                        container, elemDecl);
448:                int maxOccurs = container == null ? Integer.MAX_VALUE : Schemas
449:                        .getMaxOccurs(container, elemDecl);
450:                boolean nillable = elemDecl.isNillable();
451:
452:                if (maxOccurs == -1) {
453:                    // this happens when maxOccurs is set to "unbounded"
454:                    maxOccurs = Integer.MAX_VALUE;
455:                }
456:                Object defaultValue = null;
457:                AttributeDescriptor descriptor = typeFactory
458:                        .createAttributeDescriptor(type, elemName, minOccurs,
459:                                maxOccurs, nillable, defaultValue);
460:
461:                descriptor.putUserData(XSDElementDeclaration.class, elemDecl);
462:
463:                return descriptor;
464:            }
465:
466:            /**
467:             * If the type of elemDecl is annonymous creates a new type with the same
468:             * name than the atrribute and returns it. If it is not anonymous, looks it
469:             * up on the registry and in case the type does not exists in the registry
470:             * uses a proxy.
471:             * 
472:             * @param elemDecl
473:             * @return
474:             */
475:            private AttributeType getTypeOf(XSDElementDeclaration elemDecl) {
476:                boolean hasToBeRegistered = false;
477:                XSDTypeDefinition typeDefinition;
478:
479:                // TODO REVISIT, I'm not sure this is the way to find out if the
480:                // element's type is defined in line (an thus no need to register it
481:                // as a global type)
482:                if (elemDecl.isElementDeclarationReference()) {
483:                    elemDecl = elemDecl.getResolvedElementDeclaration();
484:                }
485:                typeDefinition = elemDecl.getAnonymousTypeDefinition();
486:                if (typeDefinition == null) {
487:                    hasToBeRegistered = true;
488:                    typeDefinition = elemDecl.getTypeDefinition();
489:                }
490:
491:                if (typeDefinition == null) {
492:                    throw new NoSuchElementException(
493:                            "The element declaration "
494:                                    + elemDecl.getTargetNamespace()
495:                                    + "#"
496:                                    + elemDecl.getName()
497:                                    + " has a null type definition, can't continue, fix it on the schema");
498:                }
499:                AttributeType type;
500:                if (hasToBeRegistered) {
501:                    String targetNamespace = typeDefinition
502:                            .getTargetNamespace();
503:                    String name = typeDefinition.getName();
504:                    Name typeName = Types.typeName(targetNamespace, name);
505:                    type = getType(typeName);
506:                    if (type == null) {
507:                        type = createType(typeName, typeDefinition);
508:                        register(type);// //////////
509:                    }
510:                } else {
511:                    String name = elemDecl.getName();
512:                    String targetNamespace = elemDecl.getTargetNamespace();
513:                    Name overrideName = Types.typeName(targetNamespace, name);
514:                    type = createType(overrideName, typeDefinition);
515:                }
516:                return type;
517:            }
518:
519:            private AttributeType createProxiedType(final Name assignedName,
520:                    final XSDTypeDefinition typeDefinition) {
521:                AttributeType type;
522:                if (null == typeDefinition.getSimpleType()
523:                        && typeDefinition instanceof  XSDComplexTypeDefinition) {
524:                    boolean isFeatureType = isDerivedFrom(typeDefinition,
525:                            GML.AbstractFeatureType);
526:                    if (isFeatureType) {
527:                        type = new FeatureTypeProxy(assignedName,
528:                                this .typeRegistry);
529:                    } else {
530:                        type = new ComplexTypeProxy(assignedName,
531:                                this .typeRegistry);
532:                    }
533:                } else {
534:                    boolean isGeometryType = isDerivedFrom(typeDefinition,
535:                            GML.AbstractGeometryType);
536:                    if (isGeometryType) {
537:                        type = new GeometryTypeProxy(assignedName,
538:                                this .typeRegistry);
539:                    } else {
540:                        type = new AttributeTypeProxy(assignedName,
541:                                this .typeRegistry);
542:                    }
543:                }
544:                return type;
545:            }
546:
547:            /**
548:             * Returns whether <code>typeDefinition</code> has an ancestor named
549:             * <code>baseTypeName</code>.
550:             * 
551:             * @param typeDefinition
552:             * @param baseTypeName
553:             * @return
554:             */
555:            private boolean isDerivedFrom(
556:                    final XSDTypeDefinition typeDefinition,
557:                    final QName baseTypeName) {
558:                Name typeName = Types.toName(baseTypeName);
559:                // XSDTypeDefinition baseTypeDefinition = Schemas.getBaseTypeDefinition(
560:                // typeDefinition, baseTypeName);
561:                // boolean isFeatureType = baseTypeDefinition != null;
562:                // return isFeatureType;
563:                return isDerivedFrom(typeDefinition, typeName);
564:            }
565:
566:            private AttributeType createType(XSDTypeDefinition typeDefinition) {
567:                String targetNamespace = typeDefinition.getTargetNamespace();
568:                String name = typeDefinition.getName();
569:                Name typeName = Types.typeName(targetNamespace, name);
570:                return createType(typeName, typeDefinition);
571:            }
572:
573:            /**
574:             * Creates an {@link AttributeType} that matches the xsd type definition as
575:             * much as possible.
576:             * <p>
577:             * The original type definition given by the {@link XSDTypeDefinition} is
578:             * kept as AttributeType's metadata stored as a "user data" property using
579:             * <code>XSDTypeDefinition.class</code> as key.
580:             * </p>
581:             * <p>
582:             * If it is a complex attribute, it will contain all the properties declared
583:             * in the <code>typeDefinition</code>, as well as all the properties
584:             * declared in its super types.
585:             * </p>
586:             * TODO: handle the case where the extension mechanism is restriction.
587:             * 
588:             * @param assignedName
589:             * @param typeDefinition
590:             * @return
591:             */
592:            private AttributeType createType(final Name assignedName,
593:                    final XSDTypeDefinition typeDefinition) {
594:
595:                AttributeType attType;
596:                // /////////
597:                if (processingTypes.contains(assignedName)) {
598:                    if (LOGGER.isLoggable(Level.FINE)) {
599:                        LOGGER.fine("Recursion found for type " + assignedName
600:                                + ". Proxying it.");
601:                    }
602:                    attType = createProxiedType(assignedName, typeDefinition);
603:                    return attType;
604:                }
605:                processingTypes.push(assignedName);
606:                // //////////
607:
608:                final XSDTypeDefinition baseType = typeDefinition.getBaseType();
609:
610:                AttributeType super Type = null;
611:                if (baseType != null) {
612:                    String targetNamespace = baseType.getTargetNamespace();
613:                    String name = baseType.getName();
614:                    super Type = getType(targetNamespace, name);
615:                    if (super Type == null) {
616:                        super Type = createType(baseType);
617:                        register(super Type);
618:                    }
619:                } else {
620:                    LOGGER.warning(assignedName + " has no super type");
621:                }
622:
623:                // if typeDefinition.getSimpleType() != null it means it is a complex
624:                // xsd type
625:                // with a simple content model, and has some xml attributes declared,
626:                // hence the
627:                // xsd complex type definition, as simple xsd types can't have
628:                // attributes
629:                XSDSimpleTypeDefinition simpleType = typeDefinition
630:                        .getSimpleType();
631:
632:                if (simpleType == null
633:                        && typeDefinition instanceof  XSDComplexTypeDefinition) {
634:                    XSDComplexTypeDefinition complexTypeDef;
635:                    complexTypeDef = (XSDComplexTypeDefinition) typeDefinition;
636:                    boolean includeParents = true;
637:                    List children;
638:                    children = Schemas.getChildElementDeclarations(
639:                            typeDefinition, includeParents);
640:
641:                    final Collection schema = new ArrayList(children.size());
642:
643:                    XSDElementDeclaration childDecl;
644:                    AttributeDescriptor descriptor;
645:                    for (Iterator it = children.iterator(); it.hasNext();) {
646:                        childDecl = (XSDElementDeclaration) it.next();
647:                        try {
648:                            descriptor = createAttributeDescriptor(
649:                                    complexTypeDef, childDecl);
650:                            schema.add(descriptor);
651:                        } catch (NoSuchElementException e) {
652:                            LOGGER.log(Level.WARNING, e.getMessage());
653:                            throw e;
654:                        }
655:                    }
656:
657:                    attType = createComplexAttributeType(assignedName, schema,
658:                            complexTypeDef, super Type);
659:
660:                } else {
661:                    Class binding = String.class;
662:                    boolean isIdentifiable = false;
663:                    boolean isAbstract = false;
664:                    Set restrictions = Collections.EMPTY_SET;
665:                    InternationalString description = null;
666:                    attType = typeFactory.createAttributeType(assignedName,
667:                            binding, isIdentifiable, isAbstract, restrictions,
668:                            super Type, description);
669:                }
670:
671:                attType.putUserData(XSDTypeDefinition.class, typeDefinition);
672:
673:                processingTypes.pop();
674:                return attType;
675:            }
676:
677:            /**
678:             * NOTE: to be called only by {@link #createType(Name, XSDTypeDefinition)}
679:             * 
680:             * @param assignedName
681:             * @param schema
682:             * @param typeDefinition
683:             * @param superType
684:             * @return
685:             */
686:            private AttributeType createComplexAttributeType(
687:                    final Name assignedName, final Collection schema,
688:                    final XSDComplexTypeDefinition typeDefinition,
689:                    final AttributeType super Type) {
690:
691:                AttributeType abstractFType = getType(GML.NAMESPACE,
692:                        GML.AbstractFeatureType.getLocalPart());
693:                assert abstractFType != null;
694:
695:                boolean isFeatureType = isDerivedFrom(typeDefinition,
696:                        abstractFType.getName());
697:                boolean isSimpleContent = isSimpleContent(schema);
698:
699:                boolean isAbstract = false;// TODO
700:                Set restrictions = Collections.EMPTY_SET;
701:                InternationalString description = null; // TODO
702:
703:                AttributeType type;
704:                if (isFeatureType) {
705:                    if (isSimpleContent) {
706:                        SimpleTypeFactory fac = new SimpleTypeFactoryImpl();
707:                        // let the factory decide
708:                        CoordinateReferenceSystem crs = null;
709:                        // let the factory decide
710:                        AttributeDescriptor defaultGeometry = null;
711:                        type = fac.createSimpleFeatureType(assignedName,
712:                                new ArrayList(schema), defaultGeometry, crs,
713:                                restrictions, description);
714:                    } else {
715:                        type = typeFactory.createFeatureType(assignedName,
716:                                schema, null, null, isAbstract, restrictions,
717:                                super Type, description);
718:
719:                    }
720:                } else {
721:                    boolean isIdentifiable = isIdentifiable((XSDComplexTypeDefinition) typeDefinition);
722:                    type = typeFactory.createComplexType(assignedName, schema,
723:                            isIdentifiable, isAbstract, restrictions,
724:                            super Type, description);
725:                }
726:                return type;
727:            }
728:
729:            /**
730:             * Determines if elements of the given complex type definition are required
731:             * to have an identifier by looking for a child element of
732:             * <code>typeDefinition</code> of the form
733:             * <code>&lt;xs:attribute ref=&quot;gml:id&quot; use=&quot;required&quot; /&gt;</code>
734:             * 
735:             * @param typeDefinition
736:             * @return
737:             */
738:            private boolean isIdentifiable(
739:                    XSDComplexTypeDefinition typeDefinition) {
740:                List attributeUses = typeDefinition.getAttributeUses();
741:
742:                final String idAttName = GML.id.getLocalPart();
743:
744:                for (Iterator it = attributeUses.iterator(); it.hasNext();) {
745:                    XSDAttributeUse use = (XSDAttributeUse) it.next();
746:                    XSDAttributeUseCategory useCategory = use.getUse();
747:
748:                    XSDAttributeDeclaration idAtt = use
749:                            .getAttributeDeclaration();
750:
751:                    String targetNamespace = idAtt.getTargetNamespace();
752:                    String name = idAtt.getName();
753:                    if (GML.NAMESPACE.equals(targetNamespace)
754:                            && idAttName.equals(name)) {
755:                        if (XSDAttributeUseCategory.REQUIRED_LITERAL
756:                                .equals(useCategory)) {
757:                            return true;
758:                        }
759:                    }
760:                }
761:                return false;
762:            }
763:
764:            /**
765:             * Returns true if all the AttributeDescriptors contained in
766:             * <code>schema</code> are of a simple type and no one has maxOccurs > 1.
767:             * <p>
768:             * Note this method ignores the attributes from the GML namespace
769:             * </p>
770:             * 
771:             * @param schema
772:             * @return
773:             */
774:            private boolean isSimpleContent(Collection schema) {
775:                AttributeDescriptor descriptor;
776:                for (Iterator it = schema.iterator(); it.hasNext();) {
777:                    descriptor = (AttributeDescriptor) it.next();
778:                    if (GML.NAMESPACE.equals(descriptor.getName()
779:                            .getNamespaceURI())) {
780:                        continue;
781:                    }
782:                    if (descriptor.getMaxOccurs() > 1) {
783:                        return false;
784:                    }
785:                    if (descriptor.type() instanceof  ComplexType) {
786:                        return false;
787:                    }
788:                }
789:                return true;
790:            }
791:
792:            /**
793:             * Returns <code>true</code> if <code>typeDefinition</code> is derived
794:             * from a type named <code>superTypeName</code>
795:             * 
796:             * @param typeDefinition
797:             * @param superTypeName
798:             * @return
799:             */
800:            private boolean isDerivedFrom(XSDTypeDefinition typeDefinition,
801:                    final Name super TypeName) {
802:
803:                XSDTypeDefinition baseType;
804:                final String super NS = super TypeName.getNamespaceURI();
805:                final String super Name = super TypeName.getLocalPart();
806:
807:                String targetNamespace;
808:                String name;
809:                while ((baseType = typeDefinition.getBaseType()) != null) {
810:                    targetNamespace = baseType.getTargetNamespace();
811:                    name = baseType.getName();
812:                    if (XS.NAMESPACE.equals(targetNamespace)
813:                            && XS.ANYTYPE.getLocalPart().equals(name)) {
814:                        return false;
815:                    }
816:                    if (super NS.equals(targetNamespace)
817:                            && super Name.equals(name)) {
818:                        return true;
819:                    }
820:                    typeDefinition = baseType;
821:                }
822:                return false;
823:            }
824:
825:            private AttributeType getType(String namespace, String name) {
826:                Name typeName = Types.typeName(namespace, name);
827:                return getType(typeName);
828:            }
829:
830:            private AttributeType getType(Name typeName) {
831:                AttributeType type = (AttributeType) typeRegistry.get(typeName);
832:                return type;
833:            }
834:
835:            private void importXsdTypeDefinitions(List typeDefinitions) {
836:                XSDTypeDefinition typeDef;
837:                AttributeType attType;
838:                for (Iterator it = typeDefinitions.iterator(); it.hasNext();) {
839:                    typeDef = (XSDTypeDefinition) it.next();
840:                    String targetNamespace = typeDef.getTargetNamespace();
841:                    String name = typeDef.getName();
842:
843:                    attType = getType(targetNamespace, name);
844:                    if (attType == null) {
845:                        LOGGER.finest("Creating attribute type "
846:                                + typeDef.getQName());
847:                        attType = createType(typeDef);
848:                        LOGGER.finest("Registering attribute type "
849:                                + attType.getName());
850:                        register(attType);
851:                    } else {
852:                        // LOGGER.finer("Ignoring type " +
853:                        // typeDef.getQName()
854:                        // + " as it already exists in the registry");
855:                    }
856:                }
857:                LOGGER.finer("--- type definitions imported successfully ---");
858:            }
859:
860:            private void importSchema(Schema schema) {
861:                for (Iterator it = schema.entrySet().iterator(); it.hasNext();) {
862:                    Map.Entry entry = (Entry) it.next();
863:                    Name key = (Name) entry.getKey();
864:                    Object value = entry.getValue();
865:                    if (typeRegistry.containsKey(key)) {
866:                        LOGGER.finer("Ignoring " + key
867:                                + " as it already exists. type "
868:                                + value.getClass().getName());
869:                    } else {
870:                        LOGGER.finer("Importing " + key + " of type "
871:                                + value.getClass().getName());
872:                        if (value instanceof  AttributeType) {
873:                            AttributeType type = (AttributeType) value;
874:                            register(type);
875:                        } else if (value instanceof  AttributeDescriptor) {
876:                            AttributeDescriptor descriptor = (AttributeDescriptor) value;
877:                            register(descriptor);
878:                        } else if (value instanceof  org.geotools.feature.AttributeType) {
879:                            org.geotools.feature.AttributeType gtType;
880:                            gtType = (org.geotools.feature.AttributeType) value;
881:                            String nsUri = schema.namespace().getURI();
882:                            AttributeType isoType = ISOAttributeTypeAdapter
883:                                    .adapter(nsUri, gtType);
884:                            register(isoType);
885:                        } else if (value instanceof  org.geotools.feature.FeatureType) {
886:                            org.geotools.feature.FeatureType gtType;
887:                            gtType = (org.geotools.feature.FeatureType) value;
888:                            FeatureType isoType = new ISOFeatureTypeAdapter(
889:                                    gtType);
890:                            register(isoType);
891:                        }
892:                    }
893:                }
894:                LOGGER.fine("Schema " + schema.namespace().getURI()
895:                        + " imported successfully");
896:            }
897:
898:            public static EmfAppSchemaReader newInstance() {
899:                return new EmfAppSchemaReader();
900:            }
901:
902:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.