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; |
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) { |