diff options
Diffstat (limited to 'libjava/classpath/gnu/java/beans')
87 files changed, 10131 insertions, 0 deletions
diff --git a/libjava/classpath/gnu/java/beans/BeanInfoEmbryo.java b/libjava/classpath/gnu/java/beans/BeanInfoEmbryo.java new file mode 100644 index 000000000..cc474e817 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/BeanInfoEmbryo.java @@ -0,0 +1,171 @@ +/* gnu.java.beans.BeanInfoEmbryo + Copyright (C) 1998, 2002 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.beans; + +import java.beans.BeanDescriptor; +import java.beans.BeanInfo; +import java.beans.EventSetDescriptor; +import java.beans.IndexedPropertyDescriptor; +import java.beans.MethodDescriptor; +import java.beans.PropertyDescriptor; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.Map; +import java.util.TreeMap; +import java.util.Vector; + +/** + ** A BeanInfoEmbryo accumulates information about a Bean + ** while it is in the process of being created, and then + ** when you are done accumulating the information, the + ** getBeanInfo() method may be called to create a BeanInfo + ** object based on the information.<P> + ** + ** This class is not well-synchronized. (It can be, it + ** just isn't yet.) + ** + ** @author John Keiser + ** @version 1.1.0, 30 Jul 1998 + ** @see java.beans.BeanInfo + **/ + +public class BeanInfoEmbryo { + + // by using a TreeMap the properties will be sorted alphabetically by name + // which matches the (undocumented) behavior of jdk + TreeMap properties = new TreeMap(); + Hashtable events = new Hashtable(); + Vector methods = new Vector(); + + BeanDescriptor beanDescriptor; + BeanInfo[] additionalBeanInfo; + java.awt.Image[] im; + String defaultPropertyName; + String defaultEventName; + + public BeanInfoEmbryo() { + } + + public BeanInfo getBeanInfo() { + int defaultProperty = -1; + int defaultEvent = -1; + + PropertyDescriptor[] Aproperties = new PropertyDescriptor[properties.size()]; + int i = 0; + Iterator it = properties.entrySet().iterator(); + while (it.hasNext()) { + Aproperties[i] = (PropertyDescriptor) (((Map.Entry)it.next()).getValue()); + if(defaultPropertyName != null && Aproperties[i].getName().equals(defaultPropertyName)) { + defaultProperty = i; + } + i++; + } + + EventSetDescriptor[] Aevents = new EventSetDescriptor[events.size()]; + i = 0; + Enumeration e = events.elements(); + while (e.hasMoreElements()) { + Aevents[i] = (EventSetDescriptor) e.nextElement(); + if(defaultEventName != null && Aevents[i].getName().equals(defaultEventName)) { + defaultEvent = i; + } + i++; + } + + MethodDescriptor[] Amethods = new MethodDescriptor[methods.size()]; + methods.copyInto(Amethods); + + return new ExplicitBeanInfo(beanDescriptor,additionalBeanInfo,Aproperties,defaultProperty,Aevents,defaultEvent,Amethods,im); + } + + public void setBeanDescriptor(BeanDescriptor b) { + beanDescriptor = b; + } + + public void setAdditionalBeanInfo(BeanInfo[] b) { + additionalBeanInfo = b; + } + + public boolean hasProperty(PropertyDescriptor p) { + return properties.get(p.getName()) != null; + } + public void addProperty(PropertyDescriptor p) { + properties.put(p.getName(),p); + } + public void addIndexedProperty(IndexedPropertyDescriptor p) { + properties.put(p.getName(),p); + } + + public boolean hasEvent(EventSetDescriptor e) { + return events.get(e.getName()) != null; + } + public void addEvent(EventSetDescriptor e) { + events.put(e.getName(),e); + } + + public boolean hasMethod(MethodDescriptor m) { + for(int i=0;i<methods.size();i++) { + Method thisMethod = ((MethodDescriptor)methods.elementAt(i)).getMethod(); + if(m.getMethod().getName().equals(thisMethod.getName()) + && Arrays.equals(m.getMethod().getParameterTypes(), + thisMethod.getParameterTypes())) { + return true; + } + } + return false; + } + public void addMethod(MethodDescriptor m) { + methods.addElement(m); + } + + public void setDefaultPropertyName(String defaultPropertyName) { + this.defaultPropertyName = defaultPropertyName; + } + + public void setDefaultEventName(String defaultEventName) { + this.defaultEventName = defaultEventName; + } + + public void setIcons(java.awt.Image[] im) { + this.im = im; + } +} diff --git a/libjava/classpath/gnu/java/beans/DefaultExceptionListener.java b/libjava/classpath/gnu/java/beans/DefaultExceptionListener.java new file mode 100644 index 000000000..124ad9c94 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/DefaultExceptionListener.java @@ -0,0 +1,66 @@ +/* gnu.java.beans.DefaultExceptionListener + Copyright (C) 2004, 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.beans; + +import java.beans.ExceptionListener; + +/** The DefaultExceptionListener is the default implementation of the + * {@link ExceptionListener} interface. An instance of + * this class is used whenever the user provided no + * <code>ExceptionListener</code> instance on its own. + * + * <p>The implementation just writes the exception's message + * to <code>System.err</code> and is used by the {@link java.beans.Encoder} + * and the {@link java.beans.XMLDecoder}. + * </p> + * + * @author Robert Schuster (robertschuster@fsfe.org) + */ +public class DefaultExceptionListener implements ExceptionListener +{ + public final static DefaultExceptionListener INSTANCE + = new DefaultExceptionListener(); + + public void exceptionThrown(Exception e) + { + System.err.println("exception thrown: " + + e + " - message: " + + e.getMessage()); + } + +} diff --git a/libjava/classpath/gnu/java/beans/DummyAppletContext.java b/libjava/classpath/gnu/java/beans/DummyAppletContext.java new file mode 100644 index 000000000..583d2f5cb --- /dev/null +++ b/libjava/classpath/gnu/java/beans/DummyAppletContext.java @@ -0,0 +1,165 @@ +/* gnu.java.beans.DummyAppletContext + Copyright (C) 2004, 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.beans; + +import java.applet.Applet; +import java.applet.AppletContext; +import java.applet.AudioClip; +import java.awt.Image; +import java.awt.Toolkit; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.Collections; +import java.util.Enumeration; +import java.util.Iterator; + +/** A placeholder <code>AppletContext</code> implementation that does nothing. + * + * <p>This is the default implementation for GNU Classpath and is used for <code>Applet</code> + * beans being created with {@link java.beans.Beans.instantiate}.</p> + * + * <p>It has no functionality in order to allow it to be used without any dependencies + * (e.g. sound, network access, ...).</p> + * + * @author Robert Schuster + */ +class DummyAppletContext implements AppletContext +{ + private static final Enumeration EMPTY_ENUMERATION = Collections.enumeration(Collections.EMPTY_SET); + + DummyAppletContext() + { + } + + /** Implementation is VM neutral and returns a dummy {@link AudioClip} instance + * for every URL that returns a non-<code>null</code> object on + * <code>URL.openConnection()</code>. + * + * @see java.applet.AppletContext#getAudioClip(java.net.URL) + * + * FIXME: When Java Sound API (javax.sound) is included in Classpath or URL is able to handle + * sampled sound this should be adjusted. + */ + public AudioClip getAudioClip(URL url) + { + return Applet.newAudioClip(url); + } + + /** Loads the <code>Image</code> instance by delegating to + * {@link java.awt.Toolkit.createImage(URL) }. + * + * @see java.applet.AppletContext#getImage(java.net.URL) + * @see java.awt.Toolkit#createImage(java.net.URL) + */ + public Image getImage(URL url) + { + return Toolkit.getDefaultToolkit().createImage(url); + } + + /** Returns <code>null</code> for every argument. + * + * @see java.applet.AppletContext#getApplet(java.lang.String) + */ + public Applet getApplet(String name) + { + return null; + } + + /** Returns always an empty <code>Enumeration</code>. + * + * @see java.applet.AppletContext#getApplets() + */ + public Enumeration getApplets() + { + return EMPTY_ENUMERATION; + } + + /** Does nothing. + * + * @see java.applet.AppletContext#showDocument(java.net.URL) + */ + public void showDocument(URL url) + { + } + + /** Does nothing. + * + * @see java.applet.AppletContext#showDocument(java.net.URL, java.lang.String) + */ + public void showDocument(URL url, String target) + { + } + + /** Does nothing. + * + * @see java.applet.AppletContext#showStatus(java.lang.String) + */ + public void showStatus(String message) + { + } + + /** Does nothing. + * + * @see java.applet.AppletContext#setStream(java.lang.String, java.io.InputStream) + */ + public void setStream(String key, InputStream stream) + throws IOException + { + throw new IOException("Dummy implementation imposes zero InputStream associations."); + } + + /** Returns <code>null</code> for every argument. + * + * @see java.applet.AppletContext#getStream(java.lang.String) + */ + public InputStream getStream(String key) + { + return null; + } + + /** Returns always an empty iterator. + * + * @see java.applet.AppletContext#getStreamKeys() + */ + public Iterator getStreamKeys() + { + return Collections.EMPTY_SET.iterator(); + } +} diff --git a/libjava/classpath/gnu/java/beans/DummyAppletStub.java b/libjava/classpath/gnu/java/beans/DummyAppletStub.java new file mode 100644 index 000000000..3bcb43534 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/DummyAppletStub.java @@ -0,0 +1,115 @@ +/* gnu.java.beans.DummyAppletStub + Copyright (C) 2004, 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.beans; + +import java.applet.AppletContext; +import java.applet.AppletStub; +import java.net.URL; + +/** Placeholder implementation of <code>AppletStub</code> providing no functionality. + * <p>This class is used for <code>Applet</code> being created with + * {@link java.beans.Bean.instantiate}.</p> + * + * @author Robert Schuster + */ +public class DummyAppletStub implements AppletStub +{ + private URL documentBase; + private URL codeBase; + private DummyAppletContext context; + + public DummyAppletStub(URL newCodeBase, URL newDocumentBase) + { + codeBase = newCodeBase; + documentBase = newDocumentBase; + + context = new DummyAppletContext(); + } + + /** Returns always <code>true</code>. + * + * @see java.applet.AppletStub#isActive() + */ + public boolean isActive() + { + return true; + } + + /** + * @see java.applet.AppletStub#getDocumentBase() + */ + public URL getDocumentBase() + { + return documentBase; + } + + /** + * @see java.applet.AppletStub#getCodeBase() + */ + public URL getCodeBase() + { + return codeBase; + } + + /** Implementation returns <code>null</code> for every parameter name. + * + * @see java.applet.AppletStub#getParameter(java.lang.String) + */ + public String getParameter(String name) + { + return null; + } + + /** Returns a non-functional context instance. + * + * @see java.applet.AppletStub#getAppletContext() + */ + public AppletContext getAppletContext() + { + return context; + } + + /** Does nothing. + * + * @see java.applet.AppletStub#appletResize(int, int) + */ + public void appletResize(int width, int height) + { + } +} diff --git a/libjava/classpath/gnu/java/beans/ExplicitBeanInfo.java b/libjava/classpath/gnu/java/beans/ExplicitBeanInfo.java new file mode 100644 index 000000000..30f1de4fc --- /dev/null +++ b/libjava/classpath/gnu/java/beans/ExplicitBeanInfo.java @@ -0,0 +1,149 @@ +/* ExplicitBeanInfo.java -- + Copyright (C) 1998, 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.beans; + +import java.awt.Image; +import java.beans.BeanDescriptor; +import java.beans.BeanInfo; +import java.beans.EventSetDescriptor; +import java.beans.MethodDescriptor; +import java.beans.PropertyDescriptor; + +/** + ** ExplicitBeanInfo lets you specify in the constructor + ** all the various parts of the BeanInfo. + ** + ** @author John Keiser + ** @version 1.1.0, 30 Jul 1998 + ** @see java.beans.BeanInfo + **/ + +public class ExplicitBeanInfo implements BeanInfo { + /** The BeanDescriptor returned by getBeanDescriptor. **/ + protected BeanDescriptor beanDescriptor; + + /** The EventSetDescriptor array returned by + ** getEventSetDescriptors(). + **/ + protected EventSetDescriptor[] eventSetDescriptors = new EventSetDescriptor[0]; + + /** The PropertyDescriptor array returned by + ** getPropertyDescriptors(). + **/ + protected PropertyDescriptor[] propertyDescriptors = new PropertyDescriptor[0]; + + /** The MethodDescriptor array returned by + ** getMethodDescriptors(). + **/ + protected MethodDescriptor[] methodDescriptors; + + /** The default property index. **/ + protected int defaultPropertyIndex; + + /** The default event index. **/ + protected int defaultEventIndex; + + /** The BeanInfo array returned by + ** getAdditionalBeanInfo(). + **/ + protected BeanInfo[] additionalBeanInfo; + + /** The set of icons. **/ + protected Image[] icons; + + public ExplicitBeanInfo(BeanDescriptor beanDescriptor, + BeanInfo[] additionalBeanInfo, + PropertyDescriptor[] propertyDescriptors, + int defaultPropertyIndex, + EventSetDescriptor[] eventSetDescriptors, + int defaultEventIndex, + MethodDescriptor[] methodDescriptors, + Image[] icons) { + this.beanDescriptor = beanDescriptor; + this.additionalBeanInfo = additionalBeanInfo; + this.propertyDescriptors = propertyDescriptors; + this.defaultPropertyIndex = defaultPropertyIndex; + this.eventSetDescriptors = eventSetDescriptors; + this.defaultEventIndex = defaultEventIndex; + this.methodDescriptors = methodDescriptors; + this.icons = icons; + } + + /** Get Bean descriptor. **/ + public BeanDescriptor getBeanDescriptor() { + return beanDescriptor; + } + + /** Get Bean events. **/ + public EventSetDescriptor[] getEventSetDescriptors() { + return eventSetDescriptors; + } + + /** Get default event set. **/ + public int getDefaultEventIndex() { + return defaultEventIndex; + } + + /** Get Bean properties. **/ + public PropertyDescriptor[] getPropertyDescriptors() { + return propertyDescriptors; + } + + /** Get "default" property. **/ + public int getDefaultPropertyIndex() { + return defaultPropertyIndex; + } + + /** Get Bean methods. **/ + public MethodDescriptor[] getMethodDescriptors() { + return methodDescriptors; + } + + /** Get additional Bean info. **/ + public BeanInfo[] getAdditionalBeanInfo() { + return additionalBeanInfo; + } + + /** Get Bean icons. + ** @param iconType the type of icon + **/ + public Image getIcon(int iconType) { + return icons != null ? icons[iconType - 1] : null; + } +} diff --git a/libjava/classpath/gnu/java/beans/IntrospectionIncubator.java b/libjava/classpath/gnu/java/beans/IntrospectionIncubator.java new file mode 100644 index 000000000..978429a1e --- /dev/null +++ b/libjava/classpath/gnu/java/beans/IntrospectionIncubator.java @@ -0,0 +1,441 @@ +/* gnu.java.beans.IntrospectionIncubator + Copyright (C) 1998, 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.beans; + +import gnu.java.lang.ArrayHelper; +import gnu.java.lang.ClassHelper; + +import java.beans.BeanInfo; +import java.beans.EventSetDescriptor; +import java.beans.IndexedPropertyDescriptor; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.MethodDescriptor; +import java.beans.PropertyDescriptor; +import java.lang.reflect.Array; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Vector; + +/** + ** IntrospectionIncubator takes in a bunch of Methods, and + ** Introspects only those Methods you give it.<br/> + ** + ** See {@link addMethod(Method)} for details which rules apply to + ** the methods. + ** + ** @author John Keiser + ** @author Robert Schuster + ** @see gnu.java.beans.ExplicitBeanInfo + ** @see java.beans.BeanInfo + **/ + +public class IntrospectionIncubator { + Hashtable propertyMethods = new Hashtable(); + Hashtable listenerMethods = new Hashtable(); + Vector otherMethods = new Vector(); + + Class propertyStopClass; + Class eventStopClass; + Class methodStopClass; + + public IntrospectionIncubator() { + } + + /** Examines the given method and files it in a suitable collection. + * It files the method as a property method if it finds: + * <ul> + * <li>boolean "is" getter</li> + * <li>"get" style getter</li> + * <li>single argument setter</li> + * <li>indiced setter and getter</li> + * </ul> + * It files the method as a listener method if all of these rules apply: + * <ul> + * <li>the method name starts with "add" or "remove"</li> + * <li>there is only a single argument</li> + * <li>the argument type is a subclass of <code>java.util.EventListener</code></li> + * </ul> + * All public methods are filed as such. + * + * @param method The method instance to examine. + */ + public void addMethod(Method method) { + if(Modifier.isPublic(method.getModifiers())) { + String name = ClassHelper.getTruncatedName(method.getName()); + Class retType = method.getReturnType(); + Class[] params = method.getParameterTypes(); + boolean isVoid = retType.equals(java.lang.Void.TYPE); + Class methodClass = method.getDeclaringClass(); + + /* Accepts the method for examination if no stop class is given or the method is declared in a subclass of the stop class. + * The rules for this are described in {@link java.beans.Introspector.getBeanInfo(Class, Class)}. + * This block finds out whether the method is a suitable getter or setter method (or read/write method). + */ + if(isReachable(propertyStopClass, methodClass)) { + /* At this point a method may regarded as a property's read or write method if its name + * starts with "is", "get" or "set". However, if a method is static it cannot be part + * of a property. + */ + if(Modifier.isStatic(method.getModifiers())) { + // files method as other because it is static + otherMethods.addElement(method); + } else if(name.startsWith("is") + && retType.equals(java.lang.Boolean.TYPE) + && params.length == 0) { + // files method as boolean "is" style getter + addToPropertyHash(name,method,IS); + } else if(name.startsWith("get") && !isVoid) { + if(params.length == 0) { + // files as legal non-argument getter + addToPropertyHash(name,method,GET); + } else if(params.length == 1 && params[0].equals(java.lang.Integer.TYPE)) { + // files as legal indiced getter + addToPropertyHash(name,method,GET_I); + } else { + // files as other because the method's signature is not Bean-like + otherMethods.addElement(method); + } + } else if(name.startsWith("set") && isVoid) { + if(params.length == 1) { + // files as legal single-argument setter method + addToPropertyHash(name,method,SET); + } else if(params.length == 2 && params[0].equals(java.lang.Integer.TYPE)) { + // files as legal indiced setter method + addToPropertyHash(name,method,SET_I); + } else { + // files as other because the method's signature is not Bean-like + otherMethods.addElement(method); + } + } + } + + if(isReachable(eventStopClass, methodClass)) { + if(name.startsWith("add") + && isVoid + && params.length == 1 + && java.util.EventListener.class.isAssignableFrom(params[0])) { + addToListenerHash(name,method,ADD); + } else if(name.startsWith("remove") + && isVoid + && params.length == 1 + && java.util.EventListener.class.isAssignableFrom(params[0])) { + addToListenerHash(name,method,REMOVE); + } + } + + if(isReachable(methodStopClass, methodClass)) { + // files as reachable public method + otherMethods.addElement(method); + } + + } + } + + public void addMethods(Method[] m) { + for(int i=0;i<m.length;i++) { + addMethod(m[i]); + } + } + + public void setPropertyStopClass(Class c) { + propertyStopClass = c; + } + + public void setEventStopClass(Class c) { + eventStopClass = c; + } + + public void setMethodStopClass(Class c) { + methodStopClass = c; + } + + + public BeanInfoEmbryo getBeanInfoEmbryo() throws IntrospectionException { + BeanInfoEmbryo b = new BeanInfoEmbryo(); + findXXX(b,IS); + findXXXInt(b,GET_I); + findXXXInt(b,SET_I); + findXXX(b,GET); + findXXX(b,SET); + findAddRemovePairs(b); + for(int i=0;i<otherMethods.size();i++) { + MethodDescriptor newMethod = new MethodDescriptor((Method)otherMethods.elementAt(i)); + if(!b.hasMethod(newMethod)) { + b.addMethod(new MethodDescriptor((Method)otherMethods.elementAt(i))); + } + } + return b; + } + + public BeanInfo getBeanInfo() throws IntrospectionException { + return getBeanInfoEmbryo().getBeanInfo(); + } + + + void findAddRemovePairs(BeanInfoEmbryo b) throws IntrospectionException { + Enumeration listenerEnum = listenerMethods.keys(); + while(listenerEnum.hasMoreElements()) { + DoubleKey k = (DoubleKey)listenerEnum.nextElement(); + Method[] m = (Method[])listenerMethods.get(k); + if(m[ADD] != null && m[REMOVE] != null) { + EventSetDescriptor e = new EventSetDescriptor(Introspector.decapitalize(k.getName()), + k.getType(), k.getType().getMethods(), + m[ADD],m[REMOVE]); + e.setUnicast(ArrayHelper.contains(m[ADD].getExceptionTypes(),java.util.TooManyListenersException.class)); + if(!b.hasEvent(e)) { + b.addEvent(e); + } + } + } + } + + void findXXX(BeanInfoEmbryo b, int funcType) throws IntrospectionException { + Enumeration keys = propertyMethods.keys(); + while(keys.hasMoreElements()) { + DoubleKey k = (DoubleKey)keys.nextElement(); + Method[] m = (Method[])propertyMethods.get(k); + if(m[funcType] != null) { + PropertyDescriptor p = new PropertyDescriptor(Introspector.decapitalize(k.getName()), + m[IS] != null ? m[IS] : m[GET], + m[SET]); + if(m[SET] != null) { + p.setConstrained(ArrayHelper.contains(m[SET].getExceptionTypes(),java.beans.PropertyVetoException.class)); + } + if(!b.hasProperty(p)) { + b.addProperty(p); + } + } + } + } + + void findXXXInt(BeanInfoEmbryo b, int funcType) throws IntrospectionException { + Enumeration keys = propertyMethods.keys(); + while(keys.hasMoreElements()) { + DoubleKey k = (DoubleKey)keys.nextElement(); + Method[] m = (Method[])propertyMethods.get(k); + if(m[funcType] != null) { + boolean constrained; + if(m[SET_I] != null) { + constrained = ArrayHelper.contains(m[SET_I].getExceptionTypes(),java.beans.PropertyVetoException.class); + } else { + constrained = false; + } + + /** Find out if there is an array type get or set **/ + Class arrayType = Array.newInstance(k.getType(),0).getClass(); + DoubleKey findSetArray = new DoubleKey(arrayType,k.getName()); + Method[] m2 = (Method[])propertyMethods.get(findSetArray); + IndexedPropertyDescriptor p; + if(m2 == null) { + p = new IndexedPropertyDescriptor(Introspector.decapitalize(k.getName()), + null,null, + m[GET_I],m[SET_I]); + } else { + if(constrained && m2[SET] != null) { + constrained = ArrayHelper.contains(m2[SET].getExceptionTypes(),java.beans.PropertyVetoException.class); + } + p = new IndexedPropertyDescriptor(Introspector.decapitalize(k.getName()), + m2[GET],m2[SET], + m[GET_I],m[SET_I]); + } + p.setConstrained(constrained); + if(!b.hasProperty(p)) { + b.addProperty(p); + } + } + } + } + + static final int IS=0; + static final int GET_I=1; + static final int SET_I=2; + static final int GET=3; + static final int SET=4; + + static final int ADD=0; + static final int REMOVE=1; + + void addToPropertyHash(String name, Method method, int funcType) { + String newName; + Class type; + + switch(funcType) { + case IS: + type = java.lang.Boolean.TYPE; + newName = name.substring(2); + break; + case GET_I: + type = method.getReturnType(); + newName = name.substring(3); + break; + case SET_I: + type = method.getParameterTypes()[1]; + newName = name.substring(3); + break; + case GET: + type = method.getReturnType(); + newName = name.substring(3); + break; + case SET: + type = method.getParameterTypes()[0]; + newName = name.substring(3); + break; + default: + return; + } + newName = capitalize(newName); + if (newName.length() == 0) + return; + + DoubleKey k = new DoubleKey(type,newName); + Method[] methods = (Method[])propertyMethods.get(k); + if(methods == null) { + methods = new Method[5]; + propertyMethods.put(k,methods); + } + methods[funcType] = method; + } + + void addToListenerHash(String name, Method method, int funcType) { + String newName; + Class type; + + switch(funcType) { + case ADD: + type = method.getParameterTypes()[0]; + newName = name.substring(3,name.length()-8); + break; + case REMOVE: + type = method.getParameterTypes()[0]; + newName = name.substring(6,name.length()-8); + break; + default: + return; + } + newName = capitalize(newName); + if (newName.length() == 0) + return; + + DoubleKey k = new DoubleKey(type,newName); + Method[] methods = (Method[])listenerMethods.get(k); + if(methods == null) { + methods = new Method[2]; + listenerMethods.put(k,methods); + } + methods[funcType] = method; + } + + /* Determines whether <code>stopClass</code> is <code>null</code> + * or <code>declaringClass<code> is a true subclass of <code>stopClass</code>. + * This expression is useful to detect whether a method should be introspected or not. + * The rules for this are described in {@link java.beans.Introspector.getBeanInfo(Class, Class)}. + */ + static boolean isReachable(Class stopClass, Class declaringClass) { + return stopClass == null || (stopClass.isAssignableFrom(declaringClass) && !stopClass.equals(declaringClass)); + } + + /** Transforms a property name into a part of a method name. + * E.g. "value" becomes "Value" which can then concatenated with + * "set", "get" or "is" to form a valid method name. + * + * Implementation notes: + * If "" is the argument, it is returned without changes. + * If <code>null</code> is the argument, <code>null</code> is returned. + * + * @param name Name of a property. + * @return Part of a method name of a property. + */ + static String capitalize(String name) { + try { + if(Character.isUpperCase(name.charAt(0))) { + return name; + } else { + char[] c = name.toCharArray(); + c[0] = Character.toLowerCase(c[0]); + return new String(c); + } + } catch(StringIndexOutOfBoundsException E) { + return name; + } catch(NullPointerException E) { + return null; + } + } +} + +/** This class is a hashmap key that consists of a <code>Class</code> and a + * <code>String</code> element. + * + * It is used for XXX: find out what this is used for + * + * @author John Keiser + * @author Robert Schuster + */ +class DoubleKey { + Class type; + String name; + + DoubleKey(Class type, String name) { + this.type = type; + this.name = name; + } + + Class getType() { + return type; + } + + String getName() { + return name; + } + + public boolean equals(Object o) { + if(o instanceof DoubleKey) { + DoubleKey d = (DoubleKey)o; + return d.type.equals(type) && d.name.equals(name); + } else { + return false; + } + } + + public int hashCode() { + return type.hashCode() ^ name.hashCode(); + } +} diff --git a/libjava/classpath/gnu/java/beans/TODO b/libjava/classpath/gnu/java/beans/TODO new file mode 100644 index 000000000..9112806ba --- /dev/null +++ b/libjava/classpath/gnu/java/beans/TODO @@ -0,0 +1 @@ +- overhaul efficiency diff --git a/libjava/classpath/gnu/java/beans/decoder/AbstractContext.java b/libjava/classpath/gnu/java/beans/decoder/AbstractContext.java new file mode 100644 index 000000000..e6f90e21f --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/AbstractContext.java @@ -0,0 +1,70 @@ +/* gnu.java.beans.decoder.AbstractContext + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.beans.decoder; + + +/** AbstractContext implements some basic functionality of the Context + * interface and is therefore the base of all Context implementations. + * + * @author Robert Schuster + */ +abstract class AbstractContext implements Context +{ + private boolean isStatement; + private String id; + + public String getId() + { + return id; + } + + public void setId(String newId) + { + id = newId; + } + + public boolean isStatement() + { + return isStatement; + } + + public void setStatement(boolean b) + { + isStatement = b; + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/AbstractCreatableObjectContext.java b/libjava/classpath/gnu/java/beans/decoder/AbstractCreatableObjectContext.java new file mode 100644 index 000000000..d108f191c --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/AbstractCreatableObjectContext.java @@ -0,0 +1,113 @@ +/* gnu.java.beans.decoder.AbstractCreatableContext + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ +package gnu.java.beans.decoder; + + +/** AbstractCreatableObjectContext is the base class for all Context implementations + * which create a result object in their lifetime. It provides means for preventing + * to create the object twice. + * + * @author Robert Schuster + * + */ +abstract class AbstractCreatableObjectContext extends AbstractObjectContext +{ + AbstractCreatableObjectContext() + { + } + + /** Adds a parameter object to this Context if the result object has not been + * created yet. Otherwise an AssemblyException is thrown that indicates a wrong + * behavior of the decoder. + */ + public final void addParameterObject(Object o) throws AssemblyException + { + if (object == null) + addParameterObjectImpl(o); + else + throw new AssemblyException(new IllegalStateException("No more parameter objects are allowed when the object as already been created.")); + } + + /** Adds a parameter object to this Context. Implement this without caring + * for illegal states because this has been done already. + * + * @param obj The parameter object to be added. + */ + protected abstract void addParameterObjectImpl(Object obj); + + /** Creates the result object if it does not exist already. + */ + public final void notifyStatement(Context outerContext) + throws AssemblyException + { + if (object != null) + return; + + object = createObject(outerContext); + } + + /** Creates the result object. This method is called only once. Implement this + * without checking for double invocations as this is already being prevented. + * + * @param outerContext The Context that exists around this one. + * @return The result object. + * @throws AssemblerException if the object creation fails somehow. + */ + protected abstract Object createObject(Context outerContext) + throws AssemblyException; + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#endContext(gnu.java.beans.decoder.Context) + */ + public final Object endContext(Context outerContext) + throws AssemblyException + { + notifyStatement(outerContext); + return object; + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#subContextFailed() + */ + public boolean subContextFailed() + { + /* Returns true when the AbstractCreatableObjectContext has not created the result object yet + * (A failed subcontext automatically lets this context fail too.) + */ + return object == null; + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/AbstractElementHandler.java b/libjava/classpath/gnu/java/beans/decoder/AbstractElementHandler.java new file mode 100644 index 000000000..51765658f --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/AbstractElementHandler.java @@ -0,0 +1,316 @@ +/* gnu.java.beans.decoder.AbstractElementHandler + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.beans.decoder; + +import java.beans.ExceptionListener; + +import org.xml.sax.Attributes; + +/** ElementHandler manages a Context instance and interacts with + * its parent and child handlers. + * + * @author Robert Schuster + */ +abstract class AbstractElementHandler implements ElementHandler +{ + /** The Context instance of this handler. The instance is available after the startElement() + * method was called. Otherwise the handler is marked as failed. + */ + private Context context; + + /** The parent handler. */ + private ElementHandler parent; + + /** Stores whether this handler is marked as failed. */ + private boolean hasFailed; + + /** Stores the character data which is contained in the body of the XML tag. */ + private StringBuffer buffer = new StringBuffer(); + + /** Stores whether this ElementHandler can have subelements. The information for this is taken from + * javabeans.dtd which can be found here: + * <a href="http://java.sun.com/products/jfc/tsc/articles/persistence3/">Java Persistence Article</a> + */ + private boolean allowsSubelements; + + /** Creates a new ElementHandler with the given ElementHandler instance + * as parent. + * + * @param parentHandler The parent handler. + */ + protected AbstractElementHandler(ElementHandler parentHandler, + boolean allowsSubs) + { + parent = parentHandler; + allowsSubelements = allowsSubs; + } + + /** Evaluates the attributes and creates a Context instance. + * If the creation of the Context instance fails the ElementHandler + * is marked as failed which may affect the parent handler other. + * + * @param attributes Attributes of the XML tag. + */ + public final void start(Attributes attributes, + ExceptionListener exceptionListener) + { + try + { + // lets the subclass create the appropriate Context instance + context = startElement(attributes, exceptionListener); + } + catch (AssemblyException pe) + { + Throwable t = pe.getCause(); + + if (t instanceof Exception) + exceptionListener.exceptionThrown((Exception) t); + else + throw new InternalError("Unexpected Throwable type in AssemblerException. Please file a bug report."); + + notifyContextFailed(); + + return; + } + } + + /** Analyses the content of the Attributes instance and creates a Context + * object accordingly. + * An AssemblerException is thrown when the Context instance could not + * be created. + * + * @param attributes Attributes of the XML tag. + * @return A Context instance. + * @throws AssemblerException when Context instance could not be created. + */ + protected abstract Context startElement(Attributes attributes, ExceptionListener exceptionListener) + throws AssemblyException; + + /** Post-processes the Context. + */ + public final void end(ExceptionListener exceptionListener) + { + // skips processing if the handler is marked as failed (because the Context + // is then invalid or may not exist at all) + if (!hasFailed) + { + try + { + // note: the order of operations is very important here + // sends the stored character data to the Context + endElement(buffer.toString()); + + // reports to the parent handler if this handler's Context is a + // statement (returning no value BACK to the parent's Context) + if (context.isStatement()) + { + // This may create a valid result in the parent's Context + // or let it fail + parent.notifyStatement(exceptionListener); + + // skips any further processing if the parent handler is now marked + // as failed + if (parent.hasFailed()) + return; + } + + // processes the Context and stores the result + putObject(context.getId(), context.endContext(parent.getContext())); + + // transfers the Context's results to the parent's Context + // if it is an expression (rather than a statement) + if (! context.isStatement()) + parent.getContext().addParameterObject(context.getResult()); + } + catch (AssemblyException pe) + { + // notifies that an exception was thrown in this handler's Context + Throwable t = pe.getCause(); + + if (t instanceof Exception) + exceptionListener.exceptionThrown((Exception) t); + else + throw (InternalError) new InternalError("Severe problem while decoding XML data.") + .initCause(t); + + // marks the handler as failed + notifyContextFailed(); + } + } + } + + /** Notifies the handler's Context that its child Context will not return + * a value back. Some Context variants need this information to know when + * a method or a constructor call can be made. + * + * This method is called by a child handler. + */ + public void notifyStatement(ExceptionListener exceptionListener) + { + try + { + + // propagates to parent handler first to generate objects + // needed by this Context instance + if(context.isStatement()) + { + parent.notifyStatement(exceptionListener); + } + + // Some Context instances do stuff which can fail now. If that + // happens this handler is marked as failed. + context.notifyStatement(parent.getContext()); + } + catch (AssemblyException ae) + { + // notifies that an exception was thrown in this handler's Context + Throwable t = ae.getCause(); + + if (t instanceof Exception) + exceptionListener.exceptionThrown((Exception) t); + else + throw (InternalError) new InternalError("Severe problem while decoding XML data.") + .initCause(t); + + // marks the handler as failed + notifyContextFailed(); + } + } + + /** Marks this and any depending parent handlers as failed. Which means that on their end + * no result is calculated. + * + * When a handler has failed no more handlers are accepted within it. + */ + public final void notifyContextFailed() + { + hasFailed = true; + + // marks the parent handler as failed if its Context + // is affected by the failure of this handler's Context + if (parent.getContext().subContextFailed()) + parent.notifyContextFailed(); + } + + /** Returns whether this handler has failed. + * + * This is used to skip child elements. + * + * @return Whether this handler has failed. + */ + public final boolean hasFailed() + { + return hasFailed; + } + + /** Processes the character data when the element ends. + * + * The default implementation does nothing for convenience. + * + * @param characters + * @throws AssemblerException + */ + protected void endElement(String characters) throws AssemblyException + { + // XXX: throw an exception when unexpected character data is available? + } + + /** Adds characters from the body of the XML tag to the buffer. + * + * @param ch + * @param start + * @param length + * @throws SAXException + */ + public final void characters(char[] ch, int start, int length) + { + // simply appends character data + buffer.append(ch, start, length); + } + + /** Stores an object globally under a unique id. If the id is + * null the object is not stored. + * + * @param objectId + * @param o + */ + public void putObject(String objectId, Object o) + { + if (objectId != null) + parent.putObject(objectId, o); + } + + /** Returns a previously stored object. If the id is null the + * result is null, too. + * + * @param objectId + * @return Returns a previously stored object or null. + */ + public Object getObject(String objectId) throws AssemblyException + { + return objectId == null ? null : parent.getObject(objectId); + } + + /** Returns the Class instance as if called Class.forName() but + * uses a ClassLoader given by the user. + * + * @param className + * @return + * @throws ClassNotFoundException + */ + public Class instantiateClass(String className) + throws ClassNotFoundException + { + return parent.instantiateClass(className); + } + + public final boolean isSubelementAllowed(String subElementName) + { + return allowsSubelements && ! subElementName.equals("java"); + } + + public final Context getContext() + { + return context; + } + + public final ElementHandler getParent() + { + return parent; + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/AbstractObjectContext.java b/libjava/classpath/gnu/java/beans/decoder/AbstractObjectContext.java new file mode 100644 index 000000000..963ef0905 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/AbstractObjectContext.java @@ -0,0 +1,127 @@ +/* gnu.java.beans.decoder.AbstractObjectContext + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ +package gnu.java.beans.decoder; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** AbstractObjectContext is the base for all Context implementations which + * create or provide a result object during their lifetime. + * + * <p>This class provides the implementation for an indexed get and set method. + * But this does not mean that the result object supports these operation.</p> + * + * @author Robert Schuster + * + */ +abstract class AbstractObjectContext extends AbstractContext +{ + protected Object object; + + AbstractObjectContext() + {} + + /** Sets the result object of the Context. + * + * @param obj The result object to be set. + */ + protected final void setObject(Object obj) + { + object = obj; + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#set(int, java.lang.Object) + */ + public final void set(int index, Object o) throws AssemblyException + { + try + { + Method method = + object.getClass().getMethod( + "set", + new Class[] { Integer.TYPE, Object.class }); + + method.invoke(object, new Object[] { new Integer(index), o }); + } + catch (NoSuchMethodException nsme) + { + throw new AssemblyException(nsme); + } + catch (InvocationTargetException ite) + { + throw new AssemblyException(ite.getCause()); + } + catch (IllegalAccessException iae) + { + throw new AssemblyException(iae); + } + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#get(int) + */ + public final Object get(int index) throws AssemblyException + { + try + { + Method method = + object.getClass().getMethod( + "get", + new Class[] { Integer.TYPE }); + + return method.invoke(object, new Object[] { new Integer(index)}); + } + catch (NoSuchMethodException nsme) + { + throw new AssemblyException(nsme); + } + catch (InvocationTargetException ite) + { + throw new AssemblyException(ite.getCause()); + } + catch (IllegalAccessException iae) + { + throw new AssemblyException(iae); + } + } + + public final Object getResult() + { + return object; + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/ArrayContext.java b/libjava/classpath/gnu/java/beans/decoder/ArrayContext.java new file mode 100644 index 000000000..bdec1c647 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/ArrayContext.java @@ -0,0 +1,122 @@ +/* gnu.java.beans.decoder.ArrayContext + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.beans.decoder; + +import java.lang.reflect.Array; + +/** A Context implementation for a fixed size array. The array + * elements have to be set using IndexContext instances. + * + * @author Robert Schuster + */ +class ArrayContext extends AbstractContext +{ + private Object array; + + ArrayContext(String id, Class klass, int length) + { + setId(id); + array = Array.newInstance(klass, length); + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#addObject(java.lang.Object) + */ + public void addParameterObject(Object o) throws AssemblyException + { + throw new AssemblyException(new IllegalStateException("Adding objects without an index to a fixed array is not possible.")); + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#reportStatement() + */ + public void notifyStatement(Context outerContext) + { + // method call intentionally ignored because there is not any useful effect + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#endContext(gnu.java.beans.decoder.Context) + */ + public Object endContext(Context outerContext) throws AssemblyException + { + return array; + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#subContextFailed() + */ + public boolean subContextFailed() + { + // returns false to indicate that assembling the array does not fail only because + // a subelement failed. + return false; + } + + public void set(int index, Object o) throws AssemblyException + { + try + { + Array.set(array, index, o); + } + catch (ArrayIndexOutOfBoundsException aioobe) + { + throw new AssemblyException(aioobe); + } + } + + public Object get(int index) throws AssemblyException + { + try + { + return Array.get(array, index); + } + catch (ArrayIndexOutOfBoundsException aioobe) + { + throw new AssemblyException(aioobe); + } + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#getResult() + */ + public Object getResult() + { + return array; + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/ArrayHandler.java b/libjava/classpath/gnu/java/beans/decoder/ArrayHandler.java new file mode 100644 index 000000000..28930f519 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/ArrayHandler.java @@ -0,0 +1,118 @@ +/* gnu.java.beans.decoder.ArrayHandler + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.beans.decoder; + +import java.beans.ExceptionListener; +import java.util.HashMap; + +import org.xml.sax.Attributes; + +/** ArrayHandler processes the <array> tag. Depending on the existance of the 'length' attribute a Context for + * a fixed-size or growable array is created. + * + * @author Robert Schuster + */ +class ArrayHandler extends AbstractElementHandler +{ + /** Contains a mapping between a textual description of a primitive type (like "byte") and + * its corresponding wrapper class. This allows it to easily construct Array objects for + * primitive data types. + */ + private static HashMap typeMap = new HashMap(); + + static + { + typeMap.put("byte", Byte.TYPE); + typeMap.put("short", Short.TYPE); + typeMap.put("int", Integer.TYPE); + typeMap.put("long", Long.TYPE); + + typeMap.put("float", Float.TYPE); + typeMap.put("double", Double.TYPE); + + typeMap.put("boolean", Boolean.TYPE); + + typeMap.put("char", Character.TYPE); + } + + /** + * @param PersistenceParser + */ + ArrayHandler(ElementHandler parent) + { + super(parent, true); + } + + protected Context startElement(Attributes attributes, ExceptionListener exceptionListener) + throws AssemblyException, AssemblyException + { + String id = attributes.getValue("id"); + String className = attributes.getValue("class"); + + if (className != null) + { + try + { + Class klass; + + if (typeMap.containsKey(className)) + klass = (Class) typeMap.get(className); + else + klass = instantiateClass(className); + + String length = attributes.getValue("length"); + if (length != null) + // creates Array with predefined length + return new ArrayContext(id, klass, Integer.parseInt(length)); + else + // creates Array without length restriction + return new GrowableArrayContext(id, klass); + } + catch (ClassNotFoundException cnfe) + { + throw new AssemblyException(cnfe); + } + catch (NumberFormatException nfe) + { + throw new AssemblyException(nfe); + } + } + + throw new AssemblyException(new IllegalArgumentException("Missing 'class' attribute in <array> tag.")); + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/AssemblyException.java b/libjava/classpath/gnu/java/beans/decoder/AssemblyException.java new file mode 100644 index 000000000..206c5841b --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/AssemblyException.java @@ -0,0 +1,57 @@ +/* gnu.java.beans.decoder.AssemblyException + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.beans.decoder; + + +/** The AssemblyException is used to wrap the cause of problems when assembling objects. + * In all cases only the wrapped exception is given to the PersistenceParser's + * ExceptionListener instance (never the AssemblyException itself). + * + * <p>Note: Often multiple steps are needed to construct a fully usuable object instance. + * Such a construction can be called assembly and thats why this exception was + * named AssemblyException.</p> + * + * @author Robert Schuster + */ +class AssemblyException extends Exception +{ + AssemblyException(Throwable cause) + { + super(cause); + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/BooleanHandler.java b/libjava/classpath/gnu/java/beans/decoder/BooleanHandler.java new file mode 100644 index 000000000..20aed9a3f --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/BooleanHandler.java @@ -0,0 +1,67 @@ +/* gnu.java.beans.decoder.BooleanHandler + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.beans.decoder; + + +/** Creates a Boolean instance from the character data in a <boolean> tag. + * + * @author Robert Schuster + */ +class BooleanHandler extends SimpleHandler +{ + /** + * @param PersistenceParser + */ + BooleanHandler(ElementHandler parent) + { + super(parent); + + // TODO Auto-generated constructor stub + } + + protected Object parse(String number) throws AssemblyException + { + if (number.equals("true")) + return Boolean.TRUE; + + if (number.equals("false")) + return Boolean.FALSE; + + throw new AssemblyException(new IllegalArgumentException("Element contained no valid boolean value.")); + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/ByteHandler.java b/libjava/classpath/gnu/java/beans/decoder/ByteHandler.java new file mode 100644 index 000000000..830bbc747 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/ByteHandler.java @@ -0,0 +1,59 @@ +/* gnu.java.beans.decoder.ByteHandler + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.beans.decoder; + + +/** Creates a Byte instance from the character data in a <byte> tag. + * + * @author Robert Schuster + */ +class ByteHandler extends SimpleHandler +{ + /** + * @param PersistenceParser + */ + ByteHandler(ElementHandler parent) + { + super(parent); + } + + protected Object parse(String number) throws NumberFormatException + { + return Byte.valueOf(number); + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/CharHandler.java b/libjava/classpath/gnu/java/beans/decoder/CharHandler.java new file mode 100644 index 000000000..114df8b79 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/CharHandler.java @@ -0,0 +1,62 @@ +/* gnu.java.beans.decoder.CharHandler + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.beans.decoder; + + +/** Creates a Character instance from the character data in a <char> tag. + * + * @author Robert Schuster + */ +class CharHandler extends SimpleHandler +{ + /** + * @param PersistenceParser + */ + CharHandler(ElementHandler parent) + { + super(parent); + } + + protected Object parse(String number) throws AssemblyException + { + if (number.length() > 1) + throw new AssemblyException(new IllegalArgumentException("Element contained no valid character.")); + + return new Character(number.charAt(0)); + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/ClassHandler.java b/libjava/classpath/gnu/java/beans/decoder/ClassHandler.java new file mode 100644 index 000000000..c67a79a48 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/ClassHandler.java @@ -0,0 +1,66 @@ +/* gnu.java.beans.decoder.ClassHandler + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.beans.decoder; + + +/** Creates a Class instance from the character data in a <class> tag. + * + * @author Robert Schuster + */ +class ClassHandler extends SimpleHandler +{ + /** + * @param PersistenceParser + */ + ClassHandler(ElementHandler parent) + { + super(parent); + } + + protected Object parse(String characters) throws AssemblyException + { + try + { + return instantiateClass(characters); + } + catch (ClassNotFoundException cnfe) + { + throw new AssemblyException(cnfe); + } + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/ConstructorContext.java b/libjava/classpath/gnu/java/beans/decoder/ConstructorContext.java new file mode 100644 index 000000000..32365eef4 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/ConstructorContext.java @@ -0,0 +1,102 @@ +/* gnu.java.beans.decoder.ConstructorContext + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.beans.decoder; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; + +/** A ConstructorContext is a {@link Context} implementation which collects the parameters for a constructor + * call and instantiates the result object using that constructor. After that sub-contexts can invoke + * methods on the result object. + * + * <p>The constructor is invoked when a sub-context is a statement or the Context ends.</p> + * + * @author Robert Schuster + */ +class ConstructorContext extends AbstractCreatableObjectContext +{ + private ArrayList arguments = new ArrayList(); + private Class klass; + + ConstructorContext(String id, Class newClass) + { + setId(id); + // sets superclass field + klass = newClass; + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#addObject(java.lang.Object) + */ + protected void addParameterObjectImpl(Object o) + { + arguments.add(o); + } + + protected Object createObject(Context outerContext) + throws AssemblyException + { + Object[] args = arguments.toArray(); + + try + { + Constructor constructor = MethodFinder.getConstructor(klass, args); + + // instantiates object (klass field gets re-set by superclass) + return constructor.newInstance(args); + } + catch (NoSuchMethodException nsme) + { + throw new AssemblyException(nsme); + } + catch (InvocationTargetException ite) + { + throw new AssemblyException(ite.getCause()); + } + catch (IllegalAccessException iae) + { + throw new AssemblyException(iae); + } + catch (InstantiationException ie) + { + throw new AssemblyException(ie); + } + } + +} diff --git a/libjava/classpath/gnu/java/beans/decoder/Context.java b/libjava/classpath/gnu/java/beans/decoder/Context.java new file mode 100644 index 000000000..4bdbc9ce5 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/Context.java @@ -0,0 +1,137 @@ +/* gnu.java.beans.decoder.Context + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.beans.decoder; + +/** A Context is the environment for an object which is being assembler. If there + * are no errors each handler creates one Context. + * <p>Depending on the result of isStatement() a Context can be statement or an + * expression. An expression returns a value to the Context of its parent handler, + * a statement does not. Whenever a Context is a statement the parent handler's + * Context is informed about that through the {@link notifyStatement}-method.</p> + * + * @author Robert Schuster + */ +interface Context +{ + /** Adds a parameter object to the context. This method is used when + * sub-Contexts return their result. + * + * Some Contexts do not accept more than a certain amount of objects + * and throw an AssemblerException if the amount is exceeded. + * + * @param o The object added to this context. + */ + void addParameterObject(Object o) throws AssemblyException; + + /** Notifies that the next element is a statement. This can mean + * that an argument list is complete to be called. + * + */ + void notifyStatement(Context outerContext) throws AssemblyException; + + /** Notifies that the context ends and the returns the appropriate result + * object. + * + * @param outerContext + * @return + */ + Object endContext(Context outerContext) throws AssemblyException; + + /** Notifies that the assembly of a subcontext failed and returns + * whether this Context is affected in a way that it fails too. + * + * @return Whether the failure of a subcontext lets this context fail, too. + */ + boolean subContextFailed(); + + /** Calls an appropriate indexed set method if it is available or + * throws an AssemblerException if that is not allowed on this Context. + * + * The behaviour of this method is equal to List.set(int, Object). + * + * @param index Index position to be set. + * @param o Object to be set at the given index position. + * @throws AssemblerException Indexed set is not allowed or otherwise failed. + */ + void set(int index, Object o) throws AssemblyException; + + /** Calls an appropriate indexed get method if it is available or + * throws an AssemblerException if that is not allowed on this Context. + * + * The behaviour of this method is equal to List.get(int). + * + * @param index Index position of the object return. + * @throws AssemblerException Indexed get is not allowed or otherwise failed. + */ + Object get(int index) throws AssemblyException; + + /** Returns the result which was calculated by calling endContext() or reportStatement(). + * Its the handler's responsibility to care that any of these two methods was called. + * + * This is used by sub-Contexts to access this Context's result. + * + * @return + */ + Object getResult(); + + /** Gives this Context a unique id. For convenience the id may be null which means + * that no id exists at all. + * + * @param id + */ + void setId(String id); + + /** Returns this Context's unique id or null if does not have such an id. + * + * @return This Context's id or null. + */ + String getId(); + + /** Returns whether this Context is a statement (not returning result back + * to parent handler's Context) or not (= expression). + * + * @return + */ + boolean isStatement(); + + /** Sets whether this Context is a statement or not. + * + * @param b + */ + void setStatement(boolean b); +} diff --git a/libjava/classpath/gnu/java/beans/decoder/DecoderContext.java b/libjava/classpath/gnu/java/beans/decoder/DecoderContext.java new file mode 100644 index 000000000..174a3b71b --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/DecoderContext.java @@ -0,0 +1,124 @@ +/* gnu.java.beans.decoder.DecoderContext + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.beans.decoder; + +import java.beans.XMLDecoder; +import java.util.ArrayList; +import java.util.Iterator; + +/** DecoderContext is a Context implementation which allows access to + * the XMLDecoder instance itself. This is used for the <java> tag. + * + * @author Robert Schuster + */ +public class DecoderContext extends AbstractContext +{ + private XMLDecoder decoder; + + public DecoderContext(XMLDecoder xmlDecoder) + { + decoder = xmlDecoder; + } + + private ArrayList objects = new ArrayList(); + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#addObject(java.lang.Object) + */ + public void addParameterObject(Object o) throws AssemblyException + { + objects.add(o); + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#reportStatement() + */ + public void notifyStatement(Context outerContext) throws AssemblyException + { + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#endContext(gnu.java.beans.decoder.Context) + */ + public Object endContext(Context outerContext) throws AssemblyException + { + return decoder; + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#subContextFailed() + */ + public boolean subContextFailed() + { + return false; + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#set(int, java.lang.Object) + */ + public void set(int index, Object o) throws AssemblyException + { + throw new AssemblyException(new IllegalArgumentException("Set method is not allowed in decoder context.")); + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#get(int) + */ + public Object get(int index) throws AssemblyException + { + throw new AssemblyException(new IllegalArgumentException("Get method is not allowed in decoder context.")); + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#getResult() + */ + public Object getResult() + { + return decoder; + } + + /** Returns an Iterator that retrieves the assembled objects. + * + * @return An Iterator retrieving assembled objects. + */ + public Iterator iterator() + { + return objects.iterator(); + } + +} diff --git a/libjava/classpath/gnu/java/beans/decoder/DoubleHandler.java b/libjava/classpath/gnu/java/beans/decoder/DoubleHandler.java new file mode 100644 index 000000000..1a14fbabf --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/DoubleHandler.java @@ -0,0 +1,59 @@ +/* gnu.java.beans.decoder.DoubleHandler + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.beans.decoder; + + +/** Creates a Double instance from the character data in a <double> tag. + * + * @author Robert Schuster + */ +class DoubleHandler extends SimpleHandler +{ + /** + * @param PersistenceParser + */ + DoubleHandler(ElementHandler parent) + { + super(parent); + } + + protected Object parse(String number) throws NumberFormatException + { + return Double.valueOf(number); + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/DummyContext.java b/libjava/classpath/gnu/java/beans/decoder/DummyContext.java new file mode 100644 index 000000000..03f209c8c --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/DummyContext.java @@ -0,0 +1,116 @@ +/* gnu.java.beans.decoder.DummyContext + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.beans.decoder; + +/** The DummyContext is used as the Context implementation for the DummyHandler. It + * just prevents having a null-reference. + * + * <p>When the implementation is correct none of this class' methods + * (except <code>notifyStatement()</code>) is called.</p> + * + * @author Robert Schuster + */ +public class DummyContext extends AbstractContext +{ + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#addObject(java.lang.Object) + */ + public void addParameterObject(Object o) throws AssemblyException + { + fail(); + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#reportStatement() + */ + public void notifyStatement(Context outerContext) throws AssemblyException + { + // intentionally ignored + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#endContext(gnu.java.beans.decoder.Context) + */ + public Object endContext(Context outerContext) throws AssemblyException + { + fail(); + return null; + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#subContextFailed() + */ + public boolean subContextFailed() + { + fail(); + return false; + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#set(int, java.lang.Object) + */ + public void set(int index, Object o) throws AssemblyException + { + fail(); + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#get(int) + */ + public Object get(int index) throws AssemblyException + { + fail(); + return null; + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#getResult() + */ + public Object getResult() + { + fail(); + return null; + } + + private void fail() + { + throw new InternalError("Invoking the DummyContext is not expected" + + " - Please file a bug report at" + + " http://www/gnu.org/software/classpath/."); + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/DummyHandler.java b/libjava/classpath/gnu/java/beans/decoder/DummyHandler.java new file mode 100644 index 000000000..f9c133e54 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/DummyHandler.java @@ -0,0 +1,156 @@ +/* gnu.java.beans.decoder.DummyHandler + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.beans.decoder; + +import java.beans.ExceptionListener; + +import org.xml.sax.Attributes; + +/** An ElementHandler implementation that is used as an artificial root + * element. This avoids having to check for a null element. + * + * @author Robert Schuster + */ +class DummyHandler implements ElementHandler +{ + /* (non-Javadoc) + * @see gnu.java.beans.decoder.ElementHandler#start(org.xml.sax.Attributes, java.beans.ExceptionListener) + */ + public void start( + Attributes attributes, + ExceptionListener exceptionListener) + { + fail(); + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.ElementHandler#end(java.beans.ExceptionListener) + */ + public void end(ExceptionListener exceptionListener) + { + fail(); + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.ElementHandler#characters(char[], int, int) + */ + public void characters(char[] ch, int start, int length) + { + fail(); + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.ElementHandler#isSubelementAllowed(java.lang.String) + */ + public boolean isSubelementAllowed(String subElementName) + { + return true; + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.ElementHandler#instantiateClass(java.lang.String) + */ + public Class instantiateClass(String className) + throws ClassNotFoundException + { + fail(); + return null; + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.ElementHandler#reportStatement(java.beans.ExceptionListener) + */ + public void notifyStatement(ExceptionListener exceptionListener) + { + // ignore + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.ElementHandler#hasFailed() + */ + public boolean hasFailed() + { + return false; + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.ElementHandler#getContext() + */ + public Context getContext() + { + return new DummyContext(); + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.ElementHandler#contextFailed() + */ + public void notifyContextFailed() + { + fail(); + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.ElementHandler#putObject(java.lang.String, java.lang.Object) + */ + public void putObject(String objectId, Object o) + { + fail(); + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.ElementHandler#getObject(java.lang.String) + */ + public Object getObject(String objectId) + { + fail(); + return null; + } + + public ElementHandler getParent() + { + fail(); + return null; + } + + private void fail() + { + throw new InternalError("Invoking the DummyHandler is not expected" + + " - Please file a bug report at " + + " http://www.gnu.org/software/classpath/."); + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/ElementHandler.java b/libjava/classpath/gnu/java/beans/decoder/ElementHandler.java new file mode 100644 index 000000000..12e945bbf --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/ElementHandler.java @@ -0,0 +1,130 @@ +/* gnu.java.beans.decoder.ElementHandler + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.beans.decoder; + +import java.beans.ExceptionListener; + +import org.xml.sax.Attributes; + +/** ElementHandler manages a Context instance and interacts with + * its parent and child handlers. + * + * @author Robert Schuster + */ +interface ElementHandler +{ + /** Evaluates the attributes and creates a Context instance. + * If the creation of the Context instance fails the ElementHandler + * is marked as failed which may affect the parent handler other. + * + * @param attributes Attributes of the XML tag. + */ + void start(Attributes attributes, ExceptionListener exceptionListener); + + /** Post-processes the Context. + */ + void end(ExceptionListener exceptionListener); + + /** Adds characters from the body of the XML tag to the buffer. + * + * @param ch + * @param start + * @param length + * @throws SAXException + */ + void characters(char[] ch, int start, int length); + + /** Returns whether a subelement of the given name is allowed. The rules + * for evaluating this are derived from the javabeans.dtd which can be found + * here: <a href="http://java.sun.com/products/jfc/tsc/articles/persistence3">Java Persistence Article</a>. + * + * @param subElementName + * @return + */ + boolean isSubelementAllowed(String subElementName); + + /** Provides the same functionality as Class.forName() but allows the decoder + * to use a different class loader. + * + * @param className + * @return + * @throws ClassNotFoundException + */ + Class instantiateClass(String className) throws ClassNotFoundException; + + /** Notifies the handler's Context that its child Context will not return + * a value back. Some Context variants need this information to know when + * a method or a constructor call can be made. + * + * This method is called by a child handler. + */ + void notifyStatement(ExceptionListener exceptionListener); + + /** Returns whether this handler has failed. + * + * This is used to skip child elements. + * + * @return Whether this handler has failed. + */ + boolean hasFailed(); + + /** Returns the Context instance this handler is working on. + * + * @return The handler's Context instance. + */ + Context getContext(); + + /** Notifies the handler that its Context failed and starts a recursive + * invocation of the parent handler if it is affected by that failure. + * + * Although the method is a public API member it is only used internally. + */ + void notifyContextFailed(); + + /** Stores the object under the given id. The object is not stored if the + * id is null. + * + * @param objectId + * @param o + */ + void putObject(String objectId, Object o); + + Object getObject(String objectId) throws AssemblyException; + + ElementHandler getParent(); +} diff --git a/libjava/classpath/gnu/java/beans/decoder/FloatHandler.java b/libjava/classpath/gnu/java/beans/decoder/FloatHandler.java new file mode 100644 index 000000000..443f38f91 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/FloatHandler.java @@ -0,0 +1,59 @@ +/* gnu.java.beans.decoder.FloatHandler + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.beans.decoder; + + +/** Creates a Float instance from the character data in a <float> tag. + * + * @author Robert Schuster + */ +class FloatHandler extends SimpleHandler +{ + /** + * @param PersistenceParser + */ + FloatHandler(ElementHandler parent) + { + super(parent); + } + + protected Object parse(String number) throws NumberFormatException + { + return Float.valueOf(number); + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/GrowableArrayContext.java b/libjava/classpath/gnu/java/beans/decoder/GrowableArrayContext.java new file mode 100644 index 000000000..fb386d1d5 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/GrowableArrayContext.java @@ -0,0 +1,138 @@ +/* gnu.java.beans.decoder.GrowableArrayContext + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ +package gnu.java.beans.decoder; + +import java.lang.reflect.Array; + +/** A Context implementation for a growable array. The array + * elements have to be set using expressions. + * + * @author Robert Schuster + */ +class GrowableArrayContext extends AbstractContext +{ + private static final int INITIAL_SIZE = 16; + + private Class klass; + private Object array; + private int length; + + GrowableArrayContext(String id, Class newClass) + { + setId(id); + klass = newClass; + array = Array.newInstance(klass, INITIAL_SIZE); + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#addObject(java.lang.Object) + */ + public void addParameterObject(Object o) throws AssemblyException + { + if (length == Array.getLength(array)) + { + Object tmp = Array.newInstance(klass, length * 2); + System.arraycopy(array, 0, tmp, 0, length); + array = tmp; + } + + try { + Array.set(array, length++, o); + } catch(IllegalArgumentException iae) { + throw new AssemblyException(iae); + } + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#reportStatement() + */ + public void notifyStatement(Context outerContext) throws AssemblyException + { + throw new AssemblyException( + new IllegalArgumentException("Statements inside a growable array are not allowed.")); + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#endContext(gnu.java.beans.decoder.Context) + */ + public Object endContext(Context outerContext) throws AssemblyException + { + if (length != Array.getLength(array)) + { + Object tmp = Array.newInstance(klass, length); + System.arraycopy(array, 0, tmp, 0, length); + array = tmp; + } + + return array; + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#subContextFailed() + */ + public boolean subContextFailed() + { + // returns false to indicate that assembling the array does not fail only because + // a subelement failed + return false; + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#set(int, java.lang.Object) + */ + public void set(int index, Object o) throws AssemblyException + { + try { + Array.set(array, index, o); + } catch(IllegalArgumentException iae) { + throw new AssemblyException(iae); + } + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#get(int) + */ + public Object get(int index) throws AssemblyException + { + return Array.get(array, index); + } + + public Object getResult() + { + return array; + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/IndexContext.java b/libjava/classpath/gnu/java/beans/decoder/IndexContext.java new file mode 100644 index 000000000..b5af9019f --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/IndexContext.java @@ -0,0 +1,130 @@ +/* gnu.java.beans.decoder.IndexContext + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.beans.decoder; + +/** IndexContext is Context implementation that senses whether it is an indexed get or set + * operation and invokes this operation. + * + * <p>An IndexContent is a get operation when no argument is provided and a set operation if one + * argument is provided.</p> + * + * @author Robert Schuster + */ +class IndexContext extends AbstractContext +{ + private Object result; + private Object argument; + private int index; + private boolean isSetter; + + IndexContext(String id, int newIndex) + { + setId(id); + index = newIndex; + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#addObject(java.lang.Object) + */ + public void addParameterObject(Object o) throws AssemblyException + { + if (! isSetter) + { + argument = o; + isSetter = true; + } + else + throw new AssemblyException(new IllegalStateException("More than one argument for indiced access is not possible.")); + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#reportStatement() + */ + public void notifyStatement(Context outerContext) throws AssemblyException + { + throw new AssemblyException(new IllegalStateException("Statements inside indiced access are not allowed.")); + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#endContext(gnu.java.beans.decoder.Context) + */ + public Object endContext(Context outerContext) throws AssemblyException + { + if (isSetter) + { + // setter + outerContext.set(index, argument); + + return null; + } + else + // getter + return result = outerContext.get(index); + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#subContextFailed() + */ + public boolean subContextFailed() + { + // returns true to indicate that indiced access assembly fails when one of its + // argument could not be assembled + return true; + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#set(int, java.lang.Object) + */ + public void set(int index, Object o) throws AssemblyException + { + throw new AssemblyException(new IllegalStateException("Setter is not allowed inside indiced access.")); + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#get(int) + */ + public Object get(int index) throws AssemblyException + { + throw new AssemblyException(new IllegalStateException("getter is not allowed insided indiced access.")); + } + + public Object getResult() + { + return result; + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/IntHandler.java b/libjava/classpath/gnu/java/beans/decoder/IntHandler.java new file mode 100644 index 000000000..bbd3560d7 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/IntHandler.java @@ -0,0 +1,59 @@ +/* gnu.java.beans.decoder.IntHandler + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.beans.decoder; + + +/** Creates a Integer instance from the character data in a <int> tag. + * + * @author Robert Schuster + */ +class IntHandler extends SimpleHandler +{ + /** + * @param PersistenceParser + */ + IntHandler(ElementHandler parent) + { + super(parent); + } + + protected Object parse(String number) throws NumberFormatException + { + return Integer.valueOf(number); + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/JavaHandler.java b/libjava/classpath/gnu/java/beans/decoder/JavaHandler.java new file mode 100644 index 000000000..c4b4f92c5 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/JavaHandler.java @@ -0,0 +1,93 @@ +/* gnu.java.beans.decoder.JavaHandler + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.beans.decoder; + +import java.beans.ExceptionListener; +import java.util.HashMap; + +import org.xml.sax.Attributes; + +/** Wraps a DecoderContext instance. + * + * @author Robert Schuster + */ +public class JavaHandler extends AbstractElementHandler +{ + private Context context; + private HashMap objectMap = new HashMap(); + private ClassLoader classLoader; + + /** + * @param PersistenceParser + */ + JavaHandler(DummyHandler parent, Context decoderContext, + ClassLoader cl) + { + super(parent, true); + + classLoader = cl; + + context = decoderContext; + + } + + protected Context startElement(Attributes attributes, ExceptionListener exceptionListener) + throws AssemblyException + { + // may expect version and class attribute but it not used in JDK + // so we do either + return context; + } + + public Object getObject(String objectId) + { + return objectMap.get(objectId); + } + + public void putObject(String objectId, Object o) + { + if (objectId != null) + objectMap.put(objectId, o); + } + + public Class instantiateClass(String className) + throws ClassNotFoundException + { + return Class.forName(className, false, classLoader); + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/LongHandler.java b/libjava/classpath/gnu/java/beans/decoder/LongHandler.java new file mode 100644 index 000000000..13e0a8dde --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/LongHandler.java @@ -0,0 +1,59 @@ +/* gnu.java.beans.decoder.LongHandler + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.beans.decoder; + + +/** Creates a Long instance from the character data in a <long> tag. + * + * @author Robert Schuster + */ +class LongHandler extends SimpleHandler +{ + /** + * @param PersistenceParser + */ + LongHandler(ElementHandler parent) + { + super(parent); + } + + protected Object parse(String number) throws NumberFormatException + { + return Long.valueOf(number); + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/MethodContext.java b/libjava/classpath/gnu/java/beans/decoder/MethodContext.java new file mode 100644 index 000000000..84eead7a0 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/MethodContext.java @@ -0,0 +1,107 @@ +/* gnu.java.beans.decoder.MethodContext + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ +package gnu.java.beans.decoder; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; + +/** MethodContext collects arguments for a method call and creates the result object + * using it. The method is called using the result object of the parent Context. + * + * <p>When the result object is available methods can be called on it using sub-Contexts.</p> + * + * @author Robert Schuster + */ +class MethodContext extends AbstractCreatableObjectContext +{ + private ArrayList arguments = new ArrayList(); + private String methodName; + + MethodContext(String id, String newMethodName) + { + setId(id); + setStatement(true); + methodName = newMethodName; + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#addObject(java.lang.Object) + */ + public void addParameterObjectImpl(Object o) + { + arguments.add(o); + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#endContext(gnu.java.beans.decoder.Context) + */ + protected Object createObject(Context outerContext) + throws AssemblyException + { + Object outerObject = outerContext.getResult(); + + if (outerObject == null) + throw new AssemblyException( + new NullPointerException( + "No object to invoke method " + methodName)); + + Object[] args = arguments.toArray(); + + try + { + Method method = + MethodFinder.getMethod( + outerObject.getClass(), + methodName, + args); + return method.invoke(outerObject, args); + } + catch (NoSuchMethodException nsme) + { + throw new AssemblyException(nsme); + } + catch (InvocationTargetException ite) + { + throw new AssemblyException(ite.getCause()); + } + catch (IllegalAccessException iae) + { + throw new AssemblyException(iae); + } + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/MethodFinder.java b/libjava/classpath/gnu/java/beans/decoder/MethodFinder.java new file mode 100644 index 000000000..82783fbde --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/MethodFinder.java @@ -0,0 +1,177 @@ +/* gnu.java.beans.decoder.MethodFinder + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.beans.decoder; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.util.HashMap; + +class MethodFinder +{ + /** Provides a mapping between a wrapper class and its corresponding primitive's type. */ + private static HashMap typeMapping = new HashMap(); + + static { + typeMapping.put(Byte.class, Byte.TYPE); + typeMapping.put(Short.class, Short.TYPE); + typeMapping.put(Integer.class, Integer.TYPE); + typeMapping.put(Long.class, Long.TYPE); + typeMapping.put(Float.class, Float.TYPE); + typeMapping.put(Double.class, Double.TYPE); + + typeMapping.put(Character.class, Character.TYPE); + typeMapping.put(Boolean.class, Boolean.TYPE); + } + + private MethodFinder() + { + } + + /** Searches a Method which can accept the given arguments. + * + * @param klass + * @param name + * @param arguments + * @return + * @throws NoSuchMethodException + */ + static Method getMethod(Class klass, String name, Object[] arguments) + throws NoSuchMethodException + { + // prepares array containing the types of the arguments + Class[] argumentTypes = getArgumentTypes(arguments); + + Method[] methods = klass.getMethods(); + + // iterates over all public methods + for (int i = 0; i < methods.length; i++) + { + if (methods[i].getName().equals(name)) + { + if (matchingArgumentTypes(methods[i].getParameterTypes(), + argumentTypes)) + return methods[i]; + } + } + + throw new NoSuchMethodException( + "Could not find a matching method named " + + name + + "() in class " + + klass); + } + + static Constructor getConstructor(Class klass, Object[] arguments) + throws NoSuchMethodException + { + Class[] argumentTypes = getArgumentTypes(arguments); + Constructor[] constructors = klass.getConstructors(); + + // iterates over all public methods + for (int i = 0; i < constructors.length; i++) + { + if (matchingArgumentTypes(constructors[i].getParameterTypes(), + argumentTypes)) + return constructors[i]; + } + + throw new NoSuchMethodException( + "Could not find a matching constructor in class " + klass); + } + + /** Transforms an array of argument objects into an array of argument types. + * For each argument being null the argument is null, too. An argument type + * being null means: Accepts everything (although this can be ambigous). + * + * @param arguments + * @return + */ + private static Class[] getArgumentTypes(Object[] arguments) + { + if (arguments == null) + return new Class[0]; + + // prepares array containing the types of the arguments + Class[] argumentTypes = new Class[arguments.length]; + for (int i = 0; i < arguments.length; i++) + argumentTypes[i] = + (arguments[i] == null) ? null : arguments[i].getClass(); + return argumentTypes; + } + + /** Tests whether the argument types supplied to the method argument types + * are assignable. In addition to the assignment specifications this method + * handles the primitive's wrapper classes as if they were of their + * primitive type (e.g Boolean.class equals Boolean.TYPE). + * When a supplied argument type is null it is assumed that no argument + * object was supplied for it and the test for this particular parameter will + * pass. + * + * @param methodArgTypes + * @param suppliedArgTypes + * @return + */ + private static boolean matchingArgumentTypes( + Class[] methodArgTypes, + Class[] suppliedArgTypes) + { + if (methodArgTypes.length != suppliedArgTypes.length) + return false; + + for (int i = 0; i < methodArgTypes.length; i++) + { + if (suppliedArgTypes[i] == null) + { + // by definition a non-existant argument type (null) can be converted to everything + continue; + } + else if (typeMapping.containsKey(suppliedArgTypes[i])) + { + Class primitiveType = + (Class) typeMapping.get(suppliedArgTypes[i]); + if (!(methodArgTypes[i].isAssignableFrom(suppliedArgTypes[i]) + || methodArgTypes[i].isAssignableFrom(primitiveType))) + return false; + } + else if (!methodArgTypes[i].isAssignableFrom(suppliedArgTypes[i])) + return false; + } + + return true; + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/NullHandler.java b/libjava/classpath/gnu/java/beans/decoder/NullHandler.java new file mode 100644 index 000000000..01c9727d4 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/NullHandler.java @@ -0,0 +1,62 @@ +/* gnu.java.beans.decoder.NullHandler + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.beans.decoder; + + +/** Just provides the 'null' object. + * + * @author Robert Schuster + */ +class NullHandler extends SimpleHandler +{ + /** + * @param PersistenceParser + */ + NullHandler(ElementHandler parent) + { + super(parent); + } + + protected Object parse(String characters) throws AssemblyException + { + if (! characters.equals("")) + throw new AssemblyException(new IllegalArgumentException("No characters inside <void> tag allowed.")); + + return null; + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/ObjectContext.java b/libjava/classpath/gnu/java/beans/decoder/ObjectContext.java new file mode 100644 index 000000000..883c1d600 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/ObjectContext.java @@ -0,0 +1,100 @@ +/* gnu.java.beans.decoder.ObjectHandler + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.beans.decoder; + +/** ObjectContext is a {@link Context} implementation that wraps a simple Object instance. + * The instance can be provided when the Context is created (due to an 'idref' + * attribute) or later (eg. <int> tag) + * + * <p>The ObjectContext does not accept any parameter object and ignores notifications + * about sub-contexts being statements.</p> + * + * @author Robert Schuster + */ +final class ObjectContext extends AbstractObjectContext +{ + ObjectContext(Object newObject) + { + setObject(newObject); + } + + ObjectContext(String id, Object newObject) + { + setId(id); + setObject(newObject); + } + + ObjectContext() + { + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#addObject(java.lang.Object) + */ + public void addParameterObject(Object o) throws AssemblyException + { + throw new AssemblyException(new IllegalArgumentException("Adding objects to an ObjectContext is not allowed.")); + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#reportStatement() + */ + public void notifyStatement(Context outerContext) throws AssemblyException + { + // can ignore that + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#endContext(gnu.java.beans.decoder.Context) + */ + public Object endContext(Context outerContext) throws AssemblyException + { + // just returns the object which is encapsuled (may be null) + return getResult(); + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#subContextFailed() + */ + public boolean subContextFailed() + { + // this context will not fail when a subcontext fails because the result is + // already available when the context is created. + return false; + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/ObjectHandler.java b/libjava/classpath/gnu/java/beans/decoder/ObjectHandler.java new file mode 100644 index 000000000..ececfbbe2 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/ObjectHandler.java @@ -0,0 +1,169 @@ +/* gnu.java.beans.decoder.ObjectHandler + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.beans.decoder; + +import java.beans.ExceptionListener; + +import org.xml.sax.Attributes; + +/** An ObjectHandler parses the <object> tag and thereby creates various + * Context implementations. + * + * @author Robert Schuster + * + */ +public class ObjectHandler extends AbstractElementHandler +{ + /** + * XXX: Can all results be stored with an object id? + * + * + * @param PersistenceParser + */ + ObjectHandler(ElementHandler parent) + { + super(parent, true); + } + + protected Context startElement(Attributes attributes, ExceptionListener exceptionListener) + throws AssemblyException + { + String className = attributes.getValue("class"); + String methodName = attributes.getValue("method"); + String fieldName = attributes.getValue("field"); + String index = attributes.getValue("index"); + String propertyName = attributes.getValue("property"); + String id = attributes.getValue("id"); + String idRef = attributes.getValue("idref"); + + /* first check if we just want to access an existing object (idref present) + * + * note: <object idref="foo" method="bar"/> is not valid to call method "bar" + * on the object with id "foo". Instead this should return the object "foo" + * itself. The right way to this is: + * <object idref="foo"> + * <object method="bar"/> + * </object> + * + * This means that if idref is present class, method, field, index and + * property are obsolete. + */ + if (idRef != null) + // reactivates an existing object and giving it another name if id exists + return new ObjectContext(id, getObject(idRef)); + + // decides whether we are in a static (className present) or dynamic context + if (className != null) + { + try + { + Class klass = instantiateClass(className); + + // class name exists which means that we are in a static context. + // so we may want to ... + // access a static field if the fieldName exists + if (fieldName != null) + { + try + { + return new ObjectContext(id, + klass.getField(fieldName).get(null)); + } + catch (NoSuchFieldException nsfe) + { + throw new AssemblyException(nsfe); + } + catch (IllegalAccessException iae) + { + throw new AssemblyException(iae); + } + } + + // (falling through is important!) + // run a constructor if methodName is "new" or null + if (methodName == null || methodName.equals("new")) + return new ConstructorContext(id, klass); + + // (falling through is important!) + // run a static method on the given class (if methodName exists, which is implied already) + return new StaticMethodContext(id, klass, methodName); + // XXX: should fail if unexpected attributes are present? + } + catch (ClassNotFoundException cnfe) + { + throw new AssemblyException(cnfe); + } + } + else + { + // className does not exist which means we are in the context of + // some object and want to ... + // access the get(int index) method if index != null + if (index != null) + { + try + { + // Note: http://java.sun.com/products/jfc/tsc/articles/persistence3/ says + // that <void index="4"/> will make up a get()-call. But this is wrong because + // <void/> tags never return values (to the surrounding context) + return new IndexContext(id, Integer.parseInt(index)); + } + catch (NumberFormatException nfe) + { + throw new AssemblyException(nfe); + } + } + + // access a method if methodName exists + if (methodName != null) + return new MethodContext(id, methodName); + + // (falling through is important!) + // access a property if a propertyName exists + if (propertyName != null && propertyName.length() > 0) + // this is reported as an ordinary method access where the propertyName is + // converted into a 'getter'-method name: convert first character of property name + // to upper case and prepend 'get' + // Note: This will be a getter-method because the <object> tag implies that a return + // value is expected. + return new PropertyContext(id, propertyName); + } + + throw new AssemblyException(new IllegalArgumentException("Wrong or missing attributes for <object> tag.")); + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/PersistenceParser.java b/libjava/classpath/gnu/java/beans/decoder/PersistenceParser.java new file mode 100644 index 000000000..c4c8866c3 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/PersistenceParser.java @@ -0,0 +1,485 @@ +/* gnu.java.beans.PersistenceParser + Copyright (C) 2004, 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.beans.decoder; + +import java.beans.ExceptionListener; +import java.beans.XMLDecoder; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; + +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +/** The PersistenceParser parses an XML data stream and delegates actions to ElementHandler + * instances. The parser catches and recovers from all exception which reside from wrong usage + * of attributes and tags. + * + * @author Robert Schuster + */ +public class PersistenceParser extends DefaultHandler implements Context +{ + /** The ExceptionListener instance which is informed of non-critical parsing exceptions. + */ + private ExceptionListener exceptionListener; + + /** When an element was not usable all elements inside it should be skipped. + * This is done by skipping startElement() and endElement() invocations whenever + * this value is above 0. + */ + private int skipElement; + + /** Stores the Creator instances which can instantiate the appropriate handler implementation + * for a given element. + */ + private HashMap handlerCreators = new HashMap(); + + /** Denotes the current ElementHandler. To avoid checking for null-values it is pre-assigned + * with a DummyHandler instance which must not be used but acts as a root element. + */ + private ElementHandler currentHandler; + + /** The real root element that stores all objects created during parsing. + * Package-private to avoid an accessor method. + */ + JavaHandler javaHandler; + + /** Stores the decoded objects. */ + private List objects = new LinkedList(); + + /** The XMLDecoder instance that started this PersistenceParser */ + private XMLDecoder decoder; + + /** Creates a PersistenceParser which reads XML data from the given InputStream, reports + * exceptions to ExceptionListener instance, stores resulting object in the DecoderContext + * and uses the given ClassLoader to resolve classes. + * + * @param inputStream + * @param exceptionListener + * @param decoderContext + * @param cl + */ + public PersistenceParser( + InputStream inputStream, + ExceptionListener exceptionListener, + ClassLoader cl, + XMLDecoder decoder) + { + + this.exceptionListener = exceptionListener; + this.decoder = decoder; + + DummyHandler dummyHandler = new DummyHandler(); + currentHandler = dummyHandler; + javaHandler = new JavaHandler(dummyHandler, this, cl); + + SAXParserFactory factory = SAXParserFactory.newInstance(); + + SAXParser parser; + try + { + parser = factory.newSAXParser(); + } + catch (ParserConfigurationException pce) + { + // should not happen when a parser is available because we did + // not request any requirements on the XML parser + throw (InternalError) new InternalError( + "No SAX Parser available.").initCause( + pce); + } + catch (SAXException saxe) + { + // should not happen when a parser is available because we did + // not request any requirements on the XML parser + throw (InternalError) new InternalError( + "No SAX Parser available.").initCause( + saxe); + } + + // prepares a map of Creator instances which can instantiate a handler which is + // appropriate for the tag that is used as a key for the Creator + handlerCreators.put("java", new JavaHandlerCreator()); + + // calls methods (properties), constructors, access fields + handlerCreators.put("object", new ObjectHandlerCreator()); + handlerCreators.put("void", new VoidHandlerCreator()); + + handlerCreators.put("array", new ArrayHandlerCreator()); + + // these handler directly create an Object (or null) + handlerCreators.put("class", new ClassHandlerCreator()); + handlerCreators.put("null", new NullHandlerCreator()); + + handlerCreators.put("char", new CharHandlerCreator()); + handlerCreators.put("string", new StringHandlerCreator()); + handlerCreators.put("boolean", new BooleanHandlerCreator()); + handlerCreators.put("byte", new ByteHandlerCreator()); + handlerCreators.put("short", new ShortHandlerCreator()); + handlerCreators.put("int", new IntHandlerCreator()); + handlerCreators.put("long", new LongHandlerCreator()); + handlerCreators.put("float", new FloatHandlerCreator()); + handlerCreators.put("double", new DoubleHandlerCreator()); + + // parses the data and sends all exceptions to the ExceptionListener + try + { + parser.parse(inputStream, this); + } + catch (SAXException saxe) + { + exceptionListener.exceptionThrown( + new IllegalArgumentException("XML data not well-formed.")); + } + catch (IOException ioe) + { + exceptionListener.exceptionThrown(ioe); + } + } + + public void startElement( + String uri, + String localName, + String qName, + Attributes attributes) + throws SAXException + { + /* The element is skipped if + * a) the current handler has already failed or a previous error occured + * which makes all children obsolete + */ + if (currentHandler.hasFailed() || skipElement > 0) + { + exceptionListener.exceptionThrown( + new IllegalArgumentException( + "Element unusable due to previous error: " + qName)); + + skipElement++; + + return; + } + + /* b) Subelements are not allowed within the current ElementHandler. + */ + if (!currentHandler.isSubelementAllowed(qName)) + { + exceptionListener.exceptionThrown( + new IllegalArgumentException( + "Element is not allowed here: " + qName)); + + skipElement++; + + return; + } + + /* c) The tag name is not a key in the map of Creator instances. This means that + * either the XML data is of a newer version or simply contains a miss-spelled element. + */ + if (!handlerCreators.containsKey(qName)) + { + exceptionListener.exceptionThrown( + new IllegalArgumentException( + "Element unusable because tag is unknown: " + qName)); + + skipElement++; + + return; + } + + // creates a new handler for the new element + AbstractElementHandler handler = + ((Creator) handlerCreators.get(qName)).createHandler( + currentHandler); + + // makes it the current handler to receive character data + currentHandler = handler; + + // starts the handler + currentHandler.start(attributes, exceptionListener); + } + + public void endElement(String uri, String localName, String qName) + throws SAXException + { + // skips processing the current handler if we are parsing an element + // which was marked invalid (in startElement() ) + if (skipElement > 0) + { + skipElement--; + return; + } + + // invokes the handler's finishing method + currentHandler.end(exceptionListener); + + // removes the current handler and reactivates its parent + currentHandler = currentHandler.getParent(); + } + + /** Transfers character data to the current handler + */ + public void characters(char[] ch, int start, int length) + throws SAXException + { + // prevents sending character data of invalid elements + if (skipElement > 0) + return; + + currentHandler.characters(ch, start, length); + } + + /** Creator interface provided a mechanism to instantiate ElementHandler instances + * for the appropriate tag. + * + * @author Robert Schuster + */ + interface Creator + { + /** Creates an ElementHandler instance using the given ElementHandler as its parent. + * + * @param parent The parent ElementHandler of the result. + * @return A new ElementHandler instance. + */ + AbstractElementHandler createHandler(ElementHandler parent); + } + + class BooleanHandlerCreator implements Creator + { + public AbstractElementHandler createHandler(ElementHandler parent) + { + return new BooleanHandler(parent); + } + } + + class ByteHandlerCreator implements Creator + { + public AbstractElementHandler createHandler(ElementHandler parent) + { + return new ByteHandler(parent); + } + } + + class ShortHandlerCreator implements Creator + { + public AbstractElementHandler createHandler(ElementHandler parent) + { + return new ShortHandler(parent); + } + } + + class IntHandlerCreator implements Creator + { + public AbstractElementHandler createHandler(ElementHandler parent) + { + return new IntHandler(parent); + } + } + + class LongHandlerCreator implements Creator + { + public AbstractElementHandler createHandler(ElementHandler parent) + { + return new LongHandler(parent); + } + } + + class FloatHandlerCreator implements Creator + { + public AbstractElementHandler createHandler(ElementHandler parent) + { + return new FloatHandler(parent); + } + } + + class DoubleHandlerCreator implements Creator + { + public AbstractElementHandler createHandler(ElementHandler parent) + { + return new DoubleHandler(parent); + } + } + + class CharHandlerCreator implements Creator + { + public AbstractElementHandler createHandler(ElementHandler parent) + { + return new CharHandler(parent); + } + } + + class StringHandlerCreator implements Creator + { + public AbstractElementHandler createHandler(ElementHandler parent) + { + return new StringHandler(parent); + } + } + + class JavaHandlerCreator implements Creator + { + public AbstractElementHandler createHandler(ElementHandler parent) + { + return javaHandler; + } + } + + class ObjectHandlerCreator implements Creator + { + public AbstractElementHandler createHandler(ElementHandler parent) + { + return new ObjectHandler(parent); + } + } + + class VoidHandlerCreator implements Creator + { + public AbstractElementHandler createHandler(ElementHandler parent) + { + return new VoidHandler(parent); + } + } + + class ClassHandlerCreator implements Creator + { + public AbstractElementHandler createHandler(ElementHandler parent) + { + return new ClassHandler(parent); + } + } + + class NullHandlerCreator implements Creator + { + public AbstractElementHandler createHandler(ElementHandler parent) + { + return new NullHandler(parent); + } + } + + class ArrayHandlerCreator implements Creator + { + public AbstractElementHandler createHandler(ElementHandler parent) + { + return new ArrayHandler(parent); + } + } + + /** Adds a decoded object to the Context. */ + public void addParameterObject(Object o) throws AssemblyException + { + objects.add(o); + } + + public void notifyStatement(Context outerContext) throws AssemblyException + { + // can be ignored because theis Context does not react to statement and expressions + // differently + } + + public Object endContext(Context outerContext) throws AssemblyException + { + return null; + } + + public boolean subContextFailed() + { + // failing of subcontexts is no problem for the mother of all contexts + return false; + } + + public void set(int index, Object o) throws AssemblyException + { + // not supported + throw new AssemblyException( + new IllegalArgumentException("Set method is not allowed in decoder context.")); + } + + public Object get(int index) throws AssemblyException + { + // not supported + throw new AssemblyException( + new IllegalArgumentException("Get method is not allowed in decoder context.")); + } + + public Object getResult() + { + // returns the XMLDecoder instance which is requested by child contexts this way. + // That is needed to invoke methods on the decoder. + return decoder; + } + + public void setId(String id) + { + exceptionListener.exceptionThrown(new IllegalArgumentException("id attribute is not allowed for <java> tag.")); + } + + public String getId() + { + // appears to have no id + return null; + } + + public boolean isStatement() + { + // this context is a statement by definition because it never returns anything to a parent because + // there is no such parent (DummyContext does not count!) + return true; + } + + public void setStatement(boolean b) + { + // ignores that because this Context is always a statement + } + + /** Returns an Iterator instance which returns the decoded objects. + * + * This method is used by the XMLDecoder directly. + */ + public Iterator iterator() + { + return objects.iterator(); + } + +} diff --git a/libjava/classpath/gnu/java/beans/decoder/PropertyContext.java b/libjava/classpath/gnu/java/beans/decoder/PropertyContext.java new file mode 100644 index 000000000..15751cdbc --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/PropertyContext.java @@ -0,0 +1,137 @@ +/* gnu.java.beans.decoder.PropertyContext + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.beans.decoder; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** PropertyContext is a Context implementation that is very similar to MethodContext + * and IndexContext. The sole purpose of PropertyContext to find out whether it should + * 'set' or 'get' a certain property. This decision is made using the number of + * arguments. + * <p>When the method call has to be made and there is no argument we 'get' the property. + * With one argument it is 'set'.</p> + * + * @author Robert Schuster + */ +class PropertyContext extends AbstractObjectContext +{ + private Object argument; + private String propertyName; + private String prefix = "get"; + private boolean methodCalled; + + PropertyContext(String id, String newPropertyName) + { + setId(id); + propertyName = newPropertyName; + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#addObject(java.lang.Object) + */ + public void addParameterObject(Object o) throws AssemblyException + { + if (methodCalled) + throw new AssemblyException(new IllegalArgumentException("Cannot add parameter object when method was already called.")); + + if (argument != null) + throw new AssemblyException(new IllegalArgumentException("Property attribut allows zero or one argument only.")); + + argument = o; + setStatement(true); + prefix = "set"; + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#endContext(gnu.java.beans.decoder.Context) + */ + public void notifyStatement(Context outerContext) throws AssemblyException + { + if (methodCalled) + return; + methodCalled = true; + + Object outerObject = outerContext.getResult(); + + if (outerObject == null) + throw new AssemblyException(new NullPointerException("No object to access property " + + propertyName)); + + + // converts property name into a method name + String methodName = prefix + propertyName.substring(0, 1).toUpperCase() + + propertyName.substring(1); + + // prepares the argument + Object[] args = (argument != null) ? new Object[] { argument } : null; + + try + { + Method method = MethodFinder.getMethod(outerObject.getClass(), + methodName, args); + + // stores the result whether it is available or not + setObject(method.invoke(outerObject, args)); + } + catch (NoSuchMethodException nsme) + { + throw new AssemblyException(nsme); + } + catch (InvocationTargetException ite) + { + throw new AssemblyException(ite.getCause()); + } + catch (IllegalAccessException iae) + { + throw new AssemblyException(iae); + } + } + + public Object endContext(Context outerContext) throws AssemblyException + { + notifyStatement(outerContext); + + return getResult(); + } + + public boolean subContextFailed() + { + return ! methodCalled; + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/ShortHandler.java b/libjava/classpath/gnu/java/beans/decoder/ShortHandler.java new file mode 100644 index 000000000..c5de50ab9 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/ShortHandler.java @@ -0,0 +1,58 @@ +/* gnu.java.beans.decoder.ShortHandler + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.beans.decoder; + +/** Creates a Short instance from the character data in a <short> tag. + * + * @author Robert Schuster + */ +class ShortHandler extends SimpleHandler +{ + /** + * @param PersistenceParser + */ + ShortHandler(ElementHandler parent) + { + super(parent); + } + + protected Object parse(String number) throws NumberFormatException + { + return Short.valueOf(number); + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/SimpleHandler.java b/libjava/classpath/gnu/java/beans/decoder/SimpleHandler.java new file mode 100644 index 000000000..1c43bb0c7 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/SimpleHandler.java @@ -0,0 +1,111 @@ +/* gnu.java.beans.decoder.SimpleHandler + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.beans.decoder; + +import java.beans.ExceptionListener; + +import org.xml.sax.Attributes; + +/** XML element handler that is specialized on tags that contains a simple string in their + * body which has to be parsed in a specific way. + * <p>All of these tags have in common that they do not accept attributes. A warning is + * send to the parser's ExceptionListener when one or more attributes exist.</p> + * + * @author Robert Schuster + */ +abstract class SimpleHandler extends AbstractElementHandler +{ + private ObjectContext context; + + /** + * @param PersistenceParser + */ + SimpleHandler(ElementHandler parent) + { + super(parent, false); + + // SimpleHandler do not accept any subelements + } + + protected final Context startElement(Attributes attributes, ExceptionListener exceptionListener) + throws AssemblyException + { + + // note: simple elements should not have any attributes. We inform + // the user of this syntactical but uncritical problem by sending + // an IllegalArgumentException for each unneccessary attribute + int size = attributes.getLength(); + for (int i = 0; i < size; i++) { + String attributeName = attributes.getQName(i); + Exception e = + new IllegalArgumentException( + "Unneccessary attribute '" + + attributeName + + "' discarded."); + exceptionListener.exceptionThrown(e); + } + + return context = new ObjectContext(); + } + + public void endElement(String characters) + throws AssemblyException, AssemblyException + { + // reports the number when the character data can be parsed + try + { + context.setObject(parse(characters)); + } + catch (NumberFormatException nfe) + { + throw new AssemblyException(nfe); + } + } + + /** Returns an object that is created from the given characters. If the string is + * converted into a number a NumberFormatException is cathed and reported + * appropriately. + * + * @param characters A string of characters that has to be processed in some way. + * @return An Object instance generated from the given data. + * @throws AssemblerException When the string was invalid. + * @throws NumberFormatException When the string could not be parsed into a number. + */ + protected abstract Object parse(String characters) + throws AssemblyException, NumberFormatException; +} diff --git a/libjava/classpath/gnu/java/beans/decoder/StaticMethodContext.java b/libjava/classpath/gnu/java/beans/decoder/StaticMethodContext.java new file mode 100644 index 000000000..b2cf0e602 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/StaticMethodContext.java @@ -0,0 +1,95 @@ +/* gnu.java.beans.decoder.StaticMethodContext + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.beans.decoder; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; + +/** + * @author Robert Schuster + */ +class StaticMethodContext extends AbstractCreatableObjectContext +{ + private ArrayList arguments = new ArrayList(); + private Class klass; + private String methodName; + + StaticMethodContext(String id, Class newClass, String newMethodName) + { + setId(id); + klass = newClass; + methodName = newMethodName; + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#addObject(java.lang.Object) + */ + public void addParameterObjectImpl(Object o) + { + arguments.add(o); + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#endContext(gnu.java.beans.decoder.Context) + */ + protected Object createObject(Context outerContext) + throws AssemblyException + { + Object[] args = arguments.toArray(); + + try + { + Method method = MethodFinder.getMethod(klass, methodName, args); + return method.invoke(null, args); + } + catch (NoSuchMethodException nsme) + { + throw new AssemblyException(nsme); + } + catch (InvocationTargetException ite) + { + // rethrows the reason for the InvocationTargetsException (ie. the exception in the called code) + throw new AssemblyException(ite.getCause()); + } + catch (IllegalAccessException iae) + { + throw new AssemblyException(iae); + } + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/StringHandler.java b/libjava/classpath/gnu/java/beans/decoder/StringHandler.java new file mode 100644 index 000000000..97fc57efd --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/StringHandler.java @@ -0,0 +1,54 @@ +/* gnu.java.beans.decoder.StringHandler + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.beans.decoder; + +class StringHandler extends SimpleHandler +{ + /** + * @param PersistenceParser + */ + StringHandler(ElementHandler parent) + { + super(parent); + } + + protected Object parse(String characters) + { + return characters; + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/VoidHandler.java b/libjava/classpath/gnu/java/beans/decoder/VoidHandler.java new file mode 100644 index 000000000..56f315639 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/VoidHandler.java @@ -0,0 +1,140 @@ +/* gnu.java.beans.decoder.VoidHandler + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.beans.decoder; + +import java.beans.ExceptionListener; + +import org.xml.sax.Attributes; + +public class VoidHandler extends AbstractElementHandler +{ + /** + * @param PersistenceParser + */ + VoidHandler(ElementHandler parent) + { + super(parent, true); + } + + protected Context startElement( + Attributes attributes, + ExceptionListener exceptionListener) + throws AssemblyException + { + Context ctx = startElementImpl(attributes); + ctx.setStatement(true); + + return ctx; + } + + private Context startElementImpl(Attributes attributes) + throws AssemblyException + { + String id = attributes.getValue("id"); + String className = attributes.getValue("class"); + String methodName = attributes.getValue("method"); + String propertyName = attributes.getValue("property"); + String index = attributes.getValue("index"); + + if (className != null) + { + try + { + Class klass = instantiateClass(className); + + // class name exists which means that we are in a static context. + // so we may want to ... + // run a constructor if methodName is "new" or null + if (methodName == null || methodName.equals("new")) + // if the id is null the result cannot be by the decoder accessed but the + // constructor may have side effects (e.g. registering itself in a global registry) + return new ConstructorContext(id, klass); + + // (falling through is important!) + // run a static method on the given class (if methodName exists, which is implied already) + return new StaticMethodContext(id, klass, methodName); + } + catch (ClassNotFoundException cnfe) + { + throw new AssemblyException(cnfe); + } + } + else + { + // className does not exist which means we are in the context of + // some object and want to ... + // access an element by index + if (index != null) + { + // note: whether this resolves into get(i) or set(i, o) depends on the + // number of arguments and is decided by the ObjectAssembler + try + { + return new IndexContext(id, Integer.parseInt(index)); + } + catch (NumberFormatException nfe) + { + throw new AssemblyException(nfe); + } + } + + // access a method if methodName exists + if (methodName != null) + return new MethodContext(id, methodName); + + // (falling through is important!) + // access a property if a propertyName exists + if (propertyName != null && propertyName.length() > 0) + // this is reported as an ordinary method invocation where the propertyName is + // converted into a 'setter'-method name: convert first character of property name + // to upper case and prepend 'set' + // Note: This will be a setter-method because the <void> tag implies that no return + // value is expected (but a side effect) + return new PropertyContext(id, propertyName); + } + + // if code reaches this point the tag has wrong attributes. The following test + // does not make it better but can provide are more specific error message for + // a common mistake: <void> tags are not allowed to have an idref attribute + throw new AssemblyException( + new IllegalArgumentException( + (attributes.getValue("idref") == null) + ? "Missing attributes for <void> tag" + : "<void> does not support 'idref' attribute.")); + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/package.html b/libjava/classpath/gnu/java/beans/decoder/package.html new file mode 100644 index 000000000..8fe65eeed --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/package.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - describes classes in gnu.java.beans.decoder package. + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. --> + +<html> +<head><title>GNU Classpath - gnu.java.beans.decoder</title></head> + +<body> +<p></p> + +</body> +</html> diff --git a/libjava/classpath/gnu/java/beans/editors/ColorEditor.java b/libjava/classpath/gnu/java/beans/editors/ColorEditor.java new file mode 100644 index 000000000..cb69344cb --- /dev/null +++ b/libjava/classpath/gnu/java/beans/editors/ColorEditor.java @@ -0,0 +1,100 @@ +/* gnu.java.beans.editors.ColorEditor + Copyright (C) 1998 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.beans.editors; + +import java.awt.Color; +import java.beans.PropertyEditorSupport; + +/** + ** NativeByteEditor is a property editor for the + ** byte type. + ** + ** @author John Keiser + ** @version 1.1.0, 29 Jul 1998 + **/ + +public class ColorEditor extends PropertyEditorSupport { + Color[] stdColors = {Color.black,Color.blue,Color.cyan, + Color.darkGray,Color.gray,Color.green, + Color.lightGray,Color.magenta,Color.orange, + Color.pink,Color.red,Color.white, + Color.yellow}; + String[] stdColorNames = {"black","blue","cyan", + "dark gray","gray","green", + "light gray","magenta","orange", + "pink","red","white", + "yellow"}; + + /** setAsText for Color checks for standard color names + ** and then checks for a #RRGGBB value or just RRGGBB, + ** both in hex. + **/ + public void setAsText(String val) throws IllegalArgumentException { + if(val.length() == 0) { + throw new IllegalArgumentException("Tried to set empty value!"); + } + for(int i=0;i<stdColorNames.length;i++) { + if(stdColorNames[i].equalsIgnoreCase(val)) { + setValue(stdColors[i]); + return; + } + } + if(val.charAt(0) == '#') { + setValue(new Color(Integer.parseInt(val.substring(1),16))); + } else { + setValue(new Color(Integer.parseInt(val,16))); + } + } + + /** getAsText for Color turns the color into either one of the standard + ** colors or into an RGB hex value with # prepended. **/ + public String getAsText() { + for(int i=0;i<stdColors.length;i++) { + if(stdColors[i].equals(getValue())) { + return stdColorNames[i]; + } + } + return "#" + Integer.toHexString(((Color)getValue()).getRGB() & 0x00FFFFFF); + } + + /** getTags for Color returns a list of standard colors. **/ + public String[] getTags() { + return stdColorNames; + } +} diff --git a/libjava/classpath/gnu/java/beans/editors/FontEditor.java b/libjava/classpath/gnu/java/beans/editors/FontEditor.java new file mode 100644 index 000000000..dfccb4ede --- /dev/null +++ b/libjava/classpath/gnu/java/beans/editors/FontEditor.java @@ -0,0 +1,77 @@ +/* gnu.java.beans.editors.FontEditor + Copyright (C) 1998 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.beans.editors; + +import java.awt.Font; +import java.beans.PropertyEditorSupport; + +/** + ** FontEditor is a property editor for java.awt.Font. + ** + ** <STRONG>To Do:</STRONG> Add custom font chooser + ** component. + ** + ** @author John Keiser + ** @version 1.1.0, 29 Jul 1998 + **/ + +public class FontEditor extends PropertyEditorSupport { + /** setAsText for Font calls Font.decode(). **/ + public void setAsText(String val) throws IllegalArgumentException { + setValue(Font.decode(val)); + } + + /** getAsText for Font returns a value in the format + ** expected by Font.decode(). + **/ + public String getAsText() { + Font f = (Font)getValue(); + if(f.isBold()) { + if(f.isItalic()) { + return f.getName()+"-bolditalic-"+f.getSize(); + } else { + return f.getName()+"-bold-"+f.getSize(); + } + } else if(f.isItalic()) { + return f.getName()+"-italic-"+f.getSize(); + } else { + return f.getName()+"-"+f.getSize(); + } + } +} diff --git a/libjava/classpath/gnu/java/beans/editors/NativeBooleanEditor.java b/libjava/classpath/gnu/java/beans/editors/NativeBooleanEditor.java new file mode 100644 index 000000000..1df94895a --- /dev/null +++ b/libjava/classpath/gnu/java/beans/editors/NativeBooleanEditor.java @@ -0,0 +1,76 @@ +/* gnu.java.beans.editors.NativeBooleanEditor + Copyright (C) 1998, 2002 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.beans.editors; + +import java.beans.PropertyEditorSupport; + +/** + ** NativeBooleanEditor is a property editor for the + ** boolean type.<P> + ** + ** <STRONG>To Do:</STRONG> add support for a checkbox + ** as the custom editor. + ** + ** @author John Keiser + ** @version 1.1.0, 29 Jul 1998 + **/ + +public class NativeBooleanEditor extends PropertyEditorSupport { + String[] tags = {"true","false"}; + + /** + * setAsText for boolean checks for true or false or t or f. + * "" also means false. + **/ + public void setAsText(String val) throws IllegalArgumentException { + if(val.equalsIgnoreCase("true") || val.equalsIgnoreCase("t")) { + setValue(Boolean.TRUE); + } else if(val.equalsIgnoreCase("false") || val.equalsIgnoreCase("f") || val.equals("")) { + setValue(Boolean.FALSE); + } else { + throw new IllegalArgumentException("Value must be true, false, t, f or empty."); + } + } + + + /** getAsText for boolean calls Boolean.toString(). **/ + public String getAsText() { + return getValue().toString(); + } +} diff --git a/libjava/classpath/gnu/java/beans/editors/NativeByteEditor.java b/libjava/classpath/gnu/java/beans/editors/NativeByteEditor.java new file mode 100644 index 000000000..d427a9e3f --- /dev/null +++ b/libjava/classpath/gnu/java/beans/editors/NativeByteEditor.java @@ -0,0 +1,61 @@ +/* gnu.java.beans.editors.NativeByteEditor + Copyright (C) 1998 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.beans.editors; + +import java.beans.PropertyEditorSupport; + +/** + ** NativeByteEditor is a property editor for the + ** byte type. + ** + ** @author John Keiser + ** @version 1.1.0, 29 Jul 1998 + **/ + +public class NativeByteEditor extends PropertyEditorSupport { + /** setAsText for byte calls Byte.valueOf(). **/ + public void setAsText(String val) throws IllegalArgumentException { + setValue(Byte.valueOf(val)); + } + + /** getAsText for byte calls Byte.toString(). **/ + public String getAsText() { + return getValue().toString(); + } +} diff --git a/libjava/classpath/gnu/java/beans/editors/NativeDoubleEditor.java b/libjava/classpath/gnu/java/beans/editors/NativeDoubleEditor.java new file mode 100644 index 000000000..aa229fad7 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/editors/NativeDoubleEditor.java @@ -0,0 +1,61 @@ +/* gnu.java.beans.editors.NativeDoubleEditor + Copyright (C) 1998 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.beans.editors; + +import java.beans.PropertyEditorSupport; + +/** + ** NativeDoubleEditor is a property editor for the + ** double type. + ** + ** @author John Keiser + ** @version 1.1.0, 29 Jul 1998 + **/ + +public class NativeDoubleEditor extends PropertyEditorSupport { + /** setAsText for double calls Double.valueOf(). **/ + public void setAsText(String val) throws IllegalArgumentException { + setValue(Double.valueOf(val)); + } + + /** getAsText for double calls Double.toString(). **/ + public String getAsText() { + return getValue().toString(); + } +} diff --git a/libjava/classpath/gnu/java/beans/editors/NativeFloatEditor.java b/libjava/classpath/gnu/java/beans/editors/NativeFloatEditor.java new file mode 100644 index 000000000..09f9d6b9c --- /dev/null +++ b/libjava/classpath/gnu/java/beans/editors/NativeFloatEditor.java @@ -0,0 +1,61 @@ +/* gnu.java.beans.editors.NativeFloatEditor + Copyright (C) 1998 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.beans.editors; + +import java.beans.PropertyEditorSupport; + +/** + ** NativeFloatEditor is a property editor for the + ** float type. + ** + ** @author John Keiser + ** @version 1.1.0, 29 Jul 1998 + **/ + +public class NativeFloatEditor extends PropertyEditorSupport { + /** setAsText for float calls Float.valueOf(). **/ + public void setAsText(String val) throws IllegalArgumentException { + setValue(Float.valueOf(val)); + } + + /** getAsText for float calls Float.toString(). **/ + public String getAsText() { + return getValue().toString(); + } +} diff --git a/libjava/classpath/gnu/java/beans/editors/NativeIntEditor.java b/libjava/classpath/gnu/java/beans/editors/NativeIntEditor.java new file mode 100644 index 000000000..28b6a67d9 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/editors/NativeIntEditor.java @@ -0,0 +1,61 @@ +/* gnu.java.beans.editors.NativeIntEditor + Copyright (C) 1998 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.beans.editors; + +import java.beans.PropertyEditorSupport; + +/** + ** NativeIntEditor is a property editor for the + ** int type. + ** + ** @author John Keiser + ** @version 1.1.0, 29 Jul 1998 + **/ + +public class NativeIntEditor extends PropertyEditorSupport { + /** setAsText for int calls Integer.valueOf(). **/ + public void setAsText(String val) throws IllegalArgumentException { + setValue(Integer.valueOf(val)); + } + + /** getAsText for int calls Integer.toString(). **/ + public String getAsText() { + return getValue().toString(); + } +} diff --git a/libjava/classpath/gnu/java/beans/editors/NativeLongEditor.java b/libjava/classpath/gnu/java/beans/editors/NativeLongEditor.java new file mode 100644 index 000000000..77223fbbc --- /dev/null +++ b/libjava/classpath/gnu/java/beans/editors/NativeLongEditor.java @@ -0,0 +1,61 @@ +/* gnu.java.beans.editors.NativeLongEditor + Copyright (C) 1998 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.beans.editors; + +import java.beans.PropertyEditorSupport; + +/** + ** NativeLongEditor is a property editor for the + ** long type. + ** + ** @author John Keiser + ** @version 1.1.0, 29 Jul 1998 + **/ + +public class NativeLongEditor extends PropertyEditorSupport { + /** setAsText for long calls Long.valueOf(). **/ + public void setAsText(String val) throws IllegalArgumentException { + setValue(Long.valueOf(val)); + } + + /** getAsText for long calls Long.toString(). **/ + public String getAsText() { + return getValue().toString(); + } +} diff --git a/libjava/classpath/gnu/java/beans/editors/NativeShortEditor.java b/libjava/classpath/gnu/java/beans/editors/NativeShortEditor.java new file mode 100644 index 000000000..1d8845bde --- /dev/null +++ b/libjava/classpath/gnu/java/beans/editors/NativeShortEditor.java @@ -0,0 +1,61 @@ +/* gnu.java.beans.editors.NativeShortEditor + Copyright (C) 1998 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.beans.editors; + +import java.beans.PropertyEditorSupport; + +/** + ** NativeShortEditor is a property editor for the + ** short type. + ** + ** @author John Keiser + ** @version 1.1.0, 29 Jul 1998 + **/ + +public class NativeShortEditor extends PropertyEditorSupport { + /** setAsText for short calls Short.valueOf(). **/ + public void setAsText(String val) throws IllegalArgumentException { + setValue(Short.valueOf(val)); + } + + /** getAsText for short calls Short.toString(). **/ + public String getAsText() { + return getValue().toString(); + } +} diff --git a/libjava/classpath/gnu/java/beans/editors/StringEditor.java b/libjava/classpath/gnu/java/beans/editors/StringEditor.java new file mode 100644 index 000000000..47fdce659 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/editors/StringEditor.java @@ -0,0 +1,61 @@ +/* gnu.java.beans.editors.StringEditor + Copyright (C) 1998 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.beans.editors; + +import java.beans.PropertyEditorSupport; + +/** + ** NativeByteEditor is a property editor for the + ** byte type. + ** + ** @author John Keiser + ** @version 1.1.0, 29 Jul 1998 + **/ + +public class StringEditor extends PropertyEditorSupport { + /** setAsText just sets the value. **/ + public void setAsText(String val) throws IllegalArgumentException { + setValue(val); + } + + /** getAsText just returns the value. **/ + public String getAsText() { + return (String)getValue(); + } +} diff --git a/libjava/classpath/gnu/java/beans/editors/TODO b/libjava/classpath/gnu/java/beans/editors/TODO new file mode 100644 index 000000000..6877f4caf --- /dev/null +++ b/libjava/classpath/gnu/java/beans/editors/TODO @@ -0,0 +1,4 @@ +- write tests for all editors +- add some sort of ColorChooser as a custom editor for ColorEditor +- add a FileNameEditor +- add a FontChooser as a custom editor for FontEditor diff --git a/libjava/classpath/gnu/java/beans/editors/package.html b/libjava/classpath/gnu/java/beans/editors/package.html new file mode 100644 index 000000000..465f68d17 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/editors/package.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - describes classes in gnu.java.beans.editors package. + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. --> + +<html> +<head><title>GNU Classpath - gnu.java.beans.editors</title></head> + +<body> +<p></p> + +</body> +</html> diff --git a/libjava/classpath/gnu/java/beans/encoder/ArrayPersistenceDelegate.java b/libjava/classpath/gnu/java/beans/encoder/ArrayPersistenceDelegate.java new file mode 100644 index 000000000..52fc45796 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/encoder/ArrayPersistenceDelegate.java @@ -0,0 +1,153 @@ +/* ArrayPersistenceDelegate.java - A PersistenceDelegate that handles arrays. + Copyright (C) 2005 Free Software Foundation, Inc. + + This file is part of GNU Classpath. + + GNU Classpath is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU Classpath is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Classpath; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. */ + + +package gnu.java.beans.encoder; + +import java.beans.Encoder; +import java.beans.Expression; +import java.beans.PersistenceDelegate; +import java.beans.Statement; + +import java.lang.reflect.Array; +import java.util.HashMap; + +public class ArrayPersistenceDelegate extends PersistenceDelegate +{ + private static final HashMap NULL_VALUES = new HashMap(); + + static + { + NULL_VALUES.put(Boolean.TYPE, Boolean.FALSE); + NULL_VALUES.put(Byte.TYPE, Byte.valueOf((byte) 0)); + NULL_VALUES.put(Short.TYPE, Short.valueOf((short) 0)); + NULL_VALUES.put(Integer.TYPE, Integer.valueOf(0)); + NULL_VALUES.put(Long.TYPE, Long.valueOf(0)); + NULL_VALUES.put(Float.TYPE, Float.valueOf(0.0f)); + NULL_VALUES.put(Double.TYPE, Double.valueOf(0.0)); + } + + protected Expression instantiate(Object oldInstance, Encoder out) + { + Class type = oldInstance.getClass().getComponentType(); + + // oldInstance is expected to be an array, then + // getClass().getComponentType() should lead + // to its component type. + assert (type != null); + + // Not handling primitive types in a special way here + // causes that Class.forName("int") is built as an Expression + // later which would cause an exception if executed. A special + // handling to avoid the execution for primitive types can be + // java.beans.Encoder.writeExpression() . + return new Expression( + oldInstance, + Array.class, + "newInstance", + new Object[] { + type, + new Integer(Array.getLength(oldInstance)) }); + } + + protected void initialize(Class type, Object oldInstance, Object newInstance, + Encoder out) + { + int length = Array.getLength(oldInstance); + + // Compares the array value against a prototypical + // null value of the array's component type in order to skip + // writing the default values of an array. + + // Note: I have no idea why the persistence delegate for arrays writes + // an Expression that reads the value and then writes a Statement that sets + // the value. However it turned out that object arrays work better with the + // get-Expression and primitive array work fine with the set-Statement. + + type = type.getComponentType(); + if (type.isPrimitive()) + { + Object nullValue = NULL_VALUES.get(type); + + for (int i = 0; i < length; i++) + { + Object oldValue = Array.get(oldInstance, i); + + if (!oldValue.equals(nullValue)) + { + out.writeExpression(new Expression(Array.class, "get", + new Object[] { oldInstance, + Integer.valueOf(i), + })); + + out.writeStatement(new Statement(Array.class, "set", + new Object[] { + oldInstance, + Integer.valueOf(i), + oldValue + })); + } + } + + } + else + { + + for (int i = 0; i < length; i++) + { + Object oldValue = Array.get(oldInstance, i); + + if (oldValue != null) + { + out.writeExpression(new Expression(Array.class, "get", + new Object[] { oldInstance, + Integer.valueOf(i), + })); + + out.writeStatement(new Statement(Array.class, "set", + new Object[] { + oldInstance, + Integer.valueOf(i), + oldValue + })); + } + } + } + + } + +} diff --git a/libjava/classpath/gnu/java/beans/encoder/ClassPersistenceDelegate.java b/libjava/classpath/gnu/java/beans/encoder/ClassPersistenceDelegate.java new file mode 100644 index 000000000..1430a6dbe --- /dev/null +++ b/libjava/classpath/gnu/java/beans/encoder/ClassPersistenceDelegate.java @@ -0,0 +1,80 @@ +/* ClassPersistenceDelegate.java - A PersistenceDelegate for the Class type. + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.beans.encoder; + +import java.beans.Encoder; +import java.beans.Expression; +import java.beans.PersistenceDelegate; + +/** <p>The <code>ClassPersistenceDelegate</code> creates + * <code>Expression</code> instances which denote class resolutions.</p> + * + * <p>The class resolution is always the last step when serializing a tree + * of objects. Due to the recursive nature of the algorithm we need a way + * to end the recursion. This is achieved by the implementation of this + * {@link instantiate} method. Arbitrary classes are described with a call + * to <code>Class.forName</code>. However for the <code>Class</code> class + * we call <code>getClass()</code> on a <code>String.class</code> instance. + * This in turn lead to the resolution of the String class which is always + * encoded as <code>"".getClass()</code>. Finally the <code>Encoder</code> + * treats strings in a special way so that the recursion ends here. + * + * @author Robert Schuster (robertschuster@fsfe.org) + */ +public class ClassPersistenceDelegate extends PersistenceDelegate +{ + + protected Expression instantiate(Object oldInstance, Encoder out) + { + Class oldClass = (Class) oldInstance; + + // Due to the special handling of String instances in the Encoder + // this Expression does not lead to further class resolutions. + if (oldClass == String.class) + return new Expression(oldClass, "", "getClass", null); + + // This Expression will lead to the class resolution of String.class. + if (oldClass == Class.class) + return new Expression(oldClass, String.class, "getClass", null); + + // This Expression will lead to the class resolution of Class.class. + return new Expression(oldClass, Class.class, "forName", + new Object[] { oldClass.getName() }); + } + +} diff --git a/libjava/classpath/gnu/java/beans/encoder/CollectionPersistenceDelegate.java b/libjava/classpath/gnu/java/beans/encoder/CollectionPersistenceDelegate.java new file mode 100644 index 000000000..bdf6fda62 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/encoder/CollectionPersistenceDelegate.java @@ -0,0 +1,84 @@ +/* CollectionPersistenceDelegate.java - A PersistenceDelegate for Collection subclasses. + Copyright (C) 2005 Free Software Foundation, Inc. + + This file is part of GNU Classpath. + + GNU Classpath is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU Classpath is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Classpath; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. */ + + +package gnu.java.beans.encoder; + +import java.util.Collection; +import java.beans.Encoder; +import java.beans.Expression; +import java.beans.PersistenceDelegate; +import java.beans.Statement; + +import java.util.Iterator; + +/** <p>A <code>PersistenceDelegate</code> implementation that calls + * the no-argument constructor to create the Collection instance and + * uses an iterator to add all the objects it reaches through it.</p> + * + * <p>It is used for <code>Set</code> and <code>List</code> + * implementations.</p> + * + * @author Robert Schuster (robertschuster@fsfe.org) + */ +public class CollectionPersistenceDelegate extends PersistenceDelegate +{ + + protected Expression instantiate(Object oldInstance, Encoder out) + { + return new Expression( + oldInstance, + oldInstance.getClass(), + "new", + null); + } + + protected void initialize(Class type, Object oldInstance, Object newInstance, + Encoder out) + { + Iterator ite = ((Collection) oldInstance).iterator(); + + while (ite.hasNext()) + { + out.writeStatement(new Statement(oldInstance, "add", + new Object[] { ite.next() })); + + } + + } + +} diff --git a/libjava/classpath/gnu/java/beans/encoder/Context.java b/libjava/classpath/gnu/java/beans/encoder/Context.java new file mode 100644 index 000000000..8acc4907b --- /dev/null +++ b/libjava/classpath/gnu/java/beans/encoder/Context.java @@ -0,0 +1,88 @@ +/* Context.java -- Provides calling context information to ScannerStates. + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.beans.encoder; + +/** A <code>Contect</code> object describes the current state + * and the call number while processing the original object + * tree in the {@link ScanEngine}. + * + * <p>The class allows to distinguish the different calling states + * and is neccessary for the child element skipping feature of + * the {@link GenericScannerState}.</p> + * + * @author Robert Schuster (robertschuster@fsfe.org) + * + */ +public class Context +{ + private String state; + + private int call; + + Context(String newState, int newCall) + { + state = newState; + call = newCall; + } + + public int hashCode() + { + int hc = 7; + hc = 31 * hc + state.hashCode(); + hc = 31 * hc + call; + + return hc; + } + + public boolean equals(Object o) + { + if (!(o instanceof Context)) + return false; + + Context that = (Context) o; + + return state.equals(that.state) + && call == that.call; + } + + public String toString() + { + return "Context [state=" + state + ", call=" + call + "]"; + } +} diff --git a/libjava/classpath/gnu/java/beans/encoder/GenericScannerState.java b/libjava/classpath/gnu/java/beans/encoder/GenericScannerState.java new file mode 100644 index 000000000..b07771dbe --- /dev/null +++ b/libjava/classpath/gnu/java/beans/encoder/GenericScannerState.java @@ -0,0 +1,257 @@ +/* GenericScannerState.java + Copyright (C) 2005 Free Software Foundation, Inc. + + This file is part of GNU Classpath. + + GNU Classpath is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU Classpath is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Classpath; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. */ + + +package gnu.java.beans.encoder; + +import java.util.HashMap; + +import gnu.java.beans.encoder.elements.ArrayInstantiation; +import gnu.java.beans.encoder.elements.Array_Get; +import gnu.java.beans.encoder.elements.Array_Set; +import gnu.java.beans.encoder.elements.ClassResolution; +import gnu.java.beans.encoder.elements.Element; +import gnu.java.beans.encoder.elements.List_Get; +import gnu.java.beans.encoder.elements.List_Set; +import gnu.java.beans.encoder.elements.MethodInvocation; +import gnu.java.beans.encoder.elements.NullObject; +import gnu.java.beans.encoder.elements.ObjectInstantiation; +import gnu.java.beans.encoder.elements.ObjectReference; +import gnu.java.beans.encoder.elements.PrimitiveInstantiation; +import gnu.java.beans.encoder.elements.StaticFieldAccess; +import gnu.java.beans.encoder.elements.StaticMethodInvocation; +import gnu.java.beans.encoder.elements.StringReference; + +/** + * This class is a {@link ScannerState} implementation that creates + * suitable {@link gnu.java.beans.encoder.elements.Element} instances + * for each transition variant. + * + * <p>Furthermore it can optionally skip a certain number of child + * elements. The algorithm can cope with the fact that one + * <code>GenericScannerState</code> instance may be called at + * different levels of recursions.</p> + * + * @author Robert Schuster (robertschuster@fsfe.org) + */ +class GenericScannerState extends ScannerState +{ + private int skipElements, initialSkipElements; + + final Root root; + + HashMap skipValues; + + GenericScannerState(Root newRoot) + { + root = newRoot; + } + + GenericScannerState(Root root, int skipElements) + { + this(root); + this.skipElements = initialSkipElements = skipElements; + + if (skipElements > 0) + skipValues = new HashMap(); + } + + protected void enterImpl(Context ctx) + { + if (skipValues != null) + { + Integer skip = (Integer) skipValues.get(ctx); + + if (skip == null) + { + skip = Integer.valueOf(initialSkipElements); + skipValues.put(ctx, skip); + } + + skipElements = skip.intValue(); + } + } + + void methodInvocation(String methodName) + { + if (skipValues != null && skipElements > 0) + return; + + root.addChild(new MethodInvocation(methodName)); + } + + void staticMethodInvocation(String className, String methodName) + { + if (skipValues != null && skipElements > 0) + return; + + root.addChild(new StaticMethodInvocation(className, methodName)); + } + + void staticFieldAccess(String className, String fieldName) + { + if (skipValues != null && skipElements > 0) + return; + + root.addChild(new StaticFieldAccess(className, fieldName)); + } + + void classResolution(String className) + { + if (skipValues != null && skipElements > 0) + return; + + root.addChild(new ClassResolution(className)); + } + + void objectInstantiation(String className, ObjectId objectId) + { + if (skipValues != null && skipElements > 0) + return; + + Element elem = new ObjectInstantiation(className); + elem.initId(objectId); + + root.addChild(elem); + } + + void primitiveInstantiation(String primitiveName, String valueAsString) + { + if (skipValues != null && skipElements > 0) + return; + + root.addChild(new PrimitiveInstantiation(primitiveName, valueAsString)); + } + + void objectArrayInstantiation(String arrayClassName, String lengthAsString, + ObjectId objectId) + { + if (skipValues != null && skipElements > 0) + return; + + Element elem = new ArrayInstantiation(arrayClassName, lengthAsString); + elem.initId(objectId); + + root.addChild(elem); + } + + void primitiveArrayInstantiation(String arrayClassName, String lengthAsString, + ObjectId objectId) + { + objectArrayInstantiation(arrayClassName, lengthAsString, objectId); + } + + void arraySet(String indexAsString) + { + if (skipValues != null && skipElements > 0) + return; + + root.addChild(new Array_Set(indexAsString)); + } + + void arrayGet(String indexAsString) + { + if (skipValues != null && skipElements > 0) + return; + + root.addChild(new Array_Get(indexAsString)); + } + + void listGet() + { + if (skipValues != null && skipElements > 0) + return; + + root.addChild(new List_Get()); + } + + void listSet() + { + if (skipValues != null && skipElements > 0) + return; + + root.addChild(new List_Set()); + } + + void nullObject() + { + if (skipValues != null && skipElements > 0) + return; + + root.addChild(new NullObject()); + } + + void stringReference(String string) + { + if (skipValues != null && skipElements > 0) + return; + + root.addChild(new StringReference(string)); + } + + void objectReference(ObjectId id) + { + if (skipValues != null && skipElements > 0) + return; + + root.addChild(new ObjectReference(id)); + } + + void end() + { + if (skipValues != null) + { + if (skipElements > 0) + skipElements--; + else + { + // Finishes the Element we are constructing. + root.end(); + } + skipValues.put(context(), Integer.valueOf(skipElements)); + } + else + root.end(); + + } + + void enter() + { + + } + +} diff --git a/libjava/classpath/gnu/java/beans/encoder/IgnoringScannerState.java b/libjava/classpath/gnu/java/beans/encoder/IgnoringScannerState.java new file mode 100644 index 000000000..3ec78cdf9 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/encoder/IgnoringScannerState.java @@ -0,0 +1,133 @@ +/* IgnoringScannerState.java -- A ScannerState that does nothing. + Copyright (C) 2005 Free Software Foundation, Inc. + + This file is part of GNU Classpath. + + GNU Classpath is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU Classpath is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Classpath; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. */ + + +package gnu.java.beans.encoder; + +/** A special {@link ScannerState} implementation that ignores all child + * elements. + * + * <p>Consider the call hierarchy: + * <code> + * methodInvocation + * objectInstantiation + * classResolution* + * objectInstantiation + * classResolution + * </code> + * </p> + * + * <p>When the ignoring state is active one can filter the elements of + * one level. One has to set up the state machine that a transition + * via "class resolution" from a state that was reached via "object + * instantation" reaches an <code>IgnoringScannerState</code>.</p> + * + * <p>Setting the default successor of a <code>IgnoringScannerState</code> + * to itself causes all elements of the call hierarchy to be skipped + * until another state is reached by going back.</p> + * + * @author Robert Schuster (robertschuster@fsfe.org) + * + */ +class IgnoringScannerState extends ScannerState +{ + + void methodInvocation(String methodName) + { + } + + void staticMethodInvocation(String className, String methodName) + { + } + + void staticFieldAccess(String className, String fieldName) + { + } + + void classResolution(String className) + { + } + + void objectInstantiation(String className, ObjectId objectId) + { + } + + void primitiveInstantiation(String primitiveName, String valueAsString) + { + } + + void objectArrayInstantiation(String arrayClassName, String lengthAsString, ObjectId objectId) + { + } + + void primitiveArrayInstantiation(String arrayClassName, String lengthAsString, ObjectId objectId) + { + } + + void arraySet(String indexAsString) + { + } + + void arrayGet(String indexAsString) + { + } + + void listGet() + { + } + + void listSet() + { + } + + void nullObject() + { + } + + void stringReference(String string) + { + } + + void objectReference(ObjectId id) + { + } + + void end() + { + } + +} diff --git a/libjava/classpath/gnu/java/beans/encoder/MapPersistenceDelegate.java b/libjava/classpath/gnu/java/beans/encoder/MapPersistenceDelegate.java new file mode 100644 index 000000000..9ffdb5686 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/encoder/MapPersistenceDelegate.java @@ -0,0 +1,81 @@ +/* MapPersistenceDelegate.java -- A PersistenceDelegate for Map subclasses. + + Copyright (C) 2005 Free Software Foundation, Inc. + + This file is part of GNU Classpath. + + GNU Classpath is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU Classpath is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Classpath; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. */ + + +package gnu.java.beans.encoder; + +import java.util.Map; +import java.beans.Encoder; +import java.beans.Expression; +import java.beans.PersistenceDelegate; +import java.beans.Statement; + +import java.util.Iterator; + +/** + * @author Robert Schuster (robertschuster@fsfe.org) + */ +public class MapPersistenceDelegate extends PersistenceDelegate +{ + + protected Expression instantiate(Object oldInstance, Encoder out) + { + return new Expression( + oldInstance, + oldInstance.getClass(), + "new", + null); + } + + protected void initialize(Class type, Object oldInstance, Object newInstance, + Encoder out) + { + Map map = (Map) oldInstance; + Iterator ite = map.keySet().iterator(); + + while (ite.hasNext()) + { + Object key = ite.next(); + out.writeStatement(new Statement(oldInstance, "put", + new Object[] { key, map.get(key) })); + + } + + } + +} diff --git a/libjava/classpath/gnu/java/beans/encoder/ObjectId.java b/libjava/classpath/gnu/java/beans/encoder/ObjectId.java new file mode 100644 index 000000000..13d75d6bb --- /dev/null +++ b/libjava/classpath/gnu/java/beans/encoder/ObjectId.java @@ -0,0 +1,132 @@ +/* ObjectId.java -- Simple object identification mechanism for XML encoding. + Copyright (C) 2005 Free Software Foundation, Inc. + + This file is part of GNU Classpath. + + GNU Classpath is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU Classpath is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Classpath; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. */ + + +package gnu.java.beans.encoder; + +import java.util.HashMap; + +/** + * <p> + * ObjectId provides an object identification mechanism which gives each object + * a name in the form <code><class><Nameindex></code>. + * </p> + * + * <p> + * Each id can be in an unused state which means that only one instance of the + * object is in use and a special id is not needed. Certain {@link + * gnu.java.beans.encoder.elements.Element} subclasses use this feature to find + * out whether they write the "id" attribute or not. + * </p> + * <p> + * An <code>ObjectId</code> instance is typically given to multiple objects. + * The second user should then invoke the {@link #init} method to generate the + * identification string and bring the id in the 'used' state. + * </p> + * + * @author Robert Schuster (robertschuster@fsfe.org) + */ +public class ObjectId +{ + /** + * Stores the index an object of a specific type should be given. + */ + private static HashMap nameIndices = new HashMap(); + + private String id; + + private Class klass; + + ObjectId(Class klass) + { + this.klass = klass; + } + + public boolean isUnused() + { + return id == null; + } + + public String toString() + { + return (id != null) ? id : "<unused id>"; + } + + /** + * <p> + * Generates a simple Id by concatenating a class name with a self-increasing + * number. + * </p> + */ + public void init() + { + assert (klass != null); + + if (id != null) + return; + + Integer count = (Integer) nameIndices.get(klass); + if (count == null) + { + count = Integer.valueOf(0); + } + + if (klass.isArray()) + { + Class ct = klass.getComponentType(); + if (ct == Boolean.TYPE) + id = "booleanArray" + count.intValue(); + else if (ct == Byte.TYPE) + id = "byteArray" + count.intValue(); + else if (ct == Short.TYPE) + id = "shortArray" + count.intValue(); + else if (ct == Integer.TYPE) + id = "intArray" + count.intValue(); + else if (ct == Long.TYPE) + id = "longArray" + count.intValue(); + else if (ct == Float.TYPE) + id = "floatArray" + count.intValue(); + else if (ct == Double.TYPE) + id = "doubleArray" + count.intValue(); + } + else + id = klass.getName() + count.intValue(); + + nameIndices.put(klass, Integer.valueOf(count.intValue() + 1)); + } + +} diff --git a/libjava/classpath/gnu/java/beans/encoder/PrimitivePersistenceDelegate.java b/libjava/classpath/gnu/java/beans/encoder/PrimitivePersistenceDelegate.java new file mode 100644 index 000000000..55626b512 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/encoder/PrimitivePersistenceDelegate.java @@ -0,0 +1,74 @@ +/* PrimitivePersistenceDelegate.java + -- A PersistenceDelegate for primitive data types. + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.beans.encoder; + +import java.beans.Encoder; +import java.beans.Expression; +import java.beans.PersistenceDelegate; + +/** + * A shared PersistenceDelegate implementation for all primitive types. + * + * @author Robert Schuster (robertschuster@fsfe.org) + */ +public class PrimitivePersistenceDelegate extends PersistenceDelegate +{ + + protected Expression instantiate(Object oldInstance, Encoder out) + { + // The implementation relies on the fact that every primitive + // wrapper class has a constructor accepting a String argument. + // By using these constructors creating a primitive instance + // depends on the String class only. + return new Expression(oldInstance, oldInstance.getClass(), "new", + new Object[] { oldInstance.toString() }); + } + + protected void initialize(Class type, Object oldInstance, Object newInstance, Encoder out) + { + // This is a hack to make serializing primitive arrays work correctly. + // Instead of modifying an existing primitive instance to make it equal + // with another instance (which is not possible because primitives are + // immutable) we create a new instance. This is against the specification + // of the initialize method but make things work fine. + out.writeExpression(new Expression(oldInstance, oldInstance.getClass(), "new", + new Object[] { oldInstance.toString() })); + } + +} diff --git a/libjava/classpath/gnu/java/beans/encoder/ReportingScannerState.java b/libjava/classpath/gnu/java/beans/encoder/ReportingScannerState.java new file mode 100644 index 000000000..c91bb1567 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/encoder/ReportingScannerState.java @@ -0,0 +1,131 @@ +/* ReportingScannerState.java -- A state for debugging purposes. + Copyright (C) 2005 Free Software Foundation, Inc. + + This file is part of GNU Classpath. + + GNU Classpath is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU Classpath is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Classpath; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. */ + + +package gnu.java.beans.encoder; + +/** + * A <code>ScannerState</code> implementation that prints useful details + * about its arguments. Use it when the XML encoding does not work correctly + * and you want to find out how things relate to each other. + * + * @author Robert Schuster (robertschuster@fsfe.org) + */ +class ReportingScannerState extends ScannerState +{ + + void methodInvocation(String methodName) + { + System.out.println("methodInvocation: " + methodName + "()"); + } + + void staticMethodInvocation(String className, String methodName) + { + System.out.println("staticMethodInvocation: " + className + "." + methodName + "()"); + } + + void staticFieldAccess(String className, String fieldName) + { + System.out.println("staticFieldAccess: " + className + "." + fieldName); + } + + void classResolution(String className) + { + System.out.println("classResolution: " + className); + } + + void objectInstantiation(String className, ObjectId objectId) + { + System.out.println("objectInstantiation: " + className); + } + + void primitiveInstantiation(String primitiveName, String valueAsString) + { + System.out.println("primitiveInstantiation: (" + primitiveName + ") " + valueAsString); + } + + void objectArrayInstantiation(String arrayClassName, String lengthAsString, ObjectId objectId) + { + System.out.println("objectArrayInstantiation: new " + arrayClassName + "[" + lengthAsString + "]"); + } + + void primitiveArrayInstantiation(String arrayClassName, String lengthAsString, ObjectId objectId) + { + System.out.println("primitiveArrayInstantiation: new " + arrayClassName + "[" + lengthAsString + "]"); + } + + void arraySet(String indexAsString) + { + System.out.println("arraySet: " + indexAsString); + } + + void arrayGet(String indexAsString) + { + System.out.println("arrayGet: " + indexAsString); + } + + void listGet() + { + System.out.println("listGet"); + } + + void listSet() + { + System.out.println("listSet"); + } + + void nullObject() + { + System.out.println("nullObject"); + } + + void stringReference(String string) + { + System.out.println("stringReference: " + string); + } + + void objectReference(ObjectId id) + { + System.out.println("objectReference: " + id); + } + + void end() + { + System.out.println("-close"); + } + +} diff --git a/libjava/classpath/gnu/java/beans/encoder/Root.java b/libjava/classpath/gnu/java/beans/encoder/Root.java new file mode 100644 index 000000000..a6410d716 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/encoder/Root.java @@ -0,0 +1,198 @@ +/* Root.java -- The root of an object tree. + Copyright (C) 2005 Free Software Foundation, Inc. + + This file is part of GNU Classpath. + + GNU Classpath is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU Classpath is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Classpath; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. */ + + +package gnu.java.beans.encoder; + +import java.beans.XMLEncoder; +import java.util.Iterator; +import java.util.Stack; + +import gnu.java.beans.encoder.elements.Element; + +/** <p><code>Root</code> provides a simple interface to a tree of + * objects.</p> + * + * <p>Using an instance of this class a logical representation of + * the real object tree that is serialized can be built. When the + * actual data should be written as XML <code>Root</code> and + * {@link gnu.java.beans.encoder.elements.Element} class can provide + * context information which is used to write the best fitting + * XML representation.</p> + * + * @author Robert Schuster (robertschuster@fsfe.org) + */ +public class Root +{ + private Stack parents = new Stack(); + + private Element rootElement, current; + + private boolean started; + + public Root() + { + rootElement = current = new RootElement(); + } + + /** <p>Adds another child element to the tree.</p> + * + * <p>The new element automatically becomes the current + * element.</p> + * + * @param elem The new child element. + */ + public void addChild(Element elem) + { + current.addChild(elem); + + parents.push(current); + current = elem; + } + + /** + * <p>Marks that the end of the current element + * is reached and that no more childs are added to + * it.</p> + * + * <p>The behavior is to return to the nearest parent + * element.</p> + */ + public void end() + { + current = (Element) parents.pop(); + } + + /** + * <p>Goes back to the nearest parent element but + * deletes the just created child.</p> + * + * <p>This is used if something went wrong while + * processing the child element's {@link java.beans.Expression} + * or {@link java.beans.Statement}.</p> + * + */ + public void deleteLast() + { + current = (Element) parents.pop(); + + current.removeLast(); + } + + /** + * <p>Traverses the elements in the object tree + * and creates their XML representation in the output + * stream of the given {@link Writer}.</p> + * + * <p>Finally the <code>Writer</code> is flushed.</p> + * + * @param writer The Writer instance that generates the XML representation. + */ + public void traverse(Writer writer) + { + if (!started) + { + writer.writePreamble(); + rootElement.writeStart(writer); + } + started = true; + + traverse(writer, rootElement.iterator()); + + rootElement.clear(); + + writer.flush(); + } + + /** Writes the closing element and closes the {@link Writer} + * + * @param writer The Writer instance that generates the XML representation. + */ + public void close(Writer writer) + { + rootElement.writeEnd(writer); + writer.close(); + } + + /** Recursively traverses the object tree. + * + * @param writer The Writer instance that generates the XML representation. + * @param ite An Iterator returning Element instances. + */ + private void traverse(Writer writer, Iterator ite) + { + while (ite.hasNext()) + { + Element e = (Element) ite.next(); + e.writeStart(writer); + + traverse(writer, e.iterator()); + + e.writeEnd(writer); + + e.clear(); + } + } + + /** <p>A special Element implementation that represents the + * encoder's context.</p> + * + * <p>This element is written only once per Writer.</p> + * + * <p>It is assumed that this element is never empty to simplify + * the implementation.</p> + * + * @author Robert Schuster (robertschuster@fsfe.org); + * + */ + static class RootElement extends Element + { + public void writeStart(Writer writer) + { + writer.write("java", new String[] { "version", "class" }, + new String[] { System.getProperty("java.version"), + XMLEncoder.class.getName() }, false); + } + + public void writeEnd(Writer writer) + { + writer.writeEnd(false); + } + + } + +} diff --git a/libjava/classpath/gnu/java/beans/encoder/ScanEngine.java b/libjava/classpath/gnu/java/beans/encoder/ScanEngine.java new file mode 100644 index 000000000..9ced143f0 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/encoder/ScanEngine.java @@ -0,0 +1,860 @@ +/* ScanEngine.java + -- Scans the input and generates an object tree that can be written as XML. + Copyright (C) 2005 Free Software Foundation, Inc. + + This file is part of GNU Classpath. + + GNU Classpath is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU Classpath is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Classpath; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. */ + + +package gnu.java.beans.encoder; + +import java.beans.Expression; +import java.beans.Statement; +import java.io.OutputStream; +import java.lang.reflect.Array; +import java.util.HashMap; +import java.util.IdentityHashMap; +import java.util.List; +import java.util.Stack; + +/** <p>The <code>ScanEngine</code> is the main class of the backend of the + * XML persistence algorithm. It scans {@link java.beans.Expression} and + * {@link java.beans.Statement} instances and some raw objects via the + * {@link #writeObject} method and feeds it to a state machine. The + * state machine then constructs and object tree which is finally + * written as XML by a {@link Writer} implementation.</p> + * + * <p>How does it work?</p> + * <p>The <code>ScanEngine</code> sits below the {@link java.beans.XMLEncoder} + * class and is called by it exclusively. The <code>XMLEncoder</code> sends + * interpretive data by invoking {@link #writeExpression}, {@link #writeStatement} + * and {@link #writeObject}. The invocations of <code>writeExpression</code> and + * <code>writeStatement</code> are usually nested into each other and provide + * more information then necessary to generate the XML representation. + * Furthermore the meaning of certain <code>Expressions</code> differs + * depending on the enclosing elements or the inner elements have to be + * simply discarded.</p> + * + * <p>To cope with this state dependant nature the <code>ScanEngine</code> + * contains a state machine which is programmed statically (no adjustments are + * needed, all <code>ScanEngine</code> engines use the same setup). The + * <code>ScanEngine</code>'s job is to decode the <code>Expression</code>s, + * <code>Statement</code>s and certain objects (namely <code>String</code>, + * <code>null</code> objects and instances which are repeatedly provided to + * the encoder) into 13 low-level (event) methods, which denote the meaning of the + * argument. For example an <code>Expression</code> can be an array + * instantiation which provokes a call to {@link arrayInstantiation} or + * it can be a class resolution leading to a call to {@link #classResolution}. + * For the state machione the 13 methods are the distinct way to transit + * from one state to another. Whenever the <code>ScanEngine</code> calls + * one of the event methods the current's state successor for that event + * is fetched from the state machine configuration, the successpr becomes + * the current state and then the event method is called in the new current + * state. The last step allows the state instance to do something meaningful + * to the object tree.</p> + * + * <p>The state machine knows the concept of returning to the previous + * state. This is done using a stack of states which is popped every + * time a call to <code>writeStatement</code>, <code>writeExpression</code> + * in the <code>XMLEncoder</code> ends by calling the {@link #end} method. + * Note that due to the inheritance relationship of <code>Encoder</code> + * and <code>XMLEncoder</code> it is impossible for the + * <code>ScanEngine</code> itself to decide when an expression or statement + * ended. This can only be done in case of {@link #writeObject} calls because + * they are not nested.</p> + * + * <p>When the XML persistence mechanism reaches an object twice (and more) + * it should generate an XML element using the "idref" attribute and add + * an "id" attribute to its first instantiation. This complicates things a bit + * because the first instantiation will always be part of the object tree + * as some {@link gnu.java.beans.encoder.elements.Element} subclass instance when the + * second and further objects accesses are written. Therefore the {@link ObjectId} + * class was introduced which is shared between all the object tree elements + * and has the notion of an "unused" state meaning that no identification + * is needed. The relationship between an object and its <code>ObjectId</code> + * instance is stored in the <code>ScanEngine</code> and gets cleared whenever + * the {@link #flush} method is called. This method also writes the currently + * built object tree and generates the XML representation.</p> + * + * @author Robert Schuster (robertschuster@fsfe.org) + */ +public class ScanEngine +{ + + /** Change this to true to let the ScanEngine print state transition + * information. + */ + boolean DEBUG = false; + + /** + * Stores the scanner engine states as values and their names as keys. + */ + HashMap states = new HashMap(); + + /** + * Stores former scanner state and makes it possible to come back to them. + */ + Stack parents = new Stack(); + + /** + * The currently active scanner state. + */ + ScannerState current; + + /** + * The root of an object tree that is later written to XML. + */ + Root root; + + /** + * The Writer used to generate the XML output. + */ + Writer writer; + + /** Stores the relationship between objects and their {@link ObjectId} instance. + */ + IdentityHashMap objects = new IdentityHashMap(); + + public ScanEngine(OutputStream os) + { + // TODO: Provide another Writer implementation (e.g. one that does not use + // the XML APIs at all). + writer = new StAXWriter(os); + root = new Root(); + + final ScannerState start = current = new GenericScannerState(root); + ScannerState conf; + + // Use the ReportingScannerState to debug serialization issues. + register(ScannerState.DEFAULT_STATE_NAME, new IgnoringScannerState()); + + register("start", start); + + // Special dead-end state where all transitions are ignored. + register("ignoreAll", new IgnoringScannerState()) + .setDefaultSuccessor("ignoreAll"); + + // Object reference, string reference, null object + start.putSuccessor(ScannerState.TRANSITION_OBJECT_REFERENCE, "simple"); + start.putSuccessor(ScannerState.TRANSITION_STRING_REFERENCE, "simple"); + start.putSuccessor(ScannerState.TRANSITION_NULL_OBJECT, "simple"); + register("simple", new GenericScannerState(root)) + .setDefaultSuccessor("ignoreAll"); + + // Class resolution. + start.putSuccessor(ScannerState.TRANSITION_CLASS_RESOLUTION, "classRes0"); + register("classRes0", + new GenericScannerState(root)).setDefaultSuccessor("ignoreAll"); + + // Object instantiation. + start.putSuccessor(ScannerState.TRANSITION_OBJECT_INSTANTIATION, + "newObj0"); + conf = register("newObj0", new GenericScannerState(root)); + conf.setDefaultSuccessor("ignoreAll"); + + // Simply use the start state to encode method invocations inside of + // objects. + conf.putSuccessor(ScannerState.TRANSITION_METHOD_INVOCATION, "start"); + + // Primitive instantiations. + start.putSuccessor(ScannerState.TRANSITION_PRIMITIVE_INSTANTIATION, + "newPrimitive0"); + register("newPrimitive0", + new GenericScannerState(root)).setDefaultSuccessor("ignoreAll"); + + // Object arrays use the ARRAY_GET transition to create setting the + // array values. + start.putSuccessor(ScannerState.TRANSITION_OBJECT_ARRAY_INSTANTIATION, + "newObjectArray"); + conf = register("newObjectArray", new GenericScannerState(root)); + conf.putSuccessor(ScannerState.TRANSITION_ARRAY_GET, "newOArrayGet"); + conf.putSuccessor(ScannerState.TRANSITION_ARRAY_SET, "ignoreAll"); + conf.putSuccessor(ScannerState.TRANSITION_CLASS_RESOLUTION, "ignoreAll"); + conf.putSuccessor(ScannerState.TRANSITION_PRIMITIVE_INSTANTIATION, + "ignoreAll"); + + // Get here when a value is set in the array. + register("newOArrayGet", + conf = new GenericScannerState(root)); + + conf.putSuccessor(ScannerState.TRANSITION_PRIMITIVE_INSTANTIATION, + "newOArrayGet_ignoreFirstInteger"); + + // "newArrayGet_ignoreFirstInteger" is set up mostly identical like the "start" + // state. Otherwise things would not behave the same when done inside + // arrays. + conf.putSuccessor(ScannerState.TRANSITION_OBJECT_REFERENCE, "simple"); + conf.putSuccessor(ScannerState.TRANSITION_STRING_REFERENCE, "simple"); + conf.putSuccessor(ScannerState.TRANSITION_NULL_OBJECT, "simple"); + conf.putSuccessor(ScannerState.TRANSITION_CLASS_RESOLUTION, "classRes0"); + conf.putSuccessor(ScannerState.TRANSITION_OBJECT_INSTANTIATION, "newObj0"); + conf.putSuccessor(ScannerState.TRANSITION_PRIMITIVE_ARRAY_INSTANTIATION, + "newPrimitiveArray"); + conf.putSuccessor(ScannerState.TRANSITION_OBJECT_ARRAY_INSTANTIATION, + "newObjectArray"); + + conf = register("newOArrayGet_ignoreFirstInteger", + new GenericScannerState(root, 1)); + + // In non-int primitive arrays class resolutions can happen + // but they should be ignored. + conf.putSuccessor(ScannerState.TRANSITION_CLASS_RESOLUTION, "ignoreAll"); + + // Spurious object and string references occur when setting array + // elements. This suppresses them. + conf.putSuccessor(ScannerState.TRANSITION_PRIMITIVE_INSTANTIATION, + "ignoreAll"); + conf.putSuccessor(ScannerState.TRANSITION_OBJECT_REFERENCE, "ignoreAll"); + conf.putSuccessor(ScannerState.TRANSITION_STRING_REFERENCE, "ignoreAll"); + + conf.setDefaultSuccessor("start"); + + // Primitive arrays use the ARRAY_SET transition to create setting the + // array values. This turned out to be the only working solution. + // When primitive arrays were handled by ARRAY_GET the values in boolean + // arrays were always skipped. + start.putSuccessor(ScannerState.TRANSITION_PRIMITIVE_ARRAY_INSTANTIATION, + "newPrimitiveArray"); + conf = register("newPrimitiveArray", new GenericScannerState(root)); + conf.putSuccessor(ScannerState.TRANSITION_ARRAY_GET, "ignoreAll"); + conf.putSuccessor(ScannerState.TRANSITION_ARRAY_SET, "newPArraySet"); + conf.putSuccessor(ScannerState.TRANSITION_CLASS_RESOLUTION, "ignoreAll"); + conf.putSuccessor(ScannerState.TRANSITION_PRIMITIVE_INSTANTIATION, + "ignoreAll"); + + conf = register("newPArraySet", new GenericScannerState(root)); + conf.putSuccessor(ScannerState.TRANSITION_PRIMITIVE_INSTANTIATION, + "newPArraySet_ignoreFirstInteger"); + + // Primitive arrays ignore all kinds of non-primitive object information. + conf.putSuccessor(ScannerState.TRANSITION_OBJECT_REFERENCE, + "ignoreAll"); + conf.putSuccessor(ScannerState.TRANSITION_STRING_REFERENCE, "ignoreAll"); + conf.putSuccessor(ScannerState.TRANSITION_NULL_OBJECT, "ignoreAll"); + conf.putSuccessor(ScannerState.TRANSITION_CLASS_RESOLUTION, "ingoreAll"); + conf.putSuccessor(ScannerState.TRANSITION_OBJECT_INSTANTIATION, "ignoreAll"); + conf.putSuccessor(ScannerState.TRANSITION_PRIMITIVE_ARRAY_INSTANTIATION, + "ignoreAll"); + conf.putSuccessor(ScannerState.TRANSITION_OBJECT_ARRAY_INSTANTIATION, + "ignoreAll"); + + conf = register("newPArraySet_ignoreFirstInteger", + new GenericScannerState(root, 1)); + + // In non-int primitive arrays class resolutions can happen + // but they should be ignored. + conf.putSuccessor(ScannerState.TRANSITION_CLASS_RESOLUTION, "ignoreAll"); + + // Spurious object and string references occur when setting array + // elements. This suppresses them. + conf.putSuccessor(ScannerState.TRANSITION_PRIMITIVE_INSTANTIATION, + "ignoreAll"); + conf.putSuccessor(ScannerState.TRANSITION_OBJECT_REFERENCE, "ignoreAll"); + conf.putSuccessor(ScannerState.TRANSITION_STRING_REFERENCE, "ignoreAll"); + conf.setDefaultSuccessor("start"); + + } + + /** Registers a <code>ScannerState</code> under a certain name. + * + * @param name Name of the state + * @param state The <code>ScannerState</code> instance. + * @return The second argument. + */ + private ScannerState register(String name, ScannerState state) + { + state.init(name); + + states.put(name, state); + + return state; + } + + /** Generates or returns an id for the given object which can be activated + * later if the object is suitable. + * + * <p>Objects are unsuitable if they are an instance of a primitive wrapper + * or String.</p> + * + * @param value The object to retrieve an id for. + * @return The id for the object or <code>null</code>. + */ + private ObjectId retrieveId(Object value) + { + Class valueClass = value.getClass(); + ObjectId id = null; + + // Although multiple accesses to Class objects are not handled + // through ids we generate one for them, too. This allows us to detect + // second time references to such objects in the writeObject method + // and handle them in a special way. + if (valueClass != String.class + && valueClass.getSuperclass() != Number.class + && valueClass != Boolean.class) + { + if ((id = (ObjectId) objects.get(value)) == null) + { + id = new ObjectId(valueClass); + objects.put(value, id); + } + } + + return id; + } + + /** Scans the argument and calls one of event methods. See + * the introduction of this class for details. + * + * @param expr The expression to serialize. + */ + public void writeExpression(Expression expr) + { + String methodName = expr.getMethodName(); + Object[] args = expr.getArguments(); + Object target = expr.getTarget(); + Object value = null; + + try + { + value = expr.getValue(); + } + catch (Exception e) + { + throw (InternalError) + new InternalError( + "The Expression's value should be available at this point.") + .initCause(e); + } + + // TODO: What if the value is null? + ObjectId id; + Class valueClass = value.getClass(); + + if (target == Array.class) + { + if (methodName.equals("newInstance")) + { + id = retrieveId(value); + + Class ct = (Class) args[0]; + + if (ct.isPrimitive() || ct == Boolean.class || ct == Byte.class + || ct == Short.class || ct == Integer.class || ct == Long.class + || ct == Float.class || ct == Double.class) + primitiveArrayInstantiation(ct.getName(), + args[1].toString(), + id); + else + objectArrayInstantiation(ct.getName(), + args[1].toString(), + id); + + return; + } + else if (methodName.equals("get")) + { + arrayGet(args[1].toString()); + + // The encoder does not call the ScanEngine + // when an object is serialized that we already know. + // We test for this situation and insert the object reference + // manually. + // Since there is already a workaround for the Class class + // in writeObject we have to except it from this behavior. + id = (ObjectId) objects.get(value); + if (id != null && valueClass != Class.class) + { + objectReference(id); + end(); + } + + return; + } + else if (methodName.equals("set")) + { + arraySet(args[1].toString()); + return; + } + } + + id = retrieveId(value); + + if (target instanceof Class) + { + if (methodName.equals("new")) + { + Class targetClass = (Class) target; + + // All primitive types have short-hand forms for their + // constructors. + if (valueClass == Boolean.class) + primitiveInstantiation("boolean", args[0].toString()); + else if (valueClass == Byte.class) + primitiveInstantiation("byte", args[0].toString()); + else if (valueClass == Short.class) + primitiveInstantiation("short", args[0].toString()); + else if (valueClass == Integer.class) + primitiveInstantiation("int", args[0].toString()); + else if (valueClass == Long.class) + primitiveInstantiation("long", args[0].toString()); + else if (valueClass == Float.class) + primitiveInstantiation("float", args[0].toString()); + else if (valueClass == Double.class) + primitiveInstantiation("double", args[0].toString()); + else + objectInstantiation(targetClass.getName(), id); + + return; + } + else if (value instanceof Class) + { + String className = ((Class) value).getName(); + + // At this point we know that some *static* method will be called. + + if (methodName.equals("forName")) + { + // However "Class.forName" represents class resolution and has a + // special syntax. + classResolution(className); + return; + } + else if (methodName.equals("getField")) + { + // The same goes for "Class.getField". + // Note: The name of the wanted field is given in + // the argument array. + staticFieldAccess(className, args[0].toString()); + return; + } + else + { + // If nothing fits it is just a static method + // invocation which we decode as such. + staticMethodInvocation(className, methodName); + return; + } + } + } + else if (target instanceof List) + { + // Special behavior for indexed get and set method for list-style + // classes. + // The arguments are in the args array but we need them as subelements. + if (methodName.equals("get")) + { + listGet(); + return; + } + else if (methodName.equals("set")) + { + listSet(); + return; + } + } + + // If nothing else could be used then this is a normal + // method invocation. + methodInvocation(methodName); + } + + /** + * Ends the current state and returns to the last one. + */ + public void end() + { + current.end(); + + if (DEBUG) System.err.print("back from " + current.getName()); + + ScannerState oldCurrent = current; + current = (ScannerState) parents.pop(); + + if (DEBUG) System.err.println(" to " + current.getName()); + } + + /** + * Returns to the last state and deletes the last element in the object tree. + */ + public void revoke() + { + ScannerState oldCurrent = current; + current = (ScannerState) parents.pop(); + + root.deleteLast(); + } + + /** Scans the argument and calls one of event methods. See + * the introduction of this class for details. + * + * @param stmt The statement to serialize. + */ + public void writeStatement(Statement stmt) + { + // This is a simplified version of writeExpression. Everything + // that would not create something that is embedded in a <void> tag + // is left out (instantiation, getters, ...). + // TODO: Is this the right thing to do? + + String methodName = stmt.getMethodName(); + Object target = stmt.getTarget(); + Object[] args = stmt.getArguments(); + + if (target == Array.class && methodName.equals("set")) + { + arraySet(args[1].toString()); + return; + } + + if (target instanceof List) + { + if (methodName.equals("set")) + { + listSet(); + return; + } + } + + // If nothing else could be used then this is a normal + // method invocation. + methodInvocation(methodName); + } + + /** Scans the argument and calls one of event methods. See + * the introduction of this class for details. + * + * @param o The object to serialize. + */ + public boolean writeObject(Object o) + { + ObjectId id = null; + + if (o == null) + { + // Handle null objects which have a special syntax. + nullObject(); + end(); + } + else if (o.getClass() == String.class) + { + // Handle strings which are treated extremely special + // in the encoder (they are never converted into a + // Expression). + stringReference((String) o); + end(); + } + else if ((id = (ObjectId) objects.get(o)) != null) + { + // Multiple references to a Class object do not generate + // an object reference but we use the id to detect that + // situation. + if (o.getClass() == Class.class) + { + classResolution(((Class) o).getName()); + end(); + return false; + } + + // If our object has a corresponding ObjectId instance + // then generate an objectReference. This will + // initialize the id (= brings it in the "used" state) + // when this is the first referal. + objectReference(id); + end(); + return false; + } + + return true; + } + + /** + * Writes the currently constructed object tree out as + * XML and clears the object to {@link ObjectId} relations. + */ + public void flush() + { + // Make all references unreachable. That means we have to generate + // new object ids. + objects.clear(); + + root.traverse(writer); + } + + /** Writes the final bits if the object tree and closes the stream + * afterwards. + */ + public void close() + { + flush(); + root.close(writer); + } + + /** + * Does a transition from one state to another using the given event. + * + * <p>This involves saving the current state, retrieving it's + * successor and setting it as the current state.</p> + * + * @param transition One of {@link ScannerStates]'s transition constants. + */ + private void transition(int transition) + { + parents.push(current); + + String stateName = current.getSuccessor(transition); + + if (DEBUG) + { + System.err.println("from state: " + current.getName() + "\n\troute: " + + ScannerState.transitionNames[transition] + + "\n\t\tto state: " + + stateName); + } + + ScannerState newState = (ScannerState) states.get(stateName); + + newState.enter(new Context(current.getName(), current.getCalls())); + + assert (newState != null) : "State '" + stateName + "' was not defined."; + + current = newState; + } + + /** Event method that denotes a (non-static) method invocation. + * + * <p>More details about this method can be found in this + * class' introduction.</p> + * + * @param methodName The name of the method which is called. + */ + void methodInvocation(String methodName) + { + transition(ScannerState.TRANSITION_METHOD_INVOCATION); + + current.methodInvocation(methodName); + } + + /** Event method that denotes a static method invocation. + * + * <p>More details about this method can be found in this + * class' introduction.</p> + * + * @param methodName The name of the method which is called. + * @param className The name of the class in which the method is called. + */ + void staticMethodInvocation(String className, String methodName) + { + transition(ScannerState.TRANSITION_STATIC_METHOD_INVOCATION); + + current.staticMethodInvocation(className, methodName); + } + + /** Event method that denotes the retrieval of a static field's value. + * + * <p>More details about this method can be found in this + * class' introduction.</p> + * + * @param fieldName The name of the field whose value is retrieved. + * @param className The name of the class in which the method is called. + */ + void staticFieldAccess(String className, String fieldName) + { + transition(ScannerState.TRANSITION_STATIC_FIELD_ACCESS); + + current.staticFieldAccess(className, fieldName); + } + + /** Event method that denotes the resolution of a class. + * + * <p>More details about this method can be found in this + * class' introduction.</p> + * + * @param className The name of the class in which the method is called. + */ + void classResolution(String className) + { + transition(ScannerState.TRANSITION_CLASS_RESOLUTION); + + current.classResolution(className); + } + + /** Event method that denotes the instantiation of an object. + * + * <p>More details about this method can be found in this + * class' introduction.</p> + * + * @param className The name of the class in which the method is called. + * @param objectId An ObjectId instance which can be activated later. + */ + void objectInstantiation(String className, ObjectId objectId) + { + transition(ScannerState.TRANSITION_OBJECT_INSTANTIATION); + + current.objectInstantiation(className, objectId); + } + + /** Event method that denotes the instantiation of a primitive. + * + * <p>More details about this method can be found in this + * class' introduction.</p> + * + * @param primitiveName One of "boolean, "byte", "short", "int", "long" + * , "float" or "double" + * @param valueAsString The value of the primitive as a String. + */ + void primitiveInstantiation(String primitiveName, String valueAsString) + { + transition(ScannerState.TRANSITION_PRIMITIVE_INSTANTIATION); + + current.primitiveInstantiation(primitiveName, valueAsString); + } + + /** Event method that denotes the instantiation of an object array. + * + * <p>More details about this method can be found in this + * class' introduction.</p> + * + * @param arrayClassName The array's class name. + * @param objectId An ObjectId instance which can be activated later. + * @param lengthAsString The array's length as String. + */ + void objectArrayInstantiation(String arrayClassName, String lengthAsString, + ObjectId objectId) + { + transition(ScannerState.TRANSITION_OBJECT_ARRAY_INSTANTIATION); + + current.objectArrayInstantiation(arrayClassName, lengthAsString, objectId); + } + + /** Event method that denotes the instantiation of a primitive array. + * + * <p>More details about this method can be found in this + * class' introduction.</p> + * + * @param arrayClassName The array's class name. + * @param objectId An ObjectId instance which can be activated later. + * @param lengthAsString The array's length as String. + */ + void primitiveArrayInstantiation(String arrayClassName, String lengthAsString, + ObjectId objectId) + { + transition(ScannerState.TRANSITION_PRIMITIVE_ARRAY_INSTANTIATION); + + current.objectArrayInstantiation(arrayClassName, lengthAsString, objectId); + } + + /** Event method that denotes the setting of a value in an array. + * + * <p>More details about this method can be found in this + * class' introduction.</p> + * + * @param indexAsString The index to as a String. + */ + void arraySet(String indexAsString) + { + transition(ScannerState.TRANSITION_ARRAY_SET); + + current.arraySet(indexAsString); + } + + /** Event method that denotes the retrieval of a value in an array. + * + * <p>More details about this method can be found in this + * class' introduction.</p> + * + * @param indexAsString The index to as a String. + */ + void arrayGet(String indexAsString) + { + transition(ScannerState.TRANSITION_ARRAY_GET); + + current.arrayGet(indexAsString); + } + + /** Event method that denotes the setting of a value in a list. + * + * <p>More details about this method can be found in this + * class' introduction.</p> + */ + void listSet() + { + transition(ScannerState.TRANSITION_LIST_SET); + + current.listSet(); + } + + /** Event method that denotes the retrieval of a value in a list. + * + * <p>More details about this method can be found in this + * class' introduction.</p> + */ + void listGet() + { + transition(ScannerState.TRANSITION_LIST_GET); + + current.listGet(); + } + + /** Event method that denotes the null value. + */ + void nullObject() + { + transition(ScannerState.TRANSITION_NULL_OBJECT); + + current.nullObject(); + } + + /** Event method that denotes a string. + * + * @param string The string that should be written. + */ + void stringReference(String string) + { + transition(ScannerState.TRANSITION_STRING_REFERENCE); + + current.stringReference(string); + } + + /** Event method that denotes a reference to an existing object. + * + * @param id The ObjectId to be used. + */ + void objectReference(ObjectId id) + { + transition(ScannerState.TRANSITION_OBJECT_REFERENCE); + + current.objectReference(id); + } + +} diff --git a/libjava/classpath/gnu/java/beans/encoder/ScannerState.java b/libjava/classpath/gnu/java/beans/encoder/ScannerState.java new file mode 100644 index 000000000..14d63056e --- /dev/null +++ b/libjava/classpath/gnu/java/beans/encoder/ScannerState.java @@ -0,0 +1,236 @@ +/* ScannerState.java + Copyright (C) 2005 Free Software Foundation, Inc. + + This file is part of GNU Classpath. + + GNU Classpath is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU Classpath is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Classpath; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. */ + + +package gnu.java.beans.encoder; + +import java.util.HashMap; + +/** <p>Provides the infrastructure for the state machine and the transition + * mechanism.</p> + * + * <p>Each states knows a set of successor. There can be one successor for + * every transition variant. Furthermore a state knows about a default + * successor which is taken when there is no special setup for a + * transition.</p> + * + * @author Robert Schuster (robertschuster@fsfe.org) + * + */ +public abstract class ScannerState +{ + + static final int TRANSITION_METHOD_INVOCATION = 0; + + static final int TRANSITION_STATIC_METHOD_INVOCATION = 1; + + static final int TRANSITION_STATIC_FIELD_ACCESS = 2; + + static final int TRANSITION_CLASS_RESOLUTION = 3; + + static final int TRANSITION_OBJECT_INSTANTIATION = 4; + + static final int TRANSITION_PRIMITIVE_INSTANTIATION = 5; + + static final int TRANSITION_OBJECT_ARRAY_INSTANTIATION = 6; + + static final int TRANSITION_PRIMITIVE_ARRAY_INSTANTIATION = 7; + + static final int TRANSITION_ARRAY_SET = 8; + + static final int TRANSITION_ARRAY_GET = 9; + + static final int TRANSITION_LIST_SET = 10; + + static final int TRANSITION_LIST_GET = 11; + + static final int TRANSITION_NULL_OBJECT = 12; + + static final int TRANSITION_STRING_REFERENCE = 13; + + static final int TRANSITION_OBJECT_REFERENCE = 14; + + static final int TRANSITION_FIRST = 0; + + static final int TRANSITION_LAST = 14; + + static final String DEFAULT_STATE_NAME = "default"; + + String defaultSuccessor = DEFAULT_STATE_NAME; + + static String[] transitionNames = { "METHOD_INVOCATION", "STATIC_METHOD_INVOCATION", + "STATIC_FIELD_ACCESS", "CLASS_RESOLUTION", + "OBJECT_INSTANTIATION", + "PRIMITIVE_INSTANTIATION", "OBJECT_ARRAY_INSTANTIATION", + "PRIMITIVE_ARRAY_INSTANTIATION", + "ARRAY_SET", "ARRAY_GET", "LIST_SET", "LIST_GET", + "NULL_OBJECT", "STRING_REFERENCE", "OBJECT_REFERENCE" }; + + /** + * Stores the transition setup as the relation + * transition->successor's state name. + */ + HashMap transitions = new HashMap(); + + int calls; + + Context context; + + String name; + + final void init(String newName) + { + assert (name == null); + + name = newName; + } + + final String getName() + { + return name; + } + + final void enter(Context ctx) + { + calls++; + context = ctx; + + enterImpl(ctx); + } + + protected void enterImpl(Context ctx) + { + } + + final Context context() + { + return context; + } + + final int getCalls() + { + return calls; + } + + /** + * <p>Stores a successor's state name for a certain transition.</p> + * + * <p>This method is only used at the configuration time of the state + * machine.</p> + * + * @param transition One of the transition constants. + * @param stateName The state name of the successor. + */ + final void putSuccessor(int transition, String stateName) + { + assert (transition >= TRANSITION_FIRST && transition <= TRANSITION_LAST) : + "Transition identifier '" + transition + "' is unknown."; + + transitions.put(new Integer(transition), stateName); + } + + /** <p>Retrieves a the state name of a successor for the given transition + * constant.</p> + * + * <p>Returns the default successor's state name if no special setup was + * prepared.</p> + * + * @param transition One of the transition constants. + * @return The state name of the successor. + */ + final String getSuccessor(int transition) + { + String state = (String) transitions.get(new Integer(transition)); + + return (state == null) ? defaultSuccessor : state; + } + + /** + * Sets the name for the default successor state. + * + * @param newDefaultSuccessor The default successor's state name. + */ + final void setDefaultSuccessor(String newDefaultSuccessor) + { + defaultSuccessor = newDefaultSuccessor; + } + + abstract void methodInvocation(String methodName); + + abstract void staticMethodInvocation(String className, String methodName); + + abstract void staticFieldAccess(String className, String fieldName); + + abstract void classResolution(String className); + + abstract void objectInstantiation(String className, ObjectId objectId); + + abstract void primitiveInstantiation(String primitiveName, + String valueAsString); + + abstract void objectArrayInstantiation(String arrayClassName, String lengthAsString, ObjectId objectId); + + abstract void primitiveArrayInstantiation(String arrayClassName, String lengthAsString, ObjectId objectId); + + abstract void arraySet(String indexAsString); + + abstract void arrayGet(String indexAsString); + + abstract void listGet(); + + abstract void listSet(); + + abstract void nullObject(); + + abstract void stringReference(String string); + + abstract void objectReference(ObjectId id); + + /** + * <p>A special event that does not provoke a direct transition.</p> + * + * <p>Instead the transition is done by the <code>ScanEngine</code>: It goes + * back to the previous state and just uses this method to inform the state + * about this happening.</p> + */ + abstract void end(); + + void enter() + { + } + +} diff --git a/libjava/classpath/gnu/java/beans/encoder/StAXWriter.java b/libjava/classpath/gnu/java/beans/encoder/StAXWriter.java new file mode 100644 index 000000000..da88c5361 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/encoder/StAXWriter.java @@ -0,0 +1,233 @@ +/* StAXWriter.java + Copyright (C) 2005 Free Software Foundation, Inc. + + This file is part of GNU Classpath. + + GNU Classpath is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU Classpath is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Classpath; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. */ + + +package gnu.java.beans.encoder; + +import java.io.OutputStream; + +import javax.xml.stream.XMLOutputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamWriter; + +/** A {@link Writer} implementation based on the StAX API. + * + * @author Robert Schuster (robertschuster@fsfe.org) + * + */ +public class StAXWriter implements Writer +{ + XMLStreamWriter writer; + + int indent = 0; + + public StAXWriter(OutputStream os) + { + try + { + XMLOutputFactory factory = XMLOutputFactory.newInstance(); + writer = factory.createXMLStreamWriter(os); + } + catch (XMLStreamException se) + { + throw (InternalError) + new InternalError( + "Could not instantiate a streaming XML writer.") + .initCause(se); + } + + } + + public void flush() + { + if (writer != null) + { + try + { + writer.flush(); + } + catch (XMLStreamException xse) + { + // TODO: find out + } + } + + } + + public void close() + { + if (writer != null) + { + try + { + writer.close(); + } + catch (XMLStreamException xse) + { + // TODO: find out + } + writer = null; + } + + } + + public void writePreamble() + { + try + { + writer.writeStartDocument("UTF-8", "1.0"); + } + catch (XMLStreamException xmlse) + { + + } + } + + public void writeEnd(boolean wasEmpty) + { + try + { + indent -= 2; + + if (wasEmpty) + return; + + for (int i = 0; i < indent; i++) + writer.writeCharacters(" "); + + writer.writeEndElement(); + + writer.writeCharacters("\n"); + } + catch (XMLStreamException xmlse) + { + + } + } + + public void writeEndNoChildren() + { + try + { + writer.writeEndElement(); + writer.writeCharacters("\n"); + } + catch (XMLStreamException xmlse) + { + + } + } + + public void write(String tagName, boolean empty) + { + write(tagName, null, null, null, empty); + } + + public void write(String tagName, String value) + { + write(tagName, value, null, null, value == null); + } + + public void writeNoChildren(String tagName, String value) + { + try + { + for (int i = 0; i < indent; i++) + writer.writeCharacters(" "); + + writer.writeStartElement(tagName); + + writer.writeCharacters(value); + } + catch (XMLStreamException xmlse) + { + + } + } + + public void write(String tagName, String attributeName, + String attributeValue, boolean empty) + { + write(tagName, null, new String[] { attributeName }, + new String[] { attributeValue }, empty); + } + + public void write(String tagName, String value, String[] attributeNames, + String[] attributeValues, boolean empty) + { + try + { + for (int i = 0; i < indent; i++) + + writer.writeCharacters(" "); + + if (empty) + writer.writeEmptyElement(tagName); + else + writer.writeStartElement(tagName); + + if (attributeNames != null) + for (int i = 0; i < attributeNames.length; i++) + writer.writeAttribute(attributeNames[i], attributeValues[i]); + + writer.writeCharacters("\n"); + + indent += 2; + + if (value != null) + { + for (int i = 0; i < indent; i++) + writer.writeCharacters(" "); + + writer.writeCharacters(value); + + writer.writeCharacters("\n"); + } + } + catch (XMLStreamException xmlse) + { + + } + } + + public void write(String tagName, String[] attributeNames, + String[] attributeValues, boolean empty) + { + write(tagName, null, attributeNames, attributeValues, empty); + } + +} diff --git a/libjava/classpath/gnu/java/beans/encoder/Writer.java b/libjava/classpath/gnu/java/beans/encoder/Writer.java new file mode 100644 index 000000000..e08c786d8 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/encoder/Writer.java @@ -0,0 +1,174 @@ +/* Writer.java -- Writing interface for XML persistence. + Copyright (C) 2005 Free Software Foundation, Inc. + + This file is part of GNU Classpath. + + GNU Classpath is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU Classpath is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Classpath; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. */ + + +package gnu.java.beans.encoder; + +/** A <code>Writer</code> represents a simplified interface to an XML + * writer that is used for the XML persistence mechanism. + * + * <p>Its sole purpose is to allow multiple backends which may remove + * the need to have certain APIs in the classpath. Eg. it is possible + * to write a stripped down XML Writer that does not rely on SAX, StAX + * or DOM APIs.</p> + * + * <p>The caller may assume that every action is done immediately. However + * it is possible that the underlying implementation uses buffering streams. + * To make sure the data is written call the {@link flush} method.</p> + * + * <p>The <code>Writer</code> implementation should care about the formatting + * of the XML stream making it possible to generate three types of formats using + * a special method invocation chain.</p> + * + * <p>Write + * <code> + * <element/> + * </code> + * by issuing <code>write("element", true)</code> (or any of the other + * write-variants that allows specifying the <code>isEmpty</code> argument) + * and <code>writeEnd(true)</code>.</p> + * + * <p>Write + * <code> + * <element>body</element> + * </code> + * by issuing <code>writeNoChildren("element", "body")</code> and <code>writeNoChildrenEnd()</code>.</p> + * + * <p> + * Write + * <code> + * <element> + * <child1/> + * <child2/> + * ... + * <element/> + * </code> + * by issuing <code>write("element", false)</code> (or any of the other + * write-variants that allows specifying the <code>isEmpty</code> argument) + * and <code>writeEnd(false)</code>.</p> + * + * <p>Note: It is important that the values of <code>isEmpty</code> and + * <code>wasEmpty</code> match. Otherwise strange things might happen to + * the layout.</p> + * + * @author Robert Schuster (robertschuster@fsfe.org) + * + */ +public interface Writer +{ + // TODO: This interface's design is not the best. Feel free to + // improve it as you like. + + /** Writes the XML preamble. */ + void writePreamble(); + + /** Writes the end of an XML tag. + * + * <p>If your tag has not generated any body text or child + * elements provide <code>true</code> as the argument to generate + * more space efficient variant of the tag.>/p> + * + * @param wasEmpty Whether the tag was empty or not. + */ + void writeEnd(boolean wasEmpty); + + /** Writes an XML tag without any attributes. + * + * @param tagName The name of the tag to write. + * @param empty Whether the element has child elements. + */ + void write(String tagName, boolean empty); + + /** Writes an XML tag with one attribute name and value. + * + * @param tagName The name of the tag to write. + * @param attributeName The name of attribute. + * @param attributeValue The attribute's value. + * @param empty Whether the element has child elements. + */ + void write(String tagName, String attributeName, String attributeValue, boolean empty); + + /** Writes an XML tag with multiple attributes and a body text. + * + * @param tagName The name of the tag to write. + * @param value The element's body content. + * @param attributeNames A set of attribute names. + * @param attributeValues A set of attribute values. + * @param empty Whether the element has child elements. + */ + void write(String tagName, String value, String[] attributeNames, + String[] attributeValues, boolean empty); + + /** Writes an XML tag with multiple attributes without a body text. + * + * @param tagName The name of the tag to write. + * @param attributeNames A set of attribute names. + * @param attributeValues A set of attribute values. + * @param empty Whether the element has child elements. + */ + void write(String tagName, String[] attributeNames, String[] attributeValues, boolean empty); + + /** Writes an XML tag with no attributes but with a body text + * that may have child elements. + * + * @param tagName The name of the tag to write. + * @param value The element's body content. + */ + void write(String tagName, String value); + + /** Writes an XML tag with no attributes but with a body text + * that does not have child elements. + * + * @param tagName The name of the tag to write. + * @param value The element's body content. + */ + void writeNoChildren(String tagName, String value); + + /** Writes the end of an XML tag that has no child elements. + * + * <p>Must be used in combination with {@link writeNoChildren} only.</p> + */ + void writeEndNoChildren(); + + /** Forces the implementation to write some data. + */ + void flush(); + + /** Closes the writer. + */ + void close(); +} diff --git a/libjava/classpath/gnu/java/beans/encoder/elements/ArrayInstantiation.java b/libjava/classpath/gnu/java/beans/encoder/elements/ArrayInstantiation.java new file mode 100644 index 000000000..51e00c361 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/encoder/elements/ArrayInstantiation.java @@ -0,0 +1,74 @@ +/* ArrayInstantiation.java + Copyright (C) 2005 Free Software Foundation, Inc. + + This file is part of GNU Classpath. + + GNU Classpath is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU Classpath is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Classpath; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. */ + + +package gnu.java.beans.encoder.elements; + +import gnu.java.beans.encoder.ObjectId; +import gnu.java.beans.encoder.Writer; + +/** Generates an XML element denoting the instantiation of an array. + * + * @author Robert Schuster (robertschuster@fsfe.org) + * + */ +public class ArrayInstantiation extends Element +{ + final String className; + + final String lengthAsString; + + public ArrayInstantiation(String newClassName, String newLengthAsString) + { + className = newClassName; + lengthAsString = newLengthAsString; + } + + public void writeStart(Writer writer) + { + ObjectId objectId = getId(); + if (objectId.isUnused()) + writer.write("array", new String[] { "class", "length" }, + new String[] { className, lengthAsString }, isEmpty()); + else + writer.write("array", new String[] { "id", "class", "length" }, + new String[] { objectId.toString(), className, + lengthAsString }, isEmpty()); + + } + +} diff --git a/libjava/classpath/gnu/java/beans/encoder/elements/Array_Get.java b/libjava/classpath/gnu/java/beans/encoder/elements/Array_Get.java new file mode 100644 index 000000000..912ecebb5 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/encoder/elements/Array_Get.java @@ -0,0 +1,62 @@ +/* Array_Get.java + Copyright (C) 2005 Free Software Foundation, Inc. + + This file is part of GNU Classpath. + + GNU Classpath is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU Classpath is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Classpath; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. */ + + +package gnu.java.beans.encoder.elements; + +import gnu.java.beans.encoder.Writer; + +/** + * Generates an XML element denoting the retrieval of an array value. + * + * @author Robert Schuster (robertschuster@fsfe.org) + */ +public class Array_Get extends Element +{ + final String indexAsString; + + public Array_Get(String newIndexAsString) + { + indexAsString = newIndexAsString; + } + + public void writeStart(Writer writer) + { + writer.write("void", "index", indexAsString, isEmpty()); + } + +} diff --git a/libjava/classpath/gnu/java/beans/encoder/elements/Array_Set.java b/libjava/classpath/gnu/java/beans/encoder/elements/Array_Set.java new file mode 100644 index 000000000..096232055 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/encoder/elements/Array_Set.java @@ -0,0 +1,57 @@ +/* Array_Set.java -- FIXME: briefly describe file purpose + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.beans.encoder.elements; + +import gnu.java.beans.encoder.Writer; + +public class Array_Set extends Element +{ + final String indexAsString; + + public Array_Set(String newIndexAsString) + { + indexAsString = newIndexAsString; + } + + public void writeStart(Writer writer) + { + writer.write("void", "index", indexAsString, isEmpty()); + } + +} diff --git a/libjava/classpath/gnu/java/beans/encoder/elements/ClassResolution.java b/libjava/classpath/gnu/java/beans/encoder/elements/ClassResolution.java new file mode 100644 index 000000000..cb736d5c0 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/encoder/elements/ClassResolution.java @@ -0,0 +1,67 @@ +/* ClassResolution.java + Copyright (C) 2005 Free Software Foundation, Inc. + + This file is part of GNU Classpath. + + GNU Classpath is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU Classpath is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Classpath; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. */ + + +package gnu.java.beans.encoder.elements; + +import gnu.java.beans.encoder.Writer; + +/** Generates an XML element denoting the resolution of a class. + * + * @author Robert Schuster (robertschuster@fsfe.org) + * + */ +public class ClassResolution extends Element +{ + final String className; + + public ClassResolution(String newClassName) + { + className = newClassName; + } + + public void writeStart(Writer writer) + { + writer.writeNoChildren("class", className); + } + + public void writeEnd(Writer writer) + { + writer.writeEndNoChildren(); + } + +} diff --git a/libjava/classpath/gnu/java/beans/encoder/elements/Element.java b/libjava/classpath/gnu/java/beans/encoder/elements/Element.java new file mode 100644 index 000000000..a8c0ecdf7 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/encoder/elements/Element.java @@ -0,0 +1,157 @@ +/* Element.java -- Base class for object tree elements. + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.beans.encoder.elements; + +import java.util.Iterator; +import java.util.LinkedList; + +import gnu.java.beans.encoder.ObjectId; +import gnu.java.beans.encoder.Writer; + +/** <code>Element</code> is the base class for the object tree elements. + * + * <p>It provides the neccessary infrastructure every element subclass + * needs in order to interact with the {@link gnu.java.beans.encoder.Root} + * class.</p> + * + * @author Robert Schuster (robertschuster@fsfe.org) + */ +public abstract class Element +{ + /** + * Stores the child elements. + */ + private LinkedList children = new LinkedList(); + + /** + * An optional ObjectId instance which is needed for certain subclasses + * only. + */ + private ObjectId objectId; + + /** Sets an {@link gnu.java.beans.encoder.ObjectId} instance in this + * <code>Element</code>. + * + * <p>This can only be done once.</p> + * + * @param objectId An ObjectId instance. + */ + public final void initId(ObjectId objectId) + { + assert (this.objectId == null); + assert (objectId != null); + + this.objectId = objectId; + } + + /** Adds a child element to this <code>Element</code>. + * + * @param elem The new child. + */ + public final void addChild(Element elem) + { + children.add(elem); + } + + /** Removes the child element added last. + */ + public final void removeLast() + { + children.removeLast(); + } + + /** Provides access to the child elements via an iterator. + * + * @return An iterator for the child elements. + */ + public final Iterator iterator(){ + return children.iterator(); + } + + /** Clears all the stored child elements. + * + */ + public final void clear() + { + children.clear(); + } + + /** Returns whether this element contains child elements. + * + * <p>This method is useful to decide which formatting variant + * for the XML element can be chosen.</p> + * + * @return Whether the element has child elements. + */ + public final boolean isEmpty() + { + return children.isEmpty(); + } + + /** Retrieves the element's {@link gnu.java.beans.encoder.ObjectId} instance + * if it has one. + * + * @return The ObjectId instance or <code>null</code>. + */ + public final ObjectId getId() + { + return objectId; + } + + /** Writes the opening XML tag. + * + * @param writer The writer to be used for XML writing. + */ + public abstract void writeStart(Writer writer); + + /** Writes the closing XML tag. + * + * <p>By default this does <code>writer.writeEnd(children.isEmpty())</code>. + * Override if neccessary, for example when using the + * {@link gnu.java.beans.encoder.Writer#writeNoChildren}</code> method + * variants. + * + * @param writer The writer to be used for XML writing. + */ + public void writeEnd(Writer writer) + { + writer.writeEnd(children.isEmpty()); + } + +} diff --git a/libjava/classpath/gnu/java/beans/encoder/elements/List_Get.java b/libjava/classpath/gnu/java/beans/encoder/elements/List_Get.java new file mode 100644 index 000000000..c14ab91f9 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/encoder/elements/List_Get.java @@ -0,0 +1,56 @@ +/* List_Get.java + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.beans.encoder.elements; + +import gnu.java.beans.encoder.Writer; + +/** Generates an XML element denoting the retrieval of a list's element. + * + * @author Robert Schuster (robertschuster@fsfe.org) + * + */ +public class List_Get extends Element +{ + + public void writeStart(Writer writer) + { + writer.write("object", "get"); + } + +} diff --git a/libjava/classpath/gnu/java/beans/encoder/elements/List_Set.java b/libjava/classpath/gnu/java/beans/encoder/elements/List_Set.java new file mode 100644 index 000000000..3e7cca628 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/encoder/elements/List_Set.java @@ -0,0 +1,56 @@ +/* List_Set.java + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.beans.encoder.elements; + +import gnu.java.beans.encoder.Writer; + +/** Generates an XML element denoting the setting of a list's element. + * + * @author Robert Schuster (robertschuster@fsfe.org) + * + */ +public class List_Set extends Element +{ + + public void writeStart(Writer writer) + { + writer.write("object", "set"); + } + +} diff --git a/libjava/classpath/gnu/java/beans/encoder/elements/MethodInvocation.java b/libjava/classpath/gnu/java/beans/encoder/elements/MethodInvocation.java new file mode 100644 index 000000000..1de5bb62d --- /dev/null +++ b/libjava/classpath/gnu/java/beans/encoder/elements/MethodInvocation.java @@ -0,0 +1,62 @@ +/* MethodCall.java + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.beans.encoder.elements; + +import gnu.java.beans.encoder.Writer; + +/** Generates an XML element denoting a non-static method call. + * + * @author Robert Schuster (robertschuster@fsfe.org) + * + */ +public class MethodInvocation extends Element +{ + final String methodName; + + public MethodInvocation(String newMethodName) + { + methodName = newMethodName; + } + + public void writeStart(Writer writer) + { + writer.write("void", "method", methodName, isEmpty()); + } + +} diff --git a/libjava/classpath/gnu/java/beans/encoder/elements/NullObject.java b/libjava/classpath/gnu/java/beans/encoder/elements/NullObject.java new file mode 100644 index 000000000..211e2a74b --- /dev/null +++ b/libjava/classpath/gnu/java/beans/encoder/elements/NullObject.java @@ -0,0 +1,61 @@ +/* NullObject.java + Copyright (C) 2005 Free Software Foundation, Inc. + + This file is part of GNU Classpath. + + GNU Classpath is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU Classpath is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Classpath; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. */ + + +package gnu.java.beans.encoder.elements; + +import gnu.java.beans.encoder.Writer; + +/** Generates an XML element denoting the <code>null</code> value. + * + * @author Robert Schuster (robertschuster@fsfe.org) + * + */ +public class NullObject extends Element +{ + + public void writeStart(Writer writer) + { + writer.write("null", true); + } + + public void writeEnd(Writer writer) + { + writer.writeEnd(true); + } + +} diff --git a/libjava/classpath/gnu/java/beans/encoder/elements/ObjectInstantiation.java b/libjava/classpath/gnu/java/beans/encoder/elements/ObjectInstantiation.java new file mode 100644 index 000000000..98614809f --- /dev/null +++ b/libjava/classpath/gnu/java/beans/encoder/elements/ObjectInstantiation.java @@ -0,0 +1,68 @@ +/* ObjectInstantiation.java + Copyright (C) 2005 Free Software Foundation, Inc. + + This file is part of GNU Classpath. + + GNU Classpath is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU Classpath is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Classpath; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. */ + + +package gnu.java.beans.encoder.elements; + +import gnu.java.beans.encoder.ObjectId; +import gnu.java.beans.encoder.Writer; + +/** Generates an XML element denoting the instantiation of an object. + * + * @author Robert Schuster (robertschuster@fsfe.org) + * + */ +public class ObjectInstantiation extends Element +{ + final String className; + + public ObjectInstantiation(String newClassName) + { + className = newClassName; + } + + public void writeStart(Writer writer) + { + ObjectId objectId = getId(); + if (objectId.isUnused()) + writer.write("object", "class", className, isEmpty()); + else + writer.write("object", new String[] { "id", "class" }, + new String[] { objectId.toString(), className }, isEmpty()); + } + +} diff --git a/libjava/classpath/gnu/java/beans/encoder/elements/ObjectReference.java b/libjava/classpath/gnu/java/beans/encoder/elements/ObjectReference.java new file mode 100644 index 000000000..13a597a58 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/encoder/elements/ObjectReference.java @@ -0,0 +1,68 @@ +/* StringInstantiation.java + Copyright (C) 2005 Free Software Foundation, Inc. + + This file is part of GNU Classpath. + + GNU Classpath is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU Classpath is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Classpath; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. */ + + +package gnu.java.beans.encoder.elements; + +import gnu.java.beans.encoder.ObjectId; +import gnu.java.beans.encoder.Writer; + +/** Generates an XML element denoting referencing an existing object. + * + * @author Robert Schuster (robertschuster@fsfe.org) + * + */ +public class ObjectReference extends Element +{ + final ObjectId id; + + public ObjectReference(ObjectId newId) + { + id = newId; + + // Initializing the Id here is making sure it gets + // actually used. This step modifies the Id instance + // in other elements. + id.init(); + } + + public void writeStart(Writer writer) + { + writer.write("object", "idref", id.toString(), isEmpty()); + } + +} diff --git a/libjava/classpath/gnu/java/beans/encoder/elements/PrimitiveInstantiation.java b/libjava/classpath/gnu/java/beans/encoder/elements/PrimitiveInstantiation.java new file mode 100644 index 000000000..ae34b9dad --- /dev/null +++ b/libjava/classpath/gnu/java/beans/encoder/elements/PrimitiveInstantiation.java @@ -0,0 +1,69 @@ +/* PrimitiveInstantiation.java + Copyright (C) 2005 Free Software Foundation, Inc. + + This file is part of GNU Classpath. + + GNU Classpath is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU Classpath is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Classpath; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. */ + + +package gnu.java.beans.encoder.elements; + +import gnu.java.beans.encoder.Writer; + +/** Generates an XML element denoting a primitive data value. + * + * @author Robert Schuster (robertschuster@fsfe.org) + * + */ +public class PrimitiveInstantiation extends Element +{ + final String primitiveName; + + final String valueAsString; + + public PrimitiveInstantiation(String newPrimitiveName, String newValueAsString) + { + primitiveName = newPrimitiveName; + valueAsString = newValueAsString; + } + + public void writeStart(Writer writer) + { + writer.writeNoChildren(primitiveName, valueAsString); + } + + public void writeEnd(Writer writer) + { + writer.writeEndNoChildren(); + } +} diff --git a/libjava/classpath/gnu/java/beans/encoder/elements/StaticFieldAccess.java b/libjava/classpath/gnu/java/beans/encoder/elements/StaticFieldAccess.java new file mode 100644 index 000000000..7fcbf5203 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/encoder/elements/StaticFieldAccess.java @@ -0,0 +1,66 @@ +/* StaticFieldAccess.java + Copyright (C) 2005 Free Software Foundation, Inc. + + This file is part of GNU Classpath. + + GNU Classpath is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU Classpath is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Classpath; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. */ + + +package gnu.java.beans.encoder.elements; + +import gnu.java.beans.encoder.Writer; + +/** Generates an XML element denoting a static method call. + * + * @author Robert Schuster (robertschuster@fsfe.org) + * + */ +public class StaticFieldAccess extends Element +{ + final String className; + + final String fieldName; + + public StaticFieldAccess(String newClassName, String newFieldName) + { + className = newClassName; + fieldName = newFieldName; + } + + public void writeStart(Writer writer) + { + writer.write("object", new String[] { "class", "field" }, + new String[] { className, fieldName }, isEmpty()); + } + +} diff --git a/libjava/classpath/gnu/java/beans/encoder/elements/StaticMethodInvocation.java b/libjava/classpath/gnu/java/beans/encoder/elements/StaticMethodInvocation.java new file mode 100644 index 000000000..92d49dc41 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/encoder/elements/StaticMethodInvocation.java @@ -0,0 +1,67 @@ +/* StaticMethodCall.java + -- A class denoting an XML element which makes up a static method call. + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.beans.encoder.elements; + +import gnu.java.beans.encoder.Writer; + +/** + * + * @author Robert Schuster (robertschuster@fsfe.org) + * + */ +public class StaticMethodInvocation extends Element +{ + final String className; + + final String methodName; + + public StaticMethodInvocation(String newClassName, String newMethodName) + { + className = newClassName; + methodName = newMethodName; + } + + public void writeStart(Writer writer) + { + writer.write("void", new String[] { "class", "method" }, + new String[] { className, methodName }, isEmpty()); + } + +} diff --git a/libjava/classpath/gnu/java/beans/encoder/elements/StringReference.java b/libjava/classpath/gnu/java/beans/encoder/elements/StringReference.java new file mode 100644 index 000000000..7e6787da3 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/encoder/elements/StringReference.java @@ -0,0 +1,63 @@ +/* StringInstantiation.java + -- A class denoting an XML element which retrieves an array element. + Copyright (C) 2005 Free Software Foundation, Inc. + + This file is part of GNU Classpath. + + GNU Classpath is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU Classpath is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Classpath; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. */ + + +package gnu.java.beans.encoder.elements; + +import gnu.java.beans.encoder.Writer; + +public class StringReference extends Element +{ + final String string; + + public StringReference(String newString) + { + string = newString; + } + + public void writeStart(Writer writer) + { + writer.writeNoChildren("string", string); + } + + public void writeEnd(Writer writer) + { + writer.writeEndNoChildren(); + } + +} diff --git a/libjava/classpath/gnu/java/beans/package.html b/libjava/classpath/gnu/java/beans/package.html new file mode 100644 index 000000000..f3b052683 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/package.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - describes classes in gnu.java.beans package. + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. --> + +<html> +<head><title>GNU Classpath - gnu.java.beans</title></head> + +<body> +<p></p> + +</body> +</html> |