Source Code Cross Referenced for Encoder.java in  » 6.0-JDK-Core » beans » java » beans » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
Java Source Code / Java Documentation
1.6.0 JDK Core
2.6.0 JDK Modules
3.6.0 JDK Modules com.sun
4.6.0 JDK Modules com.sun.java
5.6.0 JDK Modules sun
6.6.0 JDK Platform
7.Ajax
8.Apache Harmony Java SE
9.Aspect oriented
10.Authentication Authorization
11.Blogger System
12.Build
13.Byte Code
14.Cache
15.Chart
16.Chat
17.Code Analyzer
18.Collaboration
19.Content Management System
20.Database Client
21.Database DBMS
22.Database JDBC Connection Pool
23.Database ORM
24.Development
25.EJB Server
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » beans » java.beans 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001        /*
002         * Copyright 2000-2007 Sun Microsystems, Inc.  All Rights Reserved.
003         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004         *
005         * This code is free software; you can redistribute it and/or modify it
006         * under the terms of the GNU General Public License version 2 only, as
007         * published by the Free Software Foundation.  Sun designates this
008         * particular file as subject to the "Classpath" exception as provided
009         * by Sun in the LICENSE file that accompanied this code.
010         *
011         * This code is distributed in the hope that it will be useful, but WITHOUT
012         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014         * version 2 for more details (a copy is included in the LICENSE file that
015         * accompanied this code).
016         *
017         * You should have received a copy of the GNU General Public License version
018         * 2 along with this work; if not, write to the Free Software Foundation,
019         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020         *
021         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022         * CA 95054 USA or visit www.sun.com if you need additional information or
023         * have any questions.
024         */
025        package java.beans;
026
027        import java.util.Collections;
028        import java.util.HashMap;
029        import java.util.IdentityHashMap;
030        import java.util.Map;
031
032        /**
033         * An <code>Encoder</code> is a class which can be used to create 
034         * files or streams that encode the state of a collection of 
035         * JavaBeans in terms of their public APIs. The <code>Encoder</code>, 
036         * in conjunction with its persistence delegates, is responsible for 
037         * breaking the object graph down into a series of <code>Statements</code>s 
038         * and <code>Expression</code>s which can be used to create it. 
039         * A subclass typically provides a syntax for these expressions 
040         * using some human readable form - like Java source code or XML. 
041         * 
042         * @since 1.4
043         *
044         * @version 1.3 11/15/00
045         * @author Philip Milne
046         */
047
048        public class Encoder {
049            private final Map<Class<?>, PersistenceDelegate> delegates = Collections
050                    .synchronizedMap(new HashMap<Class<?>, PersistenceDelegate>());
051            private Map bindings = new IdentityHashMap();
052            private ExceptionListener exceptionListener;
053            boolean executeStatements = true;
054            private Map attributes;
055
056            /** 
057             * Write the specified object to the output stream. 
058             * The serialized form will denote a series of 
059             * expressions, the combined effect of which will create 
060             * an equivalent object when the input stream is read. 
061             * By default, the object is assumed to be a <em>JavaBean</em> 
062             * with a nullary constructor, whose state is defined by 
063             * the matching pairs of "setter" and "getter" methods 
064             * returned by the Introspector. 
065             *
066             * @param o The object to be written to the stream. 
067             * 
068             * @see XMLDecoder#readObject
069             */
070            protected void writeObject(Object o) {
071                if (o == this ) {
072                    return;
073                }
074                PersistenceDelegate info = getPersistenceDelegate(o == null ? null
075                        : o.getClass());
076                info.writeObject(o, this );
077            }
078
079            /** 
080             * Sets the exception handler for this stream to <code>exceptionListener</code>. 
081             * The exception handler is notified when this stream catches recoverable 
082             * exceptions.
083             * 
084             * @param exceptionListener The exception handler for this stream;
085             *       if <code>null</code> the default exception listener will be used.
086             *
087             * @see #getExceptionListener
088             */
089            public void setExceptionListener(ExceptionListener exceptionListener) {
090                this .exceptionListener = exceptionListener;
091            }
092
093            /**
094             * Gets the exception handler for this stream. 
095             * 
096             * @return The exception handler for this stream;
097             *    Will return the default exception listener if this has not explicitly been set.
098             *
099             * @see #setExceptionListener
100             */
101            public ExceptionListener getExceptionListener() {
102                return (exceptionListener != null) ? exceptionListener
103                        : Statement.defaultExceptionListener;
104            }
105
106            Object getValue(Expression exp) {
107                try {
108                    return (exp == null) ? null : exp.getValue();
109                } catch (Exception e) {
110                    getExceptionListener().exceptionThrown(e);
111                    throw new RuntimeException("failed to evaluate: "
112                            + exp.toString());
113                }
114            }
115
116            /**
117             * Returns the persistence delegate for the given type. 
118             * The persistence delegate is calculated 
119             * by applying the following of rules in order:   
120             * <ul>
121             * <li>
122             * If the type is an array, an internal persistence 
123             * delegate is returned which will instantiate an 
124             * array of the appropriate type and length, initializing  
125             * each of its elements as if they are properties. 
126             * <li>
127             * If the type is a proxy, an internal persistence 
128             * delegate is returned which will instantiate a 
129             * new proxy instance using the static 
130             * "newProxyInstance" method defined in the 
131             * Proxy class. 
132             * <li>
133             * If the BeanInfo for this type has a <code>BeanDescriptor</code> 
134             * which defined a "persistenceDelegate" property, this 
135             * value is returned. 
136             * <li>
137             * In all other cases the default persistence delegate 
138             * is returned. The default persistence delegate assumes 
139             * the type is a <em>JavaBean</em>, implying that it has a default constructor 
140             * and that its state may be characterized by the matching pairs 
141             * of "setter" and "getter" methods returned by the Introspector. 
142             * The default constructor is the constructor with the greatest number
143             * of parameters that has the {@link ConstructorProperties} annotation.
144             * If none of the constructors have the {@code ConstructorProperties} annotation,
145             * then the nullary constructor (constructor with no parameters) will be used.
146             * For example, in the following the nullary constructor
147             * for {@code Foo} will be used, while the two parameter constructor
148             * for {@code Bar} will be used.
149             * <code>
150             *   public class Foo {
151             *     public Foo() { ... }
152             *     public Foo(int x) { ... }
153             *   }
154             *   public class Bar {
155             *     public Bar() { ... }
156             *     &#64;ConstructorProperties({"x"})
157             *     public Bar(int x) { ... }
158             *     &#64;ConstructorProperties({"x", "y"})
159             *     public Bar(int x, int y) { ... }
160             *   }
161             * </code> 
162             * </ul>
163             * 
164             * @param  type The type of the object. 
165             * @return The persistence delegate for this type of object. 
166             *
167             * @see #setPersistenceDelegate
168             * @see java.beans.Introspector#getBeanInfo
169             * @see java.beans.BeanInfo#getBeanDescriptor
170             */
171            public PersistenceDelegate getPersistenceDelegate(Class<?> type) {
172                PersistenceDelegate pd = this .delegates.get(type);
173                return (pd != null) ? pd : MetaData
174                        .getPersistenceDelegate(type);
175            }
176
177            /**
178             * Sets the persistence delegate associated with this <code>type</code> to
179             * <code>persistenceDelegate</code>.
180             * 
181             * @param  type The class of objects that <code>persistenceDelegate</code> applies to. 
182             * @param  persistenceDelegate The persistence delegate for instances of <code>type</code>. 
183             * 
184             * @see #getPersistenceDelegate
185             * @see java.beans.Introspector#getBeanInfo
186             * @see java.beans.BeanInfo#getBeanDescriptor
187             */
188            public void setPersistenceDelegate(Class<?> type,
189                    PersistenceDelegate persistenceDelegate) {
190                if (persistenceDelegate != null) {
191                    this .delegates.put(type, persistenceDelegate);
192                } else {
193                    this .delegates.remove(type);
194                }
195            }
196
197            /**
198             * Removes the entry for this instance, returning the old entry.  
199             * 
200             * @param oldInstance The entry that should be removed. 
201             * @return The entry that was removed. 
202             *
203             * @see #get 
204             */
205            public Object remove(Object oldInstance) {
206                Expression exp = (Expression) bindings.remove(oldInstance);
207                return getValue(exp);
208            }
209
210            /**
211             * Returns a tentative value for <code>oldInstance</code> in 
212             * the environment created by this stream. A persistence 
213             * delegate can use its <code>mutatesTo</code> method to 
214             * determine whether this value may be initialized to 
215             * form the equivalent object at the output or whether 
216             * a new object must be instantiated afresh. If the 
217             * stream has not yet seen this value, null is returned.  
218             * 
219             * @param  oldInstance The instance to be looked up. 
220             * @return The object, null if the object has not been seen before. 
221             */
222            public Object get(Object oldInstance) {
223                if (oldInstance == null || oldInstance == this 
224                        || oldInstance.getClass() == String.class) {
225                    return oldInstance;
226                }
227                Expression exp = (Expression) bindings.get(oldInstance);
228                return getValue(exp);
229            }
230
231            private Object writeObject1(Object oldInstance) {
232                Object o = get(oldInstance);
233                if (o == null) {
234                    writeObject(oldInstance);
235                    o = get(oldInstance);
236                }
237                return o;
238            }
239
240            private Statement cloneStatement(Statement oldExp) {
241                Object oldTarget = oldExp.getTarget();
242                Object newTarget = writeObject1(oldTarget);
243
244                Object[] oldArgs = oldExp.getArguments();
245                Object[] newArgs = new Object[oldArgs.length];
246                for (int i = 0; i < oldArgs.length; i++) {
247                    newArgs[i] = writeObject1(oldArgs[i]);
248                }
249                if (oldExp.getClass() == Statement.class) {
250                    return new Statement(newTarget, oldExp.getMethodName(),
251                            newArgs);
252                } else {
253                    return new Expression(newTarget, oldExp.getMethodName(),
254                            newArgs);
255                }
256            }
257
258            /**
259             * Writes statement <code>oldStm</code> to the stream. 
260             * The <code>oldStm</code> should be written entirely 
261             * in terms of the callers environment, i.e. the 
262             * target and all arguments should be part of the 
263             * object graph being written. These expressions 
264             * represent a series of "what happened" expressions 
265             * which tell the output stream how to produce an 
266             * object graph like the original. 
267             * <p>
268             * The implementation of this method will produce 
269             * a second expression to represent the same expression in 
270             * an environment that will exist when the stream is read. 
271             * This is achieved simply by calling <code>writeObject</code> 
272             * on the target and all the arguments and building a new 
273             * expression with the results. 
274             * 
275             * @param oldStm The expression to be written to the stream.
276             */
277            public void writeStatement(Statement oldStm) {
278                // System.out.println("writeStatement: " + oldExp); 
279                Statement newStm = cloneStatement(oldStm);
280                if (oldStm.getTarget() != this  && executeStatements) {
281                    try {
282                        newStm.execute();
283                    } catch (Exception e) {
284                        getExceptionListener().exceptionThrown(
285                                new Exception("Encoder: discarding statement "
286                                        + newStm, e));
287                    }
288                }
289            }
290
291            /**
292             * The implementation first checks to see if an 
293             * expression with this value has already been written. 
294             * If not, the expression is cloned, using 
295             * the same procedure as <code>writeStatement</code>, 
296             * and the value of this expression is reconciled 
297             * with the value of the cloned expression   
298             * by calling <code>writeObject</code>. 
299             * 
300             * @param oldExp The expression to be written to the stream.
301             */
302            public void writeExpression(Expression oldExp) {
303                // System.out.println("Encoder::writeExpression: " + oldExp); 
304                Object oldValue = getValue(oldExp);
305                if (get(oldValue) != null) {
306                    return;
307                }
308                bindings.put(oldValue, (Expression) cloneStatement(oldExp));
309                writeObject(oldValue);
310            }
311
312            void clear() {
313                bindings.clear();
314            }
315
316            // Package private method for setting an attributes table for the encoder
317            void setAttribute(Object key, Object value) {
318                if (attributes == null) {
319                    attributes = new HashMap();
320                }
321                attributes.put(key, value);
322            }
323
324            Object getAttribute(Object key) {
325                if (attributes == null) {
326                    return null;
327                }
328                return attributes.get(key);
329            }
330        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.