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 java.beans; 26 27 import com.sun.beans.decoder.DocumentHandler; 28 29 import java.io.Closeable; 30 import java.io.InputStream; 31 import java.io.IOException; 32 import java.security.AccessControlContext; 33 import java.security.AccessController; 34 import java.security.PrivilegedAction; 35 36 import org.xml.sax.InputSource; 37 import org.xml.sax.helpers.DefaultHandler; 38 39 /** 40 * The <code>XMLDecoder</code> class is used to read XML documents 41 * created using the <code>XMLEncoder</code> and is used just like 42 * the <code>ObjectInputStream</code>. For example, one can use 43 * the following fragment to read the first object defined 44 * in an XML document written by the <code>XMLEncoder</code> 45 * class: 46 * <pre> 47 * XMLDecoder d = new XMLDecoder( 48 * new BufferedInputStream( 49 * new FileInputStream("Test.xml"))); 50 * Object result = d.readObject(); 51 * d.close(); 52 * </pre> 53 * 54 *<p> 55 * For more information you might also want to check out 56 * <a 57 href="http://java.sun.com/products/jfc/tsc/articles/persistence3">Long Term Persistence of JavaBeans Components: XML Schema</a>, 58 * an article in <em>The Swing Connection.</em> 59 * @see XMLEncoder 60 * @see java.io.ObjectInputStream 61 * 62 * @since 1.4 63 * 64 * @author Philip Milne 65 */ 66 public class XMLDecoder implements AutoCloseable { 67 private final AccessControlContext acc = AccessController.getContext(); 68 private final DocumentHandler handler = new DocumentHandler(); 69 private final InputSource input; 70 private Object owner; 71 private Object[] array; 72 private int index; 73 74 /** 75 * Creates a new input stream for reading archives 76 * created by the <code>XMLEncoder</code> class. 77 * 78 * @param in The underlying stream. 79 * 80 * @see XMLEncoder#XMLEncoder(java.io.OutputStream) 81 */ 82 public XMLDecoder(InputStream in) { 83 this(in, null); 84 } 85 86 /** 87 * Creates a new input stream for reading archives 88 * created by the <code>XMLEncoder</code> class. 89 * 90 * @param in The underlying stream. 91 * @param owner The owner of this stream. 92 * 93 */ 94 public XMLDecoder(InputStream in, Object owner) { 95 this(in, owner, null); 96 } 97 98 /** 99 * Creates a new input stream for reading archives 100 * created by the <code>XMLEncoder</code> class. 101 * 102 * @param in the underlying stream. 103 * @param owner the owner of this stream. 104 * @param exceptionListener the exception handler for the stream; 105 * if <code>null</code> the default exception listener will be used. 106 */ 107 public XMLDecoder(InputStream in, Object owner, ExceptionListener exceptionListener) { 108 this(in, owner, exceptionListener, null); 109 } 110 111 /** 112 * Creates a new input stream for reading archives 113 * created by the <code>XMLEncoder</code> class. 114 * 115 * @param in the underlying stream. <code>null</code> may be passed without 116 * error, though the resulting XMLDecoder will be useless 117 * @param owner the owner of this stream. <code>null</code> is a legal 118 * value 119 * @param exceptionListener the exception handler for the stream, or 120 * <code>null</code> to use the default 121 * @param cl the class loader used for instantiating objects. 122 * <code>null</code> indicates that the default class loader should 123 * be used 124 * @since 1.5 125 */ 126 public XMLDecoder(InputStream in, Object owner, 127 ExceptionListener exceptionListener, ClassLoader cl) { 128 this(new InputSource(in), owner, exceptionListener, cl); 129 } 130 131 132 /** 133 * Creates a new decoder to parse XML archives 134 * created by the {@code XMLEncoder} class. 135 * If the input source {@code is} is {@code null}, 136 * no exception is thrown and no parsing is performed. 137 * This behavior is similar to behavior of other constructors 138 * that use {@code InputStream} as a parameter. 139 * 140 * @param is the input source to parse 141 * 142 * @since 1.7 191 private boolean parsingComplete() { 192 if (this.input == null) { 193 return false; 194 } 195 if (this.array == null) { 196 if ((this.acc == null) && (null != System.getSecurityManager())) { 197 throw new SecurityException("AccessControlContext is not set"); 198 } 199 AccessController.doPrivileged(new PrivilegedAction<Void>() { 200 public Void run() { 201 XMLDecoder.this.handler.parse(XMLDecoder.this.input); 202 return null; 203 } 204 }, this.acc); 205 this.array = this.handler.getObjects(); 206 } 207 return true; 208 } 209 210 /** 211 * Sets the exception handler for this stream to <code>exceptionListener</code>. 212 * The exception handler is notified when this stream catches recoverable 213 * exceptions. 214 * 215 * @param exceptionListener The exception handler for this stream; 216 * if <code>null</code> the default exception listener will be used. 217 * 218 * @see #getExceptionListener 219 */ 220 public void setExceptionListener(ExceptionListener exceptionListener) { 221 if (exceptionListener == null) { 222 exceptionListener = Statement.defaultExceptionListener; 223 } 224 this.handler.setExceptionListener(exceptionListener); 225 } 226 227 /** 228 * Gets the exception handler for this stream. 229 * 230 * @return The exception handler for this stream. 231 * Will return the default exception listener if this has not explicitly been set. 232 * 233 * @see #setExceptionListener 234 */ 235 public ExceptionListener getExceptionListener() { 236 return this.handler.getExceptionListener(); 237 } 238 239 /** 240 * Reads the next object from the underlying input stream. 241 * 242 * @return the next object read 243 * 244 * @throws ArrayIndexOutOfBoundsException if the stream contains no objects 245 * (or no more objects) 246 * 247 * @see XMLEncoder#writeObject 248 */ 249 public Object readObject() { 250 return (parsingComplete()) 251 ? this.array[this.index++] 252 : null; 253 } 254 255 /** 256 * Sets the owner of this decoder to <code>owner</code>. 257 * 258 * @param owner The owner of this decoder. 259 * 260 * @see #getOwner 261 */ 262 public void setOwner(Object owner) { 263 this.owner = owner; 264 } 265 266 /** 267 * Gets the owner of this decoder. 268 * 269 * @return The owner of this decoder. 270 * 271 * @see #setOwner 272 */ 273 public Object getOwner() { 274 return owner; 275 } 276 | 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 java.beans; 26 27 import com.sun.beans.decoder.DocumentHandler; 28 29 import java.io.Closeable; 30 import java.io.InputStream; 31 import java.io.IOException; 32 import java.security.AccessControlContext; 33 import java.security.AccessController; 34 import java.security.PrivilegedAction; 35 36 import org.xml.sax.InputSource; 37 import org.xml.sax.helpers.DefaultHandler; 38 39 /** 40 * The {@code XMLDecoder} class is used to read XML documents 41 * created using the {@code XMLEncoder} and is used just like 42 * the {@code ObjectInputStream}. For example, one can use 43 * the following fragment to read the first object defined 44 * in an XML document written by the {@code XMLEncoder} 45 * class: 46 * <pre> 47 * XMLDecoder d = new XMLDecoder( 48 * new BufferedInputStream( 49 * new FileInputStream("Test.xml"))); 50 * Object result = d.readObject(); 51 * d.close(); 52 * </pre> 53 * 54 *<p> 55 * For more information you might also want to check out 56 * <a 57 href="http://java.sun.com/products/jfc/tsc/articles/persistence3">Long Term Persistence of JavaBeans Components: XML Schema</a>, 58 * an article in <em>The Swing Connection.</em> 59 * @see XMLEncoder 60 * @see java.io.ObjectInputStream 61 * 62 * @since 1.4 63 * 64 * @author Philip Milne 65 */ 66 public class XMLDecoder implements AutoCloseable { 67 private final AccessControlContext acc = AccessController.getContext(); 68 private final DocumentHandler handler = new DocumentHandler(); 69 private final InputSource input; 70 private Object owner; 71 private Object[] array; 72 private int index; 73 74 /** 75 * Creates a new input stream for reading archives 76 * created by the {@code XMLEncoder} class. 77 * 78 * @param in The underlying stream. 79 * 80 * @see XMLEncoder#XMLEncoder(java.io.OutputStream) 81 */ 82 public XMLDecoder(InputStream in) { 83 this(in, null); 84 } 85 86 /** 87 * Creates a new input stream for reading archives 88 * created by the {@code XMLEncoder} class. 89 * 90 * @param in The underlying stream. 91 * @param owner The owner of this stream. 92 * 93 */ 94 public XMLDecoder(InputStream in, Object owner) { 95 this(in, owner, null); 96 } 97 98 /** 99 * Creates a new input stream for reading archives 100 * created by the {@code XMLEncoder} class. 101 * 102 * @param in the underlying stream. 103 * @param owner the owner of this stream. 104 * @param exceptionListener the exception handler for the stream; 105 * if {@code null} the default exception listener will be used. 106 */ 107 public XMLDecoder(InputStream in, Object owner, ExceptionListener exceptionListener) { 108 this(in, owner, exceptionListener, null); 109 } 110 111 /** 112 * Creates a new input stream for reading archives 113 * created by the {@code XMLEncoder} class. 114 * 115 * @param in the underlying stream. {@code null} may be passed without 116 * error, though the resulting XMLDecoder will be useless 117 * @param owner the owner of this stream. {@code null} is a legal 118 * value 119 * @param exceptionListener the exception handler for the stream, or 120 * {@code null} to use the default 121 * @param cl the class loader used for instantiating objects. 122 * {@code null} indicates that the default class loader should 123 * be used 124 * @since 1.5 125 */ 126 public XMLDecoder(InputStream in, Object owner, 127 ExceptionListener exceptionListener, ClassLoader cl) { 128 this(new InputSource(in), owner, exceptionListener, cl); 129 } 130 131 132 /** 133 * Creates a new decoder to parse XML archives 134 * created by the {@code XMLEncoder} class. 135 * If the input source {@code is} is {@code null}, 136 * no exception is thrown and no parsing is performed. 137 * This behavior is similar to behavior of other constructors 138 * that use {@code InputStream} as a parameter. 139 * 140 * @param is the input source to parse 141 * 142 * @since 1.7 191 private boolean parsingComplete() { 192 if (this.input == null) { 193 return false; 194 } 195 if (this.array == null) { 196 if ((this.acc == null) && (null != System.getSecurityManager())) { 197 throw new SecurityException("AccessControlContext is not set"); 198 } 199 AccessController.doPrivileged(new PrivilegedAction<Void>() { 200 public Void run() { 201 XMLDecoder.this.handler.parse(XMLDecoder.this.input); 202 return null; 203 } 204 }, this.acc); 205 this.array = this.handler.getObjects(); 206 } 207 return true; 208 } 209 210 /** 211 * Sets the exception handler for this stream to {@code exceptionListener}. 212 * The exception handler is notified when this stream catches recoverable 213 * exceptions. 214 * 215 * @param exceptionListener The exception handler for this stream; 216 * if {@code null} the default exception listener will be used. 217 * 218 * @see #getExceptionListener 219 */ 220 public void setExceptionListener(ExceptionListener exceptionListener) { 221 if (exceptionListener == null) { 222 exceptionListener = Statement.defaultExceptionListener; 223 } 224 this.handler.setExceptionListener(exceptionListener); 225 } 226 227 /** 228 * Gets the exception handler for this stream. 229 * 230 * @return The exception handler for this stream. 231 * Will return the default exception listener if this has not explicitly been set. 232 * 233 * @see #setExceptionListener 234 */ 235 public ExceptionListener getExceptionListener() { 236 return this.handler.getExceptionListener(); 237 } 238 239 /** 240 * Reads the next object from the underlying input stream. 241 * 242 * @return the next object read 243 * 244 * @throws ArrayIndexOutOfBoundsException if the stream contains no objects 245 * (or no more objects) 246 * 247 * @see XMLEncoder#writeObject 248 */ 249 public Object readObject() { 250 return (parsingComplete()) 251 ? this.array[this.index++] 252 : null; 253 } 254 255 /** 256 * Sets the owner of this decoder to {@code owner}. 257 * 258 * @param owner The owner of this decoder. 259 * 260 * @see #getOwner 261 */ 262 public void setOwner(Object owner) { 263 this.owner = owner; 264 } 265 266 /** 267 * Gets the owner of this decoder. 268 * 269 * @return The owner of this decoder. 270 * 271 * @see #setOwner 272 */ 273 public Object getOwner() { 274 return owner; 275 } 276 |