KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > apache > xerces > readers > DefaultEntityHandler


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  *
5  * Copyright (c) 1999,2000 The Apache Software Foundation. All rights
6  * reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Apache Software Foundation (http://www.apache.org/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Xerces" and "Apache Software Foundation" must
28  * not be used to endorse or promote products derived from this
29  * software without prior written permission. For written
30  * permission, please contact apache@apache.org.
31  *
32  * 5. Products derived from this software may not be called "Apache",
33  * nor may "Apache" appear in their name, without prior written
34  * permission of the Apache Software Foundation.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47  * SUCH DAMAGE.
48  * ====================================================================
49  *
50  * This software consists of voluntary contributions made by many
51  * individuals on behalf of the Apache Software Foundation and was
52  * originally based on software copyright (c) 1999, International
53  * Business Machines, Inc., http://www.apache.org. For more
54  * information on the Apache Software Foundation, please see
55  * <http://www.apache.org/>.
56  */

57
58 package org.enhydra.apache.xerces.readers;
59
60 import java.io.FileNotFoundException JavaDoc;
61 import java.io.UnsupportedEncodingException JavaDoc;
62 import java.net.MalformedURLException JavaDoc;
63 import java.util.Stack JavaDoc;
64 import java.util.Vector JavaDoc;
65
66 import org.enhydra.apache.xerces.framework.XMLErrorReporter;
67 import org.enhydra.apache.xerces.utils.ImplementationMessages;
68 import org.enhydra.apache.xerces.utils.QName;
69 import org.enhydra.apache.xerces.utils.StringPool;
70 import org.enhydra.apache.xerces.utils.URI;
71 import org.enhydra.apache.xerces.utils.XMLCharacterProperties;
72 import org.enhydra.apache.xerces.utils.XMLMessages;
73 import org.xml.sax.EntityResolver JavaDoc;
74 import org.xml.sax.InputSource JavaDoc;
75 import org.xml.sax.Locator JavaDoc;
76 import org.xml.sax.helpers.LocatorImpl JavaDoc;
77
78 /**
79  * Default entity handler implementation.
80  *
81  * @version $Id: DefaultEntityHandler.java,v 1.2 2005/01/26 08:28:44 jkjome Exp $
82  */

83 public class DefaultEntityHandler
84     implements XMLEntityHandler, XMLEntityHandler.DTDHandler {
85
86     public interface EventHandler {
87         public void startEntityReference(int entityName, int entityType, int entityContext) throws Exception JavaDoc;
88         public void endEntityReference(int entityName, int entityType, int entityContext) throws Exception JavaDoc;
89         public void sendEndOfInputNotifications(int entityName, boolean moreToFollow) throws Exception JavaDoc;
90         public void sendReaderChangeNotifications(XMLEntityHandler.EntityReader reader, int readerId) throws Exception JavaDoc;
91         public boolean externalEntityStandaloneCheck();
92         public boolean getValidating();
93     }
94
95     //
96
// Data
97
//
98
private class ReaderState {
99         XMLEntityHandler.EntityReader reader;
100         InputSource JavaDoc source;
101         int entityName;
102         int entityType;
103         int entityContext;
104         String JavaDoc publicId;
105         String JavaDoc systemId;
106         int readerId;
107         int depth;
108         ReaderState nextReaderState;
109     }
110     private ReaderState fReaderStateFreeList = null;
111     private StringPool fStringPool = null;
112     private EventHandler fEventHandler = null;
113     private XMLEntityHandler.CharDataHandler fCharDataHandler = null;
114     private XMLErrorReporter fErrorReporter = null;
115     private EntityResolver JavaDoc fResolver = null;
116     private EntityPool fEntityPool = null;
117     private EntityPool fParameterEntityPool = null;
118     private byte[] fEntityTypeStack = null;
119     private int[] fEntityNameStack = null;
120     private int fEntityStackDepth = 0;
121     private Stack JavaDoc fReaderStack = new Stack JavaDoc();
122     private XMLEntityHandler.EntityReader fReader = null;
123     private InputSource JavaDoc fSource = null;
124     private int fEntityName = -1;
125     private int fEntityType = -1;
126     private int fEntityContext = -1;
127     private String JavaDoc fPublicId = null;
128     private String JavaDoc fSystemId = null;
129     private int fReaderId = -1;
130     private int fReaderDepth = -1;
131     private int fNextReaderId = 0;
132     private NullReader fNullReader = null;
133     protected XMLEntityReaderFactory fReaderFactory = null;
134     private boolean fSendCharDataAsCharArray = false;
135
136     public DefaultEntityHandler(StringPool stringPool, XMLErrorReporter errorReporter) {
137         fStringPool = stringPool;
138         fErrorReporter = errorReporter;
139         fReaderFactory = new DefaultReaderFactory();
140         fEntityPool = new EntityPool(fStringPool, fErrorReporter, true);
141     }
142
143     public void setEventHandler(EventHandler eventHandler) {
144         fEventHandler = eventHandler;
145     }
146
147     public void setCharDataHandler(XMLEntityHandler.CharDataHandler charDataHandler) {
148         fCharDataHandler = charDataHandler;
149     }
150
151     public XMLEntityHandler.CharDataHandler getCharDataHandler() {
152         return fCharDataHandler;
153     }
154
155     /**
156      * Set char data processing preference.
157      */

158     public void setSendCharDataAsCharArray(boolean flag) {
159         fSendCharDataAsCharArray = flag;
160         fReaderFactory.setSendCharDataAsCharArray(fSendCharDataAsCharArray);
161     }
162
163     /**
164      * Set the reader factory.
165      */

166     public void setReaderFactory(XMLEntityReaderFactory readerFactory) {
167         fReaderFactory = readerFactory;
168         fReaderFactory.setSendCharDataAsCharArray(fSendCharDataAsCharArray);
169     }
170
171     /**
172      * Reset the entity handler.
173      */

174     public void reset(StringPool stringPool) {
175         fStringPool = stringPool;
176         fEntityPool.reset(fStringPool);
177         fParameterEntityPool = null;
178         fReaderStack.removeAllElements();
179         fEntityStackDepth = 0;
180         fReader = null;
181         fSource = null;
182         fEntityName = -1;
183         fEntityType = -1;
184         fEntityContext = -1;
185         fPublicId = null;
186         fSystemId = null;
187         fReaderId = -1;
188         fReaderDepth = -1;
189         fNextReaderId = 0;
190     }
191
192     /**
193      *
194      */

195     public void setAllowJavaEncodings(boolean flag) {
196         fReaderFactory.setAllowJavaEncodingName(flag);
197     }
198     /**
199      *
200      */

201     public boolean getAllowJavaEncodings() {
202         return fReaderFactory.getAllowJavaEncodingName();
203     }
204
205     //
206
//
207
//
208
public int addInternalPEDecl(int name, int value, boolean isExternal) throws Exception JavaDoc {
209         if (fParameterEntityPool == null)
210             fParameterEntityPool = new EntityPool(fStringPool, fErrorReporter, false);
211         int entityHandle = fParameterEntityPool.addEntityDecl(name, value, -1, -1, -1, -1, isExternal);
212         return entityHandle;
213     }
214     public int addExternalPEDecl(int name, int publicId, int systemId, boolean isExternal) throws Exception JavaDoc {
215         if (fParameterEntityPool == null)
216             fParameterEntityPool = new EntityPool(fStringPool, fErrorReporter, false);
217         int entityHandle = fParameterEntityPool.addEntityDecl(name, -1, publicId, systemId, fStringPool.addSymbol(fSystemId), -1, isExternal);
218         return entityHandle;
219     }
220     public int addInternalEntityDecl(int name, int value, boolean isExternal) throws Exception JavaDoc {
221         int entityHandle = fEntityPool.addEntityDecl(name, value, -1, -1, -1, -1, isExternal);
222         return entityHandle;
223     }
224     public int addExternalEntityDecl(int name, int publicId, int systemId, boolean isExternal) throws Exception JavaDoc {
225         int entityHandle = fEntityPool.addEntityDecl(name, -1, publicId, systemId, fStringPool.addSymbol(fSystemId), -1, isExternal);
226         return entityHandle;
227     }
228     public int addUnparsedEntityDecl(int name, int publicId, int systemId, int notationName, boolean isExternal) throws Exception JavaDoc {
229         int entityHandle = fEntityPool.addEntityDecl(name, -1, publicId, systemId, fStringPool.addSymbol(fSystemId), notationName, isExternal);
230         if (!fEntityPool.isNotationDeclared(notationName)) {
231             Object JavaDoc[] args = { fStringPool.toString(name),
232                               fStringPool.toString(notationName) };
233             fEntityPool.addRequiredNotation(notationName,
234                                             fErrorReporter.getLocator(),
235                                             XMLMessages.MSG_NOTATION_NOT_DECLARED_FOR_UNPARSED_ENTITYDECL,
236                                             XMLMessages.VC_NOTATION_DECLARED,
237                                             args);
238         }
239         return entityHandle;
240     }
241     public int addNotationDecl(int notationName, int publicId, int systemId, boolean isExternal) throws Exception JavaDoc {
242         int notationHandle = fEntityPool.addNotationDecl(notationName, publicId, systemId, fStringPool.addSymbol(fSystemId), isExternal);
243         return notationHandle;
244     }
245     public boolean isUnparsedEntity(int entityName) {
246         int entityHandle = fEntityPool.lookupEntity(entityName);
247         return (entityHandle != -1 && fEntityPool.isUnparsedEntity(entityHandle));
248     }
249     public boolean isNotationDeclared(int notationName) {
250         return fEntityPool.isNotationDeclared(notationName);
251     }
252     public void addRequiredNotation(int notationName, Locator JavaDoc locator, int majorCode, int minorCode, Object JavaDoc[] args) {
253         fEntityPool.addRequiredNotation(notationName, locator, majorCode, minorCode, args);
254     }
255     public void checkRequiredNotations() throws Exception JavaDoc {
256         fEntityPool.checkRequiredNotations();
257     }
258
259     protected int lookupEntity(int entityNameIndex) {
260         int entityIndex = fEntityPool.lookupEntity(entityNameIndex);
261         return entityIndex;
262     }
263     private void reportRecoverableXMLError(int majorCode, int minorCode, int stringIndex1) throws Exception JavaDoc {
264         Object JavaDoc[] args = { fStringPool.toString(stringIndex1) };
265         fErrorReporter.reportError(fErrorReporter.getLocator(),
266                                    XMLMessages.XML_DOMAIN,
267                                    majorCode,
268                                    minorCode,
269                                    args,
270                                    XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
271     }
272     public boolean externalReferenceInContent(int entityHandle) throws Exception JavaDoc {
273         boolean external = fEntityPool.isExternalEntity(entityHandle);
274         if (fEventHandler.externalEntityStandaloneCheck()) {
275             if (external) {
276                 reportRecoverableXMLError(XMLMessages.MSG_EXTERNAL_ENTITY_NOT_PERMITTED,
277                                           XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
278                                           fEntityName);
279             } else if (fEntityPool.getEntityDeclIsExternal(entityHandle)) {
280                 reportRecoverableXMLError(XMLMessages.MSG_REFERENCE_TO_EXTERNALLY_DECLARED_ENTITY_WHEN_STANDALONE,
281                                           XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
282                                           fEntityName);
283             }
284         }
285         return external;
286     }
287     protected int valueOfReferenceInAttValue(int entityHandle) throws Exception JavaDoc {
288         if (fEventHandler.externalEntityStandaloneCheck() && fEntityPool.getEntityDeclIsExternal(entityHandle)) {
289             reportRecoverableXMLError(XMLMessages.MSG_REFERENCE_TO_EXTERNALLY_DECLARED_ENTITY_WHEN_STANDALONE,
290                                       XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
291                                       fEntityName);
292         }
293         int entityValue = fEntityPool.getEntityValue(entityHandle);
294         return entityValue;
295     }
296     protected boolean isExternalEntity(int entityHandle) {
297         boolean external = fEntityPool.isExternalEntity(entityHandle);
298         return external;
299     }
300     protected int getEntityValue(int entityHandle) {
301         int value = fEntityPool.getEntityValue(entityHandle);
302         return value;
303     }
304     protected String JavaDoc getPublicIdOfEntity(int entityHandle) {
305         int publicId = fEntityPool.getPublicId(entityHandle);
306         return fStringPool.toString(publicId);
307     }
308     protected String JavaDoc getSystemIdOfEntity(int entityHandle) {
309         int systemId = fEntityPool.getSystemId(entityHandle);
310         return fStringPool.toString(systemId);
311     }
312     protected int lookupParameterEntity(int peName) throws Exception JavaDoc {
313         int entityHandle = -1;
314         if (fParameterEntityPool != null)
315             entityHandle = fParameterEntityPool.lookupEntity(peName);
316         return entityHandle;
317     }
318     protected boolean isExternalParameterEntity(int peIndex) {
319         boolean external = fParameterEntityPool.isExternalEntity(peIndex);
320         return external;
321     }
322     protected int getParameterEntityValue(int peIndex) {
323         int value = fParameterEntityPool.getEntityValue(peIndex);
324         return value;
325     }
326     protected String JavaDoc getPublicIdOfParameterEntity(int peIndex) {
327         int publicId = fParameterEntityPool.getPublicId(peIndex);
328         return fStringPool.toString(publicId);
329     }
330     protected String JavaDoc getSystemIdOfParameterEntity(int peIndex) {
331         int systemId = fParameterEntityPool.getSystemId(peIndex);
332         return fStringPool.toString(systemId);
333     }
334
335     /**
336      * get the Entity reader.
337      */

338     public XMLEntityHandler.EntityReader getEntityReader() {
339         return fReader;
340     }
341
342     /**
343      * Adds a recognizer.
344      *
345      * @param recognizer The XML recognizer to add.
346      */

347     public void addRecognizer(XMLDeclRecognizer recognizer) {
348         fReaderFactory.addRecognizer(recognizer);
349     }
350
351     /**
352      * Sets the resolver used to resolve external entities. The EntityResolver
353      * interface supports resolution of public and system identifiers.
354      *
355      * @param resolver The new entity resolver. Passing a null value will
356      * uninstall the currently installed resolver.
357      */

358     public void setEntityResolver(EntityResolver JavaDoc resolver) {
359         fResolver = resolver;
360     }
361
362     /**
363      * Gets the resolver used to resolve external entities. The EntityResolver
364      * interface supports resolution of public and system identifiers.
365      *
366      * @return The current entity resolver.
367      */

368     public EntityResolver JavaDoc getEntityResolver() {
369         return fResolver;
370     }
371
372     /**
373      * Expands a system id and returns the system id as a URI, if
374      * it can be expanded. A return value of null means that the
375      * identifier is already expanded. An exception thrown
376      * indicates a failure to expand the id.
377      *
378      * @param systemId The systemId to be expanded.
379      *
380      * @return Returns the URI string representing the expanded system
381      * identifier. A null value indicates that the given
382      * system identifier is already expanded.
383      *
384      */

385     public String JavaDoc expandSystemId(String JavaDoc systemId) {
386         return expandSystemId(systemId, fSystemId);
387     }
388     private String JavaDoc expandSystemId(String JavaDoc systemId, String JavaDoc currentSystemId) {
389         String JavaDoc id = systemId;
390
391         // check for bad parameters id
392
if (id == null || id.length() == 0) {
393             // REVISIT: returning null here will result in NPE
394
// for notations and entity declarations
395
return "";
396         }
397
398         // if id already expanded, return
399
try {
400             URI uri = new URI(id);
401             if (uri != null) {
402                 return systemId;
403             }
404         }
405         catch (URI.MalformedURIException e) {
406             // continue on...
407
}
408
409         // normalize id
410
id = fixURI(id);
411
412         // normalize base
413
URI base = null;
414         URI uri = null;
415         try {
416             if (currentSystemId == null) {
417                 String JavaDoc dir;
418                 try {
419                     dir = fixURI(System.getProperty("user.dir"));
420                 }
421                 catch (SecurityException JavaDoc se) {
422                     dir = "";
423                 }
424                 if (!dir.endsWith("/")) {
425                     dir = dir + "/";
426                 }
427                 base = new URI("file", "", dir, null, null);
428             }
429             else {
430                 base = new URI(currentSystemId);
431             }
432
433             // expand id
434
uri = new URI(base, id);
435         }
436         catch (Exception JavaDoc e) {
437             // let it go through
438
}
439         if (uri == null) {
440             return systemId;
441         }
442         return uri.toString();
443     }
444
445     //
446
// Private methods
447
//
448

449     /**
450      * Fixes a platform dependent filename to standard URI form.
451      *
452      * @param str The string to fix.
453      *
454      * @return Returns the fixed URI string.
455      */

456     private static String JavaDoc fixURI(String JavaDoc str) {
457
458         // handle platform dependent strings
459
str = str.replace(java.io.File.separatorChar, '/');
460
461         // Windows fix
462
if (str.length() >= 2) {
463             char ch1 = str.charAt(1);
464             if (ch1 == ':') {
465                 char ch0 = Character.toUpperCase(str.charAt(0));
466                 if (ch0 >= 'A' && ch0 <= 'Z') {
467                     str = "/" + str;
468                 }
469             }
470         }
471
472         // done
473
return str;
474     }
475
476     public boolean startReadingFromDocument(InputSource JavaDoc source) throws Exception JavaDoc {
477         pushEntity(false, -2); // Document Entity
478
fSystemId = null;
479         pushNullReader();
480         fEntityName = -2; // Document Entity
481
fEntityType = ENTITYTYPE_DOCUMENT;
482         fEntityContext = ENTITYREF_DOCUMENT;
483         fReaderDepth = 0;
484         fReaderId = fNextReaderId++;
485         fPublicId = source.getPublicId();
486         fSystemId = source.getSystemId();
487         fEventHandler.startEntityReference(fEntityName, fEntityType, fEntityContext);
488         fSystemId = expandSystemId(fSystemId, null);
489         fSource = source;
490         boolean xmlDecl = true; // xmlDecl if true, textDecl if false
491
try {
492             fReader = fReaderFactory.createReader(this, fErrorReporter, source, fSystemId, xmlDecl, fStringPool);
493         } catch (MalformedURLException JavaDoc mu) {
494             String JavaDoc errorSystemId = fSystemId;
495             fEventHandler.endEntityReference(fEntityName, fEntityType, fEntityContext);
496             popReader();
497             popEntity();
498             fReader = null;
499             Object JavaDoc[] args = { errorSystemId };
500             fErrorReporter.reportError(fErrorReporter.getLocator(),
501                                         ImplementationMessages.XERCES_IMPLEMENTATION_DOMAIN,
502                                         ImplementationMessages.IO0,
503                                         0,
504                                         args,
505                                         XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
506         } catch (FileNotFoundException JavaDoc fnf) {
507             // according to the JAXP spec, SAXExceptions should not be
508
// generated in this case! - neilg
509
String JavaDoc errorSystemId = fSystemId;
510             fEventHandler.endEntityReference(fEntityName, fEntityType, fEntityContext);
511             popReader();
512             popEntity();
513             fReader = null;
514             Object JavaDoc[] args = { errorSystemId };
515             fErrorReporter.reportError(fErrorReporter.getLocator(),
516                                         ImplementationMessages.XERCES_IMPLEMENTATION_DOMAIN,
517                                         ImplementationMessages.IO0,
518                                         0,
519                                         args,
520                                         XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
521             throw fnf;
522         } catch (UnsupportedEncodingException JavaDoc uee) {
523             fEventHandler.endEntityReference(fEntityName, fEntityType, fEntityContext);
524             popReader();
525             popEntity();
526             fReader = null;
527             String JavaDoc encoding = uee.getMessage();
528             if (encoding == null) {
529                 fErrorReporter.reportError(fErrorReporter.getLocator(),
530                                            XMLMessages.XML_DOMAIN,
531                                            XMLMessages.MSG_ENCODING_REQUIRED,
532                                            XMLMessages.P81_REQUIRED,
533                                            null,
534                                            XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
535             } else if (!XMLCharacterProperties.validEncName(encoding)) {
536                 Object JavaDoc[] args = { encoding };
537                 fErrorReporter.reportError(fErrorReporter.getLocator(),
538                                            XMLMessages.XML_DOMAIN,
539                                            XMLMessages.MSG_ENCODINGDECL_INVALID,
540                                            XMLMessages.P81_INVALID_VALUE,
541                                            args,
542                                            XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
543             } else {
544                 Object JavaDoc[] args = { encoding };
545                 fErrorReporter.reportError(fErrorReporter.getLocator(),
546                                            XMLMessages.XML_DOMAIN,
547                                            XMLMessages.MSG_ENCODING_NOT_SUPPORTED,
548                                            XMLMessages.P81_NOT_SUPPORTED,
549                                            args,
550                                            XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
551             }
552         }
553         fEventHandler.sendReaderChangeNotifications(fReader, fReaderId);
554         return fReader != null;
555     }
556     /**
557      * start reading from an external DTD subset
558      */

559     public void startReadingFromExternalSubset(String JavaDoc publicId, String JavaDoc systemId, int readerDepth) throws Exception JavaDoc {
560         pushEntity(true, -1);
561         pushReader();
562         pushNullReader();
563         fEntityName = -1; // External Subset
564
fEntityType = ENTITYTYPE_EXTERNAL_SUBSET;
565         fEntityContext = ENTITYREF_EXTERNAL_SUBSET;
566         fReaderDepth = readerDepth;
567         fReaderId = fNextReaderId++;
568         fPublicId = publicId;
569         fSystemId = systemId;
570         startReadingFromExternalEntity(false, -1);
571     }
572     /**
573      * stop reading from an external DTD subset
574      */

575     public void stopReadingFromExternalSubset() throws Exception JavaDoc {
576         if (!(fReader instanceof NullReader))
577             throw new RuntimeException JavaDoc("FWK004 cannot happen 18"+"\n18");
578         popReader();
579         fEventHandler.sendReaderChangeNotifications(fReader, fReaderId);
580     }
581
582     /**
583      * start reading from an external entity
584      */

585     public boolean startReadingFromEntity(int entityName, int readerDepth, int context) throws Exception JavaDoc {
586         if (context > XMLEntityHandler.ENTITYREF_IN_CONTENT)
587             return startReadingFromParameterEntity(entityName, readerDepth, context);
588         int entityHandle = lookupEntity(entityName);
589         if (entityHandle < 0) {
590             int minorCode = XMLMessages.VC_ENTITY_DECLARED;
591             int errorType = XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR;
592             // REVISIT - the following test in insufficient...
593
if (fEntityContext == ENTITYREF_DOCUMENT || fEntityContext == ENTITYREF_IN_ATTVALUE) {
594                 minorCode = XMLMessages.WFC_ENTITY_DECLARED;
595                 errorType = XMLErrorReporter.ERRORTYPE_FATAL_ERROR;
596             } else if (!fEventHandler.getValidating()) {
597                 return false;
598             }
599             Object JavaDoc[] args = { fStringPool.toString(entityName) };
600             fErrorReporter.reportError(fErrorReporter.getLocator(),
601                                        XMLMessages.XML_DOMAIN,
602                                        XMLMessages.MSG_ENTITY_NOT_DECLARED,
603                                        minorCode,
604                                        args,
605                                        errorType);
606             return false;
607         }
608         if (context == ENTITYREF_IN_CONTENT) {
609             if (fEntityPool.isUnparsedEntity(entityHandle)) {
610                 Object JavaDoc[] args = { fStringPool.toString(entityName) };
611                 fErrorReporter.reportError(fErrorReporter.getLocator(),
612                                            XMLMessages.XML_DOMAIN,
613                                            XMLMessages.MSG_REFERENCE_TO_UNPARSED_ENTITY,
614                                            XMLMessages.WFC_PARSED_ENTITY,
615                                            args,
616                                            XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
617                 return false;
618             }
619         } else {
620             if (isExternalEntity(entityHandle)) {
621                 Object JavaDoc[] args = { fStringPool.toString(entityName) };
622                 fErrorReporter.reportError(fErrorReporter.getLocator(),
623                                            XMLMessages.XML_DOMAIN,
624                                            XMLMessages.MSG_REFERENCE_TO_EXTERNAL_ENTITY,
625                                            XMLMessages.WFC_NO_EXTERNAL_ENTITY_REFERENCES,
626                                            args,
627                                            XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
628                 return false;
629             }
630         }
631         if (!pushEntity(false, entityName)) {
632             Object JavaDoc[] args = { fStringPool.toString(entityName),
633                               entityReferencePath(false, entityName) };
634             fErrorReporter.reportError(fErrorReporter.getLocator(),
635                                        XMLMessages.XML_DOMAIN,
636                                        XMLMessages.MSG_RECURSIVE_REFERENCE,
637                                        XMLMessages.WFC_NO_RECURSION,
638                                        args,
639                                        XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
640             return false;
641         }
642         pushReader();
643         fEntityName = entityName;
644         fEntityContext = context;
645         fReaderDepth = readerDepth;
646         fReaderId = fNextReaderId++;
647         if (context != ENTITYREF_IN_CONTENT || !externalReferenceInContent(entityHandle)) {
648             fEntityType = ENTITYTYPE_INTERNAL;
649             fPublicId = null/*"Internal Entity: " + fStringPool.toString(entityName)*/;
650             fSystemId = fSystemId; // keep expandSystemId happy
651
int value = -1;
652             if (context == ENTITYREF_IN_CONTENT || context == ENTITYREF_IN_DEFAULTATTVALUE)
653                 value = getEntityValue(entityHandle);
654             else
655                 value = valueOfReferenceInAttValue(entityHandle);
656             startReadingFromInternalEntity(value, false);
657             return false;
658         }
659         fEntityType = ENTITYTYPE_EXTERNAL;
660         fPublicId = getPublicIdOfEntity(entityHandle);
661         fSystemId = getSystemIdOfEntity(entityHandle);
662         return startReadingFromExternalEntity(true, entityHandle);
663     }
664     private boolean startReadingFromParameterEntity(int peName, int readerDepth, int context) throws Exception JavaDoc {
665         int entityHandle = lookupParameterEntity(peName);
666         if (entityHandle == -1) {
667             // strange... this is a VC, not a WFC...
668
if (fEventHandler.getValidating()) {
669                 reportRecoverableXMLError(XMLMessages.MSG_ENTITY_NOT_DECLARED,
670                                           XMLMessages.VC_ENTITY_DECLARED,
671                                           peName);
672             }
673             return false;
674         }
675         if (!pushEntity(true, peName)) {
676             Object JavaDoc[] args = { fStringPool.toString(peName),
677                               entityReferencePath(true, peName) };
678             fErrorReporter.reportError(fErrorReporter.getLocator(),
679                                        XMLMessages.XML_DOMAIN,
680                                        XMLMessages.MSG_RECURSIVE_PEREFERENCE,
681                                        XMLMessages.WFC_NO_RECURSION,
682                                        args,
683                                        XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
684             return false;
685         }
686         pushReader();
687         fEntityName = peName;
688         fEntityContext = context;
689         fReaderDepth = readerDepth;
690         fReaderId = fNextReaderId++;
691         if (!isExternalParameterEntity(entityHandle)) {
692             fEntityType = ENTITYTYPE_INTERNAL_PE;
693             fPublicId = null/*"Internal Entity: %" + fStringPool.toString(peName)*/;
694             fSystemId = fSystemId; // keep expandSystemId happy
695
int value = getParameterEntityValue(entityHandle);
696             startReadingFromInternalEntity(value, fEntityContext == ENTITYREF_IN_ENTITYVALUE ? false : true);
697             return false;
698         }
699         fEntityType = ENTITYTYPE_EXTERNAL_PE;
700         fPublicId = getPublicIdOfParameterEntity(entityHandle);
701         fSystemId = getSystemIdOfParameterEntity(entityHandle);
702         return startReadingFromExternalEntity(true, entityHandle);
703     }
704     private void startReadingFromInternalEntity(int value, boolean addSpaces) throws Exception JavaDoc {
705         if (fEntityContext == ENTITYREF_IN_ENTITYVALUE) {
706             //
707
// REVISIT - consider optimizing the case where the entire entity value
708
// consists of a single reference to a parameter entity and do not append
709
// the value to fLiteralData again, but re-use the offset/length of the
710
// referenced entity for the value of this entity.
711
//
712
}
713         fSource = null;
714         fEventHandler.startEntityReference(fEntityName, fEntityType, fEntityContext);
715         fReader = fReaderFactory.createStringReader(this, fErrorReporter, fSendCharDataAsCharArray, getLineNumber(), getColumnNumber(), value, fStringPool, addSpaces); // REVISIT - string reader needs better location support
716
fEventHandler.sendReaderChangeNotifications(fReader, fReaderId);
717     }
718     private boolean startReadingFromExternalEntity(boolean checkForTextDecl, int entityHandle) throws Exception JavaDoc {
719         if (fEntityContext == ENTITYREF_IN_ENTITYVALUE) {
720             //
721
// REVISIT - Can we get the spec changed ?
722
// There is a perverse edge case to handle here... We have a reference
723
// to an external PE within a literal EntityValue. For the PE to be
724
// well-formed, it must match the extPE production, but the code that
725
// appends the replacement text to the entity value is in no position
726
// to do a complete well-formedness check !!
727
//
728
}
729         if (fEntityContext == ENTITYREF_IN_DTD_WITHIN_MARKUP) {
730             //
731
// REVISIT - Can we get the spec changed ?
732
// There is a perverse edge case to handle here... We have a reference
733
// to an external PE within markup. For the PE to be well-formed, it
734
// must match the extPE production, which is probably not going to be
735
// very useful expanded in the middle of a markup declaration. The
736
// problem is that an empty file, a file containing just whitespace or
737
// another PE that is just empty or whitespace, matches extPE !!
738
//
739
}
740         fEventHandler.startEntityReference(fEntityName, fEntityType, fEntityContext);
741         String JavaDoc baseSystemId = null;
742         if (entityHandle != -1) {
743             if (fEntityType == ENTITYTYPE_EXTERNAL_PE)
744                 baseSystemId =
745                     fParameterEntityPool.getBaseSystemId(entityHandle);
746             else
747                 baseSystemId = fEntityPool.getBaseSystemId(entityHandle);
748         }
749         if (baseSystemId == null) {
750             ReaderState rs = (ReaderState) fReaderStack.peek();
751             baseSystemId = rs.systemId;
752         }
753         fSystemId = expandSystemId(fSystemId, baseSystemId);
754         fSource = fResolver == null ? null : fResolver.resolveEntity(fPublicId, fSystemId);
755         if (fSource == null) {
756             fSource = new InputSource JavaDoc(fSystemId);
757             if (fPublicId != null)
758                 fSource.setPublicId(fPublicId);
759         } else {
760             if (fSource.getSystemId() != null) {
761                 fSystemId =
762                     expandSystemId(fSource.getSystemId(), baseSystemId);
763             }
764             if (fSource.getPublicId() != null) {
765                 fPublicId = fSource.getPublicId();
766             }
767         }
768
769         boolean textDecl = false; // xmlDecl if true, textDecl if false
770
try {
771             fReader = fReaderFactory.createReader(this, fErrorReporter, fSource, fSystemId, textDecl, fStringPool);
772         } catch (MalformedURLException JavaDoc mu) {
773             String JavaDoc errorSystemId = fSystemId;
774             fEventHandler.endEntityReference(fEntityName, fEntityType, fEntityContext);
775             popReader();
776             popEntity();
777             fReader = null;
778             Object JavaDoc[] args = { errorSystemId };
779             fErrorReporter.reportError(fErrorReporter.getLocator(),
780                                         ImplementationMessages.XERCES_IMPLEMENTATION_DOMAIN,
781                                         ImplementationMessages.IO0,
782                                         0,
783                                         args,
784                                         XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
785         } catch (FileNotFoundException JavaDoc fnf) {
786             String JavaDoc errorSystemId = fSystemId;
787             fEventHandler.endEntityReference(fEntityName, fEntityType, fEntityContext);
788             popReader();
789             popEntity();
790             fReader = null;
791             Object JavaDoc[] args = { errorSystemId };
792             fErrorReporter.reportError(fErrorReporter.getLocator(),
793                                         ImplementationMessages.XERCES_IMPLEMENTATION_DOMAIN,
794                                         ImplementationMessages.IO0,
795                                         0,
796                                         args,
797                                         XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
798         } catch (UnsupportedEncodingException JavaDoc uee) {
799             fEventHandler.endEntityReference(fEntityName, fEntityType, fEntityContext);
800             popReader();
801             popEntity();
802             fReader = null;
803             String JavaDoc encoding = uee.getMessage();
804             if (encoding == null) {
805                 fErrorReporter.reportError(fErrorReporter.getLocator(),
806                                            XMLMessages.XML_DOMAIN,
807                                            XMLMessages.MSG_ENCODING_REQUIRED,
808                                            XMLMessages.P81_REQUIRED,
809                                            null,
810                                            XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
811             } else if (!XMLCharacterProperties.validEncName(encoding)) {
812                 Object JavaDoc[] args = { encoding };
813                 fErrorReporter.reportError(fErrorReporter.getLocator(),
814                                            XMLMessages.XML_DOMAIN,
815                                            XMLMessages.MSG_ENCODINGDECL_INVALID,
816                                            XMLMessages.P81_INVALID_VALUE,
817                                            args,
818                                            XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
819             } else {
820                 Object JavaDoc[] args = { encoding };
821                 fErrorReporter.reportError(fErrorReporter.getLocator(),
822                                            XMLMessages.XML_DOMAIN,
823                                            XMLMessages.MSG_ENCODING_NOT_SUPPORTED,
824                                            XMLMessages.P81_NOT_SUPPORTED,
825                                            args,
826                                            XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
827             }
828         }
829         if (fReader == null || !checkForTextDecl) {
830             fEventHandler.sendReaderChangeNotifications(fReader, fReaderId);
831             return false;
832         }
833         int readerId = fReaderId;
834         fEventHandler.sendReaderChangeNotifications(fReader, fReaderId);
835         boolean parseTextDecl = fReader.lookingAtChar('<', false);
836         if (readerId != fReaderId)
837             parseTextDecl = false;
838         return parseTextDecl;
839     }
840
841     //
842
// reader stack
843
//
844
private void pushNullReader() {
845         ReaderState rs = fReaderStateFreeList;
846         if (rs == null)
847             rs = new ReaderState();
848         else
849             fReaderStateFreeList = rs.nextReaderState;
850         if (fNullReader == null)
851             fNullReader = new NullReader();
852         rs.reader = fNullReader;
853         rs.source = null;
854         rs.entityName = -1; // Null Entity
855
rs.entityType = -1; // Null Entity
856
rs.entityContext = -1; // Null Entity
857
rs.publicId = "Null Entity";
858         rs.systemId = fSystemId;
859         rs.readerId = fNextReaderId++;
860         rs.depth = -1;
861         rs.nextReaderState = null;
862         fReaderStack.push(rs);
863     }
864     private void pushReader() {
865         ReaderState rs = fReaderStateFreeList;
866         if (rs == null)
867             rs = new ReaderState();
868         else
869             fReaderStateFreeList = rs.nextReaderState;
870         rs.reader = fReader;
871         rs.source = fSource;
872         rs.entityName = fEntityName;
873         rs.entityType = fEntityType;
874         rs.entityContext = fEntityContext;
875         rs.publicId = fPublicId;
876         rs.systemId = fSystemId;
877         rs.readerId = fReaderId;
878         rs.depth = fReaderDepth;
879         rs.nextReaderState = null;
880         fReaderStack.push(rs);
881     }
882     private void popReader() {
883         if (fReaderStack.empty())
884             throw new RuntimeException JavaDoc("FWK004 cannot happen 19"+"\n19");
885         ReaderState rs = (ReaderState) fReaderStack.pop();
886         fReader = rs.reader;
887         fSource = rs.source;
888         fEntityName = rs.entityName;
889         fEntityType = rs.entityType;
890         fEntityContext = rs.entityContext;
891         fPublicId = rs.publicId;
892         fSystemId = rs.systemId;
893         fReaderId = rs.readerId;
894         fReaderDepth = rs.depth;
895         rs.nextReaderState = fReaderStateFreeList;
896         fReaderStateFreeList = rs;
897     }
898
899     /**
900      * start an entity declaration
901      */

902     public boolean startEntityDecl(boolean isPE, int entityName) throws Exception JavaDoc {
903         if (!pushEntity(isPE, entityName)) {
904             int majorCode = isPE ? XMLMessages.MSG_RECURSIVE_PEREFERENCE : XMLMessages.MSG_RECURSIVE_REFERENCE;
905             Object JavaDoc[] args = { fStringPool.toString(entityName),
906                               entityReferencePath(isPE, entityName) };
907             fErrorReporter.reportError(fErrorReporter.getLocator(),
908                                        XMLMessages.XML_DOMAIN,
909                                        majorCode,
910                                        XMLMessages.WFC_NO_RECURSION,
911                                        args,
912                                        XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
913             return false;
914         }
915         return true;
916     }
917     /**
918      * end an entity declaration
919      */

920     public void endEntityDecl() throws Exception JavaDoc {
921         popEntity();
922     }
923     //
924
// entity stack
925
//
926
private boolean pushEntity(boolean isPE, int entityName) throws Exception JavaDoc {
927         if (entityName >= 0) {
928             for (int i = 0; i < fEntityStackDepth; i++) {
929                 if (fEntityNameStack[i] == entityName && fEntityTypeStack[i] == (isPE ? 1 : 0)) {
930                     return false;
931                 }
932             }
933         }
934         if (fEntityTypeStack == null) {
935             fEntityTypeStack = new byte[8];
936             fEntityNameStack = new int[8];
937         } else if (fEntityStackDepth == fEntityTypeStack.length) {
938             byte[] newTypeStack = new byte[fEntityStackDepth * 2];
939             System.arraycopy(fEntityTypeStack, 0, newTypeStack, 0, fEntityStackDepth);
940             fEntityTypeStack = newTypeStack;
941             int[] newNameStack = new int[fEntityStackDepth * 2];
942             System.arraycopy(fEntityNameStack, 0, newNameStack, 0, fEntityStackDepth);
943             fEntityNameStack = newNameStack;
944         }
945         fEntityTypeStack[fEntityStackDepth] = (byte)(isPE ? 1 : 0);
946         fEntityNameStack[fEntityStackDepth] = entityName;
947         fEntityStackDepth++;
948         return true;
949     }
950     private String JavaDoc entityReferencePath(boolean isPE, int entityName) {
951         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
952         sb.append("(top-level)");
953         for (int i = 0; i < fEntityStackDepth; i++) {
954             if (fEntityNameStack[i] >= 0) {
955                 sb.append('-');
956                 sb.append(fEntityTypeStack[i] == 1 ? '%' : '&');
957                 sb.append(fStringPool.toString(fEntityNameStack[i]));
958                 sb.append(';');
959             }
960         }
961         sb.append('-');
962         sb.append(isPE ? '%' : '&');
963         sb.append(fStringPool.toString(entityName));
964         sb.append(';');
965         return sb.toString();
966     }
967     private void popEntity() throws Exception JavaDoc {
968         fEntityStackDepth--;
969     }
970
971     //
972
//
973
//
974
/**
975      * This method is provided for scanner implementations.
976      */

977     public int getReaderId() {
978         return fReaderId;
979     }
980     /**
981      * This method is provided for scanner implementations.
982      */

983     public void setReaderDepth(int depth) {
984         fReaderDepth = depth;
985     }
986     /**
987      * This method is provided for scanner implementations.
988      */

989     public int getReaderDepth() {
990         return fReaderDepth;
991     }
992     /**
993      * Return the public identifier of the <code>InputSource</code> that we are processing.
994      *
995      * @return The public identifier, or null if not provided.
996      */

997     public String JavaDoc getPublicId() {
998         return fPublicId;
999     }
1000    /**
1001     * Return the system identifier of the <code>InputSource</code> that we are processing.
1002     *
1003     * @return The system identifier, or null if not provided.
1004     */

1005    public String JavaDoc getSystemId() {
1006        return fSystemId;
1007    }
1008    /**
1009     * Return the line number of the current position within the document that we are processing.
1010     *
1011     * @return The current line number.
1012     */

1013    public int getLineNumber() {
1014        return fReader == null ? 0 : fReader.getLineNumber();
1015    }
1016    /**
1017     * Return the column number of the current position within the document that we are processing.
1018     *
1019     * @return The current column number.
1020     */

1021    public int getColumnNumber() {
1022        return fReader == null ? 0 : fReader.getColumnNumber();
1023    }
1024    /**
1025     * This method is called by the reader subclasses at the
1026     * end of input, and also by the scanner directly to force
1027     * a reader change during error recovery.
1028     */

1029    public XMLEntityHandler.EntityReader changeReaders() throws Exception JavaDoc {
1030        fEventHandler.sendEndOfInputNotifications(fEntityName, fReaderStack.size() > 1);
1031        fEventHandler.endEntityReference(fEntityName, fEntityType, fEntityContext);
1032        popReader();
1033        fEventHandler.sendReaderChangeNotifications(fReader, fReaderId);
1034        popEntity();
1035        return fReader;
1036    }
1037
1038    //
1039
// We use the null reader after we have reached the
1040
// end of input for the document or external subset.
1041
//
1042
private final class NullReader implements XMLEntityHandler.EntityReader {
1043        //
1044
//
1045
//
1046
public NullReader() {
1047        }
1048        public int currentOffset() {
1049            return -1;
1050        }
1051        public int getLineNumber() {
1052            return -1;
1053        }
1054        public int getColumnNumber() {
1055            return -1;
1056        }
1057        public void setInCDSect(boolean inCDSect) {
1058        }
1059        public boolean getInCDSect() {
1060            return false;
1061        }
1062        public void append(XMLEntityHandler.CharBuffer charBuffer, int offset, int length) {
1063        }
1064        public int addString(int offset, int length) {
1065            return -1;
1066        }
1067        public int addSymbol(int offset, int length) {
1068            return -1;
1069        }
1070        public boolean lookingAtChar(char ch, boolean skipPastChar) {
1071            return false;
1072        }
1073        public boolean lookingAtValidChar(boolean skipPastChar) {
1074            return false;
1075        }
1076        public boolean lookingAtSpace(boolean skipPastChar) {
1077            return false;
1078        }
1079        public void skipToChar(char ch) {
1080        }
1081        public void skipPastSpaces() {
1082        }
1083        public void skipPastName(char fastcheck) {
1084        }
1085        public void skipPastNmtoken(char fastcheck) {
1086        }
1087        public boolean skippedString(char[] s) {
1088            return false;
1089        }
1090        public int scanInvalidChar() {
1091            return -1;
1092        }
1093        public int scanCharRef(boolean hex) {
1094            return XMLEntityHandler.CHARREF_RESULT_INVALID_CHAR;
1095        }
1096        public int scanStringLiteral() {
1097            return XMLEntityHandler.STRINGLIT_RESULT_QUOTE_REQUIRED;
1098        }
1099        public int scanAttValue(char qchar, boolean asSymbol) {
1100            return XMLEntityHandler.ATTVALUE_RESULT_INVALID_CHAR;
1101        }
1102        public int scanEntityValue(int qchar, boolean createString) {
1103            return XMLEntityHandler.ENTITYVALUE_RESULT_INVALID_CHAR;
1104        }
1105        public boolean scanExpectedName(char fastcheck, StringPool.CharArrayRange expectedName) {
1106            return false;
1107        }
1108        public void scanQName(char fastcheck, QName qname) {
1109            qname.clear();
1110        }
1111        public int scanName(char fastcheck) {
1112            return -1;
1113        }
1114        public int scanContent(QName element) throws Exception JavaDoc {
1115            return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR;
1116        }
1117    }
1118
1119    //
1120
// Entity Pool
1121
//
1122

1123    //
1124
// Chunk size constants
1125
//
1126
static final int CHUNK_SHIFT = 5; // 2^5 = 32
1127
static final int CHUNK_SIZE = (1 << CHUNK_SHIFT);
1128    static final int CHUNK_MASK = CHUNK_SIZE - 1;
1129    static final int INITIAL_CHUNK_COUNT = (1 << (10 - CHUNK_SHIFT)); // 2^10 = 1k
1130

1131public final class EntityPool {
1132    //
1133
// Constants
1134
//
1135

1136    //
1137
// Instance variables
1138
//
1139
private StringPool fStringPool = null;
1140    private XMLErrorReporter fErrorReporter = null;
1141    //
1142
// We store both EntityDecl and NotationDecl instances in this pool.
1143
// A NotationDecl has an fName field of -1. The fNotationDeclHead
1144
// index is -1 if the NotationDecl list is empty, otherwise it contains
1145
// the index of the the last NotationDecl in the list and the fValue
1146
// field contains the index of the previous NotationDecl, or -1 when at
1147
// the end of the list.
1148
//
1149
private int fEntityCount = 0;
1150    private int[][] fName = new int[INITIAL_CHUNK_COUNT][];
1151    private int[][] fValue = new int[INITIAL_CHUNK_COUNT][];
1152    private int[][] fPublicId = new int[INITIAL_CHUNK_COUNT][];
1153    private int[][] fSystemId = new int[INITIAL_CHUNK_COUNT][];
1154    private int[][] fBaseSystemId = new int[INITIAL_CHUNK_COUNT][];
1155    private int[][] fNotationName = new int[INITIAL_CHUNK_COUNT][];
1156    private byte[][] fDeclIsExternal = new byte[INITIAL_CHUNK_COUNT][];
1157    private int fNotationListHead = -1;
1158    private boolean fCreateStandardEntities = false;
1159    private Vector JavaDoc fRequiredNotations = null;
1160    //
1161
// Constructor
1162
//
1163
public EntityPool(StringPool stringPool, XMLErrorReporter errorReporter, boolean createStandardEntities) {
1164        fStringPool = stringPool;
1165        fErrorReporter = errorReporter;
1166        fCreateStandardEntities = createStandardEntities;
1167        if (fCreateStandardEntities) {
1168            createInternalEntity("lt", "&#60;");
1169            createInternalEntity("gt", ">");
1170            createInternalEntity("amp", "&#38;");
1171            createInternalEntity("apos", "\'");
1172            createInternalEntity("quot", "\"");
1173        }
1174    }
1175    //
1176
//
1177
//
1178
public void reset(StringPool stringPool) {
1179        fStringPool = stringPool;
1180        fEntityCount = 0;
1181        fNotationListHead = -1;
1182        if (fRequiredNotations != null)
1183            fRequiredNotations.removeAllElements();
1184        if (fCreateStandardEntities) {
1185            createInternalEntity("lt", "&#60;");
1186            createInternalEntity("gt", ">");
1187            createInternalEntity("amp", "&#38;");
1188            createInternalEntity("apos", "\'");
1189            createInternalEntity("quot", "\"");
1190        }
1191    }
1192    //
1193
//
1194
//
1195
private void createInternalEntity(String JavaDoc name, String JavaDoc value) {
1196        int chunk = fEntityCount >> CHUNK_SHIFT;
1197        int index = fEntityCount & CHUNK_MASK;
1198        ensureCapacity(chunk);
1199        fName[chunk][index] = fStringPool.addSymbol(name);
1200        fValue[chunk][index] = fStringPool.addString(value);
1201        fPublicId[chunk][index] = -1;
1202        fSystemId[chunk][index] = -1;
1203        fBaseSystemId[chunk][index] = -1;
1204        fNotationName[chunk][index] = -1;
1205        fEntityCount++;
1206    }
1207    //
1208
//
1209
//
1210
private void ensureCapacity(int chunk) {
1211        if (chunk >= fName.length) {
1212            int[][] newIntArray = new int[chunk * 2][];
1213            System.arraycopy(fName, 0, newIntArray, 0, chunk);
1214            fName = newIntArray;
1215            newIntArray = new int[chunk * 2][];
1216            System.arraycopy(fValue, 0, newIntArray, 0, chunk);
1217            fValue = newIntArray;
1218            newIntArray = new int[chunk * 2][];
1219            System.arraycopy(fPublicId, 0, newIntArray, 0, chunk);
1220            fPublicId = newIntArray;
1221
1222            newIntArray = new int[chunk * 2][];
1223            System.arraycopy(fSystemId, 0, newIntArray, 0, chunk);
1224            fSystemId = newIntArray;
1225
1226            newIntArray = new int[chunk * 2][];
1227            System.arraycopy(fBaseSystemId, 0, newIntArray, 0, chunk);
1228            fBaseSystemId = newIntArray;
1229
1230
1231            newIntArray = new int[chunk * 2][];
1232            System.arraycopy(fNotationName, 0, newIntArray, 0, chunk);
1233            fNotationName = newIntArray;
1234            byte[][] newByteArray = new byte[chunk * 2][];
1235            System.arraycopy(fDeclIsExternal, 0, newByteArray, 0, chunk);
1236            fDeclIsExternal = newByteArray;
1237        } else if (fName[chunk] != null) {
1238            return;
1239        }
1240        fName[chunk] = new int[CHUNK_SIZE];
1241        fValue[chunk] = new int[CHUNK_SIZE];
1242        fPublicId[chunk] = new int[CHUNK_SIZE];
1243        fSystemId[chunk] = new int[CHUNK_SIZE];
1244        fBaseSystemId[chunk] = new int[CHUNK_SIZE];
1245        fNotationName[chunk] = new int[CHUNK_SIZE];
1246        fDeclIsExternal[chunk] = new byte[CHUNK_SIZE];
1247    }
1248    public int addEntityDecl(int name, int value, int publicId, int systemId, int baseSystemId, int notationName, boolean isExternal) {
1249        int chunk = fEntityCount >> CHUNK_SHIFT;
1250        int index = fEntityCount & CHUNK_MASK;
1251        ensureCapacity(chunk);
1252        fName[chunk][index] = name;
1253        fValue[chunk][index] = value;
1254        fPublicId[chunk][index] = publicId;
1255        fSystemId[chunk][index] = systemId;
1256        fBaseSystemId[chunk][index] = baseSystemId;
1257        fNotationName[chunk][index] = notationName;
1258        fDeclIsExternal[chunk][index] = isExternal ? (byte)0x80 : (byte)0;
1259        int entityIndex = fEntityCount++;
1260        return entityIndex;
1261    }
1262    public int addNotationDecl(int notationName, int publicId, int systemId, int baseSystemId, boolean isExternal) {
1263        int nIndex = fNotationListHead;
1264        while (nIndex != -1) {
1265            int chunk = nIndex >> CHUNK_SHIFT;
1266            int index = nIndex & CHUNK_MASK;
1267            if (fNotationName[chunk][index] == notationName)
1268                return -1;
1269            nIndex = fValue[chunk][index];
1270        }
1271        int chunk = fEntityCount >> CHUNK_SHIFT;
1272        int index = fEntityCount & CHUNK_MASK;
1273        ensureCapacity(chunk);
1274        fName[chunk][index] = -1;
1275        fValue[chunk][index] = fNotationListHead;
1276        fPublicId[chunk][index] = publicId;
1277        fSystemId[chunk][index] = systemId;
1278        fBaseSystemId[chunk][index] = baseSystemId;
1279        fNotationName[chunk][index] = notationName;
1280        fDeclIsExternal[chunk][index] = isExternal ? (byte)0x80 : (byte)0;
1281        fNotationListHead = fEntityCount++;
1282        return fNotationListHead;
1283    }
1284    public int lookupEntity(int nameIndex) {
1285        if (nameIndex == -1)
1286            return -1;
1287        int chunk = 0;
1288        int index = 0;
1289        for (int entityIndex = 0; entityIndex < fEntityCount; entityIndex++) {
1290            if (fName[chunk][index] == nameIndex)
1291                return entityIndex;
1292            if (++index == CHUNK_SIZE) {
1293                chunk++;
1294                index = 0;
1295            }
1296        }
1297        return -1;
1298    }
1299    public boolean isExternalEntity(int entityIndex) {
1300        int chunk = entityIndex >> CHUNK_SHIFT;
1301        int index = entityIndex & CHUNK_MASK;
1302        return (fValue[chunk][index] == -1);
1303    }
1304    public boolean isUnparsedEntity(int entityIndex) {
1305        int chunk = entityIndex >> CHUNK_SHIFT;
1306        int index = entityIndex & CHUNK_MASK;
1307        return (fNotationName[chunk][index] != -1);
1308    }
1309    public boolean getEntityDeclIsExternal(int entityIndex) {
1310        int chunk = entityIndex >> CHUNK_SHIFT;
1311        int index = entityIndex & CHUNK_MASK;
1312        return (fDeclIsExternal[chunk][index] < 0);
1313    }
1314    public int getEntityName(int entityIndex) {
1315        int chunk = entityIndex >> CHUNK_SHIFT;
1316        int index = entityIndex & CHUNK_MASK;
1317        return fName[chunk][index];
1318    }
1319    public int getEntityValue(int entityIndex) {
1320        int chunk = entityIndex >> CHUNK_SHIFT;
1321        int index = entityIndex & CHUNK_MASK;
1322        return fValue[chunk][index];
1323    }
1324    public int getPublicId(int entityIndex) {
1325        int chunk = entityIndex >> CHUNK_SHIFT;
1326        int index = entityIndex & CHUNK_MASK;
1327        return fPublicId[chunk][index];
1328    }
1329    public int getSystemId(int entityIndex) {
1330        int chunk = entityIndex >> CHUNK_SHIFT;
1331        int index = entityIndex & CHUNK_MASK;
1332        return fSystemId[chunk][index];
1333    }
1334    public String JavaDoc getBaseSystemId(int entityIndex) {
1335        int chunk = entityIndex >> CHUNK_SHIFT;
1336        int index = entityIndex & CHUNK_MASK;
1337        int baseIndex = fBaseSystemId[chunk][index];
1338        if (baseIndex == -1) {
1339            return null;
1340        } else {
1341            return fStringPool.toString(baseIndex);
1342        }
1343    }
1344    public boolean isNotationDeclared(int nameIndex) {
1345        int nIndex = fNotationListHead;
1346        while (nIndex != -1) {
1347            int chunk = nIndex >> CHUNK_SHIFT;
1348            int index = nIndex & CHUNK_MASK;
1349            if (fNotationName[chunk][index] == nameIndex)
1350                return true;
1351            nIndex = fValue[chunk][index];
1352        }
1353        return false;
1354    }
1355    public boolean getNotationDeclIsExternal(int entityIndex) {
1356        int chunk = entityIndex >> CHUNK_SHIFT;
1357        int index = entityIndex & CHUNK_MASK;
1358        return (fDeclIsExternal[chunk][index] < 0);
1359    }
1360    public int getNotationName(int entityIndex) {
1361        int chunk = entityIndex >> CHUNK_SHIFT;
1362        int index = entityIndex & CHUNK_MASK;
1363        return fNotationName[chunk][index];
1364    }
1365    class RequiredNotation {
1366        RequiredNotation(int notationName, Locator JavaDoc locator, int majorCode, int minorCode, Object JavaDoc[] args) {
1367            fNotationName = notationName;
1368            fLocator = new LocatorImpl JavaDoc(locator); // snapshot of the current location
1369
fMajorCode = majorCode;
1370            fMinorCode = minorCode;
1371            fArgs = args;
1372        }
1373        int fNotationName;
1374        LocatorImpl JavaDoc fLocator;
1375        int fMajorCode;
1376        int fMinorCode;
1377        Object JavaDoc[] fArgs;
1378    };
1379    public void addRequiredNotation(int notationName, Locator JavaDoc locator, int majorCode, int minorCode, Object JavaDoc[] args) {
1380        if (fRequiredNotations == null)
1381            fRequiredNotations = new Vector JavaDoc();
1382        for (int index = 0; index < fRequiredNotations.size(); index++) {
1383            RequiredNotation rn = (RequiredNotation)fRequiredNotations.elementAt(index);
1384            if (rn.fNotationName == notationName)
1385                return; // REVISIT - do we want to keep just the first, or all of them?
1386
}
1387        fRequiredNotations.addElement(new RequiredNotation(notationName, locator, majorCode, minorCode, args));
1388    }
1389    public void checkRequiredNotations() throws Exception JavaDoc {
1390        if (fRequiredNotations == null)
1391            return;
1392        for (int index = 0; index < fRequiredNotations.size(); index++) {
1393            RequiredNotation rn = (RequiredNotation)fRequiredNotations.elementAt(index);
1394            if (!isNotationDeclared(rn.fNotationName)) {
1395                fErrorReporter.reportError(rn.fLocator,
1396                                           XMLMessages.XML_DOMAIN,
1397                                           rn.fMajorCode,
1398                                           rn.fMinorCode,
1399                                           rn.fArgs,
1400                                           XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
1401            }
1402        }
1403    }
1404}
1405}
1406
Popular Tags