diff options
author | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
---|---|---|
committer | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
commit | 554fd8c5195424bdbcabf5de30fdc183aba391bd (patch) | |
tree | 976dc5ab7fddf506dadce60ae936f43f58787092 /libjava/classpath/gnu/java/beans/decoder | |
download | cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2 cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz |
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig;
imported gcc-4.6.4 source tree from verified upstream tarball.
downloading a git-generated archive based on the 'upstream' tag
should provide you with a source tree that is binary identical
to the one extracted from the above tarball.
if you have obtained the source via the command 'git clone',
however, do note that line-endings of files in your working
directory might differ from line-endings of the respective
files in the upstream repository.
Diffstat (limited to 'libjava/classpath/gnu/java/beans/decoder')
37 files changed, 4280 insertions, 0 deletions
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> |