jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/identity/Field.java
changeset 27111 7a491d709b83
parent 25868 686eef1e7a79
equal deleted inserted replaced
26996:a137992d750c 27111:7a491d709b83
     1 /*
     1 /*
     2  * reserved comment block
     2  * reserved comment block
     3  * DO NOT REMOVE OR ALTER!
     3  * DO NOT REMOVE OR ALTER!
     4  */
     4  */
     5 /*
     5 /*
     6  * Copyright 2001-2005 The Apache Software Foundation.
     6  * Licensed to the Apache Software Foundation (ASF) under one or more
     7  *
     7  * contributor license agreements.  See the NOTICE file distributed with
     8  * Licensed under the Apache License, Version 2.0 (the "License");
     8  * this work for additional information regarding copyright ownership.
     9  * you may not use this file except in compliance with the License.
     9  * The ASF licenses this file to You under the Apache License, Version 2.0
    10  * You may obtain a copy of the License at
    10  * (the "License"); you may not use this file except in compliance with
       
    11  * the License.  You may obtain a copy of the License at
    11  *
    12  *
    12  *      http://www.apache.org/licenses/LICENSE-2.0
    13  *      http://www.apache.org/licenses/LICENSE-2.0
    13  *
    14  *
    14  * Unless required by applicable law or agreed to in writing, software
    15  * Unless required by applicable law or agreed to in writing, software
    15  * distributed under the License is distributed on an "AS IS" BASIS,
    16  * distributed under the License is distributed on an "AS IS" BASIS,
    21 package com.sun.org.apache.xerces.internal.impl.xs.identity;
    22 package com.sun.org.apache.xerces.internal.impl.xs.identity;
    22 
    23 
    23 import com.sun.org.apache.xerces.internal.impl.xpath.XPathException;
    24 import com.sun.org.apache.xerces.internal.impl.xpath.XPathException;
    24 import com.sun.org.apache.xerces.internal.impl.xs.util.ShortListImpl;
    25 import com.sun.org.apache.xerces.internal.impl.xs.util.ShortListImpl;
    25 import com.sun.org.apache.xerces.internal.util.SymbolTable;
    26 import com.sun.org.apache.xerces.internal.util.SymbolTable;
       
    27 import com.sun.org.apache.xerces.internal.util.XMLChar;
    26 import com.sun.org.apache.xerces.internal.xni.NamespaceContext;
    28 import com.sun.org.apache.xerces.internal.xni.NamespaceContext;
    27 import com.sun.org.apache.xerces.internal.xs.ShortList;
    29 import com.sun.org.apache.xerces.internal.xs.ShortList;
    28 import com.sun.org.apache.xerces.internal.xs.XSComplexTypeDefinition;
    30 import com.sun.org.apache.xerces.internal.xs.XSComplexTypeDefinition;
    29 import com.sun.org.apache.xerces.internal.xs.XSConstants;
    31 import com.sun.org.apache.xerces.internal.xs.XSConstants;
    30 import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition;
    32 import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition;
    41     //
    43     //
    42     // Data
    44     // Data
    43     //
    45     //
    44 
    46 
    45     /** Field XPath. */
    47     /** Field XPath. */
    46     protected Field.XPath fXPath;
    48     protected final Field.XPath fXPath;
    47 
    49 
    48 
    50 
    49     /** Identity constraint. */
    51     /** Identity constraint. */
    50     protected IdentityConstraint fIdentityConstraint;
    52     protected final IdentityConstraint fIdentityConstraint;
    51 
    53 
    52     //
    54     //
    53     // Constructors
    55     // Constructors
    54     //
    56     //
    55 
    57 
    65     //
    67     //
    66 
    68 
    67     /** Returns the field XPath. */
    69     /** Returns the field XPath. */
    68     public com.sun.org.apache.xerces.internal.impl.xpath.XPath getXPath() {
    70     public com.sun.org.apache.xerces.internal.impl.xpath.XPath getXPath() {
    69         return fXPath;
    71         return fXPath;
    70     } // getXPath():com.sun.org.apache.xerces.internal.impl.v1.schema.identity.XPath
    72     } // getXPath():org.apache.xerces.impl.v1.schema.identity.XPath
    71 
    73 
    72     /** Returns the identity constraint. */
    74     /** Returns the identity constraint. */
    73     public IdentityConstraint getIdentityConstraint() {
    75     public IdentityConstraint getIdentityConstraint() {
    74         return fIdentityConstraint;
    76         return fIdentityConstraint;
    75     } // getIdentityConstraint():IdentityConstraint
    77     } // getIdentityConstraint():IdentityConstraint
    76 
    78 
    77     // factory method
    79     // factory method
    78 
    80 
    79     /** Creates a field matcher. */
    81     /** Creates a field matcher. */
    80     public XPathMatcher createMatcher(FieldActivator activator, ValueStore store) {
    82     public XPathMatcher createMatcher(ValueStore store) {
    81         return new Field.Matcher(fXPath, activator, store);
    83         return new Field.Matcher(fXPath, store);
    82     } // createMatcher(ValueStore):XPathMatcher
    84     } // createMatcher(ValueStore):XPathMatcher
    83 
    85 
    84     //
    86     //
    85     // Object methods
    87     // Object methods
    86     //
    88     //
   108 
   110 
   109         /** Constructs a field XPath expression. */
   111         /** Constructs a field XPath expression. */
   110         public XPath(String xpath,
   112         public XPath(String xpath,
   111                      SymbolTable symbolTable,
   113                      SymbolTable symbolTable,
   112                      NamespaceContext context) throws XPathException {
   114                      NamespaceContext context) throws XPathException {
   113             // NOTE: We have to prefix the field XPath with "./" in
   115             super(fixupXPath(xpath), symbolTable, context);
   114             //       order to handle selectors such as "@attr" that
       
   115             //       select the attribute because the fields could be
       
   116             //       relative to the selector element. -Ac
       
   117             //       Unless xpath starts with a descendant node -Achille Fokoue
       
   118             //      ... or a / or a . - NG
       
   119             super(((xpath.trim().startsWith("/") ||xpath.trim().startsWith("."))?
       
   120                     xpath:"./"+xpath),
       
   121                   symbolTable, context);
       
   122 
   116 
   123             // verify that only one attribute is selected per branch
   117             // verify that only one attribute is selected per branch
   124             for (int i=0;i<fLocationPaths.length;i++) {
   118             for (int i=0;i<fLocationPaths.length;i++) {
   125                 for(int j=0; j<fLocationPaths[i].steps.length; j++) {
   119                 for(int j=0; j<fLocationPaths[i].steps.length; j++) {
   126                     com.sun.org.apache.xerces.internal.impl.xpath.XPath.Axis axis =
   120                     com.sun.org.apache.xerces.internal.impl.xpath.XPath.Axis axis =
   131                     }
   125                     }
   132                 }
   126                 }
   133             }
   127             }
   134         } // <init>(String,SymbolTable,NamespacesContext)
   128         } // <init>(String,SymbolTable,NamespacesContext)
   135 
   129 
       
   130         /** Fixup XPath expression. Avoid creating a new String if possible. */
       
   131         private static String fixupXPath(String xpath) {
       
   132 
       
   133             final int end = xpath.length();
       
   134             int offset = 0;
       
   135             boolean whitespace = true;
       
   136             char c;
       
   137 
       
   138             // NOTE: We have to prefix the field XPath with "./" in
       
   139             //       order to handle selectors such as "@attr" that
       
   140             //       select the attribute because the fields could be
       
   141             //       relative to the selector element. -Ac
       
   142             //       Unless xpath starts with a descendant node -Achille Fokoue
       
   143             //      ... or a / or a . - NG
       
   144             for (; offset < end; ++offset) {
       
   145                 c = xpath.charAt(offset);
       
   146                 if (whitespace) {
       
   147                     if (!XMLChar.isSpace(c)) {
       
   148                         if (c == '.' || c == '/') {
       
   149                             whitespace = false;
       
   150                         }
       
   151                         else if (c != '|') {
       
   152                             return fixupXPath2(xpath, offset, end);
       
   153                         }
       
   154                     }
       
   155                 }
       
   156                 else if (c == '|') {
       
   157                     whitespace = true;
       
   158                 }
       
   159             }
       
   160             return xpath;
       
   161 
       
   162         } // fixupXPath(String):String
       
   163 
       
   164         private static String fixupXPath2(String xpath, int offset, final int end) {
       
   165 
       
   166             StringBuffer buffer = new StringBuffer(end + 2);
       
   167             for (int i = 0; i < offset; ++i) {
       
   168                 buffer.append(xpath.charAt(i));
       
   169             }
       
   170             buffer.append("./");
       
   171 
       
   172             boolean whitespace = false;
       
   173             char c;
       
   174 
       
   175             for (; offset < end; ++offset) {
       
   176                 c = xpath.charAt(offset);
       
   177                 if (whitespace) {
       
   178                     if (!XMLChar.isSpace(c)) {
       
   179                         if (c == '.' || c == '/') {
       
   180                             whitespace = false;
       
   181                         }
       
   182                         else if (c != '|') {
       
   183                             buffer.append("./");
       
   184                             whitespace = false;
       
   185                         }
       
   186                     }
       
   187                 }
       
   188                 else if (c == '|') {
       
   189                     whitespace = true;
       
   190                 }
       
   191                 buffer.append(c);
       
   192             }
       
   193             return buffer.toString();
       
   194 
       
   195         } // fixupXPath2(String, int, int):String
       
   196 
   136     } // class XPath
   197     } // class XPath
   137 
   198 
   138     /**
   199     /**
   139      * Field matcher.
   200      * Field matcher.
   140      *
   201      *
   145 
   206 
   146         //
   207         //
   147         // Data
   208         // Data
   148         //
   209         //
   149 
   210 
   150         /** Field activator. */
       
   151         protected FieldActivator fFieldActivator;
       
   152 
       
   153         /** Value store for data values. */
   211         /** Value store for data values. */
   154         protected ValueStore fStore;
   212         protected final ValueStore fStore;
       
   213 
       
   214         /** A flag indicating whether the field is allowed to match a value. */
       
   215         protected boolean fMayMatch = true;
   155 
   216 
   156         //
   217         //
   157         // Constructors
   218         // Constructors
   158         //
   219         //
   159 
   220 
   160         /** Constructs a field matcher. */
   221         /** Constructs a field matcher. */
   161         public Matcher(Field.XPath xpath, FieldActivator activator, ValueStore store) {
   222         public Matcher(Field.XPath xpath, ValueStore store) {
   162             super(xpath);
   223             super(xpath);
   163             fFieldActivator = activator;
       
   164             fStore = store;
   224             fStore = store;
   165         } // <init>(Field.XPath,ValueStore)
   225         } // <init>(Field.XPath,ValueStore)
   166 
   226 
   167         //
   227         //
   168         // XPathHandler methods
   228         // XPathHandler methods
   177             if(isNil && (fIdentityConstraint.getCategory() == IdentityConstraint.IC_KEY)) {
   237             if(isNil && (fIdentityConstraint.getCategory() == IdentityConstraint.IC_KEY)) {
   178                 String code = "KeyMatchesNillable";
   238                 String code = "KeyMatchesNillable";
   179                 fStore.reportError(code,
   239                 fStore.reportError(code,
   180                     new Object[]{fIdentityConstraint.getElementName(), fIdentityConstraint.getIdentityConstraintName()});
   240                     new Object[]{fIdentityConstraint.getElementName(), fIdentityConstraint.getIdentityConstraintName()});
   181             }
   241             }
   182             fStore.addValue(Field.this, actualValue, convertToPrimitiveKind(valueType), convertToPrimitiveKind(itemValueType));
   242             fStore.addValue(Field.this, fMayMatch, actualValue, convertToPrimitiveKind(valueType), convertToPrimitiveKind(itemValueType));
   183             // once we've stored the value for this field, we set the mayMatch
   243             // once we've stored the value for this field, we set the mayMatch
   184             // member to false so that, in the same scope, we don't match any more
   244             // member to false so that in the same scope, we don't match any more
   185             // values (and throw an error instead).
   245             // values (and throw an error instead).
   186             fFieldActivator.setMayMatch(Field.this, Boolean.FALSE);
   246             fMayMatch = false;
   187         } // matched(String)
   247         } // matched(String)
   188 
   248 
   189         private short convertToPrimitiveKind(short valueType) {
   249         private short convertToPrimitiveKind(short valueType) {
   190             /** Primitive datatypes. */
   250             /** Primitive datatypes. */
   191             if (valueType <= XSConstants.NOTATION_DT) {
   251             if (valueType <= XSConstants.NOTATION_DT) {