1/*
2 * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
3 */
4/*
5 * Licensed to the Apache Software Foundation (ASF) under one or more
6 * contributor license agreements.  See the NOTICE file distributed with
7 * this work for additional information regarding copyright ownership.
8 * The ASF licenses this file to You under the Apache License, Version 2.0
9 * (the "License"); you may not use this file except in compliance with
10 * the License.  You may obtain a copy of the License at
11 *
12 *      http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
21
22package com.sun.xml.internal.stream;
23
24import java.io.InputStream;
25import java.io.Reader;
26import java.io.IOException;
27
28import com.sun.xml.internal.stream.util.BufferAllocator;
29import com.sun.xml.internal.stream.util.ThreadLocalBufferAllocator;
30import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
31
32/**
33 * Entity information.
34 *
35 * @author
36 */
37public abstract class Entity {
38
39    //
40    // Data
41    //
42
43    //xxx why dont we declare the type of entities, like assign integer for external/ internal etc..
44
45    /** Entity name. */
46    public String name;
47
48    // whether this entity's declaration was found in the internal
49    // or external subset
50    public boolean inExternalSubset;
51
52    //
53    // Constructors
54    //
55
56    /** Default constructor. */
57    public Entity() {
58        clear();
59    } // <init>()
60
61    /** Constructs an entity. */
62    public Entity(String name, boolean inExternalSubset) {
63        this.name = name;
64        this.inExternalSubset = inExternalSubset;
65    } // <init>(String)
66
67    //
68    // Public methods
69    //
70
71    /** Returns true if this entity was declared in the external subset. */
72    public boolean isEntityDeclInExternalSubset() {
73        return inExternalSubset;
74    }
75
76    /** Returns true if this is an external entity. */
77    public abstract boolean isExternal();
78
79    /** Returns true if this is an unparsed entity. */
80    public abstract boolean isUnparsed();
81
82    /** Clears the entity. */
83    public void clear() {
84        name = null;
85        inExternalSubset = false;
86    } // clear()
87
88    /** Sets the values of the entity. */
89    public void setValues(Entity entity) {
90        name = entity.name;
91        inExternalSubset = entity.inExternalSubset;
92    } // setValues(Entity)
93
94
95    /**
96     * Internal entity.
97     *
98     * @author nb131165
99     */
100    public static class InternalEntity
101            extends Entity {
102
103        //
104        // Data
105        //
106
107        /** Text value of entity. */
108        public String text;
109
110        //
111        // Constructors
112        //
113
114        /** Default constructor. */
115        public InternalEntity() {
116            clear();
117        } // <init>()
118
119        /** Constructs an internal entity. */
120        public InternalEntity(String name, String text, boolean inExternalSubset) {
121            super(name,inExternalSubset);
122            this.text = text;
123        } // <init>(String,String)
124
125        //
126        // Entity methods
127        //
128
129        /** Returns true if this is an external entity. */
130        public final boolean isExternal() {
131            return false;
132        } // isExternal():boolean
133
134        /** Returns true if this is an unparsed entity. */
135        public final boolean isUnparsed() {
136            return false;
137        } // isUnparsed():boolean
138
139        /** Clears the entity. */
140        public void clear() {
141            super.clear();
142            text = null;
143        } // clear()
144
145        /** Sets the values of the entity. */
146        public void setValues(Entity entity) {
147            super.setValues(entity);
148            text = null;
149        } // setValues(Entity)
150
151        /** Sets the values of the entity. */
152        public void setValues(InternalEntity entity) {
153            super.setValues(entity);
154            text = entity.text;
155        } // setValues(InternalEntity)
156
157    } // class InternalEntity
158
159    /**
160     * External entity.
161     *
162     * @author nb131165
163     */
164    public  static class ExternalEntity
165            extends Entity {
166
167        //
168        // Data
169        //
170
171        /** container for all relevant entity location information. */
172        public XMLResourceIdentifier entityLocation;
173
174        /** Notation name for unparsed entity. */
175        public String notation;
176
177        //
178        // Constructors
179        //
180
181        /** Default constructor. */
182        public ExternalEntity() {
183            clear();
184        } // <init>()
185
186        /** Constructs an internal entity. */
187        public ExternalEntity(String name, XMLResourceIdentifier entityLocation,
188                String notation, boolean inExternalSubset) {
189            super(name,inExternalSubset);
190            this.entityLocation = entityLocation;
191            this.notation = notation;
192        } // <init>(String,XMLResourceIdentifier, String)
193
194        //
195        // Entity methods
196        //
197
198        /** Returns true if this is an external entity. */
199        public final boolean isExternal() {
200            return true;
201        } // isExternal():boolean
202
203        /** Returns true if this is an unparsed entity. */
204        public final boolean isUnparsed() {
205            return notation != null;
206        } // isUnparsed():boolean
207
208        /** Clears the entity. */
209        public void clear() {
210            super.clear();
211            entityLocation = null;
212            notation = null;
213        } // clear()
214
215        /** Sets the values of the entity. */
216        public void setValues(Entity entity) {
217            super.setValues(entity);
218            entityLocation = null;
219            notation = null;
220        } // setValues(Entity)
221
222        /** Sets the values of the entity. */
223        public void setValues(ExternalEntity entity) {
224            super.setValues(entity);
225            entityLocation = entity.entityLocation;
226            notation = entity.notation;
227        } // setValues(ExternalEntity)
228
229    } // class ExternalEntity
230
231    /**
232     * Entity state.
233     *
234     * @author nb131165
235     */
236    public static class ScannedEntity
237            extends Entity {
238
239
240        /** Default buffer size (4096). */
241        public static final int DEFAULT_BUFFER_SIZE = 8192;
242        //4096;
243
244        /**
245         * Buffer size. We get this value from a property. The default size
246         * is used if the input buffer size property is not specified.
247         * REVISIT: do we need a property for internal entity buffer size?
248         */
249        public int fBufferSize = DEFAULT_BUFFER_SIZE;
250
251        /** Default buffer size before we've finished with the XMLDecl:  */
252        public static final int DEFAULT_XMLDECL_BUFFER_SIZE = 28;
253
254        /** Default internal entity buffer size (1024). */
255        public static final int DEFAULT_INTERNAL_BUFFER_SIZE = 1024;
256
257        //
258        // Data
259        //
260
261        // i/o
262
263        /** XXX let these field remain public right now, though we have defined methods for them.
264         * Input stream. */
265        public InputStream stream;
266
267        /** XXX let these field remain public right now, though we have defined methods for them.
268         * Reader. */
269        public Reader reader;
270
271        // locator information
272
273        /** entity location information */
274        public XMLResourceIdentifier entityLocation;
275
276        // encoding
277
278        /** Auto-detected encoding. */
279        public String encoding;
280
281        // status
282
283        /** True if in a literal.  */
284        public boolean literal;
285
286        // whether this is an external or internal scanned entity
287        public boolean isExternal;
288
289        //each 'external' parsed entity may have xml/text declaration containing version information
290        public String  version ;
291
292        // buffer
293
294        /** Character buffer. */
295        public char[] ch = null;
296
297        /** Position in character buffer at any point of time. */
298        public int position;
299
300        /** Count of characters present in buffer. */
301        public int count;
302
303        /** Line number. */
304        public int lineNumber = 1;
305
306        /** Column number. */
307        public int columnNumber = 1;
308
309        /** Encoding has been set externally for eg: using DOMInput*/
310        boolean declaredEncoding = false;
311
312        // status
313
314        /**
315         * Encoding has been set externally, for example
316         * using a SAX InputSource or a DOM LSInput.
317         */
318        boolean externallySpecifiedEncoding = false;
319
320        /** XML version. **/
321        public String xmlVersion = "1.0";
322
323        /** This variable is used to calculate the current position in the XML stream.
324         * Note that fCurrentEntity.position maintains the position relative to
325         * the buffer.
326         *  At any point of time absolute position in the XML stream can be calculated
327         *  as fTotalCountTillLastLoad + fCurrentEntity.position
328         */
329        public int fTotalCountTillLastLoad ;
330
331        /** This variable stores the number of characters read during the load()
332         * operation. It is used to calculate fTotalCountTillLastLoad
333         */
334        public  int fLastCount ;
335
336        /** Base character offset for computing absolute character offset. */
337        public int baseCharOffset;
338
339        /** Start position in character buffer. */
340        public int startPosition;
341
342        // to allow the reader/inputStream to behave efficiently:
343        public boolean mayReadChunks;
344
345        // to know that prolog is read
346        public boolean xmlDeclChunkRead = false;
347
348        // flag to indicate whether the Entity is a General Entity
349        public boolean isGE = false;
350
351        /** returns the name of the current encoding
352         *  @return current encoding name
353         */
354        public String getEncodingName(){
355            return encoding ;
356        }
357
358        /**each 'external' parsed entity may have xml/text declaration containing version information
359         * @return String version of the entity, for an internal entity version would be null
360         */
361        public String getEntityVersion(){
362            return version ;
363        }
364
365        /** each 'external' parsed entity may have xml/text declaration containing version information
366         * @param String version of the external parsed entity
367         */
368        public void setEntityVersion(String version){
369            this.version = version ;
370        }
371
372        /**  Returns the java.io.Reader associated with this entity.Readers are used
373         * to read from the file. Readers wrap any particular  InputStream that was
374         * used to open the entity.
375         * @return java.io.Reader Reader associated with this entity
376         */
377        public Reader getEntityReader(){
378            return reader;
379        }
380
381
382        /** if entity was opened using the stream, return the associated inputstream
383         * with this entity
384         *@return java.io.InputStream InputStream associated with this entity
385         */
386        public InputStream getEntityInputStream(){
387            return stream;
388        }
389
390        //
391        // Constructors
392        //
393
394        /** Constructs a scanned entity. */
395        public ScannedEntity(boolean isGE, String name,
396                XMLResourceIdentifier entityLocation,
397                InputStream stream, Reader reader,
398                String encoding, boolean literal, boolean mayReadChunks, boolean isExternal) {
399            this.isGE = isGE;
400            this.name = name ;
401            this.entityLocation = entityLocation;
402            this.stream = stream;
403            this.reader = reader;
404            this.encoding = encoding;
405            this.literal = literal;
406            this.mayReadChunks = mayReadChunks;
407            this.isExternal = isExternal;
408            final int size = isExternal ? fBufferSize : DEFAULT_INTERNAL_BUFFER_SIZE;
409            BufferAllocator ba = ThreadLocalBufferAllocator.getBufferAllocator();
410            ch = ba.getCharBuffer(size);
411            if (ch == null) {
412                this.ch = new char[size];
413            }
414        } // <init>(StringXMLResourceIdentifier,InputStream,Reader,String,boolean, boolean)
415
416        /**
417         * Release any resources associated with this entity.
418         */
419        public void close() throws IOException {
420            BufferAllocator ba = ThreadLocalBufferAllocator.getBufferAllocator();
421            ba.returnCharBuffer(ch);
422            ch = null;
423            reader.close();
424        }
425
426        //
427        // Entity methods
428        //
429
430        /** Returns whether the encoding of this entity was externally specified. **/
431        public boolean isEncodingExternallySpecified() {
432            return externallySpecifiedEncoding;
433        }
434
435        /** Sets whether the encoding of this entity was externally specified. **/
436        public void setEncodingExternallySpecified(boolean value) {
437            externallySpecifiedEncoding = value;
438        }
439
440        public boolean isDeclaredEncoding() {
441            return declaredEncoding;
442        }
443
444        public void setDeclaredEncoding(boolean value) {
445            declaredEncoding = value;
446        }
447
448        /** Returns true if this is an external entity. */
449        public final boolean isExternal() {
450            return isExternal;
451        } // isExternal():boolean
452
453        /** Returns true if this is an unparsed entity. */
454        public final boolean isUnparsed() {
455            return false;
456        } // isUnparsed():boolean
457
458        //
459        // Object methods
460        //
461
462        /** Returns a string representation of this object. */
463        public String toString() {
464
465            StringBuffer str = new StringBuffer();
466            str.append("name=\""+name+'"');
467            str.append(",ch="+ new String(ch));
468            str.append(",position="+position);
469            str.append(",count="+count);
470            return str.toString();
471
472        } // toString():String
473
474    } // class ScannedEntity
475
476} // class Entity
477