author | joehw |
Wed, 18 Oct 2017 13:25:49 -0700 | |
changeset 47359 | e1a6c0168741 |
parent 47216 | 71c04702a3d5 |
child 48409 | 5ab69533994b |
permissions | -rw-r--r-- |
12005 | 1 |
/* |
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
2 |
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. |
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
3 |
* @LastModified: Oct 2017 |
12005 | 4 |
*/ |
5 |
/* |
|
33349 | 6 |
* Licensed to the Apache Software Foundation (ASF) under one or more |
7 |
* contributor license agreements. See the NOTICE file distributed with |
|
8 |
* this work for additional information regarding copyright ownership. |
|
9 |
* The ASF licenses this file to You under the Apache License, Version 2.0 |
|
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 |
|
12005 | 12 |
* |
33349 | 13 |
* http://www.apache.org/licenses/LICENSE-2.0 |
12005 | 14 |
* |
33349 | 15 |
* Unless required by applicable law or agreed to in writing, software |
16 |
* distributed under the License is distributed on an "AS IS" BASIS, |
|
17 |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
18 |
* See the License for the specific language governing permissions and |
|
19 |
* limitations under the License. |
|
12005 | 20 |
*/ |
21 |
||
22 |
package com.sun.org.apache.xerces.internal.impl.dtd; |
|
23 |
||
24 |
import com.sun.org.apache.xerces.internal.impl.dtd.models.CMAny; |
|
25 |
import com.sun.org.apache.xerces.internal.impl.dtd.models.CMBinOp; |
|
26 |
import com.sun.org.apache.xerces.internal.impl.dtd.models.CMLeaf; |
|
27 |
import com.sun.org.apache.xerces.internal.impl.dtd.models.CMNode; |
|
28 |
import com.sun.org.apache.xerces.internal.impl.dtd.models.CMUniOp; |
|
29 |
import com.sun.org.apache.xerces.internal.impl.dtd.models.ContentModelValidator; |
|
30 |
import com.sun.org.apache.xerces.internal.impl.dtd.models.DFAContentModel; |
|
31 |
import com.sun.org.apache.xerces.internal.impl.dtd.models.MixedContentModel; |
|
32 |
import com.sun.org.apache.xerces.internal.impl.dtd.models.SimpleContentModel; |
|
33 |
import com.sun.org.apache.xerces.internal.impl.dv.DatatypeValidator; |
|
34 |
import com.sun.org.apache.xerces.internal.impl.validation.EntityState; |
|
35 |
import com.sun.org.apache.xerces.internal.util.SymbolTable; |
|
36 |
import com.sun.org.apache.xerces.internal.xni.Augmentations; |
|
37 |
import com.sun.org.apache.xerces.internal.xni.QName; |
|
38 |
import com.sun.org.apache.xerces.internal.xni.XMLDTDContentModelHandler; |
|
39 |
import com.sun.org.apache.xerces.internal.xni.XMLDTDHandler; |
|
40 |
import com.sun.org.apache.xerces.internal.xni.XMLLocator; |
|
41 |
import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier; |
|
42 |
import com.sun.org.apache.xerces.internal.xni.XMLString; |
|
43 |
import com.sun.org.apache.xerces.internal.xni.XNIException; |
|
44 |
import com.sun.org.apache.xerces.internal.xni.grammars.Grammar; |
|
45 |
import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription; |
|
46 |
import com.sun.org.apache.xerces.internal.xni.parser.XMLDTDContentModelSource; |
|
47 |
import com.sun.org.apache.xerces.internal.xni.parser.XMLDTDSource; |
|
33349 | 48 |
import java.util.ArrayList; |
49 |
import java.util.HashMap; |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
50 |
import java.util.List; |
33349 | 51 |
import java.util.Map; |
52 |
import java.util.Random; |
|
12005 | 53 |
|
54 |
/** |
|
55 |
* A DTD grammar. This class implements the XNI handler interfaces |
|
33349 | 56 |
* for DTD information so that it can build the appropriate validation |
12005 | 57 |
* structures automatically from the callbacks. |
58 |
* |
|
59 |
* @xerces.internal |
|
60 |
* |
|
61 |
* @author Eric Ye, IBM |
|
62 |
* @author Jeffrey Rodriguez, IBM |
|
63 |
* @author Andy Clark, IBM |
|
64 |
* @author Neil Graham, IBM |
|
65 |
* |
|
66 |
*/ |
|
67 |
public class DTDGrammar |
|
68 |
implements XMLDTDHandler, XMLDTDContentModelHandler, EntityState, Grammar { |
|
69 |
||
70 |
// |
|
71 |
// Constants |
|
72 |
// |
|
73 |
||
74 |
/** Top level scope (-1). */ |
|
75 |
public static final int TOP_LEVEL_SCOPE = -1; |
|
76 |
||
77 |
// private |
|
78 |
||
79 |
/** Chunk shift (8). */ |
|
80 |
private static final int CHUNK_SHIFT = 8; // 2^8 = 256 |
|
81 |
||
82 |
/** Chunk size (1 << CHUNK_SHIFT). */ |
|
83 |
private static final int CHUNK_SIZE = (1 << CHUNK_SHIFT); |
|
84 |
||
85 |
/** Chunk mask (CHUNK_SIZE - 1). */ |
|
86 |
private static final int CHUNK_MASK = CHUNK_SIZE - 1; |
|
87 |
||
88 |
/** Initial chunk count (1 << (10 - CHUNK_SHIFT)). */ |
|
89 |
private static final int INITIAL_CHUNK_COUNT = (1 << (10 - CHUNK_SHIFT)); // 2^10 = 1k |
|
90 |
||
91 |
/** List flag (0x80). */ |
|
92 |
private static final short LIST_FLAG = 0x80; |
|
93 |
||
94 |
/** List mask (~LIST_FLAG). */ |
|
95 |
private static final short LIST_MASK = ~LIST_FLAG; |
|
96 |
||
97 |
// debugging |
|
98 |
||
99 |
/** Debug DTDGrammar. */ |
|
100 |
private static final boolean DEBUG = false; |
|
101 |
||
102 |
// |
|
103 |
// Data |
|
104 |
// |
|
105 |
||
106 |
protected XMLDTDSource fDTDSource = null; |
|
107 |
protected XMLDTDContentModelSource fDTDContentModelSource = null; |
|
108 |
||
109 |
/** Current element index. */ |
|
110 |
protected int fCurrentElementIndex; |
|
111 |
||
112 |
/** Current attribute index. */ |
|
113 |
protected int fCurrentAttributeIndex; |
|
114 |
||
115 |
/** fReadingExternalDTD */ |
|
116 |
protected boolean fReadingExternalDTD = false; |
|
117 |
||
118 |
/** Symbol table. */ |
|
119 |
private SymbolTable fSymbolTable; |
|
120 |
||
121 |
// The XMLDTDDescription with which this Grammar is associated |
|
122 |
protected XMLDTDDescription fGrammarDescription = null; |
|
123 |
||
124 |
// element declarations |
|
125 |
||
126 |
/** Number of element declarations. */ |
|
127 |
private int fElementDeclCount = 0; |
|
128 |
||
129 |
/** Element declaration name. */ |
|
130 |
private QName fElementDeclName[][] = new QName[INITIAL_CHUNK_COUNT][]; |
|
131 |
||
132 |
/** |
|
133 |
* Element declaration type. |
|
134 |
* @see XMLElementDecl |
|
135 |
*/ |
|
136 |
private short fElementDeclType[][] = new short[INITIAL_CHUNK_COUNT][]; |
|
137 |
||
138 |
/** |
|
139 |
* Element declaration content spec index. This index value is used |
|
140 |
* to refer to the content spec information tables. |
|
141 |
*/ |
|
142 |
private int fElementDeclContentSpecIndex[][] = new int[INITIAL_CHUNK_COUNT][]; |
|
143 |
||
144 |
/** |
|
145 |
* Element declaration content model validator. This validator is |
|
146 |
* constructed from the content spec nodes. |
|
147 |
*/ |
|
148 |
private ContentModelValidator fElementDeclContentModelValidator[][] = new ContentModelValidator[INITIAL_CHUNK_COUNT][]; |
|
149 |
||
150 |
/** First attribute declaration of an element declaration. */ |
|
151 |
private int fElementDeclFirstAttributeDeclIndex[][] = new int[INITIAL_CHUNK_COUNT][]; |
|
152 |
||
153 |
/** Last attribute declaration of an element declaration. */ |
|
154 |
private int fElementDeclLastAttributeDeclIndex[][] = new int[INITIAL_CHUNK_COUNT][]; |
|
155 |
||
156 |
// attribute declarations |
|
157 |
||
158 |
/** Number of attribute declarations. */ |
|
159 |
private int fAttributeDeclCount = 0 ; |
|
160 |
||
161 |
/** Attribute declaration name. */ |
|
162 |
private QName fAttributeDeclName[][] = new QName[INITIAL_CHUNK_COUNT][]; |
|
163 |
||
164 |
// is this grammar immutable? (fully constructed and not changeable) |
|
165 |
private boolean fIsImmutable = false; |
|
166 |
||
167 |
/** |
|
168 |
* Attribute declaration type. |
|
169 |
* @see XMLAttributeDecl |
|
170 |
*/ |
|
171 |
private short fAttributeDeclType[][] = new short[INITIAL_CHUNK_COUNT][]; |
|
172 |
||
173 |
/** Attribute declaration enumeration values. */ |
|
174 |
private String[] fAttributeDeclEnumeration[][] = new String[INITIAL_CHUNK_COUNT][][]; |
|
175 |
private short fAttributeDeclDefaultType[][] = new short[INITIAL_CHUNK_COUNT][]; |
|
176 |
private DatatypeValidator fAttributeDeclDatatypeValidator[][] = new DatatypeValidator[INITIAL_CHUNK_COUNT][]; |
|
177 |
private String fAttributeDeclDefaultValue[][] = new String[INITIAL_CHUNK_COUNT][]; |
|
178 |
private String fAttributeDeclNonNormalizedDefaultValue[][] = new String[INITIAL_CHUNK_COUNT][]; |
|
179 |
private int fAttributeDeclNextAttributeDeclIndex[][] = new int[INITIAL_CHUNK_COUNT][]; |
|
180 |
||
181 |
// content specs |
|
182 |
||
183 |
// here saves the content spec binary trees for element decls, |
|
184 |
// each element with a content model will hold a pointer which is |
|
185 |
// the index of the head node of the content spec tree. |
|
186 |
||
187 |
private int fContentSpecCount = 0; |
|
188 |
private short fContentSpecType[][] = new short[INITIAL_CHUNK_COUNT][]; |
|
189 |
private Object fContentSpecValue[][] = new Object[INITIAL_CHUNK_COUNT][]; |
|
190 |
private Object fContentSpecOtherValue[][] = new Object[INITIAL_CHUNK_COUNT][]; |
|
191 |
||
192 |
// entities |
|
193 |
||
194 |
private int fEntityCount = 0; |
|
195 |
private String fEntityName[][] = new String[INITIAL_CHUNK_COUNT][]; |
|
196 |
private String[][] fEntityValue = new String[INITIAL_CHUNK_COUNT][]; |
|
197 |
private String[][] fEntityPublicId = new String[INITIAL_CHUNK_COUNT][]; |
|
198 |
private String[][] fEntitySystemId = new String[INITIAL_CHUNK_COUNT][]; |
|
199 |
private String[][] fEntityBaseSystemId = new String[INITIAL_CHUNK_COUNT][]; |
|
200 |
private String[][] fEntityNotation = new String[INITIAL_CHUNK_COUNT][]; |
|
201 |
private byte[][] fEntityIsPE = new byte[INITIAL_CHUNK_COUNT][]; |
|
202 |
private byte[][] fEntityInExternal = new byte[INITIAL_CHUNK_COUNT][]; |
|
203 |
||
204 |
// notations |
|
205 |
||
206 |
private int fNotationCount = 0; |
|
207 |
private String fNotationName[][] = new String[INITIAL_CHUNK_COUNT][]; |
|
208 |
private String[][] fNotationPublicId = new String[INITIAL_CHUNK_COUNT][]; |
|
209 |
private String[][] fNotationSystemId = new String[INITIAL_CHUNK_COUNT][]; |
|
210 |
private String[][] fNotationBaseSystemId = new String[INITIAL_CHUNK_COUNT][]; |
|
211 |
||
212 |
// other information |
|
213 |
||
214 |
/** Element index mapping table. */ |
|
33349 | 215 |
private final Map<String, Integer> fElementIndexMap = new HashMap<>(); |
12005 | 216 |
|
217 |
/** Entity index mapping table. */ |
|
33349 | 218 |
private final Map<String, Integer> fEntityIndexMap = new HashMap<>(); |
12005 | 219 |
|
220 |
/** Notation index mapping table. */ |
|
33349 | 221 |
private final Map<String, Integer> fNotationIndexMap = new HashMap<>(); |
12005 | 222 |
|
223 |
// temp variables |
|
224 |
||
225 |
/** Mixed. */ |
|
226 |
private boolean fMixed; |
|
227 |
||
228 |
/** Temporary qualified name. */ |
|
229 |
private final QName fQName = new QName(); |
|
230 |
||
231 |
/** Temporary qualified name. */ |
|
232 |
private final QName fQName2 = new QName(); |
|
233 |
||
234 |
/** Temporary Attribute decl. */ |
|
235 |
protected final XMLAttributeDecl fAttributeDecl = new XMLAttributeDecl(); |
|
236 |
||
237 |
// for buildSyntaxTree method |
|
238 |
||
239 |
private int fLeafCount = 0; |
|
240 |
private int fEpsilonIndex = -1; |
|
241 |
||
242 |
/** Element declaration. */ |
|
243 |
private XMLElementDecl fElementDecl = new XMLElementDecl(); |
|
244 |
||
245 |
/** Entity declaration. */ |
|
246 |
private XMLEntityDecl fEntityDecl = new XMLEntityDecl(); |
|
247 |
||
248 |
/** Simple type. */ |
|
249 |
private XMLSimpleType fSimpleType = new XMLSimpleType(); |
|
250 |
||
251 |
/** Content spec node. */ |
|
252 |
private XMLContentSpec fContentSpec = new XMLContentSpec(); |
|
253 |
||
254 |
/** table of XMLElementDecl */ |
|
33349 | 255 |
Map<String, XMLElementDecl> fElementDeclTab = new HashMap<>(); |
12005 | 256 |
|
257 |
/** Children content model operation stack. */ |
|
258 |
private short[] fOpStack = null; |
|
259 |
||
260 |
/** Children content model index stack. */ |
|
261 |
private int[] fNodeIndexStack = null; |
|
262 |
||
263 |
/** Children content model previous node index stack. */ |
|
264 |
private int[] fPrevNodeIndexStack = null; |
|
265 |
||
266 |
/** Stack depth */ |
|
267 |
private int fDepth = 0; |
|
268 |
||
269 |
/** Entity stack. */ |
|
270 |
private boolean[] fPEntityStack = new boolean[4]; |
|
271 |
private int fPEDepth = 0; |
|
272 |
||
273 |
// additional fields(columns) for the element Decl pool in the Grammar |
|
274 |
||
275 |
/** flag if the elementDecl is External. */ |
|
276 |
private int fElementDeclIsExternal[][] = new int[INITIAL_CHUNK_COUNT][]; |
|
277 |
||
278 |
||
279 |
// additional fields(columns) for the attribute Decl pool in the Grammar |
|
280 |
||
281 |
/** flag if the AttributeDecl is External. */ |
|
282 |
private int fAttributeDeclIsExternal[][] = new int[INITIAL_CHUNK_COUNT][]; |
|
283 |
||
284 |
// for mixedElement method |
|
285 |
||
286 |
int valueIndex = -1; |
|
287 |
int prevNodeIndex = -1; |
|
288 |
int nodeIndex = -1; |
|
289 |
||
290 |
// |
|
291 |
// Constructors |
|
292 |
// |
|
293 |
||
294 |
/** Default constructor. */ |
|
295 |
public DTDGrammar(SymbolTable symbolTable, XMLDTDDescription desc) { |
|
296 |
fSymbolTable = symbolTable; |
|
297 |
fGrammarDescription = desc; |
|
298 |
} // <init>(SymbolTable) |
|
299 |
||
300 |
// Grammar methods |
|
301 |
||
302 |
// return the XMLDTDDescription object with which this is associated |
|
303 |
public XMLGrammarDescription getGrammarDescription() { |
|
304 |
return fGrammarDescription; |
|
305 |
} // getGrammarDescription(): XMLGrammarDescription |
|
306 |
||
307 |
// |
|
308 |
// Public methods |
|
309 |
// |
|
310 |
||
311 |
/** |
|
312 |
* Returns true if the specified element declaration is external. |
|
313 |
* |
|
314 |
* @param elementDeclIndex The element declaration index. |
|
315 |
*/ |
|
316 |
public boolean getElementDeclIsExternal(int elementDeclIndex) { |
|
317 |
||
318 |
if (elementDeclIndex < 0) { |
|
319 |
return false; |
|
320 |
} |
|
321 |
||
322 |
int chunk = elementDeclIndex >> CHUNK_SHIFT; |
|
323 |
int index = elementDeclIndex & CHUNK_MASK; |
|
324 |
return (fElementDeclIsExternal[chunk][index] != 0); |
|
325 |
||
326 |
} // getElementDeclIsExternal(int):boolean |
|
327 |
||
328 |
/** |
|
329 |
* Returns true if the specified attribute declaration is external. |
|
330 |
* |
|
331 |
* @param attributeDeclIndex Attribute declaration index. |
|
332 |
*/ |
|
333 |
public boolean getAttributeDeclIsExternal(int attributeDeclIndex) { |
|
334 |
||
335 |
if (attributeDeclIndex < 0) { |
|
336 |
return false; |
|
337 |
} |
|
338 |
||
339 |
int chunk = attributeDeclIndex >> CHUNK_SHIFT; |
|
340 |
int index = attributeDeclIndex & CHUNK_MASK; |
|
341 |
return (fAttributeDeclIsExternal[chunk][index] != 0); |
|
342 |
} |
|
343 |
||
344 |
public int getAttributeDeclIndex(int elementDeclIndex, String attributeDeclName) { |
|
345 |
if (elementDeclIndex == -1) { |
|
346 |
return -1; |
|
347 |
} |
|
348 |
int attDefIndex = getFirstAttributeDeclIndex(elementDeclIndex); |
|
349 |
while (attDefIndex != -1) { |
|
350 |
getAttributeDecl(attDefIndex, fAttributeDecl); |
|
351 |
||
352 |
if (fAttributeDecl.name.rawname == attributeDeclName |
|
353 |
|| attributeDeclName.equals(fAttributeDecl.name.rawname) ) { |
|
354 |
return attDefIndex; |
|
355 |
} |
|
356 |
attDefIndex = getNextAttributeDeclIndex(attDefIndex); |
|
357 |
} |
|
358 |
return -1; |
|
359 |
} // getAttributeDeclIndex (int,QName) |
|
360 |
||
361 |
// |
|
362 |
// XMLDTDHandler methods |
|
363 |
// |
|
364 |
||
365 |
/** |
|
366 |
* The start of the DTD. |
|
367 |
* |
|
368 |
* @param locator The document locator, or null if the document |
|
369 |
* location cannot be reported during the parsing of |
|
370 |
* the document DTD. However, it is <em>strongly</em> |
|
371 |
* recommended that a locator be supplied that can |
|
372 |
* at least report the base system identifier of the |
|
373 |
* DTD. |
|
374 |
* |
|
375 |
* @param augs Additional information that may include infoset |
|
376 |
* augmentations. |
|
377 |
* @throws XNIException Thrown by handler to signal an error. |
|
378 |
*/ |
|
379 |
public void startDTD(XMLLocator locator, Augmentations augs) throws XNIException { |
|
380 |
//Initialize stack |
|
381 |
fOpStack = null; |
|
382 |
fNodeIndexStack = null; |
|
383 |
fPrevNodeIndexStack = null; |
|
384 |
} // startDTD(XMLLocator) |
|
385 |
||
386 |
/** |
|
387 |
* This method notifies of the start of an entity. The DTD has the |
|
388 |
* pseudo-name of "[dtd]" and parameter entity names start with '%'. |
|
389 |
* <p> |
|
390 |
* <strong>Note:</strong> Since the DTD is an entity, the handler |
|
391 |
* will be notified of the start of the DTD entity by calling the |
|
392 |
* startParameterEntity method with the entity name "[dtd]" <em>before</em> calling |
|
393 |
* the startDTD method. |
|
394 |
* |
|
395 |
* @param name The name of the parameter entity. |
|
396 |
* @param identifier The resource identifier. |
|
397 |
* @param encoding The auto-detected IANA encoding name of the entity |
|
398 |
* stream. This value will be null in those situations |
|
399 |
* where the entity encoding is not auto-detected (e.g. |
|
400 |
* internal parameter entities). |
|
401 |
* @param augs Additional information that may include infoset |
|
402 |
* augmentations. |
|
403 |
* |
|
404 |
* @throws XNIException Thrown by handler to signal an error. |
|
405 |
*/ |
|
406 |
public void startParameterEntity(String name, |
|
407 |
XMLResourceIdentifier identifier, |
|
408 |
String encoding, |
|
409 |
Augmentations augs) throws XNIException { |
|
410 |
||
411 |
// keep track of this entity before fEntityDepth is increased |
|
412 |
if (fPEDepth == fPEntityStack.length) { |
|
413 |
boolean[] entityarray = new boolean[fPEntityStack.length * 2]; |
|
414 |
System.arraycopy(fPEntityStack, 0, entityarray, 0, fPEntityStack.length); |
|
415 |
fPEntityStack = entityarray; |
|
416 |
} |
|
417 |
fPEntityStack[fPEDepth] = fReadingExternalDTD; |
|
418 |
fPEDepth++; |
|
419 |
||
420 |
} // startParameterEntity(String,XMLResourceIdentifier,String,Augmentations) |
|
421 |
||
422 |
/** |
|
423 |
* The start of the DTD external subset. |
|
424 |
* |
|
425 |
* @param augs Additional information that may include infoset |
|
426 |
* augmentations. |
|
427 |
* |
|
428 |
* @throws XNIException Thrown by handler to signal an error. |
|
429 |
*/ |
|
430 |
public void startExternalSubset(XMLResourceIdentifier identifier, |
|
431 |
Augmentations augs) throws XNIException { |
|
432 |
fReadingExternalDTD = true; |
|
433 |
} // startExternalSubset(Augmentations) |
|
434 |
||
435 |
/** |
|
436 |
* This method notifies the end of an entity. The DTD has the pseudo-name |
|
437 |
* of "[dtd]" and parameter entity names start with '%'. |
|
438 |
* <p> |
|
439 |
* <strong>Note:</strong> Since the DTD is an entity, the handler |
|
440 |
* will be notified of the end of the DTD entity by calling the |
|
441 |
* endEntity method with the entity name "[dtd]" <em>after</em> calling |
|
442 |
* the endDTD method. |
|
443 |
* |
|
444 |
* @param name The name of the entity. |
|
445 |
* @param augs Additional information that may include infoset |
|
446 |
* augmentations. |
|
447 |
* @throws XNIException Thrown by handler to signal an error. |
|
448 |
*/ |
|
449 |
public void endParameterEntity(String name, Augmentations augs) throws XNIException { |
|
450 |
||
451 |
fPEDepth--; |
|
452 |
fReadingExternalDTD = fPEntityStack[fPEDepth]; |
|
453 |
||
454 |
} // endParameterEntity(String,Augmentations) |
|
455 |
||
456 |
/** |
|
457 |
* The end of the DTD external subset. |
|
458 |
* |
|
459 |
* @param augs Additional information that may include infoset |
|
460 |
* augmentations. |
|
461 |
* |
|
462 |
* @throws XNIException Thrown by handler to signal an error. |
|
463 |
*/ |
|
464 |
public void endExternalSubset(Augmentations augs) throws XNIException { |
|
465 |
fReadingExternalDTD = false; |
|
466 |
} // endExternalSubset(Augmentations) |
|
467 |
||
468 |
/** |
|
469 |
* An element declaration. |
|
470 |
* |
|
471 |
* @param name The name of the element. |
|
472 |
* @param contentModel The element content model. |
|
473 |
* @param augs Additional information that may include infoset |
|
474 |
* augmentations. |
|
475 |
* @throws XNIException Thrown by handler to signal an error. |
|
476 |
*/ |
|
477 |
public void elementDecl(String name, String contentModel, Augmentations augs) |
|
478 |
throws XNIException { |
|
479 |
||
33349 | 480 |
XMLElementDecl tmpElementDecl = fElementDeclTab.get(name) ; |
12005 | 481 |
|
482 |
// check if it is already defined |
|
483 |
if ( tmpElementDecl != null ) { |
|
484 |
if (tmpElementDecl.type == -1) { |
|
485 |
fCurrentElementIndex = getElementDeclIndex(name); |
|
486 |
} |
|
487 |
else { |
|
488 |
// duplicate element, ignored. |
|
489 |
return; |
|
490 |
} |
|
491 |
} |
|
492 |
else { |
|
493 |
fCurrentElementIndex = createElementDecl();//create element decl |
|
494 |
} |
|
495 |
||
496 |
XMLElementDecl elementDecl = new XMLElementDecl(); |
|
497 |
||
498 |
fQName.setValues(null, name, name, null); |
|
499 |
||
500 |
elementDecl.name.setValues(fQName); |
|
501 |
||
502 |
elementDecl.contentModelValidator = null; |
|
503 |
elementDecl.scope= -1; |
|
504 |
if (contentModel.equals("EMPTY")) { |
|
505 |
elementDecl.type = XMLElementDecl.TYPE_EMPTY; |
|
506 |
} |
|
507 |
else if (contentModel.equals("ANY")) { |
|
508 |
elementDecl.type = XMLElementDecl.TYPE_ANY; |
|
509 |
} |
|
510 |
else if (contentModel.startsWith("(") ) { |
|
511 |
if (contentModel.indexOf("#PCDATA") > 0 ) { |
|
512 |
elementDecl.type = XMLElementDecl.TYPE_MIXED; |
|
513 |
} |
|
514 |
else { |
|
515 |
elementDecl.type = XMLElementDecl.TYPE_CHILDREN; |
|
516 |
} |
|
517 |
} |
|
518 |
||
519 |
||
520 |
//add(or set) this elementDecl to the local cache |
|
521 |
this.fElementDeclTab.put(name, elementDecl ); |
|
522 |
||
523 |
fElementDecl = elementDecl; |
|
524 |
addContentSpecToElement(elementDecl); |
|
525 |
||
526 |
if ( DEBUG ) { |
|
527 |
System.out.println( "name = " + fElementDecl.name.localpart ); |
|
528 |
System.out.println( "Type = " + fElementDecl.type ); |
|
529 |
} |
|
530 |
||
531 |
setElementDecl(fCurrentElementIndex, fElementDecl );//set internal structure |
|
532 |
||
533 |
int chunk = fCurrentElementIndex >> CHUNK_SHIFT; |
|
534 |
int index = fCurrentElementIndex & CHUNK_MASK; |
|
535 |
ensureElementDeclCapacity(chunk); |
|
536 |
fElementDeclIsExternal[chunk][index] = (fReadingExternalDTD || fPEDepth > 0) ? 1 : 0; |
|
537 |
||
538 |
} // elementDecl(String,String) |
|
539 |
||
540 |
/** |
|
541 |
* An attribute declaration. |
|
542 |
* |
|
543 |
* @param elementName The name of the element that this attribute |
|
544 |
* is associated with. |
|
545 |
* @param attributeName The name of the attribute. |
|
546 |
* @param type The attribute type. This value will be one of |
|
547 |
* the following: "CDATA", "ENTITY", "ENTITIES", |
|
548 |
* "ENUMERATION", "ID", "IDREF", "IDREFS", |
|
549 |
* "NMTOKEN", "NMTOKENS", or "NOTATION". |
|
550 |
* @param enumeration If the type has the value "ENUMERATION", this |
|
551 |
* array holds the allowed attribute values; |
|
552 |
* otherwise, this array is null. |
|
553 |
* @param defaultType The attribute default type. This value will be |
|
554 |
* one of the following: "#FIXED", "#IMPLIED", |
|
555 |
* "#REQUIRED", or null. |
|
556 |
* @param defaultValue The attribute default value, or null if no |
|
557 |
* default value is specified. |
|
558 |
* @param nonNormalizedDefaultValue The attribute default value with no normalization |
|
559 |
* performed, or null if no default value is specified. |
|
560 |
* |
|
561 |
* @param augs Additional information that may include infoset |
|
562 |
* augmentations. |
|
563 |
* @throws XNIException Thrown by handler to signal an error. |
|
564 |
*/ |
|
565 |
public void attributeDecl(String elementName, String attributeName, |
|
566 |
String type, String[] enumeration, |
|
567 |
String defaultType, XMLString defaultValue, |
|
568 |
XMLString nonNormalizedDefaultValue, Augmentations augs) throws XNIException { |
|
569 |
||
33349 | 570 |
if ( this.fElementDeclTab.containsKey(elementName) ) { |
12005 | 571 |
//if ElementDecl has already being created in the Grammar then remove from table, |
572 |
//this.fElementDeclTab.remove( (String) elementName ); |
|
573 |
} |
|
574 |
// then it is forward reference to a element decl, create the elementDecl first. |
|
575 |
else { |
|
576 |
fCurrentElementIndex = createElementDecl();//create element decl |
|
577 |
||
578 |
XMLElementDecl elementDecl = new XMLElementDecl(); |
|
579 |
elementDecl.name.setValues(null, elementName, elementName, null); |
|
580 |
||
581 |
elementDecl.scope= -1; |
|
582 |
||
583 |
//add(or set) this elementDecl to the local cache |
|
584 |
this.fElementDeclTab.put(elementName, elementDecl ); |
|
585 |
||
586 |
//set internal structure |
|
587 |
setElementDecl(fCurrentElementIndex, elementDecl ); |
|
588 |
} |
|
589 |
||
590 |
//Get Grammar index to grammar array |
|
591 |
int elementIndex = getElementDeclIndex(elementName); |
|
592 |
||
593 |
//return, when more than one definition is provided for the same attribute of given element type |
|
594 |
//only the first declaration is binding and later declarations are ignored |
|
595 |
if (getAttributeDeclIndex(elementIndex, attributeName) != -1) { |
|
596 |
return; |
|
597 |
} |
|
598 |
||
599 |
fCurrentAttributeIndex = createAttributeDecl();// Create current Attribute Decl |
|
600 |
||
601 |
fSimpleType.clear(); |
|
602 |
if ( defaultType != null ) { |
|
603 |
if ( defaultType.equals( "#FIXED") ) { |
|
604 |
fSimpleType.defaultType = XMLSimpleType.DEFAULT_TYPE_FIXED; |
|
605 |
} else if ( defaultType.equals( "#IMPLIED") ) { |
|
606 |
fSimpleType.defaultType = XMLSimpleType.DEFAULT_TYPE_IMPLIED; |
|
607 |
} else if ( defaultType.equals( "#REQUIRED") ) { |
|
608 |
fSimpleType.defaultType = XMLSimpleType.DEFAULT_TYPE_REQUIRED; |
|
609 |
} |
|
610 |
} |
|
611 |
if ( DEBUG ) { |
|
612 |
System.out.println("defaultvalue = " + defaultValue.toString() ); |
|
613 |
} |
|
614 |
fSimpleType.defaultValue = defaultValue!=null ? defaultValue.toString() : null; |
|
615 |
fSimpleType.nonNormalizedDefaultValue = nonNormalizedDefaultValue!=null ? nonNormalizedDefaultValue.toString() : null; |
|
616 |
fSimpleType.enumeration = enumeration; |
|
617 |
||
618 |
if (type.equals("CDATA")) { |
|
619 |
fSimpleType.type = XMLSimpleType.TYPE_CDATA; |
|
620 |
} |
|
621 |
else if ( type.equals("ID") ) { |
|
622 |
fSimpleType.type = XMLSimpleType.TYPE_ID; |
|
623 |
} |
|
624 |
else if ( type.startsWith("IDREF") ) { |
|
625 |
fSimpleType.type = XMLSimpleType.TYPE_IDREF; |
|
626 |
if (type.indexOf("S") > 0) { |
|
627 |
fSimpleType.list = true; |
|
628 |
} |
|
629 |
} |
|
630 |
else if (type.equals("ENTITIES")) { |
|
631 |
fSimpleType.type = XMLSimpleType.TYPE_ENTITY; |
|
632 |
fSimpleType.list = true; |
|
633 |
} |
|
634 |
else if (type.equals("ENTITY")) { |
|
635 |
fSimpleType.type = XMLSimpleType.TYPE_ENTITY; |
|
636 |
} |
|
637 |
else if (type.equals("NMTOKENS")) { |
|
638 |
fSimpleType.type = XMLSimpleType.TYPE_NMTOKEN; |
|
639 |
fSimpleType.list = true; |
|
640 |
} |
|
641 |
else if (type.equals("NMTOKEN")) { |
|
642 |
fSimpleType.type = XMLSimpleType.TYPE_NMTOKEN; |
|
643 |
} |
|
644 |
else if (type.startsWith("NOTATION") ) { |
|
645 |
fSimpleType.type = XMLSimpleType.TYPE_NOTATION; |
|
646 |
} |
|
647 |
else if (type.startsWith("ENUMERATION") ) { |
|
648 |
fSimpleType.type = XMLSimpleType.TYPE_ENUMERATION; |
|
649 |
} |
|
650 |
else { |
|
651 |
// REVISIT: Report error message. -Ac |
|
652 |
System.err.println("!!! unknown attribute type "+type); |
|
653 |
} |
|
654 |
// REVISIT: The datatype should be stored with the attribute value |
|
655 |
// and not special-cased in the XMLValidator. -Ac |
|
656 |
//fSimpleType.datatypeValidator = fDatatypeValidatorFactory.createDatatypeValidator(type, null, facets, fSimpleType.list); |
|
657 |
||
658 |
fQName.setValues(null, attributeName, attributeName, null); |
|
659 |
fAttributeDecl.setValues( fQName, fSimpleType, false ); |
|
660 |
||
661 |
setAttributeDecl(elementIndex, fCurrentAttributeIndex, fAttributeDecl); |
|
662 |
||
663 |
int chunk = fCurrentAttributeIndex >> CHUNK_SHIFT; |
|
664 |
int index = fCurrentAttributeIndex & CHUNK_MASK; |
|
665 |
ensureAttributeDeclCapacity(chunk); |
|
666 |
fAttributeDeclIsExternal[chunk][index] = (fReadingExternalDTD || fPEDepth > 0) ? 1 : 0; |
|
667 |
||
668 |
} // attributeDecl(String,String,String,String[],String,XMLString,XMLString, Augmentations) |
|
669 |
||
670 |
/** |
|
671 |
* An internal entity declaration. |
|
672 |
* |
|
673 |
* @param name The name of the entity. Parameter entity names start with |
|
674 |
* '%', whereas the name of a general entity is just the |
|
675 |
* entity name. |
|
676 |
* @param text The value of the entity. |
|
677 |
* @param nonNormalizedText The non-normalized value of the entity. This |
|
678 |
* value contains the same sequence of characters that was in |
|
679 |
* the internal entity declaration, without any entity |
|
680 |
* references expanded. |
|
681 |
* @param augs Additional information that may include infoset |
|
682 |
* augmentations. |
|
683 |
* @throws XNIException Thrown by handler to signal an error. |
|
684 |
*/ |
|
685 |
public void internalEntityDecl(String name, XMLString text, |
|
686 |
XMLString nonNormalizedText, |
|
687 |
Augmentations augs) throws XNIException { |
|
688 |
||
689 |
int entityIndex = getEntityDeclIndex(name); |
|
690 |
if( entityIndex == -1){ |
|
691 |
entityIndex = createEntityDecl(); |
|
692 |
boolean isPE = name.startsWith("%"); |
|
693 |
boolean inExternal = (fReadingExternalDTD || fPEDepth > 0); |
|
694 |
XMLEntityDecl entityDecl = new XMLEntityDecl(); |
|
695 |
entityDecl.setValues(name,null,null, null, null, |
|
696 |
text.toString(), isPE, inExternal); |
|
697 |
||
698 |
setEntityDecl(entityIndex, entityDecl); |
|
699 |
} |
|
700 |
||
701 |
} // internalEntityDecl(String,XMLString,XMLString) |
|
702 |
||
703 |
/** |
|
704 |
* An external entity declaration. |
|
705 |
* |
|
706 |
* @param name The name of the entity. Parameter entity names start |
|
707 |
* with '%', whereas the name of a general entity is just |
|
708 |
* the entity name. |
|
709 |
* @param identifier An object containing all location information |
|
710 |
* pertinent to this external entity declaration. |
|
711 |
* @param augs Additional information that may include infoset |
|
712 |
* augmentations. |
|
713 |
* @throws XNIException Thrown by handler to signal an error. |
|
714 |
*/ |
|
715 |
public void externalEntityDecl(String name, |
|
716 |
XMLResourceIdentifier identifier, |
|
717 |
Augmentations augs) throws XNIException { |
|
718 |
||
719 |
int entityIndex = getEntityDeclIndex(name); |
|
720 |
if( entityIndex == -1){ |
|
721 |
entityIndex = createEntityDecl(); |
|
722 |
boolean isPE = name.startsWith("%"); |
|
723 |
boolean inExternal = (fReadingExternalDTD || fPEDepth > 0); |
|
724 |
||
725 |
XMLEntityDecl entityDecl = new XMLEntityDecl(); |
|
726 |
entityDecl.setValues(name, identifier.getPublicId(), identifier.getLiteralSystemId(), |
|
727 |
identifier.getBaseSystemId(), |
|
728 |
null, null, isPE, inExternal); |
|
729 |
||
730 |
setEntityDecl(entityIndex, entityDecl); |
|
731 |
} |
|
732 |
} // externalEntityDecl(String, XMLResourceIdentifier, Augmentations) |
|
733 |
||
734 |
/** |
|
735 |
* An unparsed entity declaration. |
|
736 |
* |
|
737 |
* @param name The name of the entity. |
|
738 |
* @param identifier An object containing all location information |
|
739 |
* pertinent to this entity. |
|
740 |
* @param notation The name of the notation. |
|
741 |
* @param augs Additional information that may include infoset |
|
742 |
* augmentations. |
|
743 |
* @throws XNIException Thrown by handler to signal an error. |
|
744 |
*/ |
|
745 |
public void unparsedEntityDecl(String name, XMLResourceIdentifier identifier, |
|
746 |
String notation, |
|
747 |
Augmentations augs) throws XNIException { |
|
748 |
||
749 |
XMLEntityDecl entityDecl = new XMLEntityDecl(); |
|
750 |
boolean isPE = name.startsWith("%"); |
|
751 |
boolean inExternal = (fReadingExternalDTD || fPEDepth > 0); |
|
752 |
||
753 |
entityDecl.setValues(name,identifier.getPublicId(),identifier.getLiteralSystemId(), |
|
754 |
identifier.getBaseSystemId(), notation, |
|
755 |
null, isPE, inExternal); |
|
756 |
int entityIndex = getEntityDeclIndex(name); |
|
757 |
if (entityIndex == -1) { |
|
758 |
entityIndex = createEntityDecl(); |
|
759 |
setEntityDecl(entityIndex, entityDecl); |
|
760 |
} |
|
761 |
||
762 |
} // unparsedEntityDecl(String,StringXMLResourceIdentifier,Augmentations) |
|
763 |
||
764 |
/** |
|
765 |
* A notation declaration |
|
766 |
* |
|
767 |
* @param name The name of the notation. |
|
768 |
* @param identifier An object containing all location information |
|
769 |
* pertinent to this notation. |
|
770 |
* @param augs Additional information that may include infoset |
|
771 |
* augmentations. |
|
772 |
* @throws XNIException Thrown by handler to signal an error. |
|
773 |
*/ |
|
774 |
public void notationDecl(String name, XMLResourceIdentifier identifier, |
|
775 |
Augmentations augs) throws XNIException { |
|
776 |
||
777 |
XMLNotationDecl notationDecl = new XMLNotationDecl(); |
|
778 |
notationDecl.setValues(name,identifier.getPublicId(),identifier.getLiteralSystemId(), |
|
779 |
identifier.getBaseSystemId()); |
|
780 |
int notationIndex = getNotationDeclIndex(name); |
|
781 |
if (notationIndex == -1) { |
|
782 |
notationIndex = createNotationDecl(); |
|
783 |
setNotationDecl(notationIndex, notationDecl); |
|
784 |
} |
|
785 |
||
786 |
} // notationDecl(String,XMLResourceIdentifier,Augmentations) |
|
787 |
||
788 |
/** |
|
789 |
* The end of the DTD. |
|
790 |
* |
|
791 |
* @param augs Additional information that may include infoset |
|
792 |
* augmentations. |
|
793 |
* @throws XNIException Thrown by handler to signal an error. |
|
794 |
*/ |
|
795 |
public void endDTD(Augmentations augs) throws XNIException { |
|
796 |
fIsImmutable = true; |
|
797 |
// make sure our description contains useful stuff... |
|
798 |
if (fGrammarDescription.getRootName() == null) { |
|
799 |
// we don't know what the root is; so use possibleRoots... |
|
800 |
int chunk, index = 0; |
|
801 |
String currName = null; |
|
802 |
final int size = fElementDeclCount; |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
803 |
List<String> elements = new ArrayList<>(size); |
12005 | 804 |
for (int i = 0; i < size; ++i) { |
805 |
chunk = i >> CHUNK_SHIFT; |
|
806 |
index = i & CHUNK_MASK; |
|
807 |
currName = fElementDeclName[chunk][index].rawname; |
|
808 |
elements.add(currName); |
|
809 |
} |
|
810 |
fGrammarDescription.setPossibleRoots(elements); |
|
811 |
} |
|
812 |
} // endDTD() |
|
813 |
||
814 |
// sets the source of this handler |
|
815 |
public void setDTDSource(XMLDTDSource source) { |
|
816 |
fDTDSource = source; |
|
817 |
} // setDTDSource(XMLDTDSource) |
|
818 |
||
819 |
// returns the source of this handler |
|
820 |
public XMLDTDSource getDTDSource() { |
|
821 |
return fDTDSource; |
|
822 |
} // getDTDSource(): XMLDTDSource |
|
823 |
||
824 |
// no-op methods |
|
825 |
||
826 |
/** |
|
827 |
* Notifies of the presence of a TextDecl line in an entity. If present, |
|
828 |
* this method will be called immediately following the startEntity call. |
|
829 |
* <p> |
|
830 |
* <strong>Note:</strong> This method is only called for external |
|
831 |
* parameter entities referenced in the DTD. |
|
832 |
* |
|
833 |
* @param version The XML version, or null if not specified. |
|
834 |
* @param encoding The IANA encoding name of the entity. |
|
835 |
* |
|
836 |
* @param augs Additional information that may include infoset |
|
837 |
* augmentations. |
|
838 |
* @throws XNIException Thrown by handler to signal an error. |
|
839 |
*/ |
|
840 |
public void textDecl(String version, String encoding, Augmentations augs) |
|
841 |
throws XNIException {} |
|
842 |
||
843 |
/** |
|
844 |
* A comment. |
|
845 |
* |
|
846 |
* @param text The text in the comment. |
|
847 |
* @param augs Additional information that may include infoset |
|
848 |
* augmentations. |
|
849 |
* @throws XNIException Thrown by application to signal an error. |
|
850 |
*/ |
|
851 |
public void comment(XMLString text, Augmentations augs) throws XNIException {} |
|
852 |
||
853 |
/** |
|
854 |
* A processing instruction. Processing instructions consist of a |
|
855 |
* target name and, optionally, text data. The data is only meaningful |
|
856 |
* to the application. |
|
857 |
* <p> |
|
858 |
* Typically, a processing instruction's data will contain a series |
|
859 |
* of pseudo-attributes. These pseudo-attributes follow the form of |
|
860 |
* element attributes but are <strong>not</strong> parsed or presented |
|
861 |
* to the application as anything other than text. The application is |
|
862 |
* responsible for parsing the data. |
|
863 |
* |
|
864 |
* @param target The target. |
|
865 |
* @param data The data or null if none specified. |
|
866 |
* @param augs Additional information that may include infoset |
|
867 |
* augmentations. |
|
868 |
* @throws XNIException Thrown by handler to signal an error. |
|
869 |
*/ |
|
870 |
public void processingInstruction(String target, XMLString data, |
|
871 |
Augmentations augs) throws XNIException {} |
|
872 |
||
873 |
/** |
|
874 |
* The start of an attribute list. |
|
875 |
* |
|
876 |
* @param elementName The name of the element that this attribute |
|
877 |
* list is associated with. |
|
878 |
* @param augs Additional information that may include infoset |
|
879 |
* augmentations. |
|
880 |
* @throws XNIException Thrown by handler to signal an error. |
|
881 |
*/ |
|
882 |
public void startAttlist(String elementName, Augmentations augs) |
|
883 |
throws XNIException {} |
|
884 |
||
885 |
/** |
|
886 |
* The end of an attribute list. |
|
887 |
* @param augs Additional information that may include infoset |
|
888 |
* augmentations. |
|
889 |
* @throws XNIException Thrown by handler to signal an error. |
|
890 |
*/ |
|
891 |
public void endAttlist(Augmentations augs) throws XNIException {} |
|
892 |
||
893 |
/** |
|
894 |
* The start of a conditional section. |
|
895 |
* |
|
896 |
* @param type The type of the conditional section. This value will |
|
897 |
* either be CONDITIONAL_INCLUDE or CONDITIONAL_IGNORE. |
|
898 |
* @param augs Additional information that may include infoset |
|
899 |
* augmentations. |
|
900 |
* @throws XNIException Thrown by handler to signal an error. |
|
901 |
* |
|
902 |
* @see XMLDTDHandler#CONDITIONAL_INCLUDE |
|
903 |
* @see XMLDTDHandler#CONDITIONAL_IGNORE |
|
904 |
*/ |
|
905 |
public void startConditional(short type, Augmentations augs) |
|
906 |
throws XNIException {} |
|
907 |
||
908 |
/** |
|
909 |
* Characters within an IGNORE conditional section. |
|
910 |
* |
|
911 |
* @param text The ignored text. |
|
912 |
* @param augs Additional information that may include infoset |
|
913 |
* augmentations. |
|
914 |
*/ |
|
915 |
public void ignoredCharacters(XMLString text, Augmentations augs) |
|
916 |
throws XNIException {} |
|
917 |
||
918 |
/** |
|
919 |
* The end of a conditional section. |
|
920 |
* @param augs Additional information that may include infoset |
|
921 |
* augmentations. |
|
922 |
* @throws XNIException Thrown by handler to signal an error. |
|
923 |
*/ |
|
924 |
public void endConditional(Augmentations augs) throws XNIException {} |
|
925 |
||
926 |
// |
|
927 |
// XMLDTDContentModelHandler methods |
|
928 |
// |
|
929 |
||
930 |
// set content model source |
|
931 |
public void setDTDContentModelSource(XMLDTDContentModelSource source) { |
|
932 |
fDTDContentModelSource = source; |
|
933 |
} |
|
934 |
||
935 |
// get content model source |
|
936 |
public XMLDTDContentModelSource getDTDContentModelSource() { |
|
937 |
return fDTDContentModelSource; |
|
938 |
} |
|
939 |
||
940 |
/** |
|
941 |
* The start of a content model. Depending on the type of the content |
|
942 |
* model, specific methods may be called between the call to the |
|
943 |
* startContentModel method and the call to the endContentModel method. |
|
944 |
* |
|
945 |
* @param elementName The name of the element. |
|
946 |
* @param augs Additional information that may include infoset |
|
947 |
* augmentations. |
|
948 |
* @throws XNIException Thrown by handler to signal an error. |
|
949 |
*/ |
|
950 |
public void startContentModel(String elementName, Augmentations augs) |
|
951 |
throws XNIException { |
|
952 |
||
33349 | 953 |
XMLElementDecl elementDecl = this.fElementDeclTab.get(elementName); |
12005 | 954 |
if ( elementDecl != null ) { |
955 |
fElementDecl = elementDecl; |
|
956 |
} |
|
957 |
fDepth = 0; |
|
958 |
initializeContentModelStack(); |
|
959 |
||
960 |
} // startContentModel(String) |
|
961 |
||
962 |
/** |
|
963 |
* A start of either a mixed or children content model. A mixed |
|
964 |
* content model will immediately be followed by a call to the |
|
965 |
* <code>pcdata()</code> method. A children content model will |
|
966 |
* contain additional groups and/or elements. |
|
967 |
* |
|
968 |
* @param augs Additional information that may include infoset |
|
969 |
* augmentations. |
|
970 |
* @throws XNIException Thrown by handler to signal an error. |
|
971 |
* |
|
972 |
* @see #any |
|
973 |
* @see #empty |
|
974 |
*/ |
|
975 |
public void startGroup(Augmentations augs) throws XNIException { |
|
976 |
fDepth++; |
|
977 |
initializeContentModelStack(); |
|
978 |
fMixed = false; |
|
979 |
} // startGroup() |
|
980 |
||
981 |
/** |
|
982 |
* The appearance of "#PCDATA" within a group signifying a |
|
983 |
* mixed content model. This method will be the first called |
|
984 |
* following the content model's <code>startGroup()</code>. |
|
985 |
* |
|
986 |
*@param augs Additional information that may include infoset |
|
987 |
* augmentations. |
|
988 |
* |
|
989 |
* @throws XNIException Thrown by handler to signal an error. |
|
990 |
* |
|
991 |
* @see #startGroup |
|
992 |
*/ |
|
993 |
public void pcdata(Augmentations augs) throws XNIException { |
|
994 |
fMixed = true; |
|
995 |
} // pcdata() |
|
996 |
||
997 |
/** |
|
998 |
* A referenced element in a mixed or children content model. |
|
999 |
* |
|
1000 |
* @param elementName The name of the referenced element. |
|
1001 |
* @param augs Additional information that may include infoset |
|
1002 |
* augmentations. |
|
1003 |
* |
|
1004 |
* @throws XNIException Thrown by handler to signal an error. |
|
1005 |
*/ |
|
1006 |
public void element(String elementName, Augmentations augs) throws XNIException { |
|
1007 |
if (fMixed) { |
|
1008 |
if (fNodeIndexStack[fDepth] == -1 ) { |
|
1009 |
fNodeIndexStack[fDepth] = addUniqueLeafNode(elementName); |
|
1010 |
} |
|
1011 |
else { |
|
1012 |
fNodeIndexStack[fDepth] = addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_CHOICE, |
|
1013 |
fNodeIndexStack[fDepth], |
|
1014 |
addUniqueLeafNode(elementName)); |
|
1015 |
} |
|
1016 |
} |
|
1017 |
else { |
|
1018 |
fNodeIndexStack[fDepth] = addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_LEAF, elementName); |
|
1019 |
} |
|
1020 |
} // element(String) |
|
1021 |
||
1022 |
/** |
|
1023 |
* The separator between choices or sequences of a mixed or children |
|
1024 |
* content model. |
|
1025 |
* |
|
1026 |
* @param separator The type of children separator. |
|
1027 |
* @param augs Additional information that may include infoset |
|
1028 |
* augmentations. |
|
1029 |
* @throws XNIException Thrown by handler to signal an error. |
|
1030 |
* |
|
1031 |
* @see org.apache.xerces.xni.XMLDTDContentModelHandler#SEPARATOR_CHOICE |
|
1032 |
* @see org.apache.xerces.xni.XMLDTDContentModelHandler#SEPARATOR_SEQUENCE |
|
1033 |
*/ |
|
1034 |
public void separator(short separator, Augmentations augs) throws XNIException { |
|
1035 |
||
1036 |
if (!fMixed) { |
|
1037 |
if (fOpStack[fDepth] != XMLContentSpec.CONTENTSPECNODE_SEQ && separator == XMLDTDContentModelHandler.SEPARATOR_CHOICE ) { |
|
1038 |
if (fPrevNodeIndexStack[fDepth] != -1) { |
|
1039 |
fNodeIndexStack[fDepth] = addContentSpecNode(fOpStack[fDepth], fPrevNodeIndexStack[fDepth], fNodeIndexStack[fDepth]); |
|
1040 |
} |
|
1041 |
fPrevNodeIndexStack[fDepth] = fNodeIndexStack[fDepth]; |
|
1042 |
fOpStack[fDepth] = XMLContentSpec.CONTENTSPECNODE_CHOICE; |
|
1043 |
} else if (fOpStack[fDepth] != XMLContentSpec.CONTENTSPECNODE_CHOICE && separator == XMLDTDContentModelHandler.SEPARATOR_SEQUENCE) { |
|
1044 |
if (fPrevNodeIndexStack[fDepth] != -1) { |
|
1045 |
fNodeIndexStack[fDepth] = addContentSpecNode(fOpStack[fDepth], fPrevNodeIndexStack[fDepth], fNodeIndexStack[fDepth]); |
|
1046 |
} |
|
1047 |
fPrevNodeIndexStack[fDepth] = fNodeIndexStack[fDepth]; |
|
1048 |
fOpStack[fDepth] = XMLContentSpec.CONTENTSPECNODE_SEQ; |
|
1049 |
} |
|
1050 |
} |
|
1051 |
||
1052 |
} // separator(short) |
|
1053 |
||
1054 |
/** |
|
1055 |
* The occurrence count for a child in a children content model or |
|
1056 |
* for the mixed content model group. |
|
1057 |
* |
|
1058 |
* @param occurrence The occurrence count for the last element |
|
1059 |
* or group. |
|
1060 |
* @param augs Additional information that may include infoset |
|
1061 |
* augmentations. |
|
1062 |
* @throws XNIException Thrown by handler to signal an error. |
|
1063 |
* |
|
1064 |
* @see org.apache.xerces.xni.XMLDTDContentModelHandler#OCCURS_ZERO_OR_ONE |
|
1065 |
* @see org.apache.xerces.xni.XMLDTDContentModelHandler#OCCURS_ZERO_OR_MORE |
|
1066 |
* @see org.apache.xerces.xni.XMLDTDContentModelHandler#OCCURS_ONE_OR_MORE |
|
1067 |
*/ |
|
1068 |
public void occurrence(short occurrence, Augmentations augs) throws XNIException { |
|
1069 |
||
1070 |
if (!fMixed) { |
|
1071 |
if (occurrence == XMLDTDContentModelHandler.OCCURS_ZERO_OR_ONE ) { |
|
1072 |
fNodeIndexStack[fDepth] = addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE, fNodeIndexStack[fDepth], -1); |
|
1073 |
} else if ( occurrence == XMLDTDContentModelHandler.OCCURS_ZERO_OR_MORE ) { |
|
1074 |
fNodeIndexStack[fDepth] = addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE, fNodeIndexStack[fDepth], -1 ); |
|
1075 |
} else if ( occurrence == XMLDTDContentModelHandler.OCCURS_ONE_OR_MORE) { |
|
1076 |
fNodeIndexStack[fDepth] = addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE, fNodeIndexStack[fDepth], -1 ); |
|
1077 |
} |
|
1078 |
} |
|
1079 |
||
1080 |
} // occurrence(short) |
|
1081 |
||
1082 |
/** |
|
1083 |
* The end of a group for mixed or children content models. |
|
1084 |
* |
|
1085 |
* @param augs Additional information that may include infoset |
|
1086 |
* augmentations. |
|
1087 |
* @throws XNIException Thrown by handler to signal an error. |
|
1088 |
*/ |
|
1089 |
public void endGroup(Augmentations augs) throws XNIException { |
|
1090 |
||
1091 |
if (!fMixed) { |
|
1092 |
if (fPrevNodeIndexStack[fDepth] != -1) { |
|
1093 |
fNodeIndexStack[fDepth] = addContentSpecNode(fOpStack[fDepth], fPrevNodeIndexStack[fDepth], fNodeIndexStack[fDepth]); |
|
1094 |
} |
|
1095 |
int nodeIndex = fNodeIndexStack[fDepth--]; |
|
1096 |
fNodeIndexStack[fDepth] = nodeIndex; |
|
1097 |
} |
|
1098 |
||
1099 |
} // endGroup() |
|
1100 |
||
1101 |
// no-op methods |
|
1102 |
||
1103 |
/** |
|
1104 |
* A content model of ANY. |
|
1105 |
* |
|
1106 |
* @param augs Additional information that may include infoset |
|
1107 |
* augmentations. |
|
1108 |
* @throws XNIException Thrown by handler to signal an error. |
|
1109 |
* |
|
1110 |
* @see #empty |
|
1111 |
* @see #startGroup |
|
1112 |
*/ |
|
1113 |
public void any(Augmentations augs) throws XNIException {} |
|
1114 |
||
1115 |
/** |
|
1116 |
* A content model of EMPTY. |
|
1117 |
* |
|
1118 |
* @param augs Additional information that may include infoset |
|
1119 |
* augmentations. |
|
1120 |
* @throws XNIException Thrown by handler to signal an error. |
|
1121 |
* |
|
1122 |
* @see #any |
|
1123 |
* @see #startGroup |
|
1124 |
*/ |
|
1125 |
public void empty(Augmentations augs) throws XNIException {} |
|
1126 |
||
1127 |
/** |
|
1128 |
* The end of a content model. |
|
1129 |
* @param augs Additional information that may include infoset |
|
1130 |
* augmentations. |
|
1131 |
* |
|
1132 |
* @throws XNIException Thrown by handler to signal an error. |
|
1133 |
*/ |
|
1134 |
public void endContentModel(Augmentations augs) throws XNIException {} |
|
1135 |
||
1136 |
// |
|
1137 |
// Grammar methods |
|
1138 |
// |
|
1139 |
||
1140 |
/** Returns true if this grammar is namespace aware. */ |
|
1141 |
public boolean isNamespaceAware() { |
|
1142 |
return false; |
|
1143 |
} // isNamespaceAware():boolean |
|
1144 |
||
1145 |
/** Returns the symbol table. */ |
|
1146 |
public SymbolTable getSymbolTable() { |
|
1147 |
return fSymbolTable; |
|
1148 |
} // getSymbolTable():SymbolTable |
|
1149 |
||
1150 |
/** |
|
1151 |
* Returns the index of the first element declaration. This index |
|
1152 |
* is then used to query more information about the element declaration. |
|
1153 |
* |
|
1154 |
* @see #getNextElementDeclIndex |
|
1155 |
* @see #getElementDecl |
|
1156 |
*/ |
|
1157 |
public int getFirstElementDeclIndex() { |
|
1158 |
return fElementDeclCount >= 0 ? 0 : -1; |
|
1159 |
} // getFirstElementDeclIndex():int |
|
1160 |
||
1161 |
/** |
|
1162 |
* Returns the next index of the element declaration following the |
|
1163 |
* specified element declaration. |
|
1164 |
* |
|
1165 |
* @param elementDeclIndex The element declaration index. |
|
1166 |
*/ |
|
1167 |
public int getNextElementDeclIndex(int elementDeclIndex) { |
|
1168 |
return elementDeclIndex < fElementDeclCount - 1 |
|
1169 |
? elementDeclIndex + 1 : -1; |
|
1170 |
} // getNextElementDeclIndex(int):int |
|
1171 |
||
1172 |
/** |
|
1173 |
* getElementDeclIndex |
|
1174 |
* |
|
1175 |
* @param elementDeclName |
|
1176 |
* |
|
1177 |
* @return index of the elementDeclName in scope |
|
1178 |
*/ |
|
1179 |
public int getElementDeclIndex(String elementDeclName) { |
|
33349 | 1180 |
Integer mapping = fElementIndexMap.get(elementDeclName); |
1181 |
if (mapping == null) { |
|
1182 |
mapping = -1; |
|
1183 |
} |
|
12005 | 1184 |
//System.out.println("getElementDeclIndex("+elementDeclName+") -> "+mapping); |
1185 |
return mapping; |
|
1186 |
} // getElementDeclIndex(String):int |
|
1187 |
||
1188 |
/** Returns the element decl index. |
|
1189 |
* @param elementDeclQName qualilfied name of the element |
|
1190 |
*/ |
|
1191 |
public int getElementDeclIndex(QName elementDeclQName) { |
|
1192 |
return getElementDeclIndex(elementDeclQName.rawname); |
|
1193 |
} // getElementDeclIndex(QName):int |
|
1194 |
||
1195 |
/** make separate function for getting contentSpecType of element. |
|
1196 |
* we can avoid setting of the element values. |
|
1197 |
*/ |
|
1198 |
||
1199 |
public short getContentSpecType(int elementIndex){ |
|
1200 |
if (elementIndex < 0 || elementIndex >= fElementDeclCount) { |
|
1201 |
return -1 ; |
|
1202 |
} |
|
1203 |
||
1204 |
int chunk = elementIndex >> CHUNK_SHIFT; |
|
1205 |
int index = elementIndex & CHUNK_MASK; |
|
1206 |
||
1207 |
if(fElementDeclType[chunk][index] == -1){ |
|
1208 |
return -1 ; |
|
1209 |
} |
|
1210 |
else{ |
|
1211 |
return (short) (fElementDeclType[chunk][index] & LIST_MASK); |
|
1212 |
} |
|
1213 |
||
1214 |
}//getContentSpecType |
|
1215 |
||
1216 |
/** |
|
1217 |
* getElementDecl |
|
1218 |
* |
|
1219 |
* @param elementDeclIndex |
|
1220 |
* @param elementDecl The values of this structure are set by this call. |
|
1221 |
* |
|
1222 |
* @return True if find the element, False otherwise. |
|
1223 |
*/ |
|
1224 |
public boolean getElementDecl(int elementDeclIndex, |
|
1225 |
XMLElementDecl elementDecl) { |
|
1226 |
||
1227 |
if (elementDeclIndex < 0 || elementDeclIndex >= fElementDeclCount) { |
|
1228 |
return false; |
|
1229 |
} |
|
1230 |
||
1231 |
int chunk = elementDeclIndex >> CHUNK_SHIFT; |
|
1232 |
int index = elementDeclIndex & CHUNK_MASK; |
|
1233 |
||
1234 |
elementDecl.name.setValues(fElementDeclName[chunk][index]); |
|
1235 |
||
1236 |
if (fElementDeclType[chunk][index] == -1) { |
|
1237 |
elementDecl.type = -1; |
|
1238 |
elementDecl.simpleType.list = false; |
|
1239 |
} else { |
|
1240 |
elementDecl.type = (short) (fElementDeclType[chunk][index] & LIST_MASK); |
|
1241 |
elementDecl.simpleType.list = (fElementDeclType[chunk][index] & LIST_FLAG) != 0; |
|
1242 |
} |
|
1243 |
||
1244 |
/* Validators are null until we add that code */ |
|
1245 |
if (elementDecl.type == XMLElementDecl.TYPE_CHILDREN || elementDecl.type == XMLElementDecl.TYPE_MIXED) { |
|
1246 |
elementDecl.contentModelValidator = getElementContentModelValidator(elementDeclIndex); |
|
1247 |
} |
|
1248 |
||
1249 |
elementDecl.simpleType.datatypeValidator = null; |
|
1250 |
elementDecl.simpleType.defaultType = -1; |
|
1251 |
elementDecl.simpleType.defaultValue = null; |
|
1252 |
||
1253 |
return true; |
|
1254 |
||
1255 |
} // getElementDecl(int,XMLElementDecl):boolean |
|
1256 |
||
1257 |
QName getElementDeclName(int elementDeclIndex) { |
|
1258 |
if (elementDeclIndex < 0 || elementDeclIndex >= fElementDeclCount) { |
|
1259 |
return null; |
|
1260 |
} |
|
1261 |
int chunk = elementDeclIndex >> CHUNK_SHIFT; |
|
1262 |
int index = elementDeclIndex & CHUNK_MASK; |
|
1263 |
return fElementDeclName[chunk][index]; |
|
1264 |
} |
|
1265 |
||
1266 |
// REVISIT: Make this getAttributeDeclCount/getAttributeDeclAt. -Ac |
|
1267 |
||
1268 |
/** |
|
1269 |
* getFirstAttributeDeclIndex |
|
1270 |
* |
|
1271 |
* @param elementDeclIndex |
|
1272 |
* |
|
1273 |
* @return index of the first attribute for element declaration elementDeclIndex |
|
1274 |
*/ |
|
1275 |
public int getFirstAttributeDeclIndex(int elementDeclIndex) { |
|
1276 |
int chunk = elementDeclIndex >> CHUNK_SHIFT; |
|
1277 |
int index = elementDeclIndex & CHUNK_MASK; |
|
1278 |
||
1279 |
return fElementDeclFirstAttributeDeclIndex[chunk][index]; |
|
1280 |
} // getFirstAttributeDeclIndex |
|
1281 |
||
1282 |
/** |
|
1283 |
* getNextAttributeDeclIndex |
|
1284 |
* |
|
1285 |
* @param attributeDeclIndex |
|
1286 |
* |
|
1287 |
* @return index of the next attribute of the attribute at attributeDeclIndex |
|
1288 |
*/ |
|
1289 |
public int getNextAttributeDeclIndex(int attributeDeclIndex) { |
|
1290 |
int chunk = attributeDeclIndex >> CHUNK_SHIFT; |
|
1291 |
int index = attributeDeclIndex & CHUNK_MASK; |
|
1292 |
||
1293 |
return fAttributeDeclNextAttributeDeclIndex[chunk][index]; |
|
1294 |
} // getNextAttributeDeclIndex |
|
1295 |
||
1296 |
/** |
|
1297 |
* getAttributeDecl |
|
1298 |
* |
|
1299 |
* @param attributeDeclIndex |
|
1300 |
* @param attributeDecl The values of this structure are set by this call. |
|
1301 |
* |
|
1302 |
* @return true if getAttributeDecl was able to fill in the value of attributeDecl |
|
1303 |
*/ |
|
1304 |
public boolean getAttributeDecl(int attributeDeclIndex, XMLAttributeDecl attributeDecl) { |
|
1305 |
if (attributeDeclIndex < 0 || attributeDeclIndex >= fAttributeDeclCount) { |
|
1306 |
return false; |
|
1307 |
} |
|
1308 |
int chunk = attributeDeclIndex >> CHUNK_SHIFT; |
|
1309 |
int index = attributeDeclIndex & CHUNK_MASK; |
|
1310 |
||
1311 |
attributeDecl.name.setValues(fAttributeDeclName[chunk][index]); |
|
1312 |
||
1313 |
short attributeType; |
|
1314 |
boolean isList; |
|
1315 |
||
1316 |
if (fAttributeDeclType[chunk][index] == -1) { |
|
1317 |
||
1318 |
attributeType = -1; |
|
1319 |
isList = false; |
|
1320 |
} else { |
|
1321 |
attributeType = (short) (fAttributeDeclType[chunk][index] & LIST_MASK); |
|
1322 |
isList = (fAttributeDeclType[chunk][index] & LIST_FLAG) != 0; |
|
1323 |
} |
|
1324 |
attributeDecl.simpleType.setValues(attributeType,fAttributeDeclName[chunk][index].localpart, |
|
1325 |
fAttributeDeclEnumeration[chunk][index], |
|
1326 |
isList, fAttributeDeclDefaultType[chunk][index], |
|
1327 |
fAttributeDeclDefaultValue[chunk][index], |
|
1328 |
fAttributeDeclNonNormalizedDefaultValue[chunk][index], |
|
1329 |
fAttributeDeclDatatypeValidator[chunk][index]); |
|
1330 |
return true; |
|
1331 |
||
1332 |
} // getAttributeDecl |
|
1333 |
||
1334 |
||
1335 |
/** |
|
1336 |
* Returns whether the given attribute is of type CDATA or not |
|
1337 |
* |
|
1338 |
* @param elName The element name. |
|
1339 |
* @param atName The attribute name. |
|
1340 |
* |
|
1341 |
* @return true if the attribute is of type CDATA |
|
1342 |
*/ |
|
1343 |
public boolean isCDATAAttribute(QName elName, QName atName) { |
|
1344 |
int elDeclIdx = getElementDeclIndex(elName); |
|
1345 |
if (getAttributeDecl(elDeclIdx, fAttributeDecl) |
|
1346 |
&& fAttributeDecl.simpleType.type != XMLSimpleType.TYPE_CDATA){ |
|
1347 |
return false; |
|
1348 |
} |
|
1349 |
return true; |
|
1350 |
} |
|
1351 |
||
1352 |
/** |
|
1353 |
* getEntityDeclIndex |
|
1354 |
* |
|
1355 |
* @param entityDeclName |
|
1356 |
* |
|
1357 |
* @return the index of the EntityDecl |
|
1358 |
*/ |
|
1359 |
public int getEntityDeclIndex(String entityDeclName) { |
|
33349 | 1360 |
if (entityDeclName == null || fEntityIndexMap.get(entityDeclName) == null) { |
12005 | 1361 |
return -1; |
1362 |
} |
|
1363 |
||
1364 |
return fEntityIndexMap.get(entityDeclName); |
|
1365 |
} // getEntityDeclIndex |
|
1366 |
||
1367 |
/** |
|
1368 |
* getEntityDecl |
|
1369 |
* |
|
1370 |
* @param entityDeclIndex |
|
1371 |
* @param entityDecl |
|
1372 |
* |
|
1373 |
* @return true if getEntityDecl was able to fill entityDecl with the contents of the entity |
|
1374 |
* with index entityDeclIndex |
|
1375 |
*/ |
|
1376 |
public boolean getEntityDecl(int entityDeclIndex, XMLEntityDecl entityDecl) { |
|
1377 |
if (entityDeclIndex < 0 || entityDeclIndex >= fEntityCount) { |
|
1378 |
return false; |
|
1379 |
} |
|
1380 |
int chunk = entityDeclIndex >> CHUNK_SHIFT; |
|
1381 |
int index = entityDeclIndex & CHUNK_MASK; |
|
1382 |
||
1383 |
entityDecl.setValues(fEntityName[chunk][index], |
|
1384 |
fEntityPublicId[chunk][index], |
|
1385 |
fEntitySystemId[chunk][index], |
|
1386 |
fEntityBaseSystemId[chunk][index], |
|
1387 |
fEntityNotation[chunk][index], |
|
1388 |
fEntityValue[chunk][index], |
|
1389 |
fEntityIsPE[chunk][index] == 0 ? false : true , |
|
1390 |
fEntityInExternal[chunk][index] == 0 ? false : true ); |
|
1391 |
||
1392 |
return true; |
|
1393 |
} // getEntityDecl |
|
1394 |
||
1395 |
/** |
|
1396 |
* getNotationDeclIndex |
|
1397 |
* |
|
1398 |
* @param notationDeclName |
|
1399 |
* |
|
1400 |
* @return the index if found a notation with the name, otherwise -1. |
|
1401 |
*/ |
|
1402 |
public int getNotationDeclIndex(String notationDeclName) { |
|
33349 | 1403 |
if (notationDeclName == null || fNotationIndexMap.get(notationDeclName) == null) { |
12005 | 1404 |
return -1; |
1405 |
} |
|
1406 |
||
1407 |
return fNotationIndexMap.get(notationDeclName); |
|
1408 |
} // getNotationDeclIndex |
|
1409 |
||
1410 |
/** |
|
1411 |
* getNotationDecl |
|
1412 |
* |
|
1413 |
* @param notationDeclIndex |
|
1414 |
* @param notationDecl |
|
1415 |
* |
|
1416 |
* @return return true of getNotationDecl can fill notationDecl with information about |
|
1417 |
* the notation at notationDeclIndex. |
|
1418 |
*/ |
|
1419 |
public boolean getNotationDecl(int notationDeclIndex, XMLNotationDecl notationDecl) { |
|
1420 |
if (notationDeclIndex < 0 || notationDeclIndex >= fNotationCount) { |
|
1421 |
return false; |
|
1422 |
} |
|
1423 |
int chunk = notationDeclIndex >> CHUNK_SHIFT; |
|
1424 |
int index = notationDeclIndex & CHUNK_MASK; |
|
1425 |
||
1426 |
notationDecl.setValues(fNotationName[chunk][index], |
|
1427 |
fNotationPublicId[chunk][index], |
|
1428 |
fNotationSystemId[chunk][index], |
|
1429 |
fNotationBaseSystemId[chunk][index]); |
|
1430 |
||
1431 |
return true; |
|
1432 |
||
1433 |
} // getNotationDecl |
|
1434 |
||
1435 |
/** |
|
1436 |
* getContentSpec |
|
1437 |
* |
|
1438 |
* @param contentSpecIndex |
|
1439 |
* @param contentSpec |
|
1440 |
* |
|
1441 |
* @return true if find the requested contentSpec node, false otherwise |
|
1442 |
*/ |
|
1443 |
public boolean getContentSpec(int contentSpecIndex, XMLContentSpec contentSpec) { |
|
1444 |
if (contentSpecIndex < 0 || contentSpecIndex >= fContentSpecCount ) |
|
1445 |
return false; |
|
1446 |
||
1447 |
int chunk = contentSpecIndex >> CHUNK_SHIFT; |
|
1448 |
int index = contentSpecIndex & CHUNK_MASK; |
|
1449 |
||
1450 |
contentSpec.type = fContentSpecType[chunk][index]; |
|
1451 |
contentSpec.value = fContentSpecValue[chunk][index]; |
|
1452 |
contentSpec.otherValue = fContentSpecOtherValue[chunk][index]; |
|
1453 |
return true; |
|
1454 |
} |
|
1455 |
||
1456 |
/** |
|
1457 |
* Returns the index to the content spec for the given element |
|
1458 |
* declaration, or <code>-1</code> if the element declaration |
|
1459 |
* index was invalid. |
|
1460 |
*/ |
|
1461 |
public int getContentSpecIndex(int elementDeclIndex) { |
|
1462 |
if (elementDeclIndex < 0 || elementDeclIndex >= fElementDeclCount) { |
|
1463 |
return -1; |
|
1464 |
} |
|
1465 |
final int chunk = elementDeclIndex >> CHUNK_SHIFT; |
|
1466 |
final int index = elementDeclIndex & CHUNK_MASK; |
|
1467 |
return fElementDeclContentSpecIndex[chunk][index]; |
|
1468 |
} |
|
1469 |
||
1470 |
/** |
|
1471 |
* getContentSpecAsString |
|
1472 |
* |
|
1473 |
* @param elementDeclIndex |
|
1474 |
* |
|
1475 |
* @return String |
|
1476 |
*/ |
|
1477 |
public String getContentSpecAsString(int elementDeclIndex){ |
|
1478 |
||
1479 |
if (elementDeclIndex < 0 || elementDeclIndex >= fElementDeclCount) { |
|
1480 |
return null; |
|
1481 |
} |
|
1482 |
||
1483 |
int chunk = elementDeclIndex >> CHUNK_SHIFT; |
|
1484 |
int index = elementDeclIndex & CHUNK_MASK; |
|
1485 |
||
1486 |
int contentSpecIndex = fElementDeclContentSpecIndex[chunk][index]; |
|
1487 |
||
1488 |
// lookup content spec node |
|
1489 |
XMLContentSpec contentSpec = new XMLContentSpec(); |
|
1490 |
||
1491 |
if (getContentSpec(contentSpecIndex, contentSpec)) { |
|
1492 |
||
1493 |
// build string |
|
1494 |
StringBuffer str = new StringBuffer(); |
|
1495 |
int parentContentSpecType = contentSpec.type & 0x0f; |
|
1496 |
int nextContentSpec; |
|
1497 |
switch (parentContentSpecType) { |
|
1498 |
case XMLContentSpec.CONTENTSPECNODE_LEAF: { |
|
1499 |
str.append('('); |
|
1500 |
if (contentSpec.value == null && contentSpec.otherValue == null) { |
|
1501 |
str.append("#PCDATA"); |
|
1502 |
} |
|
1503 |
else { |
|
1504 |
str.append(contentSpec.value); |
|
1505 |
} |
|
1506 |
str.append(')'); |
|
1507 |
break; |
|
1508 |
} |
|
1509 |
case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE: { |
|
1510 |
getContentSpec(((int[])contentSpec.value)[0], contentSpec); |
|
1511 |
nextContentSpec = contentSpec.type; |
|
1512 |
||
1513 |
if (nextContentSpec == XMLContentSpec.CONTENTSPECNODE_LEAF) { |
|
1514 |
str.append('('); |
|
1515 |
str.append(contentSpec.value); |
|
1516 |
str.append(')'); |
|
1517 |
} else if( nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE || |
|
1518 |
nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE || |
|
1519 |
nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE ) { |
|
1520 |
str.append('(' ); |
|
1521 |
appendContentSpec(contentSpec, str, |
|
1522 |
true, parentContentSpecType ); |
|
1523 |
str.append(')'); |
|
1524 |
} else { |
|
1525 |
appendContentSpec(contentSpec, str, |
|
1526 |
true, parentContentSpecType ); |
|
1527 |
} |
|
1528 |
str.append('?'); |
|
1529 |
break; |
|
1530 |
} |
|
1531 |
case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE: { |
|
1532 |
getContentSpec(((int[])contentSpec.value)[0], contentSpec); |
|
1533 |
nextContentSpec = contentSpec.type; |
|
1534 |
||
1535 |
if ( nextContentSpec == XMLContentSpec.CONTENTSPECNODE_LEAF) { |
|
1536 |
str.append('('); |
|
1537 |
if (contentSpec.value == null && contentSpec.otherValue == null) { |
|
1538 |
str.append("#PCDATA"); |
|
1539 |
} |
|
1540 |
else if (contentSpec.otherValue != null) { |
|
1541 |
str.append("##any:uri=").append(contentSpec.otherValue); |
|
1542 |
} |
|
1543 |
else if (contentSpec.value == null) { |
|
1544 |
str.append("##any"); |
|
1545 |
} |
|
1546 |
else { |
|
1547 |
appendContentSpec(contentSpec, str, |
|
1548 |
true, parentContentSpecType ); |
|
1549 |
} |
|
1550 |
str.append(')'); |
|
1551 |
} else if( nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE || |
|
1552 |
nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE || |
|
1553 |
nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE ) { |
|
1554 |
str.append('(' ); |
|
1555 |
appendContentSpec(contentSpec, str, |
|
1556 |
true, parentContentSpecType ); |
|
1557 |
str.append(')'); |
|
1558 |
} else { |
|
1559 |
appendContentSpec(contentSpec, str, |
|
1560 |
true, parentContentSpecType ); |
|
1561 |
} |
|
1562 |
str.append('*'); |
|
1563 |
break; |
|
1564 |
} |
|
1565 |
case XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE: { |
|
1566 |
getContentSpec(((int[])contentSpec.value)[0], contentSpec); |
|
1567 |
nextContentSpec = contentSpec.type; |
|
1568 |
||
1569 |
if ( nextContentSpec == XMLContentSpec.CONTENTSPECNODE_LEAF) { |
|
1570 |
str.append('('); |
|
1571 |
if (contentSpec.value == null && contentSpec.otherValue == null) { |
|
1572 |
str.append("#PCDATA"); |
|
1573 |
} |
|
1574 |
else if (contentSpec.otherValue != null) { |
|
1575 |
str.append("##any:uri=").append(contentSpec.otherValue); |
|
1576 |
} |
|
1577 |
else if (contentSpec.value == null) { |
|
1578 |
str.append("##any"); |
|
1579 |
} |
|
1580 |
else { |
|
1581 |
str.append(contentSpec.value); |
|
1582 |
} |
|
1583 |
str.append(')'); |
|
1584 |
} else if( nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE || |
|
1585 |
nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE || |
|
1586 |
nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE ) { |
|
1587 |
str.append('(' ); |
|
1588 |
appendContentSpec(contentSpec, str, |
|
1589 |
true, parentContentSpecType ); |
|
1590 |
str.append(')'); |
|
1591 |
} else { |
|
1592 |
appendContentSpec(contentSpec, str, |
|
1593 |
true, parentContentSpecType); |
|
1594 |
} |
|
1595 |
str.append('+'); |
|
1596 |
break; |
|
1597 |
} |
|
1598 |
case XMLContentSpec.CONTENTSPECNODE_CHOICE: |
|
1599 |
case XMLContentSpec.CONTENTSPECNODE_SEQ: { |
|
1600 |
appendContentSpec(contentSpec, str, |
|
1601 |
true, parentContentSpecType ); |
|
1602 |
break; |
|
1603 |
} |
|
1604 |
case XMLContentSpec.CONTENTSPECNODE_ANY: { |
|
1605 |
str.append("##any"); |
|
1606 |
if (contentSpec.otherValue != null) { |
|
1607 |
str.append(":uri="); |
|
1608 |
str.append(contentSpec.otherValue); |
|
1609 |
} |
|
1610 |
break; |
|
1611 |
} |
|
1612 |
case XMLContentSpec.CONTENTSPECNODE_ANY_OTHER: { |
|
1613 |
str.append("##other:uri="); |
|
1614 |
str.append(contentSpec.otherValue); |
|
1615 |
break; |
|
1616 |
} |
|
1617 |
case XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL: { |
|
1618 |
str.append("##local"); |
|
1619 |
break; |
|
1620 |
} |
|
1621 |
default: { |
|
1622 |
str.append("???"); |
|
1623 |
} |
|
1624 |
||
1625 |
} // switch type |
|
1626 |
||
1627 |
// return string |
|
1628 |
return str.toString(); |
|
1629 |
} |
|
1630 |
||
1631 |
// not found |
|
1632 |
return null; |
|
1633 |
||
1634 |
} // getContentSpecAsString(int):String |
|
1635 |
||
1636 |
// debugging |
|
1637 |
||
1638 |
public void printElements( ) { |
|
1639 |
int elementDeclIndex = 0; |
|
1640 |
XMLElementDecl elementDecl = new XMLElementDecl(); |
|
1641 |
while (getElementDecl(elementDeclIndex++, elementDecl)) { |
|
1642 |
||
1643 |
System.out.println("element decl: "+elementDecl.name+ |
|
1644 |
", "+ elementDecl.name.rawname ); |
|
1645 |
||
1646 |
// ", "+ elementDecl.contentModelValidator.toString()); |
|
1647 |
} |
|
1648 |
} |
|
1649 |
||
1650 |
public void printAttributes(int elementDeclIndex) { |
|
1651 |
int attributeDeclIndex = getFirstAttributeDeclIndex(elementDeclIndex); |
|
1652 |
System.out.print(elementDeclIndex); |
|
1653 |
System.out.print(" ["); |
|
1654 |
while (attributeDeclIndex != -1) { |
|
1655 |
System.out.print(' '); |
|
1656 |
System.out.print(attributeDeclIndex); |
|
1657 |
printAttribute(attributeDeclIndex); |
|
1658 |
attributeDeclIndex = getNextAttributeDeclIndex(attributeDeclIndex); |
|
1659 |
if (attributeDeclIndex != -1) { |
|
1660 |
System.out.print(","); |
|
1661 |
} |
|
1662 |
} |
|
1663 |
System.out.println(" ]"); |
|
1664 |
} |
|
1665 |
||
1666 |
// |
|
1667 |
// Protected methods |
|
1668 |
// |
|
1669 |
||
1670 |
/** |
|
1671 |
* Adds the content spec to the given element declaration. |
|
1672 |
*/ |
|
1673 |
protected void addContentSpecToElement(XMLElementDecl elementDecl) { |
|
1674 |
if ((fDepth == 0 || (fDepth == 1 && elementDecl.type == XMLElementDecl.TYPE_MIXED)) && |
|
1675 |
fNodeIndexStack != null) { |
|
1676 |
if (elementDecl.type == XMLElementDecl.TYPE_MIXED) { |
|
1677 |
int pcdata = addUniqueLeafNode(null); |
|
1678 |
if (fNodeIndexStack[0] == -1) { |
|
1679 |
fNodeIndexStack[0] = pcdata; |
|
1680 |
} |
|
1681 |
else { |
|
1682 |
fNodeIndexStack[0] = addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_CHOICE, |
|
1683 |
pcdata, fNodeIndexStack[0]); |
|
1684 |
} |
|
1685 |
} |
|
1686 |
setContentSpecIndex(fCurrentElementIndex, fNodeIndexStack[fDepth]); |
|
1687 |
} |
|
1688 |
} |
|
1689 |
||
1690 |
/** |
|
1691 |
* getElementContentModelValidator |
|
1692 |
* |
|
1693 |
* @param elementDeclIndex |
|
1694 |
* |
|
1695 |
* @return its ContentModelValidator if any. |
|
1696 |
*/ |
|
1697 |
protected ContentModelValidator getElementContentModelValidator(int elementDeclIndex) { |
|
1698 |
||
1699 |
int chunk = elementDeclIndex >> CHUNK_SHIFT; |
|
1700 |
int index = elementDeclIndex & CHUNK_MASK; |
|
1701 |
||
1702 |
ContentModelValidator contentModel = fElementDeclContentModelValidator[chunk][index]; |
|
1703 |
||
1704 |
// If we have one, just return that. Otherwise, gotta create one |
|
1705 |
if (contentModel != null) { |
|
1706 |
return contentModel; |
|
1707 |
} |
|
1708 |
||
1709 |
int contentType = fElementDeclType[chunk][index]; |
|
1710 |
if (contentType == XMLElementDecl.TYPE_SIMPLE) { |
|
1711 |
return null; |
|
1712 |
} |
|
1713 |
||
1714 |
// Get the type of content this element has |
|
1715 |
int contentSpecIndex = fElementDeclContentSpecIndex[chunk][index]; |
|
1716 |
||
1717 |
/*** |
|
1718 |
if ( contentSpecIndex == -1 ) |
|
1719 |
return null; |
|
1720 |
/***/ |
|
1721 |
||
1722 |
XMLContentSpec contentSpec = new XMLContentSpec(); |
|
1723 |
getContentSpec( contentSpecIndex, contentSpec ); |
|
1724 |
||
1725 |
// And create the content model according to the spec type |
|
1726 |
if ( contentType == XMLElementDecl.TYPE_MIXED ) { |
|
1727 |
// |
|
1728 |
// Just create a mixel content model object. This type of |
|
1729 |
// content model is optimized for mixed content validation. |
|
1730 |
// |
|
1731 |
ChildrenList children = new ChildrenList(); |
|
1732 |
contentSpecTree(contentSpecIndex, contentSpec, children); |
|
1733 |
contentModel = new MixedContentModel(children.qname, |
|
1734 |
children.type, |
|
1735 |
0, children.length, |
|
1736 |
false); |
|
1737 |
} else if (contentType == XMLElementDecl.TYPE_CHILDREN) { |
|
1738 |
// This method will create an optimal model for the complexity |
|
1739 |
// of the element's defined model. If its simple, it will create |
|
1740 |
// a SimpleContentModel object. If its a simple list, it will |
|
1741 |
// create a SimpleListContentModel object. If its complex, it |
|
1742 |
// will create a DFAContentModel object. |
|
1743 |
// |
|
1744 |
contentModel = createChildModel(contentSpecIndex); |
|
1745 |
} else { |
|
1746 |
throw new RuntimeException("Unknown content type for a element decl " |
|
1747 |
+ "in getElementContentModelValidator() in AbstractDTDGrammar class"); |
|
1748 |
} |
|
1749 |
||
1750 |
// Add the new model to the content model for this element |
|
1751 |
fElementDeclContentModelValidator[chunk][index] = contentModel; |
|
1752 |
||
1753 |
return contentModel; |
|
1754 |
||
1755 |
} // getElementContentModelValidator(int):ContentModelValidator |
|
1756 |
||
1757 |
protected int createElementDecl() { |
|
1758 |
int chunk = fElementDeclCount >> CHUNK_SHIFT; |
|
1759 |
int index = fElementDeclCount & CHUNK_MASK; |
|
1760 |
ensureElementDeclCapacity(chunk); |
|
1761 |
fElementDeclName[chunk][index] = new QName(); |
|
1762 |
fElementDeclType[chunk][index] = -1; |
|
1763 |
fElementDeclContentModelValidator[chunk][index] = null; |
|
1764 |
fElementDeclFirstAttributeDeclIndex[chunk][index] = -1; |
|
1765 |
fElementDeclLastAttributeDeclIndex[chunk][index] = -1; |
|
1766 |
return fElementDeclCount++; |
|
1767 |
} |
|
1768 |
||
1769 |
protected void setElementDecl(int elementDeclIndex, XMLElementDecl elementDecl) { |
|
1770 |
if (elementDeclIndex < 0 || elementDeclIndex >= fElementDeclCount) { |
|
1771 |
return; |
|
1772 |
} |
|
1773 |
int chunk = elementDeclIndex >> CHUNK_SHIFT; |
|
1774 |
int index = elementDeclIndex & CHUNK_MASK; |
|
1775 |
||
1776 |
fElementDeclName[chunk][index].setValues(elementDecl.name); |
|
1777 |
fElementDeclType[chunk][index] = elementDecl.type; |
|
1778 |
||
1779 |
fElementDeclContentModelValidator[chunk][index] = elementDecl.contentModelValidator; |
|
1780 |
||
1781 |
if (elementDecl.simpleType.list == true ) { |
|
1782 |
fElementDeclType[chunk][index] |= LIST_FLAG; |
|
1783 |
} |
|
1784 |
||
1785 |
fElementIndexMap.put(elementDecl.name.rawname, elementDeclIndex); |
|
1786 |
} |
|
1787 |
||
1788 |
||
1789 |
||
1790 |
||
1791 |
protected void putElementNameMapping(QName name, int scope, |
|
1792 |
int elementDeclIndex) { |
|
1793 |
} |
|
1794 |
||
1795 |
protected void setFirstAttributeDeclIndex(int elementDeclIndex, int newFirstAttrIndex){ |
|
1796 |
||
1797 |
if (elementDeclIndex < 0 || elementDeclIndex >= fElementDeclCount) { |
|
1798 |
return; |
|
1799 |
} |
|
1800 |
||
1801 |
int chunk = elementDeclIndex >> CHUNK_SHIFT; |
|
1802 |
int index = elementDeclIndex & CHUNK_MASK; |
|
1803 |
||
1804 |
fElementDeclFirstAttributeDeclIndex[chunk][index] = newFirstAttrIndex; |
|
1805 |
} |
|
1806 |
||
1807 |
protected void setContentSpecIndex(int elementDeclIndex, int contentSpecIndex){ |
|
1808 |
||
1809 |
if (elementDeclIndex < 0 || elementDeclIndex >= fElementDeclCount) { |
|
1810 |
return; |
|
1811 |
} |
|
1812 |
||
1813 |
int chunk = elementDeclIndex >> CHUNK_SHIFT; |
|
1814 |
int index = elementDeclIndex & CHUNK_MASK; |
|
1815 |
||
1816 |
fElementDeclContentSpecIndex[chunk][index] = contentSpecIndex; |
|
1817 |
} |
|
1818 |
||
1819 |
||
1820 |
protected int createAttributeDecl() { |
|
1821 |
int chunk = fAttributeDeclCount >> CHUNK_SHIFT; |
|
1822 |
int index = fAttributeDeclCount & CHUNK_MASK; |
|
1823 |
||
1824 |
ensureAttributeDeclCapacity(chunk); |
|
1825 |
fAttributeDeclName[chunk][index] = new QName(); |
|
1826 |
fAttributeDeclType[chunk][index] = -1; |
|
1827 |
fAttributeDeclDatatypeValidator[chunk][index] = null; |
|
1828 |
fAttributeDeclEnumeration[chunk][index] = null; |
|
1829 |
fAttributeDeclDefaultType[chunk][index] = XMLSimpleType.DEFAULT_TYPE_IMPLIED; |
|
1830 |
fAttributeDeclDefaultValue[chunk][index] = null; |
|
1831 |
fAttributeDeclNonNormalizedDefaultValue[chunk][index] = null; |
|
1832 |
fAttributeDeclNextAttributeDeclIndex[chunk][index] = -1; |
|
1833 |
return fAttributeDeclCount++; |
|
1834 |
} |
|
1835 |
||
1836 |
||
1837 |
protected void setAttributeDecl(int elementDeclIndex, int attributeDeclIndex, |
|
1838 |
XMLAttributeDecl attributeDecl) { |
|
1839 |
int attrChunk = attributeDeclIndex >> CHUNK_SHIFT; |
|
1840 |
int attrIndex = attributeDeclIndex & CHUNK_MASK; |
|
1841 |
fAttributeDeclName[attrChunk][attrIndex].setValues(attributeDecl.name); |
|
1842 |
fAttributeDeclType[attrChunk][attrIndex] = attributeDecl.simpleType.type; |
|
1843 |
||
1844 |
if (attributeDecl.simpleType.list) { |
|
1845 |
fAttributeDeclType[attrChunk][attrIndex] |= LIST_FLAG; |
|
1846 |
} |
|
1847 |
fAttributeDeclEnumeration[attrChunk][attrIndex] = attributeDecl.simpleType.enumeration; |
|
1848 |
fAttributeDeclDefaultType[attrChunk][attrIndex] = attributeDecl.simpleType.defaultType; |
|
1849 |
fAttributeDeclDatatypeValidator[attrChunk][attrIndex] = attributeDecl.simpleType.datatypeValidator; |
|
1850 |
||
1851 |
fAttributeDeclDefaultValue[attrChunk][attrIndex] = attributeDecl.simpleType.defaultValue; |
|
1852 |
fAttributeDeclNonNormalizedDefaultValue[attrChunk][attrIndex] = attributeDecl.simpleType.nonNormalizedDefaultValue; |
|
1853 |
||
1854 |
int elemChunk = elementDeclIndex >> CHUNK_SHIFT; |
|
1855 |
int elemIndex = elementDeclIndex & CHUNK_MASK; |
|
1856 |
int index = fElementDeclFirstAttributeDeclIndex[elemChunk][elemIndex]; |
|
1857 |
while (index != -1) { |
|
1858 |
if (index == attributeDeclIndex) { |
|
1859 |
break; |
|
1860 |
} |
|
1861 |
attrChunk = index >> CHUNK_SHIFT; |
|
1862 |
attrIndex = index & CHUNK_MASK; |
|
1863 |
index = fAttributeDeclNextAttributeDeclIndex[attrChunk][attrIndex]; |
|
1864 |
} |
|
1865 |
if (index == -1) { |
|
1866 |
if (fElementDeclFirstAttributeDeclIndex[elemChunk][elemIndex] == -1) { |
|
1867 |
fElementDeclFirstAttributeDeclIndex[elemChunk][elemIndex] = attributeDeclIndex; |
|
1868 |
} else { |
|
1869 |
index = fElementDeclLastAttributeDeclIndex[elemChunk][elemIndex]; |
|
1870 |
attrChunk = index >> CHUNK_SHIFT; |
|
1871 |
attrIndex = index & CHUNK_MASK; |
|
1872 |
fAttributeDeclNextAttributeDeclIndex[attrChunk][attrIndex] = attributeDeclIndex; |
|
1873 |
} |
|
1874 |
fElementDeclLastAttributeDeclIndex[elemChunk][elemIndex] = attributeDeclIndex; |
|
1875 |
} |
|
1876 |
} |
|
1877 |
||
1878 |
protected int createContentSpec() { |
|
1879 |
int chunk = fContentSpecCount >> CHUNK_SHIFT; |
|
1880 |
int index = fContentSpecCount & CHUNK_MASK; |
|
1881 |
||
1882 |
ensureContentSpecCapacity(chunk); |
|
1883 |
fContentSpecType[chunk][index] = -1; |
|
1884 |
fContentSpecValue[chunk][index] = null; |
|
1885 |
fContentSpecOtherValue[chunk][index] = null; |
|
1886 |
||
1887 |
return fContentSpecCount++; |
|
1888 |
} |
|
1889 |
||
1890 |
protected void setContentSpec(int contentSpecIndex, XMLContentSpec contentSpec) { |
|
1891 |
int chunk = contentSpecIndex >> CHUNK_SHIFT; |
|
1892 |
int index = contentSpecIndex & CHUNK_MASK; |
|
1893 |
||
1894 |
fContentSpecType[chunk][index] = contentSpec.type; |
|
1895 |
fContentSpecValue[chunk][index] = contentSpec.value; |
|
1896 |
fContentSpecOtherValue[chunk][index] = contentSpec.otherValue; |
|
1897 |
} |
|
1898 |
||
1899 |
||
1900 |
protected int createEntityDecl() { |
|
1901 |
int chunk = fEntityCount >> CHUNK_SHIFT; |
|
1902 |
int index = fEntityCount & CHUNK_MASK; |
|
1903 |
||
1904 |
ensureEntityDeclCapacity(chunk); |
|
1905 |
fEntityIsPE[chunk][index] = 0; |
|
1906 |
fEntityInExternal[chunk][index] = 0; |
|
1907 |
||
1908 |
return fEntityCount++; |
|
1909 |
} |
|
1910 |
||
1911 |
protected void setEntityDecl(int entityDeclIndex, XMLEntityDecl entityDecl) { |
|
1912 |
int chunk = entityDeclIndex >> CHUNK_SHIFT; |
|
1913 |
int index = entityDeclIndex & CHUNK_MASK; |
|
1914 |
||
1915 |
fEntityName[chunk][index] = entityDecl.name; |
|
1916 |
fEntityValue[chunk][index] = entityDecl.value; |
|
1917 |
fEntityPublicId[chunk][index] = entityDecl.publicId; |
|
1918 |
fEntitySystemId[chunk][index] = entityDecl.systemId; |
|
1919 |
fEntityBaseSystemId[chunk][index] = entityDecl.baseSystemId; |
|
1920 |
fEntityNotation[chunk][index] = entityDecl.notation; |
|
1921 |
fEntityIsPE[chunk][index] = entityDecl.isPE ? (byte)1 : (byte)0; |
|
1922 |
fEntityInExternal[chunk][index] = entityDecl.inExternal ? (byte)1 : (byte)0; |
|
1923 |
||
1924 |
fEntityIndexMap.put(entityDecl.name, entityDeclIndex); |
|
1925 |
} |
|
1926 |
||
1927 |
protected int createNotationDecl() { |
|
1928 |
int chunk = fNotationCount >> CHUNK_SHIFT; |
|
1929 |
ensureNotationDeclCapacity(chunk); |
|
1930 |
return fNotationCount++; |
|
1931 |
} |
|
1932 |
||
1933 |
protected void setNotationDecl(int notationDeclIndex, XMLNotationDecl notationDecl) { |
|
1934 |
int chunk = notationDeclIndex >> CHUNK_SHIFT; |
|
1935 |
int index = notationDeclIndex & CHUNK_MASK; |
|
1936 |
||
1937 |
fNotationName[chunk][index] = notationDecl.name; |
|
1938 |
fNotationPublicId[chunk][index] = notationDecl.publicId; |
|
1939 |
fNotationSystemId[chunk][index] = notationDecl.systemId; |
|
1940 |
fNotationBaseSystemId[chunk][index] = notationDecl.baseSystemId; |
|
1941 |
||
1942 |
fNotationIndexMap.put(notationDecl.name, notationDeclIndex); |
|
1943 |
} |
|
1944 |
||
1945 |
/** |
|
1946 |
* Create an XMLContentSpec for a single non-leaf |
|
1947 |
* |
|
1948 |
* @param nodeType the type of XMLContentSpec to create - from XMLContentSpec.CONTENTSPECNODE_* |
|
1949 |
* @param nodeValue handle to an XMLContentSpec |
|
1950 |
* @return handle to the newly create XMLContentSpec |
|
1951 |
*/ |
|
1952 |
protected int addContentSpecNode(short nodeType, String nodeValue) { |
|
1953 |
||
1954 |
// create content spec node |
|
1955 |
int contentSpecIndex = createContentSpec(); |
|
1956 |
||
1957 |
// set content spec node values |
|
1958 |
fContentSpec.setValues(nodeType, nodeValue, null); |
|
1959 |
setContentSpec(contentSpecIndex, fContentSpec); |
|
1960 |
||
1961 |
// return index |
|
1962 |
return contentSpecIndex; |
|
1963 |
||
1964 |
} // addContentSpecNode(short,String):int |
|
1965 |
||
1966 |
/** |
|
1967 |
* create an XMLContentSpec for a leaf |
|
1968 |
* |
|
1969 |
* @param elementName the name (Element) for the node |
|
1970 |
* @return handle to the newly create XMLContentSpec |
|
1971 |
*/ |
|
1972 |
protected int addUniqueLeafNode(String elementName) { |
|
1973 |
||
1974 |
// create content spec node |
|
1975 |
int contentSpecIndex = createContentSpec(); |
|
1976 |
||
1977 |
// set content spec node values |
|
1978 |
fContentSpec.setValues( XMLContentSpec.CONTENTSPECNODE_LEAF, |
|
1979 |
elementName, null); |
|
1980 |
setContentSpec(contentSpecIndex, fContentSpec); |
|
1981 |
||
1982 |
// return index |
|
1983 |
return contentSpecIndex; |
|
1984 |
||
1985 |
} // addUniqueLeafNode(String):int |
|
1986 |
||
1987 |
/** |
|
1988 |
* Create an XMLContentSpec for a two child leaf |
|
1989 |
* |
|
1990 |
* @param nodeType the type of XMLContentSpec to create - from XMLContentSpec.CONTENTSPECNODE_* |
|
1991 |
* @param leftNodeIndex handle to an XMLContentSpec |
|
1992 |
* @param rightNodeIndex handle to an XMLContentSpec |
|
1993 |
* @return handle to the newly create XMLContentSpec |
|
1994 |
*/ |
|
1995 |
protected int addContentSpecNode(short nodeType, |
|
1996 |
int leftNodeIndex, int rightNodeIndex) { |
|
1997 |
||
1998 |
// create content spec node |
|
1999 |
int contentSpecIndex = createContentSpec(); |
|
2000 |
||
2001 |
// set content spec node values |
|
2002 |
int[] leftIntArray = new int[1]; |
|
2003 |
int[] rightIntArray = new int[1]; |
|
2004 |
||
2005 |
leftIntArray[0] = leftNodeIndex; |
|
2006 |
rightIntArray[0] = rightNodeIndex; |
|
2007 |
fContentSpec.setValues(nodeType, leftIntArray, rightIntArray); |
|
2008 |
setContentSpec(contentSpecIndex, fContentSpec); |
|
2009 |
||
2010 |
// return index |
|
2011 |
return contentSpecIndex; |
|
2012 |
||
2013 |
} // addContentSpecNode(short,int,int):int |
|
2014 |
||
2015 |
/** Initialize content model stack. */ |
|
2016 |
protected void initializeContentModelStack() { |
|
2017 |
||
2018 |
if (fOpStack == null) { |
|
2019 |
fOpStack = new short[8]; |
|
2020 |
fNodeIndexStack = new int[8]; |
|
2021 |
fPrevNodeIndexStack = new int[8]; |
|
2022 |
} else if (fDepth == fOpStack.length) { |
|
2023 |
short[] newStack = new short[fDepth * 2]; |
|
2024 |
System.arraycopy(fOpStack, 0, newStack, 0, fDepth); |
|
2025 |
fOpStack = newStack; |
|
2026 |
int[] newIntStack = new int[fDepth * 2]; |
|
2027 |
System.arraycopy(fNodeIndexStack, 0, newIntStack, 0, fDepth); |
|
2028 |
fNodeIndexStack = newIntStack; |
|
2029 |
newIntStack = new int[fDepth * 2]; |
|
2030 |
System.arraycopy(fPrevNodeIndexStack, 0, newIntStack, 0, fDepth); |
|
2031 |
fPrevNodeIndexStack = newIntStack; |
|
2032 |
} |
|
2033 |
fOpStack[fDepth] = -1; |
|
2034 |
fNodeIndexStack[fDepth] = -1; |
|
2035 |
fPrevNodeIndexStack[fDepth] = -1; |
|
2036 |
||
2037 |
} // initializeContentModelStack() |
|
2038 |
||
2039 |
boolean isImmutable() { |
|
2040 |
return fIsImmutable; |
|
2041 |
} |
|
2042 |
||
2043 |
// |
|
2044 |
// Private methods |
|
2045 |
// |
|
2046 |
||
2047 |
private void appendContentSpec(XMLContentSpec contentSpec, |
|
2048 |
StringBuffer str, boolean parens, |
|
2049 |
int parentContentSpecType ) { |
|
2050 |
||
2051 |
int thisContentSpec = contentSpec.type & 0x0f; |
|
2052 |
switch (thisContentSpec) { |
|
2053 |
case XMLContentSpec.CONTENTSPECNODE_LEAF: { |
|
2054 |
if (contentSpec.value == null && contentSpec.otherValue == null) { |
|
2055 |
str.append("#PCDATA"); |
|
2056 |
} |
|
2057 |
else if (contentSpec.value == null && contentSpec.otherValue != null) { |
|
2058 |
str.append("##any:uri=").append(contentSpec.otherValue); |
|
2059 |
} |
|
2060 |
else if (contentSpec.value == null) { |
|
2061 |
str.append("##any"); |
|
2062 |
} |
|
2063 |
else { |
|
2064 |
str.append(contentSpec.value); |
|
2065 |
} |
|
2066 |
break; |
|
2067 |
} |
|
2068 |
case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE: { |
|
2069 |
if (parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE || |
|
2070 |
parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE || |
|
2071 |
parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE ) { |
|
2072 |
getContentSpec(((int[])contentSpec.value)[0], contentSpec); |
|
2073 |
str.append('('); |
|
2074 |
appendContentSpec(contentSpec, str, true, thisContentSpec ); |
|
2075 |
str.append(')'); |
|
2076 |
} |
|
2077 |
else { |
|
2078 |
getContentSpec(((int[])contentSpec.value)[0], contentSpec); |
|
2079 |
appendContentSpec( contentSpec, str, true, thisContentSpec ); |
|
2080 |
} |
|
2081 |
str.append('?'); |
|
2082 |
break; |
|
2083 |
} |
|
2084 |
case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE: { |
|
2085 |
if (parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE || |
|
2086 |
parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE || |
|
2087 |
parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE ) { |
|
2088 |
getContentSpec(((int[])contentSpec.value)[0], contentSpec); |
|
2089 |
str.append('('); |
|
2090 |
appendContentSpec(contentSpec, str, true, thisContentSpec); |
|
2091 |
str.append(')' ); |
|
2092 |
} |
|
2093 |
else { |
|
2094 |
getContentSpec(((int[])contentSpec.value)[0], contentSpec); |
|
2095 |
appendContentSpec(contentSpec, str, true, thisContentSpec); |
|
2096 |
} |
|
2097 |
str.append('*'); |
|
2098 |
break; |
|
2099 |
} |
|
2100 |
case XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE: { |
|
2101 |
if (parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE || |
|
2102 |
parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE || |
|
2103 |
parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE ) { |
|
2104 |
||
2105 |
str.append('('); |
|
2106 |
getContentSpec(((int[])contentSpec.value)[0], contentSpec); |
|
2107 |
appendContentSpec(contentSpec, str, true, thisContentSpec); |
|
2108 |
str.append(')' ); |
|
2109 |
} |
|
2110 |
else { |
|
2111 |
getContentSpec(((int[])contentSpec.value)[0], contentSpec); |
|
2112 |
appendContentSpec(contentSpec, str, true, thisContentSpec); |
|
2113 |
} |
|
2114 |
str.append('+'); |
|
2115 |
break; |
|
2116 |
} |
|
2117 |
case XMLContentSpec.CONTENTSPECNODE_CHOICE: |
|
2118 |
case XMLContentSpec.CONTENTSPECNODE_SEQ: { |
|
2119 |
if (parens) { |
|
2120 |
str.append('('); |
|
2121 |
} |
|
2122 |
int type = contentSpec.type; |
|
2123 |
int otherValue = ((int[])contentSpec.otherValue)[0]; |
|
2124 |
getContentSpec(((int[])contentSpec.value)[0], contentSpec); |
|
2125 |
appendContentSpec(contentSpec, str, contentSpec.type != type, thisContentSpec); |
|
2126 |
if (type == XMLContentSpec.CONTENTSPECNODE_CHOICE) { |
|
2127 |
str.append('|'); |
|
2128 |
} |
|
2129 |
else { |
|
2130 |
str.append(','); |
|
2131 |
} |
|
2132 |
getContentSpec(otherValue, contentSpec); |
|
2133 |
appendContentSpec(contentSpec, str, true, thisContentSpec); |
|
2134 |
if (parens) { |
|
2135 |
str.append(')'); |
|
2136 |
} |
|
2137 |
break; |
|
2138 |
} |
|
2139 |
case XMLContentSpec.CONTENTSPECNODE_ANY: { |
|
2140 |
str.append("##any"); |
|
2141 |
if (contentSpec.otherValue != null) { |
|
2142 |
str.append(":uri="); |
|
2143 |
str.append(contentSpec.otherValue); |
|
2144 |
} |
|
2145 |
break; |
|
2146 |
} |
|
2147 |
case XMLContentSpec.CONTENTSPECNODE_ANY_OTHER: { |
|
2148 |
str.append("##other:uri="); |
|
2149 |
str.append(contentSpec.otherValue); |
|
2150 |
break; |
|
2151 |
} |
|
2152 |
case XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL: { |
|
2153 |
str.append("##local"); |
|
2154 |
break; |
|
2155 |
} |
|
2156 |
default: { |
|
2157 |
str.append("???"); |
|
2158 |
break; |
|
2159 |
} |
|
2160 |
||
2161 |
} // switch type |
|
2162 |
||
2163 |
} // appendContentSpec(XMLContentSpec.Provider,StringPool,XMLContentSpec,StringBuffer,boolean) |
|
2164 |
||
2165 |
// debugging |
|
2166 |
||
2167 |
private void printAttribute(int attributeDeclIndex) { |
|
2168 |
||
2169 |
XMLAttributeDecl attributeDecl = new XMLAttributeDecl(); |
|
2170 |
if (getAttributeDecl(attributeDeclIndex, attributeDecl)) { |
|
2171 |
System.out.print(" { "); |
|
2172 |
System.out.print(attributeDecl.name.localpart); |
|
2173 |
System.out.print(" }"); |
|
2174 |
} |
|
2175 |
||
2176 |
} // printAttribute(int) |
|
2177 |
||
2178 |
// content models |
|
2179 |
||
2180 |
/** |
|
2181 |
* When the element has a 'CHILDREN' model, this method is called to |
|
2182 |
* create the content model object. It looks for some special case simple |
|
2183 |
* models and creates SimpleContentModel objects for those. For the rest |
|
2184 |
* it creates the standard DFA style model. |
|
2185 |
*/ |
|
2186 |
private synchronized ContentModelValidator createChildModel(int contentSpecIndex) { |
|
2187 |
||
2188 |
// |
|
2189 |
// Get the content spec node for the element we are working on. |
|
2190 |
// This will tell us what kind of node it is, which tells us what |
|
2191 |
// kind of model we will try to create. |
|
2192 |
// |
|
2193 |
XMLContentSpec contentSpec = new XMLContentSpec(); |
|
2194 |
getContentSpec(contentSpecIndex, contentSpec); |
|
2195 |
||
2196 |
if ((contentSpec.type & 0x0f ) == XMLContentSpec.CONTENTSPECNODE_ANY || |
|
2197 |
(contentSpec.type & 0x0f ) == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER || |
|
2198 |
(contentSpec.type & 0x0f ) == XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL) { |
|
2199 |
// let fall through to build a DFAContentModel |
|
2200 |
} |
|
2201 |
||
2202 |
else if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_LEAF) { |
|
2203 |
// |
|
2204 |
// Check that the left value is not -1, since any content model |
|
2205 |
// with PCDATA should be MIXED, so we should not have gotten here. |
|
2206 |
// |
|
2207 |
if (contentSpec.value == null && contentSpec.otherValue == null) |
|
2208 |
throw new RuntimeException("ImplementationMessages.VAL_NPCD"); |
|
2209 |
||
2210 |
// |
|
2211 |
// Its a single leaf, so its an 'a' type of content model, i.e. |
|
2212 |
// just one instance of one element. That one is definitely a |
|
2213 |
// simple content model. |
|
2214 |
// |
|
2215 |
||
2216 |
fQName.setValues(null, (String)contentSpec.value, |
|
2217 |
(String)contentSpec.value, (String)contentSpec.otherValue); |
|
2218 |
return new SimpleContentModel(contentSpec.type, fQName, null); |
|
2219 |
} else if ((contentSpec.type == XMLContentSpec.CONTENTSPECNODE_CHOICE) |
|
2220 |
|| (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_SEQ)) { |
|
2221 |
// |
|
2222 |
// Lets see if both of the children are leafs. If so, then it |
|
2223 |
// it has to be a simple content model |
|
2224 |
// |
|
2225 |
XMLContentSpec contentSpecLeft = new XMLContentSpec(); |
|
2226 |
XMLContentSpec contentSpecRight = new XMLContentSpec(); |
|
2227 |
||
2228 |
getContentSpec( ((int[])contentSpec.value)[0], contentSpecLeft); |
|
2229 |
getContentSpec( ((int[])contentSpec.otherValue)[0], contentSpecRight); |
|
2230 |
||
2231 |
if ((contentSpecLeft.type == XMLContentSpec.CONTENTSPECNODE_LEAF) |
|
2232 |
&& (contentSpecRight.type == XMLContentSpec.CONTENTSPECNODE_LEAF)) { |
|
2233 |
// |
|
2234 |
// Its a simple choice or sequence, so we can do a simple |
|
2235 |
// content model for it. |
|
2236 |
// |
|
2237 |
fQName.setValues(null, (String)contentSpecLeft.value, |
|
2238 |
(String)contentSpecLeft.value, (String)contentSpecLeft.otherValue); |
|
2239 |
fQName2.setValues(null, (String)contentSpecRight.value, |
|
2240 |
(String)contentSpecRight.value, (String)contentSpecRight.otherValue); |
|
2241 |
return new SimpleContentModel(contentSpec.type, fQName, fQName2); |
|
2242 |
} |
|
2243 |
} else if ((contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE) |
|
2244 |
|| (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE) |
|
2245 |
|| (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE)) { |
|
2246 |
// |
|
2247 |
// Its a repetition, so see if its one child is a leaf. If so |
|
2248 |
// its a repetition of a single element, so we can do a simple |
|
2249 |
// content model for that. |
|
2250 |
// |
|
2251 |
XMLContentSpec contentSpecLeft = new XMLContentSpec(); |
|
2252 |
getContentSpec(((int[])contentSpec.value)[0], contentSpecLeft); |
|
2253 |
||
2254 |
if (contentSpecLeft.type == XMLContentSpec.CONTENTSPECNODE_LEAF) { |
|
2255 |
// |
|
2256 |
// It is, so we can create a simple content model here that |
|
2257 |
// will check for this repetition. We pass -1 for the unused |
|
2258 |
// right node. |
|
2259 |
// |
|
2260 |
fQName.setValues(null, (String)contentSpecLeft.value, |
|
2261 |
(String)contentSpecLeft.value, (String)contentSpecLeft.otherValue); |
|
2262 |
return new SimpleContentModel(contentSpec.type, fQName, null); |
|
2263 |
} |
|
2264 |
} else { |
|
2265 |
throw new RuntimeException("ImplementationMessages.VAL_CST"); |
|
2266 |
} |
|
2267 |
||
2268 |
// |
|
2269 |
// Its not a simple content model, so here we have to create a DFA |
|
2270 |
// for this element. So we create a DFAContentModel object. He |
|
2271 |
// encapsulates all of the work to create the DFA. |
|
2272 |
// |
|
2273 |
||
2274 |
fLeafCount = 0; |
|
2275 |
//int leafCount = countLeaves(contentSpecIndex); |
|
2276 |
fLeafCount = 0; |
|
2277 |
CMNode cmn = buildSyntaxTree(contentSpecIndex, contentSpec); |
|
2278 |
||
2279 |
// REVISIT: has to be fLeafCount because we convert x+ to x,x*, one more leaf |
|
2280 |
return new DFAContentModel( cmn, fLeafCount, false); |
|
2281 |
||
2282 |
} // createChildModel(int):ContentModelValidator |
|
2283 |
||
2284 |
private final CMNode buildSyntaxTree(int startNode, |
|
2285 |
XMLContentSpec contentSpec) { |
|
2286 |
||
2287 |
// We will build a node at this level for the new tree |
|
2288 |
CMNode nodeRet = null; |
|
2289 |
getContentSpec(startNode, contentSpec); |
|
2290 |
if ((contentSpec.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY) { |
|
2291 |
//nodeRet = new CMAny(contentSpec.type, -1, fLeafCount++); |
|
2292 |
nodeRet = new CMAny(contentSpec.type, (String)contentSpec.otherValue, fLeafCount++); |
|
2293 |
} |
|
2294 |
else if ((contentSpec.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER) { |
|
2295 |
nodeRet = new CMAny(contentSpec.type, (String)contentSpec.otherValue, fLeafCount++); |
|
2296 |
} |
|
2297 |
else if ((contentSpec.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL) { |
|
2298 |
nodeRet = new CMAny(contentSpec.type, null, fLeafCount++); |
|
2299 |
} |
|
2300 |
// |
|
2301 |
// If this node is a leaf, then its an easy one. We just add it |
|
2302 |
// to the tree. |
|
2303 |
// |
|
2304 |
else if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_LEAF) { |
|
2305 |
// |
|
2306 |
// Create a new leaf node, and pass it the current leaf count, |
|
2307 |
// which is its DFA state position. Bump the leaf count after |
|
2308 |
// storing it. This makes the positions zero based since we |
|
2309 |
// store first and then increment. |
|
2310 |
// |
|
2311 |
fQName.setValues(null, (String)contentSpec.value, |
|
2312 |
(String)contentSpec.value, (String)contentSpec.otherValue); |
|
2313 |
nodeRet = new CMLeaf(fQName, fLeafCount++); |
|
2314 |
} |
|
2315 |
else { |
|
2316 |
// |
|
2317 |
// Its not a leaf, so we have to recurse its left and maybe right |
|
2318 |
// nodes. Save both values before we recurse and trash the node. |
|
2319 |
final int leftNode = ((int[])contentSpec.value)[0]; |
|
2320 |
final int rightNode = ((int[])contentSpec.otherValue)[0]; |
|
2321 |
||
2322 |
if ((contentSpec.type == XMLContentSpec.CONTENTSPECNODE_CHOICE) |
|
2323 |
|| (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_SEQ)) { |
|
2324 |
// |
|
2325 |
// Recurse on both children, and return a binary op node |
|
2326 |
// with the two created sub nodes as its children. The node |
|
2327 |
// type is the same type as the source. |
|
2328 |
// |
|
2329 |
||
2330 |
nodeRet = new CMBinOp( contentSpec.type, buildSyntaxTree(leftNode, contentSpec) |
|
2331 |
, buildSyntaxTree(rightNode, contentSpec)); |
|
2332 |
} |
|
2333 |
else if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE) { |
|
2334 |
nodeRet = new CMUniOp( contentSpec.type, buildSyntaxTree(leftNode, contentSpec)); |
|
2335 |
} |
|
2336 |
else if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE |
|
2337 |
|| contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE |
|
2338 |
|| contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE) { |
|
2339 |
nodeRet = new CMUniOp(contentSpec.type, buildSyntaxTree(leftNode, contentSpec)); |
|
2340 |
} |
|
2341 |
else { |
|
2342 |
throw new RuntimeException("ImplementationMessages.VAL_CST"); |
|
2343 |
} |
|
2344 |
} |
|
2345 |
// And return our new node for this level |
|
2346 |
return nodeRet; |
|
2347 |
} |
|
2348 |
||
2349 |
/** |
|
2350 |
* Build a vector of valid QNames from Content Spec |
|
2351 |
* table. |
|
2352 |
* |
|
2353 |
* @param contentSpecIndex |
|
2354 |
* Content Spec index |
|
2355 |
* @param vectorQName |
|
2356 |
* Array of QName |
|
2357 |
* @exception RuntimeException |
|
2358 |
*/ |
|
2359 |
private void contentSpecTree(int contentSpecIndex, |
|
2360 |
XMLContentSpec contentSpec, |
|
2361 |
ChildrenList children) { |
|
2362 |
||
2363 |
// Handle any and leaf nodes |
|
2364 |
getContentSpec( contentSpecIndex, contentSpec); |
|
2365 |
if ( contentSpec.type == XMLContentSpec.CONTENTSPECNODE_LEAF || |
|
2366 |
(contentSpec.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY || |
|
2367 |
(contentSpec.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL || |
|
2368 |
(contentSpec.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER) { |
|
2369 |
||
2370 |
// resize arrays, if needed |
|
2371 |
if (children.length == children.qname.length) { |
|
2372 |
QName[] newQName = new QName[children.length * 2]; |
|
2373 |
System.arraycopy(children.qname, 0, newQName, 0, children.length); |
|
2374 |
children.qname = newQName; |
|
2375 |
int[] newType = new int[children.length * 2]; |
|
2376 |
System.arraycopy(children.type, 0, newType, 0, children.length); |
|
2377 |
children.type = newType; |
|
2378 |
} |
|
2379 |
||
2380 |
// save values and return length |
|
2381 |
children.qname[children.length] = new QName(null, (String)contentSpec.value, |
|
2382 |
(String) contentSpec.value, |
|
2383 |
(String) contentSpec.otherValue); |
|
2384 |
children.type[children.length] = contentSpec.type; |
|
2385 |
children.length++; |
|
2386 |
return; |
|
2387 |
} |
|
2388 |
||
2389 |
// |
|
2390 |
// Its not a leaf, so we have to recurse its left and maybe right |
|
2391 |
// nodes. Save both values before we recurse and trash the node. |
|
2392 |
// |
|
2393 |
final int leftNode = contentSpec.value != null |
|
2394 |
? ((int[])(contentSpec.value))[0] : -1; |
|
2395 |
int rightNode = -1 ; |
|
2396 |
if (contentSpec.otherValue != null ) |
|
2397 |
rightNode = ((int[])(contentSpec.otherValue))[0]; |
|
2398 |
else |
|
2399 |
return; |
|
2400 |
||
2401 |
if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_CHOICE || |
|
2402 |
contentSpec.type == XMLContentSpec.CONTENTSPECNODE_SEQ) { |
|
2403 |
contentSpecTree(leftNode, contentSpec, children); |
|
2404 |
contentSpecTree(rightNode, contentSpec, children); |
|
2405 |
return; |
|
2406 |
} |
|
2407 |
||
2408 |
if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE || |
|
2409 |
contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE || |
|
2410 |
contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE) { |
|
2411 |
contentSpecTree(leftNode, contentSpec, children); |
|
2412 |
return; |
|
2413 |
} |
|
2414 |
||
2415 |
// error |
|
2416 |
throw new RuntimeException("Invalid content spec type seen in contentSpecTree() method of AbstractDTDGrammar class : "+contentSpec.type); |
|
2417 |
||
2418 |
} // contentSpecTree(int,XMLContentSpec,ChildrenList) |
|
2419 |
||
2420 |
// ensure capacity |
|
2421 |
||
2422 |
private void ensureElementDeclCapacity(int chunk) { |
|
2423 |
if (chunk >= fElementDeclName.length) { |
|
2424 |
fElementDeclIsExternal = resize(fElementDeclIsExternal, |
|
2425 |
fElementDeclIsExternal.length * 2); |
|
2426 |
||
2427 |
fElementDeclName = resize(fElementDeclName, fElementDeclName.length * 2); |
|
2428 |
fElementDeclType = resize(fElementDeclType, fElementDeclType.length * 2); |
|
2429 |
fElementDeclContentModelValidator = resize(fElementDeclContentModelValidator, fElementDeclContentModelValidator.length * 2); |
|
2430 |
fElementDeclContentSpecIndex = resize(fElementDeclContentSpecIndex,fElementDeclContentSpecIndex.length * 2); |
|
2431 |
fElementDeclFirstAttributeDeclIndex = resize(fElementDeclFirstAttributeDeclIndex, fElementDeclFirstAttributeDeclIndex.length * 2); |
|
2432 |
fElementDeclLastAttributeDeclIndex = resize(fElementDeclLastAttributeDeclIndex, fElementDeclLastAttributeDeclIndex.length * 2); |
|
2433 |
} |
|
2434 |
else if (fElementDeclName[chunk] != null) { |
|
2435 |
return; |
|
2436 |
} |
|
2437 |
||
2438 |
fElementDeclIsExternal[chunk] = new int[CHUNK_SIZE]; |
|
2439 |
fElementDeclName[chunk] = new QName[CHUNK_SIZE]; |
|
2440 |
fElementDeclType[chunk] = new short[CHUNK_SIZE]; |
|
2441 |
fElementDeclContentModelValidator[chunk] = new ContentModelValidator[CHUNK_SIZE]; |
|
2442 |
fElementDeclContentSpecIndex[chunk] = new int[CHUNK_SIZE]; |
|
2443 |
fElementDeclFirstAttributeDeclIndex[chunk] = new int[CHUNK_SIZE]; |
|
2444 |
fElementDeclLastAttributeDeclIndex[chunk] = new int[CHUNK_SIZE]; |
|
2445 |
return; |
|
2446 |
} |
|
2447 |
||
2448 |
private void ensureAttributeDeclCapacity(int chunk) { |
|
2449 |
||
2450 |
if (chunk >= fAttributeDeclName.length) { |
|
2451 |
fAttributeDeclIsExternal = resize(fAttributeDeclIsExternal, |
|
2452 |
fAttributeDeclIsExternal.length * 2); |
|
2453 |
fAttributeDeclName = resize(fAttributeDeclName, fAttributeDeclName.length * 2); |
|
2454 |
fAttributeDeclType = resize(fAttributeDeclType, fAttributeDeclType.length * 2); |
|
2455 |
fAttributeDeclEnumeration = resize(fAttributeDeclEnumeration, fAttributeDeclEnumeration.length * 2); |
|
2456 |
fAttributeDeclDefaultType = resize(fAttributeDeclDefaultType, fAttributeDeclDefaultType.length * 2); |
|
2457 |
fAttributeDeclDatatypeValidator = resize(fAttributeDeclDatatypeValidator, fAttributeDeclDatatypeValidator.length * 2); |
|
2458 |
fAttributeDeclDefaultValue = resize(fAttributeDeclDefaultValue, fAttributeDeclDefaultValue.length * 2); |
|
2459 |
fAttributeDeclNonNormalizedDefaultValue = resize(fAttributeDeclNonNormalizedDefaultValue, fAttributeDeclNonNormalizedDefaultValue.length * 2); |
|
2460 |
fAttributeDeclNextAttributeDeclIndex = resize(fAttributeDeclNextAttributeDeclIndex, fAttributeDeclNextAttributeDeclIndex.length * 2); |
|
2461 |
} |
|
2462 |
else if (fAttributeDeclName[chunk] != null) { |
|
2463 |
return; |
|
2464 |
} |
|
2465 |
||
2466 |
fAttributeDeclIsExternal[chunk] = new int[CHUNK_SIZE]; |
|
2467 |
fAttributeDeclName[chunk] = new QName[CHUNK_SIZE]; |
|
2468 |
fAttributeDeclType[chunk] = new short[CHUNK_SIZE]; |
|
2469 |
fAttributeDeclEnumeration[chunk] = new String[CHUNK_SIZE][]; |
|
2470 |
fAttributeDeclDefaultType[chunk] = new short[CHUNK_SIZE]; |
|
2471 |
fAttributeDeclDatatypeValidator[chunk] = new DatatypeValidator[CHUNK_SIZE]; |
|
2472 |
fAttributeDeclDefaultValue[chunk] = new String[CHUNK_SIZE]; |
|
2473 |
fAttributeDeclNonNormalizedDefaultValue[chunk] = new String[CHUNK_SIZE]; |
|
2474 |
fAttributeDeclNextAttributeDeclIndex[chunk] = new int[CHUNK_SIZE]; |
|
2475 |
return; |
|
2476 |
} |
|
2477 |
||
2478 |
private void ensureEntityDeclCapacity(int chunk) { |
|
2479 |
if (chunk >= fEntityName.length) { |
|
2480 |
fEntityName = resize(fEntityName, fEntityName.length * 2); |
|
2481 |
fEntityValue = resize(fEntityValue, fEntityValue.length * 2); |
|
2482 |
fEntityPublicId = resize(fEntityPublicId, fEntityPublicId.length * 2); |
|
2483 |
fEntitySystemId = resize(fEntitySystemId, fEntitySystemId.length * 2); |
|
2484 |
fEntityBaseSystemId = resize(fEntityBaseSystemId, fEntityBaseSystemId.length * 2); |
|
2485 |
fEntityNotation = resize(fEntityNotation, fEntityNotation.length * 2); |
|
2486 |
fEntityIsPE = resize(fEntityIsPE, fEntityIsPE.length * 2); |
|
2487 |
fEntityInExternal = resize(fEntityInExternal, fEntityInExternal.length * 2); |
|
2488 |
} |
|
2489 |
else if (fEntityName[chunk] != null) { |
|
2490 |
return; |
|
2491 |
} |
|
2492 |
||
2493 |
fEntityName[chunk] = new String[CHUNK_SIZE]; |
|
2494 |
fEntityValue[chunk] = new String[CHUNK_SIZE]; |
|
2495 |
fEntityPublicId[chunk] = new String[CHUNK_SIZE]; |
|
2496 |
fEntitySystemId[chunk] = new String[CHUNK_SIZE]; |
|
2497 |
fEntityBaseSystemId[chunk] = new String[CHUNK_SIZE]; |
|
2498 |
fEntityNotation[chunk] = new String[CHUNK_SIZE]; |
|
2499 |
fEntityIsPE[chunk] = new byte[CHUNK_SIZE]; |
|
2500 |
fEntityInExternal[chunk] = new byte[CHUNK_SIZE]; |
|
2501 |
return; |
|
2502 |
} |
|
2503 |
||
2504 |
private void ensureNotationDeclCapacity(int chunk) { |
|
2505 |
if (chunk >= fNotationName.length) { |
|
2506 |
fNotationName = resize(fNotationName, fNotationName.length * 2); |
|
2507 |
fNotationPublicId = resize(fNotationPublicId, fNotationPublicId.length * 2); |
|
2508 |
fNotationSystemId = resize(fNotationSystemId, fNotationSystemId.length * 2); |
|
2509 |
fNotationBaseSystemId = resize(fNotationBaseSystemId, fNotationBaseSystemId.length * 2); |
|
2510 |
} |
|
2511 |
else if (fNotationName[chunk] != null) { |
|
2512 |
return; |
|
2513 |
} |
|
2514 |
||
2515 |
fNotationName[chunk] = new String[CHUNK_SIZE]; |
|
2516 |
fNotationPublicId[chunk] = new String[CHUNK_SIZE]; |
|
2517 |
fNotationSystemId[chunk] = new String[CHUNK_SIZE]; |
|
2518 |
fNotationBaseSystemId[chunk] = new String[CHUNK_SIZE]; |
|
2519 |
return; |
|
2520 |
} |
|
2521 |
||
2522 |
private void ensureContentSpecCapacity(int chunk) { |
|
2523 |
if (chunk >= fContentSpecType.length) { |
|
2524 |
fContentSpecType = resize(fContentSpecType, fContentSpecType.length * 2); |
|
2525 |
fContentSpecValue = resize(fContentSpecValue, fContentSpecValue.length * 2); |
|
2526 |
fContentSpecOtherValue = resize(fContentSpecOtherValue, fContentSpecOtherValue.length * 2); |
|
2527 |
} |
|
2528 |
else if (fContentSpecType[chunk] != null) { |
|
2529 |
return; |
|
2530 |
} |
|
2531 |
||
2532 |
fContentSpecType[chunk] = new short[CHUNK_SIZE]; |
|
2533 |
fContentSpecValue[chunk] = new Object[CHUNK_SIZE]; |
|
2534 |
fContentSpecOtherValue[chunk] = new Object[CHUNK_SIZE]; |
|
2535 |
return; |
|
2536 |
} |
|
2537 |
||
2538 |
// |
|
2539 |
// Private static methods |
|
2540 |
// |
|
2541 |
||
2542 |
// resize chunks |
|
2543 |
||
2544 |
private static byte[][] resize(byte array[][], int newsize) { |
|
2545 |
byte newarray[][] = new byte[newsize][]; |
|
2546 |
System.arraycopy(array, 0, newarray, 0, array.length); |
|
2547 |
return newarray; |
|
2548 |
} |
|
2549 |
||
2550 |
private static short[][] resize(short array[][], int newsize) { |
|
2551 |
short newarray[][] = new short[newsize][]; |
|
2552 |
System.arraycopy(array, 0, newarray, 0, array.length); |
|
2553 |
return newarray; |
|
2554 |
} |
|
2555 |
||
2556 |
private static int[][] resize(int array[][], int newsize) { |
|
2557 |
int newarray[][] = new int[newsize][]; |
|
2558 |
System.arraycopy(array, 0, newarray, 0, array.length); |
|
2559 |
return newarray; |
|
2560 |
} |
|
2561 |
||
2562 |
private static DatatypeValidator[][] resize(DatatypeValidator array[][], int newsize) { |
|
2563 |
DatatypeValidator newarray[][] = new DatatypeValidator[newsize][]; |
|
2564 |
System.arraycopy(array, 0, newarray, 0, array.length); |
|
2565 |
return newarray; |
|
2566 |
} |
|
2567 |
||
2568 |
private static ContentModelValidator[][] resize(ContentModelValidator array[][], int newsize) { |
|
2569 |
ContentModelValidator newarray[][] = new ContentModelValidator[newsize][]; |
|
2570 |
System.arraycopy(array, 0, newarray, 0, array.length); |
|
2571 |
return newarray; |
|
2572 |
} |
|
2573 |
||
2574 |
private static Object[][] resize(Object array[][], int newsize) { |
|
2575 |
Object newarray[][] = new Object[newsize][]; |
|
2576 |
System.arraycopy(array, 0, newarray, 0, array.length); |
|
2577 |
return newarray; |
|
2578 |
} |
|
2579 |
||
2580 |
private static QName[][] resize(QName array[][], int newsize) { |
|
2581 |
QName newarray[][] = new QName[newsize][]; |
|
2582 |
System.arraycopy(array, 0, newarray, 0, array.length); |
|
2583 |
return newarray; |
|
2584 |
} |
|
2585 |
||
2586 |
private static String[][] resize(String array[][], int newsize) { |
|
2587 |
String newarray[][] = new String[newsize][]; |
|
2588 |
System.arraycopy(array, 0, newarray, 0, array.length); |
|
2589 |
return newarray; |
|
2590 |
} |
|
2591 |
||
2592 |
private static String[][][] resize(String array[][][], int newsize) { |
|
2593 |
String newarray[][][] = new String[newsize] [][]; |
|
2594 |
System.arraycopy(array, 0, newarray, 0, array.length); |
|
2595 |
return newarray; |
|
2596 |
} |
|
2597 |
||
2598 |
// |
|
2599 |
// Classes |
|
2600 |
// |
|
2601 |
||
2602 |
/** |
|
2603 |
* Children list for <code>contentSpecTree</code> method. |
|
2604 |
* |
|
2605 |
* @xerces.internal |
|
2606 |
* |
|
2607 |
* @author Eric Ye, IBM |
|
2608 |
*/ |
|
2609 |
private static class ChildrenList { |
|
2610 |
||
2611 |
// |
|
2612 |
// Data |
|
2613 |
// |
|
2614 |
||
2615 |
/** Length. */ |
|
2616 |
public int length = 0; |
|
2617 |
||
2618 |
// NOTE: The following set of data is mutually exclusive. It is |
|
2619 |
// written this way because Java doesn't have a native |
|
2620 |
// union data structure. -Ac |
|
2621 |
||
2622 |
/** Left and right children names. */ |
|
2623 |
public QName[] qname = new QName[2]; |
|
2624 |
||
2625 |
/** Left and right children types. */ |
|
2626 |
public int[] type = new int[2]; |
|
2627 |
||
2628 |
// |
|
2629 |
// Constructors |
|
2630 |
// |
|
2631 |
||
2632 |
public ChildrenList () {} |
|
2633 |
||
2634 |
} // class ChildrenList |
|
2635 |
||
2636 |
// |
|
2637 |
// EntityState methods |
|
2638 |
// |
|
2639 |
public boolean isEntityDeclared (String name){ |
|
2640 |
return (getEntityDeclIndex(name)!=-1)?true:false; |
|
2641 |
} |
|
2642 |
||
2643 |
public boolean isEntityUnparsed (String name){ |
|
2644 |
int entityIndex = getEntityDeclIndex(name); |
|
2645 |
if (entityIndex >-1) { |
|
2646 |
int chunk = entityIndex >> CHUNK_SHIFT; |
|
2647 |
int index = entityIndex & CHUNK_MASK; |
|
2648 |
//for unparsed entity notation!=null |
|
2649 |
return (fEntityNotation[chunk][index]!=null)?true:false; |
|
2650 |
} |
|
2651 |
return false; |
|
2652 |
} |
|
2653 |
} // class DTDGrammar |