Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/com/sun/beans/decoder/DocumentHandler.java
38923 views
1
/*
2
* Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
package com.sun.beans.decoder;
26
27
import com.sun.beans.finder.ClassFinder;
28
29
import java.beans.ExceptionListener;
30
31
import java.io.IOException;
32
import java.io.StringReader;
33
34
import java.lang.ref.Reference;
35
import java.lang.ref.WeakReference;
36
37
import java.util.ArrayList;
38
import java.util.HashMap;
39
import java.util.List;
40
import java.util.Map;
41
import java.security.AccessControlContext;
42
import java.security.AccessController;
43
import java.security.PrivilegedAction;
44
45
import javax.xml.parsers.ParserConfigurationException;
46
import javax.xml.parsers.SAXParserFactory;
47
48
import org.xml.sax.Attributes;
49
import org.xml.sax.InputSource;
50
import org.xml.sax.SAXException;
51
import org.xml.sax.helpers.DefaultHandler;
52
53
import sun.misc.SharedSecrets;
54
55
/**
56
* The main class to parse JavaBeans XML archive.
57
*
58
* @since 1.7
59
*
60
* @author Sergey A. Malenkov
61
*
62
* @see ElementHandler
63
*/
64
public final class DocumentHandler extends DefaultHandler {
65
private final AccessControlContext acc = AccessController.getContext();
66
private final Map<String, Class<? extends ElementHandler>> handlers = new HashMap<>();
67
private final Map<String, Object> environment = new HashMap<>();
68
private final List<Object> objects = new ArrayList<>();
69
70
private Reference<ClassLoader> loader;
71
private ExceptionListener listener;
72
private Object owner;
73
74
private ElementHandler handler;
75
76
/**
77
* Creates new instance of document handler.
78
*/
79
public DocumentHandler() {
80
setElementHandler("java", JavaElementHandler.class); // NON-NLS: the element name
81
setElementHandler("null", NullElementHandler.class); // NON-NLS: the element name
82
setElementHandler("array", ArrayElementHandler.class); // NON-NLS: the element name
83
setElementHandler("class", ClassElementHandler.class); // NON-NLS: the element name
84
setElementHandler("string", StringElementHandler.class); // NON-NLS: the element name
85
setElementHandler("object", ObjectElementHandler.class); // NON-NLS: the element name
86
87
setElementHandler("void", VoidElementHandler.class); // NON-NLS: the element name
88
setElementHandler("char", CharElementHandler.class); // NON-NLS: the element name
89
setElementHandler("byte", ByteElementHandler.class); // NON-NLS: the element name
90
setElementHandler("short", ShortElementHandler.class); // NON-NLS: the element name
91
setElementHandler("int", IntElementHandler.class); // NON-NLS: the element name
92
setElementHandler("long", LongElementHandler.class); // NON-NLS: the element name
93
setElementHandler("float", FloatElementHandler.class); // NON-NLS: the element name
94
setElementHandler("double", DoubleElementHandler.class); // NON-NLS: the element name
95
setElementHandler("boolean", BooleanElementHandler.class); // NON-NLS: the element name
96
97
// some handlers for new elements
98
setElementHandler("new", NewElementHandler.class); // NON-NLS: the element name
99
setElementHandler("var", VarElementHandler.class); // NON-NLS: the element name
100
setElementHandler("true", TrueElementHandler.class); // NON-NLS: the element name
101
setElementHandler("false", FalseElementHandler.class); // NON-NLS: the element name
102
setElementHandler("field", FieldElementHandler.class); // NON-NLS: the element name
103
setElementHandler("method", MethodElementHandler.class); // NON-NLS: the element name
104
setElementHandler("property", PropertyElementHandler.class); // NON-NLS: the element name
105
}
106
107
/**
108
* Returns the class loader used to instantiate objects.
109
* If the class loader has not been explicitly set
110
* then {@code null} is returned.
111
*
112
* @return the class loader used to instantiate objects
113
*/
114
public ClassLoader getClassLoader() {
115
return (this.loader != null)
116
? this.loader.get()
117
: null;
118
}
119
120
/**
121
* Sets the class loader used to instantiate objects.
122
* If the class loader is not set
123
* then default class loader will be used.
124
*
125
* @param loader a classloader to use
126
*/
127
public void setClassLoader(ClassLoader loader) {
128
this.loader = new WeakReference<ClassLoader>(loader);
129
}
130
131
/**
132
* Returns the exception listener for parsing.
133
* The exception listener is notified
134
* when handler catches recoverable exceptions.
135
* If the exception listener has not been explicitly set
136
* then default exception listener is returned.
137
*
138
* @return the exception listener for parsing
139
*/
140
public ExceptionListener getExceptionListener() {
141
return this.listener;
142
}
143
144
/**
145
* Sets the exception listener for parsing.
146
* The exception listener is notified
147
* when handler catches recoverable exceptions.
148
*
149
* @param listener the exception listener for parsing
150
*/
151
public void setExceptionListener(ExceptionListener listener) {
152
this.listener = listener;
153
}
154
155
/**
156
* Returns the owner of this document handler.
157
*
158
* @return the owner of this document handler
159
*/
160
public Object getOwner() {
161
return this.owner;
162
}
163
164
/**
165
* Sets the owner of this document handler.
166
*
167
* @param owner the owner of this document handler
168
*/
169
public void setOwner(Object owner) {
170
this.owner = owner;
171
}
172
173
/**
174
* Returns the handler for the element with specified name.
175
*
176
* @param name the name of the element
177
* @return the corresponding element handler
178
*/
179
public Class<? extends ElementHandler> getElementHandler(String name) {
180
Class<? extends ElementHandler> type = this.handlers.get(name);
181
if (type == null) {
182
throw new IllegalArgumentException("Unsupported element: " + name);
183
}
184
return type;
185
}
186
187
/**
188
* Sets the handler for the element with specified name.
189
*
190
* @param name the name of the element
191
* @param handler the corresponding element handler
192
*/
193
public void setElementHandler(String name, Class<? extends ElementHandler> handler) {
194
this.handlers.put(name, handler);
195
}
196
197
/**
198
* Indicates whether the variable with specified identifier is defined.
199
*
200
* @param id the identifier
201
* @return @{code true} if the variable is defined;
202
* @{code false} otherwise
203
*/
204
public boolean hasVariable(String id) {
205
return this.environment.containsKey(id);
206
}
207
208
/**
209
* Returns the value of the variable with specified identifier.
210
*
211
* @param id the identifier
212
* @return the value of the variable
213
*/
214
public Object getVariable(String id) {
215
if (!this.environment.containsKey(id)) {
216
throw new IllegalArgumentException("Unbound variable: " + id);
217
}
218
return this.environment.get(id);
219
}
220
221
/**
222
* Sets new value of the variable with specified identifier.
223
*
224
* @param id the identifier
225
* @param value new value of the variable
226
*/
227
public void setVariable(String id, Object value) {
228
this.environment.put(id, value);
229
}
230
231
/**
232
* Returns the array of readed objects.
233
*
234
* @return the array of readed objects
235
*/
236
public Object[] getObjects() {
237
return this.objects.toArray();
238
}
239
240
/**
241
* Adds the object to the list of readed objects.
242
*
243
* @param object the object that is readed from XML document
244
*/
245
void addObject(Object object) {
246
this.objects.add(object);
247
}
248
249
/**
250
* Disables any external entities.
251
*/
252
@Override
253
public InputSource resolveEntity(String publicId, String systemId) {
254
return new InputSource(new StringReader(""));
255
}
256
257
/**
258
* Prepares this handler to read objects from XML document.
259
*/
260
@Override
261
public void startDocument() {
262
this.objects.clear();
263
this.handler = null;
264
}
265
266
/**
267
* Parses opening tag of XML element
268
* using corresponding element handler.
269
*
270
* @param uri the namespace URI, or the empty string
271
* if the element has no namespace URI or
272
* if namespace processing is not being performed
273
* @param localName the local name (without prefix), or the empty string
274
* if namespace processing is not being performed
275
* @param qName the qualified name (with prefix), or the empty string
276
* if qualified names are not available
277
* @param attributes the attributes attached to the element
278
*/
279
@Override
280
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
281
ElementHandler parent = this.handler;
282
try {
283
this.handler = getElementHandler(qName).newInstance();
284
this.handler.setOwner(this);
285
this.handler.setParent(parent);
286
}
287
catch (Exception exception) {
288
throw new SAXException(exception);
289
}
290
for (int i = 0; i < attributes.getLength(); i++)
291
try {
292
String name = attributes.getQName(i);
293
String value = attributes.getValue(i);
294
this.handler.addAttribute(name, value);
295
}
296
catch (RuntimeException exception) {
297
handleException(exception);
298
}
299
300
this.handler.startElement();
301
}
302
303
/**
304
* Parses closing tag of XML element
305
* using corresponding element handler.
306
*
307
* @param uri the namespace URI, or the empty string
308
* if the element has no namespace URI or
309
* if namespace processing is not being performed
310
* @param localName the local name (without prefix), or the empty string
311
* if namespace processing is not being performed
312
* @param qName the qualified name (with prefix), or the empty string
313
* if qualified names are not available
314
*/
315
@Override
316
public void endElement(String uri, String localName, String qName) {
317
try {
318
this.handler.endElement();
319
}
320
catch (RuntimeException exception) {
321
handleException(exception);
322
}
323
finally {
324
this.handler = this.handler.getParent();
325
}
326
}
327
328
/**
329
* Parses character data inside XML element.
330
*
331
* @param chars the array of characters
332
* @param start the start position in the character array
333
* @param length the number of characters to use
334
*/
335
@Override
336
public void characters(char[] chars, int start, int length) {
337
if (this.handler != null) {
338
try {
339
while (0 < length--) {
340
this.handler.addCharacter(chars[start++]);
341
}
342
}
343
catch (RuntimeException exception) {
344
handleException(exception);
345
}
346
}
347
}
348
349
/**
350
* Handles an exception using current exception listener.
351
*
352
* @param exception an exception to handle
353
* @see #setExceptionListener
354
*/
355
public void handleException(Exception exception) {
356
if (this.listener == null) {
357
throw new IllegalStateException(exception);
358
}
359
this.listener.exceptionThrown(exception);
360
}
361
362
/**
363
* Starts parsing of the specified input source.
364
*
365
* @param input the input source to parse
366
*/
367
public void parse(final InputSource input) {
368
if ((this.acc == null) && (null != System.getSecurityManager())) {
369
throw new SecurityException("AccessControlContext is not set");
370
}
371
AccessControlContext stack = AccessController.getContext();
372
SharedSecrets.getJavaSecurityAccess().doIntersectionPrivilege(new PrivilegedAction<Void>() {
373
public Void run() {
374
try {
375
SAXParserFactory.newInstance().newSAXParser().parse(input, DocumentHandler.this);
376
}
377
catch (ParserConfigurationException exception) {
378
handleException(exception);
379
}
380
catch (SAXException wrapper) {
381
Exception exception = wrapper.getException();
382
if (exception == null) {
383
exception = wrapper;
384
}
385
handleException(exception);
386
}
387
catch (IOException exception) {
388
handleException(exception);
389
}
390
return null;
391
}
392
}, stack, this.acc);
393
}
394
395
/**
396
* Resolves class by name using current class loader.
397
* This method handles exception using current exception listener.
398
*
399
* @param name the name of the class
400
* @return the object that represents the class
401
*/
402
public Class<?> findClass(String name) {
403
try {
404
return ClassFinder.resolveClass(name, getClassLoader());
405
}
406
catch (ClassNotFoundException exception) {
407
handleException(exception);
408
return null;
409
}
410
}
411
}
412
413