1 package com.ctc.wstx.io;
2
3 import java.io.IOException;
4 import java.net.URL;
5
6 import javax.xml.stream.XMLStreamException;
7
8 /**
9  * Abstract base class that implements shared functionality that all current
10  * {@link WstxInputSource} implementations Woodstox includes need.
11  */

12 public abstract class BaseInputSource
13     extends WstxInputSource
14 {
15     final String mPublicId;
16
17     /**
18      * URL for/from systemId points to original source of input, if known; null if not
19      * known (source constructed with just a stream or reader). Used for
20      * resolving references from the input that's read from this source.
21      * Can be overridden by reader; done if P_BASE_URL is changed on
22      * stream reader for which this input source is the currently
23      * active input source.
24      */

25     SystemId mSystemId;
26     
27     /**
28      * Input buffer this input source uses, if any.
29      */

30     protected char[] mBuffer;
31
32     /**
33      * Length of the buffer, if buffer used
34      */

35     protected int mInputLast;
36
37     /*
38     ////////////////////////////////////////////////////////////////
39     // Saved location information; active information is directly
40     // handled by Reader, and then saved to input source when switching
41     // to a nested input source.
42     ////////////////////////////////////////////////////////////////
43     */

44
45     /**
46      * Number of characters read from the current input source prior to
47      * the current buffer
48      */

49     long mSavedInputProcessed = 0;
50
51     int mSavedInputRow = 1;
52     int mSavedInputRowStart = 0;
53
54     int mSavedInputPtr = 0;
55
56     /*
57     ////////////////////////////////////////////////////////////////
58     // Some simple lazy-loading/reusing support...
59     ////////////////////////////////////////////////////////////////
60     */

61
62     transient WstxInputLocation mParentLocation = null;
63
64     /*
65     ////////////////////////////////////////////////////////////////
66     // Life-cycle
67     ////////////////////////////////////////////////////////////////
68     */

69     protected BaseInputSource(WstxInputSource parent, String fromEntity,
70                               String publicId, SystemId systemId)
71     {
72         super(parent, fromEntity);
73         mSystemId = systemId;
74         mPublicId = publicId;
75     }
76
77     @Override
78     public void overrideSource(URL src)
79     {
80         //19-May-2014, tatu: I assume this should also override observed systemId...
81         mSystemId = SystemId.construct(src);
82     }
83
84     @Override
85     public abstract boolean fromInternalEntity();
86
87     @Override
88     public URL getSource() throws IOException {
89         return (mSystemId == null) ? null : mSystemId.asURL();
90     }
91
92     @Override
93     public String getPublicId() {
94       return mPublicId;
95     }
96
97     @Override
98     public String getSystemId() {
99         return (mSystemId == null) ? null : mSystemId.toString();
100     }
101
102     @Override
103     protected abstract void doInitInputLocation(WstxInputData reader);
104
105     @Override
106     public abstract int readInto(WstxInputData reader)
107         throws IOException, XMLStreamException;
108     
109     @Override
110     public abstract boolean readMore(WstxInputData reader, int minAmount)
111         throws IOException, XMLStreamException;
112
113     @Override
114     public void saveContext(WstxInputData reader)
115     {
116         // First actual input data
117         mSavedInputPtr = reader.mInputPtr;
118
119         // then location
120         mSavedInputProcessed = reader.mCurrInputProcessed;
121         mSavedInputRow = reader.mCurrInputRow;
122         mSavedInputRowStart = reader.mCurrInputRowStart;
123     }
124
125     @Override
126     public void restoreContext(WstxInputData reader)
127     {
128         reader.mInputBuffer = mBuffer;
129         reader.mInputEnd = mInputLast;
130         reader.mInputPtr = mSavedInputPtr;
131
132         // then location
133         reader.mCurrInputProcessed = mSavedInputProcessed;
134         reader.mCurrInputRow = mSavedInputRow;
135         reader.mCurrInputRowStart = mSavedInputRowStart;
136     }
137
138     @Override
139     public abstract void close() throws IOException;
140
141     /*
142     //////////////////////////////////////////////////////////
143     // Methods for accessing location information
144     //////////////////////////////////////////////////////////
145      */

146
147     /**
148      * This method only gets called by the 'child' input source (for example,
149      * contents of an expanded entity), to get the enclosing context location.
150      */

151     @Override
152     protected final WstxInputLocation getLocation()
153     {
154         // Note: columns are 1-based, need to add 1.
155         return getLocation(mSavedInputProcessed + mSavedInputPtr - 1L,
156                            mSavedInputRow,
157                            mSavedInputPtr - mSavedInputRowStart + 1);
158     }
159
160     @Override
161     public final WstxInputLocation getLocation(long total, int row, int col)
162     {
163         WstxInputLocation pl;
164
165         if (mParent == null) {
166             pl = null;
167         } else {
168             /* 13-Apr-2005, TSa: We can actually reuse parent location, since
169              *   it can not change during lifetime of this child context...
170              */

171             pl = mParentLocation;
172             if (pl == null) {
173                 mParentLocation = pl = mParent.getLocation();
174             }
175             pl = mParent.getLocation();
176         }
177         /* !!! 15-Apr-2005, TSa: This will cause overflow for total count,
178          *   but since StAX 1.0 API doesn't have any way to deal with that,
179          *   let's just let that be...
180          */

181         return new WstxInputLocation(pl, getPublicId(), getSystemId(),
182                                      total, row, col);
183     }
184 }
185