History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/com/sun/beans/decoder/DocumentHandler.java (1 of 18352 files). Show all

Unified · Split

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