Source Code Cross Referenced for XPath.java in  » GIS » GeoTools-2.4.1 » org » geotools » data » complex » filter » 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.filter 
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.filter;
018:
019:        import java.util.ArrayList;
020:        import java.util.Collection;
021:        import java.util.Iterator;
022:        import java.util.List;
023:        import java.util.logging.Level;
024:        import java.util.logging.Logger;
025:
026:        import javax.xml.XMLConstants;
027:        import javax.xml.namespace.QName;
028:
029:        import org.geotools.factory.CommonFactoryFinder;
030:        import org.geotools.feature.iso.AttributeBuilder;
031:        import org.geotools.feature.iso.AttributeFactoryImpl;
032:        import org.geotools.feature.iso.Types;
033:        import org.geotools.feature.iso.type.TypeFactoryImpl;
034:        import org.geotools.util.CheckedArrayList;
035:        import org.opengis.feature.Attribute;
036:        import org.opengis.feature.ComplexAttribute;
037:        import org.opengis.feature.FeatureFactory;
038:        import org.opengis.feature.type.AttributeDescriptor;
039:        import org.opengis.feature.type.AttributeType;
040:        import org.opengis.feature.type.ComplexType;
041:        import org.opengis.feature.type.Name;
042:        import org.opengis.feature.type.PropertyDescriptor;
043:        import org.opengis.feature.type.TypeFactory;
044:        import org.opengis.filter.FilterFactory;
045:        import org.opengis.filter.expression.Literal;
046:        import org.opengis.filter.expression.PropertyName;
047:        import org.opengis.util.Cloneable;
048:        import org.xml.sax.helpers.NamespaceSupport;
049:
050:        /**
051:         * Utility class to evaluate XPath expressions against an Attribute instance,
052:         * which may be any Attribute, wether it is simple, complex, a feature, etc.
053:         * <p>
054:         * At the difference of the Filter subsystem, which works against Attribute
055:         * contents (for example to evaluate a comparison filter), the XPath subsystem,
056:         * for which this class is the single entry point, works against Attribute
057:         * instances. That is, the result of an XPath expression, if a single value, is
058:         * an Attribtue, not the attribute content, or a List of Attributes, for
059:         * instance.
060:         * </p>
061:         * 
062:         * @author Gabriel Roldan, Axios Engineering
063:         * @version $Id: XPath.java 29122 2008-02-07 03:43:28Z groldan $
064:         * @source $URL:
065:         *         http://svn.geotools.org/geotools/branches/2.4.x/modules/unsupported/community-schemas/community-schema-ds/src/main/java/org/geotools/data/complex/filter/XPath.java $
066:         * @since 2.4
067:         */
068:        public class XPath {
069:            private static final Logger LOGGER = org.geotools.util.logging.Logging
070:                    .getLogger(XPath.class.getPackage().getName());
071:
072:            private FilterFactory FF;
073:
074:            private FeatureFactory featureFactory;
075:
076:            /**
077:             * Used to create specific attribute descriptors for
078:             * {@link #set(Attribute, String, Object, String, AttributeType)} when the
079:             * actual attribute instance is of a derived type of the corresponding one
080:             * declared in the feature type.
081:             */
082:            private TypeFactory descriptorFactory;
083:
084:            public XPath() {
085:                this .FF = CommonFactoryFinder.getFilterFactory(null);
086:                this .featureFactory = new AttributeFactoryImpl();
087:                this .descriptorFactory = new TypeFactoryImpl();
088:            }
089:
090:            public XPath(FilterFactory ff, FeatureFactory featureFactory) {
091:                setFilterFactory(ff);
092:                setFeatureFactory(featureFactory);
093:                this .descriptorFactory = new TypeFactoryImpl();
094:            }
095:
096:            public void setFilterFactory(FilterFactory ff) {
097:                this .FF = ff;
098:            }
099:
100:            public void setFeatureFactory(FeatureFactory featureFactory) {
101:                this .featureFactory = featureFactory;
102:            }
103:
104:            public static class StepList extends CheckedArrayList implements 
105:                    List, Cloneable {
106:                private static final long serialVersionUID = -5612786286175355862L;
107:
108:                private StepList() {
109:                    super (XPath.Step.class);
110:                }
111:
112:                public StepList(StepList steps) {
113:                    super (XPath.Step.class);
114:                    addAll(steps);
115:                }
116:
117:                public String toString() {
118:                    StringBuffer sb = new StringBuffer();
119:                    for (Iterator it = iterator(); it.hasNext();) {
120:                        Step s = (Step) it.next();
121:                        sb.append(s.toString());
122:                        if (it.hasNext()) {
123:                            sb.append("/");
124:                        }
125:                    }
126:                    return sb.toString();
127:                }
128:
129:                public Object clone() {
130:                    StepList copy = new StepList();
131:                    Step step;
132:                    for (Iterator it = iterator(); it.hasNext();) {
133:                        step = (Step) it.next();
134:                        copy.add(step.clone());
135:                    }
136:                    return copy;
137:                }
138:
139:                /**
140:                 * Compares this StepList with another for equivalence regardless of the
141:                 * indexes of each Step.
142:                 * 
143:                 * @param propertyName
144:                 * @return <code>true</code> if this step list has the same location
145:                 *         paths than <code>propertyName</code> ignoring the indexes
146:                 *         in each step. <code>false</code> otherwise.
147:                 */
148:                public boolean equalsIgnoreIndex(final StepList propertyName) {
149:                    if (propertyName == null) {
150:                        return false;
151:                    }
152:                    if (propertyName == this ) {
153:                        return true;
154:                    }
155:                    if (size() != propertyName.size()) {
156:                        return false;
157:                    }
158:                    Iterator mine = iterator();
159:                    Iterator him = propertyName.iterator();
160:                    Step myStep;
161:                    Step hisStep;
162:                    while (mine.hasNext()) {
163:                        myStep = (Step) mine.next();
164:                        hisStep = (Step) him.next();
165:                        if (!myStep.equalsIgnoreIndex(hisStep)) {
166:                            return false;
167:                        }
168:                    }
169:                    return true;
170:                }
171:            }
172:
173:            /**
174:             * 
175:             * @author gabriel
176:             * 
177:             */
178:            public static class Step implements  Cloneable {
179:                private int index;
180:
181:                private QName attributeName;
182:
183:                private boolean isXmlAttribute;
184:
185:                /**
186:                 * Creates a "property" xpath step (i.e. isXmlAttribute() == false).
187:                 * 
188:                 * @param name
189:                 * @param index
190:                 */
191:                public Step(final QName name, final int index) {
192:                    this (name, index, false);
193:                }
194:
195:                /**
196:                 * Creates an xpath step for the given qualified name and index; and the
197:                 * given flag to indicate if it it an "attribute" or "property" step.
198:                 * 
199:                 * @param name
200:                 *            the qualified name of the step (name should include prefix
201:                 *            to be reflected in toString())
202:                 * @param index
203:                 *            the index (indexing starts at 1 for Xpath) of the step
204:                 * @param isXmlAttribute
205:                 *            whether the step referers to an "attribute" or a
206:                 *            "property" (like for attributes and elements in xml)
207:                 * @throws NullPointerException
208:                 *             if <code>name==null</code>
209:                 * @throws IllegalArgumentException
210:                 *             if <code>index &lt; 1</code>
211:                 */
212:                public Step(final QName name, final int index,
213:                        boolean isXmlAttribute) {
214:                    if (name == null) {
215:                        throw new NullPointerException("name");
216:                    }
217:                    if (index < 1) {
218:                        throw new IllegalArgumentException(
219:                                "index shall be >= 1");
220:                    }
221:                    this .attributeName = name;
222:                    this .index = index;
223:                    this .isXmlAttribute = isXmlAttribute;
224:                }
225:
226:                /**
227:                 * Compares this Step with another for equivalence ignoring the steps
228:                 * indexes.
229:                 * 
230:                 * @param hisStep
231:                 * @return
232:                 */
233:                public boolean equalsIgnoreIndex(Step other) {
234:                    if (other == null) {
235:                        return false;
236:                    }
237:                    if (other == this ) {
238:                        return true;
239:                    }
240:                    return other.getName().equals(getName());
241:                }
242:
243:                public int getIndex() {
244:                    return index;
245:                }
246:
247:                public QName getName() {
248:                    return attributeName;
249:                }
250:
251:                public String toString() {
252:                    StringBuffer sb = new StringBuffer(isXmlAttribute ? "@"
253:                            : "");
254:                    if (XMLConstants.DEFAULT_NS_PREFIX != attributeName
255:                            .getPrefix()) {
256:                        sb.append(attributeName.getPrefix()).append(':');
257:                    }
258:                    sb.append(attributeName.getLocalPart());
259:                    if (index > 1) {
260:                        sb.append("[").append(index).append("]");
261:                    }
262:                    return sb.toString();
263:                }
264:
265:                public boolean equals(Object o) {
266:                    if (!(o instanceof  Step)) {
267:                        return false;
268:                    }
269:                    Step s = (Step) o;
270:                    return attributeName.equals(s.attributeName)
271:                            && index == s.index
272:                            && isXmlAttribute == s.isXmlAttribute;
273:                }
274:
275:                public int hashCode() {
276:                    return 17 * attributeName.hashCode() + 37 * index;
277:                }
278:
279:                public Object clone() {
280:                    return new Step(this .attributeName, this .index,
281:                            this .isXmlAttribute);
282:                }
283:
284:                /**
285:                 * Flag that indicates that this single step refers to an "attribute"
286:                 * rather than a "property".
287:                 * <p>
288:                 * I.e. it was created from the last step of an expression like
289:                 * <code>foo/bar@attribute</code>.
290:                 * </p>
291:                 * 
292:                 * @return
293:                 */
294:                public boolean isXmlAttribute() {
295:                    return isXmlAttribute;
296:                }
297:            }
298:
299:            /**
300:             * Returns the list of stepts in <code>xpathExpression</code> by cleaning
301:             * it up removing unnecessary elements.
302:             * <p>
303:             * </p>
304:             * 
305:             * @param root
306:             *            non null descriptor of the root attribute, generally the
307:             *            Feature descriptor. Used to ignore the first step in
308:             *            xpathExpression if the expression's first step is named as
309:             *            rootName.
310:             * 
311:             * @param xpathExpression
312:             * @return
313:             * @throws IllegalArgumentException
314:             *             if <code>xpathExpression</code> has no steps or it isn't a
315:             *             valid XPath expression against <code>type</code>.
316:             */
317:            public static StepList steps(final AttributeDescriptor root,
318:                    final String xpathExpression,
319:                    final NamespaceSupport namespaces)
320:                    throws IllegalArgumentException {
321:
322:                if (root == null) {
323:                    throw new NullPointerException("root");
324:                }
325:
326:                if (xpathExpression == null) {
327:                    throw new NullPointerException("xpathExpression");
328:                }
329:
330:                String expression = xpathExpression.trim();
331:
332:                if ("".equals(expression)) {
333:                    throw new IllegalArgumentException("expression is empty");
334:                }
335:
336:                StepList steps = new StepList();
337:
338:                if ("/".equals(expression)) {
339:                    expression = root.getName().getLocalPart();
340:                }
341:
342:                if (expression.startsWith("/")) {
343:                    expression = expression.substring(1);
344:                }
345:
346:                final String[] partialSteps = expression.split("[/]");
347:
348:                if (partialSteps.length == 0) {
349:                    throw new IllegalArgumentException("no steps provided");
350:                }
351:
352:                int startIndex = 0;
353:
354:                for (int i = startIndex; i < partialSteps.length; i++) {
355:
356:                    String step = partialSteps[i];
357:                    if ("..".equals(step)) {
358:                        steps.remove(steps.size() - 1);
359:                    } else if (".".equals(step)) {
360:                        continue;
361:                    } else {
362:                        int index = 1;
363:                        boolean isXmlAttribute = false;
364:                        String stepName = step;
365:                        if (step.indexOf('[') != -1) {
366:                            int start = step.indexOf('[');
367:                            int end = step.indexOf(']');
368:                            stepName = step.substring(0, start);
369:                            index = Integer.parseInt(step.substring(start + 1,
370:                                    end));
371:                        }
372:                        if (step.charAt(0) == '@') {
373:                            isXmlAttribute = true;
374:                            stepName = stepName.substring(1);
375:                        }
376:                        QName qName = deglose(stepName, root, namespaces);
377:                        steps.add(new Step(qName, index, isXmlAttribute));
378:                    }
379:                    //            
380:                    //            if (step.indexOf('[') != -1) {
381:                    //                int start = step.indexOf('[');
382:                    //                int end = step.indexOf(']');
383:                    //                String stepName = step.substring(0, start);
384:                    //                int stepIndex = Integer.parseInt(step.substring(start + 1, end));
385:                    //                QName qName = deglose(stepName, root, namespaces);
386:                    //                steps.add(new Step(qName, stepIndex));
387:                    //            } else if ("..".equals(step)) {
388:                    //                steps.remove(steps.size() - 1);
389:                    //            } else if (".".equals(step)) {
390:                    //                continue;
391:                    //            } else {
392:                    //                QName qName = deglose(step, root, namespaces);
393:                    //                steps.add(new Step(qName, 1));
394:                    //            }
395:                }
396:
397:                // XPath simplification phase: if the xpath expression contains more
398:                // nodes
399:                // than the root node itself, and the root node is present, remove the
400:                // root
401:                // node as it is redundant
402:                if (root != null && steps.size() > 1) {
403:                    Step step = (Step) steps.get(0);
404:                    Name rootName = root.getName();
405:                    QName stepName = step.getName();
406:                    if (Types.equals(rootName, stepName)) {
407:                        LOGGER.fine("removing root name from xpath " + steps
408:                                + " as it is redundant");
409:                        steps.remove(0);
410:                    }
411:                }
412:
413:                return steps;
414:            }
415:
416:            private static QName deglose(final String prefixedName,
417:                    final AttributeDescriptor root,
418:                    final NamespaceSupport namespaces) {
419:                if (prefixedName == null) {
420:                    throw new NullPointerException("prefixedName");
421:                }
422:
423:                QName name = null;
424:
425:                final String prefix;
426:                final String namespaceUri;
427:                final String localName;
428:                final Name rootName = root.getName();
429:                final String defaultNamespace = rootName.getNamespaceURI() == null ? XMLConstants.NULL_NS_URI
430:                        : rootName.getNamespaceURI();
431:
432:                int prefixIdx = prefixedName.indexOf(':');
433:
434:                if (prefixIdx == -1) {
435:                    localName = prefixedName;
436:                    namespaceUri = defaultNamespace;
437:                    if (XMLConstants.NULL_NS_URI.equals(defaultNamespace)) {
438:                        prefix = XMLConstants.DEFAULT_NS_PREFIX;
439:                    } else {
440:                        if (!localName.equals(rootName.getLocalPart())) {
441:                            LOGGER.warning("Using root's namespace "
442:                                    + defaultNamespace + " for step named '"
443:                                    + localName + "', as no prefix was stated");
444:                        }
445:                        prefix = namespaces.getPrefix(defaultNamespace);
446:
447:                        if (prefix == null) {
448:                            throw new IllegalStateException(
449:                                    "Default namespace is not mapped to a prefix: "
450:                                            + defaultNamespace);
451:                        }
452:                    }
453:                } else {
454:                    prefix = prefixedName.substring(0, prefixIdx);
455:                    localName = prefixedName.substring(prefixIdx + 1);
456:                    namespaceUri = namespaces.getURI(prefix);
457:                }
458:
459:                name = new QName(namespaceUri, localName, prefix);
460:
461:                return name;
462:            }
463:
464:            /**
465:             * Sets the value of the attribute of <code>att</code> addressed by
466:             * <code>xpath</code> and of type <code>targetNodeType</code> to be
467:             * <code>value</code> with id <code>id</code>.
468:             * 
469:             * @param att
470:             *            the root attribute for which to set the child attribute value
471:             * @param xpath
472:             *            the xpath expression that addresses the <code>att</code>
473:             *            child whose value is to be set
474:             * @param value
475:             *            the value of the attribute addressed by <code>xpath</code>
476:             * @param id
477:             *            the identifier of the attribute addressed by
478:             *            <code>xpath</code>, might be <code>null</code>
479:             * @param targetNodeType
480:             *            the expected type of the attribute addressed by
481:             *            <code>xpath</code>, or <code>null</code> if unknown
482:             * @return
483:             */
484:            public Attribute set(final Attribute att, final StepList xpath,
485:                    Object value, String id, AttributeType targetNodeType) {
486:                if (XPath.LOGGER.isLoggable(Level.CONFIG)) {
487:                    XPath.LOGGER.entering("XPath", "set", new Object[] { att,
488:                            xpath, value, id, targetNodeType });
489:                }
490:
491:                final StepList steps = new StepList(xpath);
492:
493:                // if (steps.size() < 2) {
494:                // throw new IllegalArgumentException("parent not yet built for " +
495:                // xpath);
496:                // }
497:
498:                ComplexAttribute parent = (ComplexAttribute) att;
499:                Name rootName = null;
500:                if (parent.getDescriptor() != null) {
501:                    rootName = parent.getDescriptor().getName();
502:                    Step rootStep = (Step) steps.get(0);
503:                    QName stepName = rootStep.getName();
504:                    if (stepName.getLocalPart().equals(rootName.getLocalPart())) {
505:                        if (XMLConstants.NULL_NS_URI.equals(stepName
506:                                .getNamespaceURI())
507:                                || stepName.getNamespaceURI().equals(
508:                                        rootName.getNamespaceURI())) {
509:                            // first step is the self reference to att, so skip it
510:                            steps.remove(0);
511:                        }
512:                    }
513:                }
514:
515:                Iterator stepsIterator = steps.iterator();
516:
517:                for (; stepsIterator.hasNext();) {
518:                    final XPath.Step currStep = (Step) stepsIterator.next();
519:                    final ComplexType parentType = (ComplexType) parent
520:                            .getType();
521:                    final QName stepName = currStep.getName();
522:                    final Name attributeName = Types.toName(stepName);
523:
524:                    AttributeDescriptor currStepDescriptor = null;
525:
526:                    if (targetNodeType == null) {
527:                        if (null == attributeName.getNamespaceURI()) {
528:                            currStepDescriptor = (AttributeDescriptor) Types
529:                                    .descriptor(parentType, attributeName
530:                                            .getLocalPart());
531:                        } else {
532:                            currStepDescriptor = (AttributeDescriptor) Types
533:                                    .descriptor(parentType, attributeName);
534:                        }
535:
536:                        if (currStepDescriptor == null) {
537:                            // need to take the non easy way, may be the instance has a
538:                            // value for this step with a different name, of a derived
539:                            // type of the one declared in the parent type
540:                            String prefixedStepName = currStep.toString();
541:                            PropertyName name = FF.property(prefixedStepName);
542:                            Attribute child = (Attribute) name.evaluate(parent);
543:                            if (child != null) {
544:                                currStepDescriptor = child.getDescriptor();
545:                            }
546:                        }
547:                    } else {
548:                        AttributeDescriptor actualDescriptor;
549:                        if (null == attributeName.getNamespaceURI()) {
550:                            actualDescriptor = (AttributeDescriptor) Types
551:                                    .descriptor(parentType, attributeName
552:                                            .getLocalPart(), targetNodeType);
553:                        } else {
554:                            actualDescriptor = (AttributeDescriptor) Types
555:                                    .descriptor(parentType, attributeName,
556:                                            targetNodeType);
557:                        }
558:
559:                        if (actualDescriptor != null) {
560:                            int minOccurs = actualDescriptor.getMinOccurs();
561:                            int maxOccurs = actualDescriptor.getMaxOccurs();
562:                            boolean nillable = actualDescriptor.isNillable();
563:                            currStepDescriptor = descriptorFactory
564:                                    .createAttributeDescriptor(targetNodeType,
565:                                            attributeName, minOccurs,
566:                                            maxOccurs, nillable, null);
567:                        }
568:                    }
569:
570:                    if (currStepDescriptor == null) {
571:                        StringBuffer parentAtts = new StringBuffer();
572:                        Collection properties = parentType.getProperties();
573:                        for (Iterator it = properties.iterator(); it.hasNext();) {
574:                            PropertyDescriptor desc = (PropertyDescriptor) it
575:                                    .next();
576:                            Name name = desc.getName();
577:                            parentAtts.append(name.getNamespaceURI());
578:                            parentAtts.append("#");
579:                            parentAtts.append(name.getLocalPart());
580:                            if (it.hasNext()) {
581:                                parentAtts.append(", ");
582:                            }
583:                        }
584:                        throw new IllegalArgumentException(currStep
585:                                + " is not a valid location path for type "
586:                                + parentType.getName() + ". " + currStep
587:                                + " ns: "
588:                                + currStep.getName().getNamespaceURI() + ", "
589:                                + parentType.getName().getLocalPart()
590:                                + " properties: " + parentAtts);
591:                    }
592:
593:                    final boolean isLastStep = !stepsIterator.hasNext();
594:
595:                    if (isLastStep) {
596:                        // reached the leaf
597:                        if (currStepDescriptor == null) {
598:                            throw new IllegalArgumentException(currStep
599:                                    + " is not a valid location path for type "
600:                                    + parentType.getName());
601:                        }
602:                        int index = currStep.getIndex();
603:                        Attribute attribute = setValue(currStepDescriptor, id,
604:                                value, index, parent, targetNodeType);
605:                        return attribute;
606:                    } else {
607:                        // parent = appendComplexProperty(parent, currStep,
608:                        // currStepDescriptor);
609:                        int index = currStep.getIndex();
610:                        Attribute _parent = setValue(currStepDescriptor, null,
611:                                null, index, parent, null);
612:                        parent = (ComplexAttribute) _parent;
613:                    }
614:                }
615:                throw new IllegalStateException();
616:            }
617:
618:            private Attribute setValue(final AttributeDescriptor descriptor,
619:                    final String id, Object value, final int index,
620:                    final ComplexAttribute parent,
621:                    final AttributeType targetNodeType) {
622:
623:                final Name attributeName = descriptor.getName();
624:
625:                // adapt value to context
626:                Literal literal = FF.literal(value);
627:                Class binding = ((AttributeType) descriptor.type())
628:                        .getBinding();
629:                value = literal.evaluate(value, binding);
630:
631:                Attribute leafAttribute = null;
632:
633:                Object currStepValue = parent.get(attributeName);
634:
635:                if (currStepValue instanceof  Collection) {
636:                    List values = new ArrayList((Collection) currStepValue);
637:                    if (values.size() >= index) {
638:                        leafAttribute = (Attribute) values.get(index - 1);
639:                    }
640:                } else if (currStepValue instanceof  Attribute) {
641:                    leafAttribute = (Attribute) currStepValue;
642:                } else if (currStepValue != null) {
643:                    throw new IllegalStateException(
644:                            "Unkown addressed object. Xpath:" + attributeName
645:                                    + ", addressed: "
646:                                    + currStepValue.getClass().getName() + " ["
647:                                    + currStepValue.toString() + "]");
648:                }
649:
650:                if (leafAttribute == null) {
651:                    AttributeBuilder builder = new AttributeBuilder(
652:                            featureFactory);
653:                    builder.init(parent);
654:                    if (targetNodeType != null) {
655:                        leafAttribute = builder.add(id, value, attributeName,
656:                                targetNodeType);
657:                    } else {
658:                        leafAttribute = builder.add(id, value, attributeName);
659:                    }
660:                    List newValue = new ArrayList();
661:                    newValue.addAll((Collection) parent.getValue());
662:                    newValue.add(leafAttribute);
663:                    parent.setValue(newValue);
664:                }
665:
666:                if (value != null) {
667:                    leafAttribute.setValue(value);
668:                }
669:                return leafAttribute;
670:            }
671:
672:            public boolean isComplexType(final StepList attrXPath,
673:                    final AttributeDescriptor featureType) {
674:                PropertyName attExp = FF.property(attrXPath.toString());
675:                Object type = attExp.evaluate(featureType);
676:                if (type == null) {
677:                    type = attExp.evaluate(featureType);
678:                    throw new IllegalArgumentException("path not found: "
679:                            + attrXPath);
680:                }
681:
682:                AttributeDescriptor node = (AttributeDescriptor) type;
683:                return node.type() instanceof  ComplexType;
684:            }
685:
686:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.