Source Code Cross Referenced for QueryTableTree.java in  » GIS » deegree » org » deegree » io » datastore » sql » wherebuilder » 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 » deegree » org.deegree.io.datastore.sql.wherebuilder 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/trunk/src/org/deegree/io/datastore/sql/wherebuilder/QueryTableTree.java $
002:        /*----------------    FILE HEADER  ------------------------------------------
003:
004:         This file is part of deegree.
005:         Copyright (C) 2001-2008 by:
006:         EXSE, Department of Geography, University of Bonn
007:         http://www.giub.uni-bonn.de/deegree/
008:         lat/lon GmbH
009:         http://www.lat-lon.de
010:
011:         This library is free software; you can redistribute it and/or
012:         modify it under the terms of the GNU Lesser General Public
013:         License as published by the Free Software Foundation; either
014:         version 2.1 of the License, or (at your option) any later version.
015:
016:         This library is distributed in the hope that it will be useful,
017:         but WITHOUT ANY WARRANTY; without even the implied warranty of
018:         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
019:         Lesser General Public License for more details.
020:
021:         You should have received a copy of the GNU Lesser General Public
022:         License along with this library; if not, write to the Free Software
023:         Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
024:
025:         Contact:
026:
027:         Andreas Poth
028:         lat/lon GmbH
029:         Aennchenstraße 19
030:         53177 Bonn
031:         Germany
032:         E-Mail: poth@lat-lon.de
033:
034:         Prof. Dr. Klaus Greve
035:         Department of Geography
036:         University of Bonn
037:         Meckenheimer Allee 166
038:         53115 Bonn
039:         Germany
040:         E-Mail: greve@giub.uni-bonn.de
041:
042:         ---------------------------------------------------------------------------*/
043:        package org.deegree.io.datastore.sql.wherebuilder;
044:
045:        import java.util.ArrayList;
046:        import java.util.HashMap;
047:        import java.util.List;
048:        import java.util.Map;
049:
050:        import org.deegree.datatypes.QualifiedName;
051:        import org.deegree.datatypes.Types;
052:        import org.deegree.framework.log.ILogger;
053:        import org.deegree.framework.log.LoggerFactory;
054:        import org.deegree.i18n.Messages;
055:        import org.deegree.io.datastore.PropertyPathResolvingException;
056:        import org.deegree.io.datastore.schema.MappedFeaturePropertyType;
057:        import org.deegree.io.datastore.schema.MappedFeatureType;
058:        import org.deegree.io.datastore.schema.MappedGMLId;
059:        import org.deegree.io.datastore.schema.MappedGMLSchema;
060:        import org.deegree.io.datastore.schema.MappedGeometryPropertyType;
061:        import org.deegree.io.datastore.schema.MappedPropertyType;
062:        import org.deegree.io.datastore.schema.MappedSimplePropertyType;
063:        import org.deegree.io.datastore.schema.TableRelation;
064:        import org.deegree.io.datastore.schema.content.ConstantContent;
065:        import org.deegree.io.datastore.schema.content.SimpleContent;
066:        import org.deegree.io.datastore.sql.TableAliasGenerator;
067:        import org.deegree.ogcbase.AttributeStep;
068:        import org.deegree.ogcbase.CommonNamespaces;
069:        import org.deegree.ogcbase.PropertyPath;
070:        import org.deegree.ogcbase.PropertyPathStep;
071:
072:        /**
073:         * Represents selected {@link MappedFeatureType}s and {@link PropertyPath} instances (properties used in an OGC filter
074:         * and as sort criteria) and their mapping to a certain relational schema.
075:         * <p>
076:         * The requested {@link MappedFeatureType}s are the root nodes of the tree. If there is more than root node (feature
077:         * type), the query requests a join between feature types.
078:         * 
079:         * @author <a href="mailto:schneider@lat-lon.de">Markus Schneider </a>
080:         * @author last edited by: $Author: apoth $
081:         * 
082:         * @version $Revision: 9342 $, $Date: 2007-12-27 04:32:57 -0800 (Thu, 27 Dec 2007) $
083:         */
084:        public class QueryTableTree {
085:
086:            private static final ILogger LOG = LoggerFactory
087:                    .getLogger(QueryTableTree.class);
088:
089:            private TableAliasGenerator aliasGenerator;
090:
091:            private FeatureTypeNode[] roots;
092:
093:            // maps the aliases (specified in the query) to the corresponding FeatureTypeNode
094:            private Map<String, FeatureTypeNode> ftAliasToRootFtNode = new HashMap<String, FeatureTypeNode>();
095:
096:            // uses 2 lists instead of Map, because PropertyPath.equals() is overwritten,
097:            // and identity (==) is needed here (different occurences of "equal" PropertyName
098:            // in filter must be treated as different PropertyPaths)
099:            private List<PropertyPath> propertyPaths = new ArrayList<PropertyPath>();
100:
101:            private List<PropertyNode> propertyNodes = new ArrayList<PropertyNode>();
102:
103:            /**
104:             * Creates a new instance of <code>QueryTableTree</code>.
105:             * 
106:             * @param rootFts
107:             *            selected feature types, more than one type means that the types are joined
108:             * @param aliases
109:             *            aliases for the feature types, may be null (must have same length as rootFts otherwise)
110:             * @param aliasGenerator
111:             *            aliasGenerator to be used to generate table aliases, may be null
112:             */
113:            public QueryTableTree(MappedFeatureType[] rootFts,
114:                    String[] aliases, TableAliasGenerator aliasGenerator) {
115:
116:                if (aliasGenerator != null) {
117:                    this .aliasGenerator = aliasGenerator;
118:                } else {
119:                    this .aliasGenerator = new TableAliasGenerator();
120:                }
121:                this .roots = new FeatureTypeNode[rootFts.length];
122:                for (int i = 0; i < rootFts.length; i++) {
123:                    FeatureTypeNode rootFtNode = new FeatureTypeNode(
124:                            rootFts[i], aliases != null ? aliases[i] : null,
125:                            aliasGenerator.generateUniqueAlias());
126:                    this .roots[i] = rootFtNode;
127:                    if (aliases != null) {
128:                        this .ftAliasToRootFtNode.put(aliases[i], rootFtNode);
129:                        LOG.logDebug("Alias '" + aliases[i] + "' maps to '"
130:                                + rootFtNode + "'.");
131:                    }
132:                }
133:            }
134:
135:            /**
136:             * Returns the root feature type nodes of the tree.
137:             * 
138:             * @return the root feature type nodes of the tree, contains at least one entry
139:             */
140:            public FeatureTypeNode[] getRootNodes() {
141:                return this .roots;
142:            }
143:
144:            /**
145:             * Returns the alias for the root table.
146:             * 
147:             * TODO support more than one root node
148:             * 
149:             * @return the alias for the root table
150:             */
151:            public String getRootAlias() {
152:                return this .roots[0].getTableAlias();
153:            }
154:
155:            /**
156:             * Returns the property node for the given property path.
157:             * 
158:             * @param path
159:             *            property to be looked up
160:             * @return the property node for the given property path
161:             */
162:            public PropertyNode getPropertyNode(PropertyPath path) {
163:
164:                PropertyNode node = null;
165:                for (int i = 0; i < this .propertyPaths.size(); i++) {
166:                    if (this .propertyPaths.get(i) == path) {
167:                        node = this .propertyNodes.get(i);
168:                        break;
169:                    }
170:                }
171:                return node;
172:            }
173:
174:            /**
175:             * Tries to insert the given {@link PropertyPath} as a filter criterion into the tree.
176:             * <p>
177:             * The {@link PropertyPath} is validated during insertion.
178:             * 
179:             * @param property
180:             *            property to be inserted, has to have at least one step
181:             * @throws PropertyPathResolvingException
182:             *             if the path violates the feature type's schema
183:             */
184:            public void addFilterProperty(PropertyPath property)
185:                    throws PropertyPathResolvingException {
186:                MappedPropertyType pt = validate(property, false);
187:                if (pt instanceof  MappedSimplePropertyType) {
188:                    SimpleContent content = ((MappedSimplePropertyType) pt)
189:                            .getContent();
190:                    if (content instanceof  ConstantContent) {
191:                        // add SimplePropertyNode to root node (because table path is irrelevant)
192:                        String[] tableAliases = generateTableAliases(pt);
193:                        PropertyNode propertyNode = new SimplePropertyNode(
194:                                (MappedSimplePropertyType) pt, roots[0],
195:                                tableAliases);
196:                        this .propertyPaths.add(property);
197:                        this .propertyNodes.add(propertyNode);
198:                        // root.addPropertyNode( propertyNode );
199:                    } else {
200:                        insertValidatedPath(property);
201:                    }
202:                } else {
203:                    insertValidatedPath(property);
204:                }
205:            }
206:
207:            /**
208:             * Tries to insert the given {@link PropertyPath} as a sort criterion into the tree.
209:             * <p>
210:             * The {@link PropertyPath} is validated during insertion. It is also checked that the path is unique, i.e. every
211:             * property type on the path must have maxOccurs set to 1.
212:             * 
213:             * @param property
214:             *            property to be inserted, has to have at least one step
215:             * @throws PropertyPathResolvingException
216:             *             if the path violates the feature type's schema
217:             */
218:            public void addSortProperty(PropertyPath property)
219:                    throws PropertyPathResolvingException {
220:                MappedPropertyType pt = validate(property, false);
221:                if (pt instanceof  MappedSimplePropertyType) {
222:                    SimpleContent content = ((MappedSimplePropertyType) pt)
223:                            .getContent();
224:                    if (content.isSortable()) {
225:                        insertValidatedPath(property);
226:                    } else {
227:                        String msg = "Skipping property '" + property
228:                                + "' as sort criterion.";
229:                        LOG.logDebug(msg);
230:                        // add SimplePropertyNode to root node (because table path is irrelevant)
231:                        String[] tableAliases = generateTableAliases(pt);
232:                        PropertyNode propertyNode = new SimplePropertyNode(
233:                                (MappedSimplePropertyType) pt, roots[0],
234:                                tableAliases);
235:                        this .propertyPaths.add(property);
236:                        this .propertyNodes.add(propertyNode);
237:                        // root.addPropertyNode( propertyNode );
238:                    }
239:                } else {
240:                    String msg = Messages.getMessage(
241:                            "DATASTORE_PROPERTY_PATH_SORT1", property);
242:                    throw new PropertyPathResolvingException(msg);
243:                }
244:            }
245:
246:            /**
247:             * Validates the (normalized) {@link PropertyPath} against the {@link MappedGMLSchema} and returns the
248:             * {@link MappedPropertyType} that the path refers to.
249:             * 
250:             * @param propertyPath
251:             *            PropertyPath to be validated, has to have at least one step
252:             * @param forceUniquePath
253:             *            if set to true, an exeption is thrown if the path is not unique, i.e. at least one property on the
254:             *            path has maxOccurs set to a value > 1
255:             * @return the property type that the path ends with
256:             * @throws PropertyPathResolvingException
257:             *             if the path violates the feature type's schema
258:             */
259:            private MappedPropertyType validate(PropertyPath propertyPath,
260:                    boolean forceUniquePath)
261:                    throws PropertyPathResolvingException {
262:
263:                MappedPropertyType endingPt = null;
264:                MappedFeatureType currentFt = null;
265:                int firstPropertyPos = 1;
266:
267:                // check if path starts with (valid) alias
268:                QualifiedName firstStep = propertyPath.getStep(0)
269:                        .getPropertyName();
270:                if (firstStep.getLocalName().startsWith("$")) {
271:                    // path starts with alias
272:                    String ftAlias = firstStep.getLocalName().substring(1);
273:                    FeatureTypeNode rootNode = this .ftAliasToRootFtNode
274:                            .get(ftAlias);
275:                    if (rootNode == null) {
276:                        String msg = Messages.getMessage(
277:                                "DATASTORE_PROPERTY_PATH_RESOLVE6",
278:                                propertyPath, firstStep.getLocalName());
279:                        throw new PropertyPathResolvingException(msg);
280:                    }
281:                    currentFt = rootNode.getFeatureType();
282:                } else {
283:                    // path does not start with an alias
284:                    if (this .roots.length > 1) {
285:                        LOG
286:                                .logDebug("Multiple (join) feature type request. First step of '"
287:                                        + propertyPath
288:                                        + "' must be the name (or an alias) of a requested feature type then...");
289:                        QualifiedName ftName = propertyPath.getStep(0)
290:                                .getPropertyName();
291:                        for (FeatureTypeNode rootNode : this .roots) {
292:                            if (rootNode.getFeatureType().getName().equals(
293:                                    ftName)) {
294:                                currentFt = rootNode.getFeatureType();
295:                                break;
296:                            }
297:                        }
298:                        if (currentFt == null) {
299:                            String msg = Messages.getMessage(
300:                                    "DATASTORE_PROPERTY_PATH_RESOLVE5",
301:                                    propertyPath, propertyPath.getStep(0));
302:                            throw new PropertyPathResolvingException(msg);
303:                        }
304:                    } else {
305:                        currentFt = this .roots[0].getFeatureType();
306:                        LOG
307:                                .logDebug("Single feature type request. Trying to validate '"
308:                                        + propertyPath
309:                                        + "' against schema of feature type '"
310:                                        + currentFt.getName() + "'...");
311:
312:                        QualifiedName elementName = propertyPath.getStep(0)
313:                                .getPropertyName();
314:
315:                        // must be the name of the feature type or the name of a property of the feature
316:                        // type
317:                        if (elementName.equals(currentFt.getName())) {
318:                            LOG
319:                                    .logDebug("First step matches the name of the feature type.");
320:                        } else {
321:                            LOG
322:                                    .logDebug("First step does not match the name of the feature type. "
323:                                            + "Must be the name of a property then.");
324:                            firstPropertyPos = 0;
325:                        }
326:                    }
327:                }
328:
329:                for (int step = firstPropertyPos; step < propertyPath
330:                        .getSteps(); step += 2) {
331:                    LOG.logDebug("Looking up property: "
332:                            + propertyPath.getStep(step).getPropertyName());
333:                    endingPt = getPropertyType(currentFt, propertyPath
334:                            .getStep(step));
335:
336:                    if (endingPt == null) {
337:                        String msg = Messages
338:                                .getMessage("DATASTORE_PROPERTY_PATH_RESOLVE4",
339:                                        propertyPath, step, propertyPath
340:                                                .getStep(step), currentFt
341:                                                .getName(), propertyPath
342:                                                .getStep(step));
343:                        throw new PropertyPathResolvingException(msg);
344:                    }
345:
346:                    if (forceUniquePath) {
347:                        if (endingPt.getMaxOccurs() != 1) {
348:                            String msg = Messages.getMessage(
349:                                    "DATASTORE_PROPERTY_PATH_SORT2",
350:                                    propertyPath, step, endingPt.getName());
351:                            throw new PropertyPathResolvingException(msg);
352:                        }
353:                    }
354:
355:                    if (endingPt instanceof  MappedSimplePropertyType) {
356:                        if (step < propertyPath.getSteps() - 1) {
357:                            String msg = Messages.getMessage(
358:                                    "DATASTORE_PROPERTY_PATH_RESOLVE1",
359:                                    propertyPath, step, endingPt.getName(),
360:                                    "simple");
361:                            throw new PropertyPathResolvingException(msg);
362:                        }
363:                    } else if (endingPt instanceof  MappedGeometryPropertyType) {
364:                        if (step < propertyPath.getSteps() - 1) {
365:                            String msg = Messages.getMessage(
366:                                    "DATASTORE_PROPERTY_PATH_RESOLVE1",
367:                                    propertyPath, step, endingPt.getName(),
368:                                    "geometry");
369:                            throw new PropertyPathResolvingException(msg);
370:                        }
371:                    } else if (endingPt instanceof  MappedFeaturePropertyType) {
372:                        if (step == propertyPath.getSteps() - 1) {
373:                            String msg = Messages.getMessage(
374:                                    "DATASTORE_PROPERTY_PATH_RESOLVE2",
375:                                    propertyPath, step, endingPt.getName());
376:                            throw new PropertyPathResolvingException(msg);
377:                        }
378:                        MappedFeaturePropertyType pt = (MappedFeaturePropertyType) endingPt;
379:                        MappedFeatureType[] allowedTypes = pt
380:                                .getFeatureTypeReference().getFeatureType()
381:                                .getConcreteSubstitutions();
382:                        QualifiedName givenTypeName = propertyPath.getStep(
383:                                step + 1).getPropertyName();
384:
385:                        // check if an alias is used
386:                        if (givenTypeName.getLocalName().startsWith("$")) {
387:                            String ftAlias = givenTypeName.getLocalName()
388:                                    .substring(1);
389:                            FeatureTypeNode ftNode = this .ftAliasToRootFtNode
390:                                    .get(ftAlias);
391:                            if (ftNode == null) {
392:                                String msg = Messages.getMessage(
393:                                        "DATASTORE_PROPERTY_PATH_RESOLVE6",
394:                                        propertyPath, step + 1, propertyPath
395:                                                .getStep(step + 1));
396:                                throw new PropertyPathResolvingException(msg);
397:                            }
398:                            givenTypeName = ftNode.getFeatureType().getName();
399:                        }
400:
401:                        MappedFeatureType givenType = null;
402:
403:                        for (int i = 0; i < allowedTypes.length; i++) {
404:                            if (allowedTypes[i].getName().equals(givenTypeName)) {
405:                                givenType = allowedTypes[i];
406:                                break;
407:                            }
408:                        }
409:                        if (givenType == null) {
410:                            StringBuffer validTypeList = new StringBuffer();
411:                            for (int i = 0; i < allowedTypes.length; i++) {
412:                                validTypeList.append('\'');
413:                                validTypeList.append(allowedTypes[i].getName());
414:                                validTypeList.append('\'');
415:                                if (i != allowedTypes.length - 1) {
416:                                    validTypeList.append(", ");
417:                                }
418:                            }
419:                            String msg = Messages.getMessage(
420:                                    "DATASTORE_PROPERTY_PATH_RESOLVE3",
421:                                    propertyPath, step + 1, propertyPath
422:                                            .getStep(step + 1), validTypeList);
423:                            throw new PropertyPathResolvingException(msg
424:                                    .toString());
425:                        }
426:                        currentFt = pt.getFeatureTypeReference()
427:                                .getFeatureType();
428:                    } else {
429:                        assert (false);
430:                    }
431:                }
432:                return endingPt;
433:            }
434:
435:            /**
436:             * Inserts the (already validated!!!) {@link PropertyPath} into the query tree.
437:             * 
438:             * @see #validate(PropertyPath, boolean)
439:             * 
440:             * @param propertyPath
441:             *            validated PropertyPath to be inserted into the tree
442:             */
443:            private void insertValidatedPath(PropertyPath propertyPath) {
444:
445:                LOG.logDebug("Inserting '" + propertyPath
446:                        + "' into the query table tree.");
447:
448:                FeatureTypeNode ftNode = null;
449:                int firstPropertyPos = 1;
450:
451:                // check if path starts with an alias
452:                QualifiedName firstStep = propertyPath.getStep(0)
453:                        .getPropertyName();
454:                if (firstStep.getLocalName().startsWith("$")) {
455:                    String ftAlias = firstStep.getLocalName().substring(1);
456:                    ftNode = this .ftAliasToRootFtNode.get(ftAlias);
457:                } else {
458:                    if (this .roots.length > 1) {
459:                        QualifiedName ftName = propertyPath.getStep(0)
460:                                .getPropertyName();
461:                        for (FeatureTypeNode rootNode : this .roots) {
462:                            if (rootNode.getFeatureType().getName().equals(
463:                                    ftName)) {
464:                                ftNode = rootNode;
465:                                break;
466:                            }
467:                        }
468:                    } else {
469:                        PropertyPathStep step = propertyPath.getStep(0);
470:                        QualifiedName elementName = step.getPropertyName();
471:
472:                        // must be the name of the feature type or the name of a property of the feature type
473:                        if (elementName.equals(this .roots[0].getFeatureType()
474:                                .getName())) {
475:                            LOG
476:                                    .logDebug("First step matches the name of the feature type.");
477:                        } else {
478:                            LOG
479:                                    .logDebug("First step does not match the name of the feature type. "
480:                                            + "Must be the name of a property then.");
481:                            firstPropertyPos = 0;
482:                        }
483:                        ftNode = this .roots[0];
484:                    }
485:                }
486:
487:                PropertyNode propNode = null;
488:                for (int i = firstPropertyPos; i < propertyPath.getSteps(); i += 2) {
489:
490:                    // check for property with step name in the feature type
491:                    MappedFeatureType currentFt = ftNode.getFeatureType();
492:                    MappedPropertyType pt = getPropertyType(currentFt,
493:                            propertyPath.getStep(i));
494:
495:                    // check if feature type node already has such a property node, add it otherwise
496:                    propNode = ftNode.getPropertyNode(pt);
497:                    if (propNode == null
498:                            || propNode.getProperty().getMaxOccurs() != 1) {
499:                        propNode = createPropertyNode(ftNode, pt);
500:                        ftNode.addPropertyNode(propNode);
501:                    }
502:
503:                    if (i + 1 < propertyPath.getSteps()) {
504:                        // more steps? propNode must be a FeaturePropertyNode then
505:                        assert propNode instanceof  FeaturePropertyNode;
506:                        QualifiedName featureStep = propertyPath.getStep(i + 1)
507:                                .getPropertyName();
508:                        ftNode = findOrAddSubFtNode(
509:                                (FeaturePropertyNode) propNode, featureStep);
510:                    }
511:                }
512:
513:                this .propertyPaths.add(propertyPath);
514:                this .propertyNodes.add(propNode);
515:
516:                //        // "equal" path is already registered, map this one to existing instance
517:                //        if ( getPropertyNode( propertyPath ) == null ) {
518:                //            this.propertyPaths.add( propertyPath );
519:                //            this.propertyNodes.add( propNode );
520:                //        }
521:            }
522:
523:            private PropertyNode createPropertyNode(FeatureTypeNode ftNode,
524:                    MappedPropertyType pt) {
525:
526:                PropertyNode propNode = null;
527:                if (pt instanceof  MappedSimplePropertyType) {
528:                    String[] tableAliases = generateTableAliases(pt);
529:                    propNode = new SimplePropertyNode(
530:                            (MappedSimplePropertyType) pt, ftNode, tableAliases);
531:                } else if (pt instanceof  MappedGeometryPropertyType) {
532:                    String[] tableAliases = generateTableAliases(pt);
533:                    propNode = new GeometryPropertyNode(
534:                            (MappedGeometryPropertyType) pt, ftNode,
535:                            tableAliases);
536:                } else if (pt instanceof  MappedFeaturePropertyType) {
537:                    String[] tableAliases = this .aliasGenerator
538:                            .generateUniqueAliases(pt.getTableRelations().length - 1);
539:                    propNode = new FeaturePropertyNode(
540:                            ((MappedFeaturePropertyType) pt), ftNode,
541:                            tableAliases);
542:                } else {
543:                    assert (false);
544:                }
545:                return propNode;
546:            }
547:
548:            /**
549:             * Returns a {@link FeatureTypeNode} that select a child of the given {@link FeaturePropertyNode}.
550:             * <p>
551:             * If the step specifies a feature type alias (instead of the feature type name), the corresponding root feature
552:             * type node is returned.
553:             * 
554:             * @param propNode
555:             * @param featureStep
556:             */
557:            private FeatureTypeNode findOrAddSubFtNode(
558:                    FeaturePropertyNode propNode, QualifiedName featureStep) {
559:
560:                FeatureTypeNode childNode = null;
561:
562:                // check if step specifies an alias -> use corresponding root feature node then
563:                if (featureStep.getLocalName().startsWith("$")) {
564:                    String alias = featureStep.getLocalName().substring(1);
565:                    FeatureTypeNode[] childNodes = propNode
566:                            .getFeatureTypeNodes();
567:                    for (FeatureTypeNode node : childNodes) {
568:                        if (alias.equals(node.getFtAlias())) {
569:                            childNode = node;
570:                            break;
571:                        }
572:                    }
573:                    if (childNode == null) {
574:                        childNode = this .ftAliasToRootFtNode.get(alias);
575:                        propNode.addFeatureTypeNode(childNode);
576:                    }
577:                } else {
578:                    FeatureTypeNode[] subFtNodes = propNode
579:                            .getFeatureTypeNodes();
580:                    for (FeatureTypeNode node : subFtNodes) {
581:                        if (node.getFeatureType().getName().equals(featureStep)) {
582:                            childNode = node;
583:                            break;
584:                        }
585:                    }
586:                    if (childNode == null) {
587:                        MappedFeatureType subFt = this .roots[0]
588:                                .getFeatureType().getGMLSchema()
589:                                .getFeatureType(featureStep);
590:                        String tableAlias = this .aliasGenerator
591:                                .generateUniqueAlias();
592:                        childNode = new FeatureTypeNode(subFt, null, tableAlias);
593:                        propNode.addFeatureTypeNode(childNode);
594:                    }
595:                }
596:
597:                return childNode;
598:            }
599:
600:            // private FeaturePropertyNode createFeaturePropertyNode( FeatureTypeNode ftNode, MappedFeaturePropertyType pt) {
601:            //
602:            // // MappedFeatureType[] allowedTypes = pt.getFeatureTypeReference().getFeatureType().getConcreteSubstitutions();
603:            // // QualifiedName givenTypeName = propertyPath.getStep( step + 1 ).getPropertyName();
604:            // // MappedFeatureType givenType = null;
605:            //
606:            //
607:            // }
608:
609:            // private void addPathFragment( FeatureTypeNode ftNode, PropertyPath propertyPath, int startStep ) {
610:            //
611:            // for ( int step = startStep; step < propertyPath.getSteps(); step += 2 ) {
612:            // LOG.logDebug( "Looking up property: " + propertyPath.getStep( step ).getPropertyName() );
613:            // MappedPropertyType pt = getPropertyType( ftNode.getFeatureType(), propertyPath.getStep( step ) );
614:            // if ( pt instanceof MappedSimplePropertyType ) {
615:            // addSimplePropertyNode( ftNode, (MappedSimplePropertyType) pt, propertyPath, step );
616:            // break;
617:            // } else if ( pt instanceof MappedGeometryPropertyType ) {
618:            // addGeometryPropertyNode( ftNode, (MappedGeometryPropertyType) pt, propertyPath, step );
619:            // break;
620:            // } else if ( pt instanceof MappedFeaturePropertyType ) {
621:            // MappedFeaturePropertyType featurePT = (MappedFeaturePropertyType) pt;
622:            // ftNode = addFeaturePropertyNode( ftNode, featurePT, propertyPath, step );
623:            // } else {
624:            // assert ( false );
625:            // }
626:            // }
627:            // }
628:
629:            /**
630:             * Returns the {@link MappedPropertyType} for the given {@link MappedFeatureType} that matches the given
631:             * {@link PropertyPathStep}.
632:             * 
633:             * @param ft
634:             * @param step
635:             * @return matching property type or null, if none exists
636:             */
637:            private MappedPropertyType getPropertyType(MappedFeatureType ft,
638:                    PropertyPathStep step) {
639:
640:                MappedPropertyType pt = null;
641:                QualifiedName name = step.getPropertyName();
642:
643:                if (step instanceof  AttributeStep) {
644:                    // TODO remove handling of gml:id here (after adaptation of feature model)
645:                    if (CommonNamespaces.GMLNS.equals(name.getNamespace())
646:                            && "id".equals(name.getLocalName())) {
647:                        MappedGMLId gmlId = ft.getGMLId();
648:                        pt = new MappedSimplePropertyType(name, Types.VARCHAR,
649:                                1, 1, false, null, gmlId.getIdFields()[0]);
650:                    }
651:                } else {
652:                    // normal property (not gml:id)
653:                    pt = (MappedPropertyType) ft.getProperty(name);
654:                }
655:
656:                return pt;
657:            }
658:
659:            // private void addSimplePropertyNode( FeatureTypeNode featureTypeNode, MappedSimplePropertyType propertyType,
660:            // PropertyPath propertyPath, int step ) {
661:            //
662:            // assert ( step == propertyPath.getSteps() - 1 );
663:            // String[] tableAliases = generateTableAliases( propertyType );
664:            // PropertyNode propertyNode = new SimplePropertyNode( propertyType, featureTypeNode, tableAliases );
665:            // this.propertyPaths.add( propertyPath );
666:            // this.propertyNodes.add( propertyNode );
667:            // featureTypeNode.addPropertyNode( propertyNode );
668:            // }
669:            //
670:            // private void addGeometryPropertyNode( FeatureTypeNode featureTypeNode, MappedGeometryPropertyType propertyType,
671:            // PropertyPath propertyPath, int step ) {
672:            //
673:            // assert ( step == propertyPath.getSteps() - 1 );
674:            // String[] tableAliases = generateTableAliases( propertyType );
675:            // PropertyNode propertyNode = new GeometryPropertyNode( propertyType, featureTypeNode, tableAliases );
676:            // this.propertyPaths.add( propertyPath );
677:            // this.propertyNodes.add( propertyNode );
678:            // featureTypeNode.addPropertyNode( propertyNode );
679:            // }
680:            //
681:            // private FeatureTypeNode addFeaturePropertyNode( FeatureTypeNode ftNode, MappedFeaturePropertyType pt,
682:            // PropertyPath propertyPath, int step ) {
683:            //
684:            // assert ( step < propertyPath.getSteps() - 1 );
685:            // MappedFeatureType[] allowedTypes = pt.getFeatureTypeReference().getFeatureType().getConcreteSubstitutions();
686:            // QualifiedName givenTypeName = propertyPath.getStep( step + 1 ).getPropertyName();
687:            // MappedFeatureType givenType = null;
688:            //
689:            // for ( int i = 0; i < allowedTypes.length; i++ ) {
690:            // if ( allowedTypes[i].getName().equals( givenTypeName ) ) {
691:            // givenType = allowedTypes[i];
692:            // break;
693:            // }
694:            // }
695:            // assert ( givenType != null );
696:            //
697:            // // TODO make proper
698:            // String[] tableAliases = this.aliasGenerator.generateUniqueAliases( pt.getTableRelations().length - 1 );
699:            // String tableAlias = this.aliasGenerator.generateUniqueAlias();
700:            // FeatureTypeNode childFeatureTypeNode = new FeatureTypeNode( givenType, null, tableAlias );
701:            //
702:            // FeatureType ft = pt.getFeatureTypeReference().getFeatureType();
703:            // LOG.logDebug( "featureType: " + ft.getName() );
704:            //
705:            // PropertyNode propertyNode = new FeaturePropertyNode( pt, ftNode, tableAliases, childFeatureTypeNode );
706:            // // this.propertyPaths.add (propertyPath);
707:            // // this.propertyNodes.add (propertyNode);
708:            // ftNode.addPropertyNode( propertyNode );
709:            // return childFeatureTypeNode;
710:            // }
711:
712:            private String[] generateTableAliases(MappedPropertyType pt) {
713:                String[] aliases = null;
714:                TableRelation[] relations = pt.getTableRelations();
715:                if (relations != null) {
716:                    aliases = new String[relations.length];
717:                    for (int i = 0; i < aliases.length; i++) {
718:                        aliases[i] = this .aliasGenerator.generateUniqueAlias();
719:                    }
720:                }
721:                return aliases;
722:            }
723:
724:            @Override
725:            public String toString() {
726:                StringBuffer sb = new StringBuffer();
727:                for (FeatureTypeNode root : this .roots) {
728:                    sb.append(root.toString(""));
729:                    sb.append('\n');
730:                }
731:                return sb.toString();
732:            }
733:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.