Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/share/classes/com/sun/beans/decoder/DocumentHandler.java
41171 views
1
/*
2
* Copyright (c) 2008, 2021, 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 jdk.internal.access.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
@SuppressWarnings("removal")
66
private final AccessControlContext acc = AccessController.getContext();
67
private final Map<String, Class<? extends ElementHandler>> handlers = new HashMap<>();
68
private final Map<String, Object> environment = new HashMap<>();
69
private final List<Object> objects = new ArrayList<>();
70
71
private Reference<ClassLoader> loader;
72
private ExceptionListener listener;
73
private Object owner;
74
75
private ElementHandler handler;
76
77
/**
78
* Creates new instance of document handler.
79
*/
80
public DocumentHandler() {
81
setElementHandler("java", JavaElementHandler.class); // NON-NLS: the element name
82
setElementHandler("null", NullElementHandler.class); // NON-NLS: the element name
83
setElementHandler("array", ArrayElementHandler.class); // NON-NLS: the element name
84
setElementHandler("class", ClassElementHandler.class); // NON-NLS: the element name
85
setElementHandler("string", StringElementHandler.class); // NON-NLS: the element name
86
setElementHandler("object", ObjectElementHandler.class); // NON-NLS: the element name
87
88
setElementHandler("void", VoidElementHandler.class); // NON-NLS: the element name
89
setElementHandler("char", CharElementHandler.class); // NON-NLS: the element name
90
setElementHandler("byte", ByteElementHandler.class); // NON-NLS: the element name
91
setElementHandler("short", ShortElementHandler.class); // NON-NLS: the element name
92
setElementHandler("int", IntElementHandler.class); // NON-NLS: the element name
93
setElementHandler("long", LongElementHandler.class); // NON-NLS: the element name
94
setElementHandler("float", FloatElementHandler.class); // NON-NLS: the element name
95
setElementHandler("double", DoubleElementHandler.class); // NON-NLS: the element name
96
setElementHandler("boolean", BooleanElementHandler.class); // NON-NLS: the element name
97
98
// some handlers for new elements
99
setElementHandler("new", NewElementHandler.class); // NON-NLS: the element name
100
setElementHandler("var", VarElementHandler.class); // NON-NLS: the element name
101
setElementHandler("true", TrueElementHandler.class); // NON-NLS: the element name
102
setElementHandler("false", FalseElementHandler.class); // NON-NLS: the element name
103
setElementHandler("field", FieldElementHandler.class); // NON-NLS: the element name
104
setElementHandler("method", MethodElementHandler.class); // NON-NLS: the element name
105
setElementHandler("property", PropertyElementHandler.class); // NON-NLS: the element name
106
}
107
108
/**
109
* Returns the class loader used to instantiate objects.
110
* If the class loader has not been explicitly set
111
* then {@code null} is returned.
112
*
113
* @return the class loader used to instantiate objects
114
*/
115
public ClassLoader getClassLoader() {
116
return (this.loader != null)
117
? this.loader.get()
118
: null;
119
}
120
121
/**
122
* Sets the class loader used to instantiate objects.
123
* If the class loader is not set
124
* then default class loader will be used.
125
*
126
* @param loader a classloader to use
127
*/
128
public void setClassLoader(ClassLoader loader) {
129
this.loader = new WeakReference<ClassLoader>(loader);
130
}
131
132
/**
133
* Returns the exception listener for parsing.
134
* The exception listener is notified
135
* when handler catches recoverable exceptions.
136
* If the exception listener has not been explicitly set
137
* then default exception listener is returned.
138
*
139
* @return the exception listener for parsing
140
*/
141
public ExceptionListener getExceptionListener() {
142
return this.listener;
143
}
144
145
/**
146
* Sets the exception listener for parsing.
147
* The exception listener is notified
148
* when handler catches recoverable exceptions.
149
*
150
* @param listener the exception listener for parsing
151
*/
152
public void setExceptionListener(ExceptionListener listener) {
153
this.listener = listener;
154
}
155
156
/**
157
* Returns the owner of this document handler.
158
*
159
* @return the owner of this document handler
160
*/
161
public Object getOwner() {
162
return this.owner;
163
}
164
165
/**
166
* Sets the owner of this document handler.
167
*
168
* @param owner the owner of this document handler
169
*/
170
public void setOwner(Object owner) {
171
this.owner = owner;
172
}
173
174
/**
175
* Returns the handler for the element with specified name.
176
*
177
* @param name the name of the element
178
* @return the corresponding element handler
179
*/
180
public Class<? extends ElementHandler> getElementHandler(String name) {
181
Class<? extends ElementHandler> type = this.handlers.get(name);
182
if (type == null) {
183
throw new IllegalArgumentException("Unsupported element: " + name);
184
}
185
return type;
186
}
187
188
/**
189
* Sets the handler for the element with specified name.
190
*
191
* @param name the name of the element
192
* @param handler the corresponding element handler
193
*/
194
public void setElementHandler(String name, Class<? extends ElementHandler> handler) {
195
this.handlers.put(name, handler);
196
}
197
198
/**
199
* Indicates whether the variable with specified identifier is defined.
200
*
201
* @param id the identifier
202
* @return @{code true} if the variable is defined;
203
* @{code false} otherwise
204
*/
205
public boolean hasVariable(String id) {
206
return this.environment.containsKey(id);
207
}
208
209
/**
210
* Returns the value of the variable with specified identifier.
211
*
212
* @param id the identifier
213
* @return the value of the variable
214
*/
215
public Object getVariable(String id) {
216
if (!this.environment.containsKey(id)) {
217
throw new IllegalArgumentException("Unbound variable: " + id);
218
}
219
return this.environment.get(id);
220
}
221
222
/**
223
* Sets new value of the variable with specified identifier.
224
*
225
* @param id the identifier
226
* @param value new value of the variable
227
*/
228
public void setVariable(String id, Object value) {
229
this.environment.put(id, value);
230
}
231
232
/**
233
* Returns the array of readed objects.
234
*
235
* @return the array of readed objects
236
*/
237
public Object[] getObjects() {
238
return this.objects.toArray();
239
}
240
241
/**
242
* Adds the object to the list of readed objects.
243
*
244
* @param object the object that is readed from XML document
245
*/
246
void addObject(Object object) {
247
this.objects.add(object);
248
}
249
250
/**
251
* Disables any external entities.
252
*/
253
@Override
254
public InputSource resolveEntity(String publicId, String systemId) {
255
return new InputSource(new StringReader(""));
256
}
257
258
/**
259
* Prepares this handler to read objects from XML document.
260
*/
261
@Override
262
public void startDocument() {
263
this.objects.clear();
264
this.handler = null;
265
}
266
267
/**
268
* Parses opening tag of XML element
269
* using corresponding element handler.
270
*
271
* @param uri the namespace URI, or the empty string
272
* if the element has no namespace URI or
273
* if namespace processing is not being performed
274
* @param localName the local name (without prefix), or the empty string
275
* if namespace processing is not being performed
276
* @param qName the qualified name (with prefix), or the empty string
277
* if qualified names are not available
278
* @param attributes the attributes attached to the element
279
*/
280
@Override
281
@SuppressWarnings("deprecation")
282
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
283
ElementHandler parent = this.handler;
284
try {
285
this.handler =
286
getElementHandler(qName).newInstance();
287
this.handler.setOwner(this);
288
this.handler.setParent(parent);
289
}
290
catch (Exception exception) {
291
throw new SAXException(exception);
292
}
293
for (int i = 0; i < attributes.getLength(); i++)
294
try {
295
String name = attributes.getQName(i);
296
String value = attributes.getValue(i);
297
this.handler.addAttribute(name, value);
298
}
299
catch (RuntimeException exception) {
300
handleException(exception);
301
}
302
303
this.handler.startElement();
304
}
305
306
/**
307
* Parses closing tag of XML element
308
* using corresponding element handler.
309
*
310
* @param uri the namespace URI, or the empty string
311
* if the element has no namespace URI or
312
* if namespace processing is not being performed
313
* @param localName the local name (without prefix), or the empty string
314
* if namespace processing is not being performed
315
* @param qName the qualified name (with prefix), or the empty string
316
* if qualified names are not available
317
*/
318
@Override
319
public void endElement(String uri, String localName, String qName) {
320
try {
321
this.handler.endElement();
322
}
323
catch (RuntimeException exception) {
324
handleException(exception);
325
}
326
finally {
327
this.handler = this.handler.getParent();
328
}
329
}
330
331
/**
332
* Parses character data inside XML element.
333
*
334
* @param chars the array of characters
335
* @param start the start position in the character array
336
* @param length the number of characters to use
337
*/
338
@Override
339
public void characters(char[] chars, int start, int length) {
340
if (this.handler != null) {
341
try {
342
while (0 < length--) {
343
this.handler.addCharacter(chars[start++]);
344
}
345
}
346
catch (RuntimeException exception) {
347
handleException(exception);
348
}
349
}
350
}
351
352
/**
353
* Handles an exception using current exception listener.
354
*
355
* @param exception an exception to handle
356
* @see #setExceptionListener
357
*/
358
public void handleException(Exception exception) {
359
if (this.listener == null) {
360
throw new IllegalStateException(exception);
361
}
362
this.listener.exceptionThrown(exception);
363
}
364
365
/**
366
* Starts parsing of the specified input source.
367
*
368
* @param input the input source to parse
369
*/
370
@SuppressWarnings("removal")
371
public void parse(final InputSource input) {
372
if ((this.acc == null) && (null != System.getSecurityManager())) {
373
throw new SecurityException("AccessControlContext is not set");
374
}
375
AccessControlContext stack = AccessController.getContext();
376
SharedSecrets.getJavaSecurityAccess().doIntersectionPrivilege(new PrivilegedAction<Void>() {
377
public Void run() {
378
try {
379
SAXParserFactory.newInstance().newSAXParser().parse(input, DocumentHandler.this);
380
}
381
catch (ParserConfigurationException exception) {
382
handleException(exception);
383
}
384
catch (SAXException wrapper) {
385
Exception exception = wrapper.getException();
386
if (exception == null) {
387
exception = wrapper;
388
}
389
handleException(exception);
390
}
391
catch (IOException exception) {
392
handleException(exception);
393
}
394
return null;
395
}
396
}, stack, this.acc);
397
}
398
399
/**
400
* Resolves class by name using current class loader.
401
* This method handles exception using current exception listener.
402
*
403
* @param name the name of the class
404
* @return the object that represents the class
405
*/
406
public Class<?> findClass(String name) {
407
try {
408
return ClassFinder.resolveClass(name, getClassLoader());
409
}
410
catch (ClassNotFoundException exception) {
411
handleException(exception);
412
return null;
413
}
414
}
415
}
416
417