diff options
author | tromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-09-23 19:36:46 +0000 |
---|---|---|
committer | tromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-09-23 19:36:46 +0000 |
commit | 49792907376493f0939563eb0219b96a48f1ae3b (patch) | |
tree | b2c2abf473309eac532cafbad81b20f3270ff45f /libjava/classpath/gnu | |
parent | 68cf394a99ed232a528346d711e946d4c9a902b5 (diff) | |
download | gcc-49792907376493f0939563eb0219b96a48f1ae3b.tar.gz |
Initial revision
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@104578 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava/classpath/gnu')
174 files changed, 35042 insertions, 0 deletions
diff --git a/libjava/classpath/gnu/CORBA/CDR/noHeaderInput.java b/libjava/classpath/gnu/CORBA/CDR/noHeaderInput.java new file mode 100644 index 00000000000..0c787ddc2df --- /dev/null +++ b/libjava/classpath/gnu/CORBA/CDR/noHeaderInput.java @@ -0,0 +1,166 @@ +/* noHeaderInput.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.CDR; + +import org.omg.CORBA.CustomMarshal; +import org.omg.CORBA.DataInputStream; +import org.omg.CORBA.MARSHAL; +import org.omg.CORBA.portable.BoxedValueHelper; +import org.omg.CORBA.portable.Streamable; +import org.omg.CORBA.portable.ValueFactory; + +import java.io.Serializable; + +/** + * Substitutes the main stream in factories when the header is already + * behind. Overrides methods that may be invoked from the factory, + * forcing not to read the header if called first time on this stream. + * + * This stream reverts to default behavior if one or more call are + * made (reading value types that are nested fields of the value type). + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +class noHeaderInput + extends cdrBufInput + implements DataInputStream +{ + /** + * If true, this is not the first call. + */ + boolean notFirst; + + /** + * Create an instance, reading from the given buffer. + */ + public noHeaderInput(byte[] buffer) + { + super(buffer); + } + + /** + * Read when knowning the class instance. + */ + public Serializable read_value(Class clz) + { + if (notFirst) + return super.read_value(clz); + else + { + try + { + notFirst = true; + return read_value((Serializable) clz.newInstance()); + } + catch (Exception ex) + { + MARSHAL m = new MARSHAL("Unable to create an instance"); + m.initCause(ex); + throw m; + } + } + } + + /** + * Tries to read using boxed value helper. + */ + public Serializable read_value(BoxedValueHelper helper) + { + if (notFirst) + return super.read_value(helper); + else + { + notFirst = true; + return helper.read_value(this); + } + } + + /** + * Tries to locate a factory using repository id. + */ + public Serializable read_value(String repository_id) + { + if (notFirst) + return super.read_value(repository_id); + else + { + notFirst = true; + + ValueFactory factory = + ((org.omg.CORBA_2_3.ORB) orb()).lookup_value_factory(repository_id); + if (factory == null) + throw new MARSHAL("No factory"); + return factory.read_value(this); + } + } + + /** + * Try to read when having an unitialised value. + */ + public Serializable read_value(Serializable value) + { + if (notFirst) + return super.read_value(value); + else + { + notFirst = true; + + // The user-defines io operations are implemented. + if (value instanceof CustomMarshal) + { + CustomMarshal marsh = (CustomMarshal) value; + try + { + marsh.unmarshal((DataInputStream) this); + } + catch (ClassCastException ex) + { + Vio.incorrect_plug_in(ex); + } + } + else + // The IDL-generated io operations are implemented. + if (value instanceof Streamable) + { + ((Streamable) value)._read(this); + } + return value; + } + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/DynAn/abstractDynAny.java b/libjava/classpath/gnu/CORBA/DynAn/abstractDynAny.java new file mode 100644 index 00000000000..47176c4b589 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/DynAn/abstractDynAny.java @@ -0,0 +1,177 @@ +/* abstractDynAny.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.DynAn; + +import gnu.CORBA.typeNamer; + +import org.omg.CORBA.Any; +import org.omg.CORBA.LocalObject; +import org.omg.CORBA.ORB; +import org.omg.CORBA.TypeCode; +import org.omg.DynamicAny.DynAnyPackage.TypeMismatch; + +import java.io.Serializable; + +/** + * The top of our DynAny implementation, this class provides ORB that is + * required to create anys and factory that is required to initialise DynAnys. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public abstract class abstractDynAny + extends LocalObject + implements Serializable +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * The "initial final_type" that can be an alias of the known final_type. + */ + public TypeCode official_type; + + /** + * The "basic" final_type to that the final_type finally evaluates. + */ + public final TypeCode final_type; + + /** + * The DynAny factory, required in initializations. + */ + public final gnuDynAnyFactory factory; + + /** + * The ORB, to that this DynAny belongs. + */ + public final ORB orb; + + /** + * The minor code, indicating the error, related to work with non - GNU + * Classpath DynAny. + */ + short MINOR = 8148; + + /** + * The message about the empty structure or exception. + */ + static final String EMPTY = "Empty structure with no fields."; + + /** + * The message about the structure or exception size mismatch. + */ + static final String SIZE = "Size mismatch."; + + /** + * The message about the content of this DynAny being equal to + * <code>null</code> + */ + static final String ISNULL = "The content is null"; + + /** + * The change value listener. + */ + valueChangedListener listener; + + /** + * Create the abstract dyn any. + */ + public abstractDynAny(TypeCode oType, TypeCode aType, + gnuDynAnyFactory aFactory, ORB anOrb + ) + { + official_type = oType; + final_type = aType; + factory = aFactory; + orb = anOrb; + } + + /** + * Get the typecode. + */ + public TypeCode type() + { + return official_type; + } + + /** + * Create the Any. + */ + public Any createAny() + { + return orb.create_any(); + } + + /** + * The "value changed" listener. + */ + protected void valueChanged() + { + if (listener != null) + listener.changed(); + } + + /** + * Check the type. + */ + void checkType(TypeCode expected, TypeCode actual) + throws TypeMismatch + { + if (!expected.equal(actual)) + throw new TypeMismatch(typeMismatch(expected, actual)); + } + + /** + * Format "Type mismatch" string. + */ + String typeMismatch(TypeCode expected, TypeCode actual) + { + return typeNamer.nameIt(expected) + " expected " + + typeNamer.nameIt(actual); + } + + /** + * Format "size mismatch" string. + */ + String sizeMismatch(int here, int other) + { + return "Size mismatch, " + other + " (expected " + here + ")"; + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/DynAn/abstractRecord.java b/libjava/classpath/gnu/CORBA/DynAn/abstractRecord.java new file mode 100644 index 00000000000..8d8b7a559b1 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/DynAn/abstractRecord.java @@ -0,0 +1,405 @@ +/* abstractRecord.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.DynAn; + +import gnu.CORBA.Unexpected; +import gnu.CORBA.holderFactory; + +import org.omg.CORBA.Any; +import org.omg.CORBA.ORB; +import org.omg.CORBA.TCKind; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.TypeCodePackage.BadKind; +import org.omg.CORBA.TypeCodePackage.Bounds; +import org.omg.CORBA.portable.Streamable; +import org.omg.DynamicAny.DynAny; +import org.omg.DynamicAny.DynAnyPackage.InvalidValue; +import org.omg.DynamicAny.DynAnyPackage.TypeMismatch; +import org.omg.DynamicAny.DynStruct; +import org.omg.DynamicAny.DynValueCommonOperations; +import org.omg.DynamicAny.NameDynAnyPair; +import org.omg.DynamicAny.NameValuePair; + +import java.io.Serializable; + +import java.lang.reflect.Field; + +/** + * A shared base for both dynamic structure an dynamic value final_type. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public abstract class abstractRecord + extends anyDivideable + implements DynAny, Serializable +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + String[] fNames; + + /** + * Creates the structure with the given typecode. + * + * @param fields The DynAny's, representing the fields of the structure. + */ + public abstractRecord(TypeCode oType, TypeCode aType, + gnuDynAnyFactory aFactory, ORB anOrb + ) + { + super(oType, aType, aFactory, anOrb); + } + + /** @inheritDoc */ + public TCKind current_member_kind() + throws TypeMismatch, InvalidValue + { + if (array.length == 0) + throw new TypeMismatch(EMPTY); + try + { + return final_type.member_type(pos).kind(); + } + catch (BadKind e) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(e); + throw t; + } + catch (Bounds e) + { + InvalidValue t = new InvalidValue(); + t.initCause(e); + throw t; + } + } + + /** @inheritDoc */ + public String current_member_name() + throws TypeMismatch, InvalidValue + { + if (array.length == 0) + throw new TypeMismatch(EMPTY); + try + { + return final_type.member_name(pos); + } + catch (BadKind e) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(e); + throw t; + } + catch (Bounds e) + { + InvalidValue t = new InvalidValue(); + t.initCause(e); + throw t; + } + } + + /** + * Get content of the structure. This method must be defined on a different + * name because get_members_as_dyn_any() throws exception only in some of the + * supported interfaces. + */ + public NameDynAnyPair[] gnu_get_members_as_dyn_any() + { + NameDynAnyPair[] r = new NameDynAnyPair[ array.length ]; + for (int i = 0; i < r.length; i++) + { + try + { + r [ i ] = new NameDynAnyPair(fNames [ i ], array [ i ]); + } + catch (Exception ex) + { + throw new Unexpected(ex); + } + } + return r; + } + + /** + * Get content of the structure. This method must be defined on a different + * name because get_members_as_dyn_any() throws exception only in some of the + * supported interfaces. + */ + public NameValuePair[] gnu_get_members() + { + NameValuePair[] r = new NameValuePair[ array.length ]; + for (int i = 0; i < r.length; i++) + { + try + { + r [ i ] = new NameValuePair(fNames [ i ], array [ i ].to_any()); + } + catch (Exception ex) + { + throw new Unexpected(ex); + } + } + return r; + } + + /** + * Set members from the provided array. + */ + public void set_members_as_dyn_any(NameDynAnyPair[] value) + throws TypeMismatch, InvalidValue + { + if (value.length != array.length) + throw new InvalidValue(sizeMismatch(array.length, value.length)); + + for (int i = 0; i < value.length; i++) + { + DynAny dynAny = value [ i ].value; + checkType(dynAny.type(), i); + checkName(value [ i ].id, i); + + array [ i ] = dynAny; + } + pos = 0; + } + + /** + * Check the name at the given position ("" matches everything). + */ + private void checkName(String xName, int i) + throws TypeMismatch + { + if (xName.length() > 0 && fNames [ i ].length() > 0) + if (!xName.equals(fNames [ i ])) + throw new TypeMismatch("Field name mismatch " + xName + " expected " + + fNames [ i ] + ); + } + + /** + * Check the type at the given position. + */ + private void checkType(TypeCode t, int i) + throws TypeMismatch + { + if (!array [ i ].type().equal(t)) + throw new TypeMismatch(typeMismatch(array [ i ].type(), t) + " field " + + i + ); + } + + /** + * Set members from the provided array. + */ + public void set_members(NameValuePair[] value) + throws TypeMismatch, InvalidValue + { + if (value.length != array.length) + throw new InvalidValue(sizeMismatch(array.length, value.length)); + + for (int i = 0; i < value.length; i++) + { + Any any = value [ i ].value; + checkType(any.type(), i); + checkName(value [ i ].id, i); + + array [ i ].from_any(any); + } + pos = 0; + } + + /** @inheritDoc */ + public void assign(DynAny from) + throws TypeMismatch + { + checkType(official_type, from.type()); + if (from instanceof DynStruct) + { + try + { + set_members_as_dyn_any(((DynStruct) from).get_members_as_dyn_any()); + } + catch (InvalidValue e) + { + TypeMismatch t = new TypeMismatch("Invalid value"); + t.initCause(e); + throw t; + } + } + else + throw new TypeMismatch("Not a DynStruct"); + } + + /** + * Create a copy. + */ + public DynAny copy() + { + DynAny[] c = new DynAny[ array.length ]; + for (int i = 0; i < c.length; i++) + { + c [ i ] = array [ i ].copy(); + } + + abstractRecord d = newInstance(official_type, final_type, factory, orb); + d.array = c; + return d; + } + + /** + * Create a new instance when copying. + */ + protected abstract abstractRecord newInstance(TypeCode oType, TypeCode aType, + gnuDynAnyFactory aFactory, + ORB anOrb + ); + + /** + * Done via reflection. + */ + public Any to_any() + { + try + { + Streamable sHolder = holderFactory.createHolder(official_type); + + Class sHolderClass = sHolder.getClass(); + Field sHolderValue = sHolderClass.getField("value"); + Class sClass = sHolderValue.getType(); + + Object structure = sClass.newInstance(); + Object member; + Any am; + Field vread; + Field vwrite; + Streamable memberHolder; + + for (int i = 0; i < array.length; i++) + { + am = array [ i ].to_any(); + memberHolder = am.extract_Streamable(); + vwrite = structure.getClass().getField(final_type.member_name(i)); + vread = memberHolder.getClass().getField("value"); + member = vread.get(memberHolder); + vwrite.set(structure, member); + } + + Any g = createAny(); + sHolderValue.set(sHolder, structure); + g.insert_Streamable(sHolder); + g.type(official_type); + return g; + } + catch (Exception e) + { + throw new Unexpected(e); + } + } + + /** + * Done via reflection. + */ + public void from_any(Any an_any) + throws TypeMismatch, InvalidValue + { + checkType(official_type, an_any.type()); + try + { + Streamable s = an_any.extract_Streamable(); + if (s == null) + { + if (this instanceof DynValueCommonOperations) + { + ((DynValueCommonOperations) this).set_to_null(); + return; + } + else + throw new InvalidValue(ISNULL); + } + + Object structure = s.getClass().getField("value").get(s); + if (structure == null && (this instanceof DynValueCommonOperations)) + { + ((DynValueCommonOperations) this).set_to_null(); + return; + } + + Any member; + Streamable holder; + Object field; + TypeCode fType; + Field fField; + + for (int i = 0; i < array.length; i++) + { + fField = structure.getClass().getField(fNames [ i ]); + field = fField.get(structure); + fType = array [ i ].type(); + holder = holderFactory.createHolder(fType); + + member = createAny(); + holder.getClass().getField("value").set(holder, field); + member.insert_Streamable(holder); + member.type(fType); + + array [ i ].from_any(member); + } + + if (this instanceof DynValueCommonOperations) + ((DynValueCommonOperations) this).set_to_value(); + } + catch (InvalidValue v) + { + throw v; + } + catch (NoSuchFieldException ex) + { + TypeMismatch v = + new TypeMismatch("holder value does not match typecode"); + v.initCause(ex); + throw v; + } + catch (Exception ex) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(ex); + throw t; + } + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/DynAn/anyDivideable.java b/libjava/classpath/gnu/CORBA/DynAn/anyDivideable.java new file mode 100644 index 00000000000..5f52c8078eb --- /dev/null +++ b/libjava/classpath/gnu/CORBA/DynAn/anyDivideable.java @@ -0,0 +1,514 @@ +/* anyDivideable.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.DynAn; + +import gnu.CORBA.typeNamer; + +import org.omg.CORBA.Any; +import org.omg.CORBA.CompletionStatus; +import org.omg.CORBA.ORB; +import org.omg.CORBA.Object; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.UNKNOWN; +import org.omg.DynamicAny.DynAny; +import org.omg.DynamicAny.DynAnyPackage.InvalidValue; +import org.omg.DynamicAny.DynAnyPackage.TypeMismatch; +import org.omg.DynamicAny.DynValueCommon; + +import java.io.Serializable; + +/** + * Provides a base for DynAnys, having multiple components. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public abstract class anyDivideable + extends abstractDynAny + implements Serializable +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * The array of the components that in general case may have different + * final_type. + */ + protected DynAny[] array; + + /** + * The internal pointer. + */ + protected int pos = 0; + + public anyDivideable(TypeCode oType, TypeCode aType, + gnuDynAnyFactory aFactory, ORB anOrb + ) + { + super(oType, aType, aFactory, anOrb); + } + + /** + * Advance forward. + */ + public boolean next() + { + pos++; + return array.length > pos; + } + + /** + * Set zero position. + */ + public void rewind() + { + pos = 0; + } + + /** + * Set a position. + */ + public boolean seek(int p) + { + pos = p; + return pos >= 0 && array.length > pos; + } + + /** + * Get the insertion point as DynAny. This method may throw exceptions if the + * current insertion point does not support reading or insertion of the + * primitive types. + * + * @return the focused component, from where the primitve value can be read or + * where it can be inserted. + * @throws InvalidValue if the primitive value cannot be inserted at the given + * point. + */ + protected DynAny focused() + throws InvalidValue, TypeMismatch + { + if (pos >= 0 && pos < array.length) + { + if (array [ pos ].component_count() == 0) + return array [ pos ]; + else + throw new TypeMismatch("Multiple coponents at " + pos); + } + else + throw new InvalidValue("Out of bounds at " + pos + " valid 0.." + + (array.length - 1) + ); + } + + /** {@inheritDoc} */ + public int component_count() + { + return array.length; + } + + /** + * Return the second (enclosed any) that is stored in the wrapped Any. + */ + public Any get_any() + throws TypeMismatch, InvalidValue + { + return focused().get_any(); + } + + /** {@inheritDoc} */ + public boolean get_boolean() + throws TypeMismatch, InvalidValue + { + return focused().get_boolean(); + } + + /** {@inheritDoc} */ + public char get_char() + throws TypeMismatch, InvalidValue + { + return focused().get_char(); + } + + /** {@inheritDoc} */ + public double get_double() + throws TypeMismatch, InvalidValue + { + return focused().get_double(); + } + + /** {@inheritDoc} */ + public float get_float() + throws TypeMismatch, InvalidValue + { + return focused().get_float(); + } + + /** {@inheritDoc} */ + public int get_long() + throws TypeMismatch, InvalidValue + { + return focused().get_long(); + } + + /** {@inheritDoc} */ + public long get_longlong() + throws TypeMismatch, InvalidValue + { + return focused().get_longlong(); + } + + /** {@inheritDoc} */ + public byte get_octet() + throws TypeMismatch, InvalidValue + { + return focused().get_octet(); + } + + /** {@inheritDoc} */ + public Object get_reference() + throws TypeMismatch, InvalidValue + { + return focused().get_reference(); + } + + /** {@inheritDoc} */ + public short get_short() + throws TypeMismatch, InvalidValue + { + return focused().get_short(); + } + + /** {@inheritDoc} */ + public String get_string() + throws TypeMismatch, InvalidValue + { + return focused().get_string(); + } + + /** {@inheritDoc} */ + public TypeCode get_typecode() + throws TypeMismatch, InvalidValue + { + return focused().get_typecode(); + } + + /** {@inheritDoc} */ + public int get_ulong() + throws TypeMismatch, InvalidValue + { + return focused().get_ulong(); + } + + /** {@inheritDoc} */ + public long get_ulonglong() + throws TypeMismatch, InvalidValue + { + return focused().get_ulonglong(); + } + + /** {@inheritDoc} */ + public short get_ushort() + throws TypeMismatch, InvalidValue + { + return focused().get_ushort(); + } + + /** {@inheritDoc} */ + public Serializable get_val() + throws TypeMismatch, InvalidValue + { + if (pos >= 0 && pos < array.length) + { + if (array [ pos ] instanceof DynValueCommon) + return array [ pos ].get_val(); + else + throw new TypeMismatch(); + } + else + throw new InvalidValue("Out of bounds at " + pos + " valid 0.." + + (array.length - 1) + ); + } + + /** {@inheritDoc} */ + public char get_wchar() + throws TypeMismatch, InvalidValue + { + return focused().get_wchar(); + } + + /** {@inheritDoc} */ + public String get_wstring() + throws TypeMismatch, InvalidValue + { + return focused().get_wstring(); + } + + /** {@inheritDoc} */ + public void insert_any(Any a_x) + throws TypeMismatch, InvalidValue + { + focused().insert_any(a_x); + valueChanged(); + } + + /** {@inheritDoc} */ + public void insert_boolean(boolean a_x) + throws InvalidValue, TypeMismatch + { + focused().insert_boolean(a_x); + valueChanged(); + } + + /** {@inheritDoc} */ + public void insert_char(char a_x) + throws InvalidValue, TypeMismatch + { + focused().insert_char(a_x); + valueChanged(); + } + + /** {@inheritDoc} */ + public void insert_double(double a_x) + throws InvalidValue, TypeMismatch + { + focused().insert_double(a_x); + valueChanged(); + } + + /** {@inheritDoc} */ + public void insert_float(float a_x) + throws InvalidValue, TypeMismatch + { + focused().insert_float(a_x); + valueChanged(); + } + + /** {@inheritDoc} */ + public void insert_long(int a_x) + throws InvalidValue, TypeMismatch + { + focused().insert_long(a_x); + valueChanged(); + } + + /** {@inheritDoc} */ + public void insert_longlong(long a_x) + throws InvalidValue, TypeMismatch + { + focused().insert_longlong(a_x); + valueChanged(); + } + + /** {@inheritDoc} */ + public void insert_octet(byte a_x) + throws InvalidValue, TypeMismatch + { + focused().insert_octet(a_x); + valueChanged(); + } + + /** {@inheritDoc} */ + public void insert_reference(Object a_x) + throws InvalidValue, TypeMismatch + { + focused().insert_reference(a_x); + valueChanged(); + } + + /** {@inheritDoc} */ + public void insert_short(short a_x) + throws InvalidValue, TypeMismatch + { + focused().insert_short(a_x); + valueChanged(); + } + + /** {@inheritDoc} */ + public void insert_string(String a_x) + throws InvalidValue, TypeMismatch + { + focused().insert_string(a_x); + valueChanged(); + } + + /** {@inheritDoc} */ + public void insert_typecode(TypeCode a_x) + throws InvalidValue, TypeMismatch + { + focused().insert_typecode(a_x); + valueChanged(); + } + + /** {@inheritDoc} */ + public void insert_ulong(int a_x) + throws InvalidValue, TypeMismatch + { + focused().insert_ulong(a_x); + valueChanged(); + } + + /** {@inheritDoc} */ + public void insert_ulonglong(long a_x) + throws InvalidValue, TypeMismatch + { + focused().insert_ulonglong(a_x); + valueChanged(); + } + + /** {@inheritDoc} */ + public void insert_ushort(short a_x) + throws InvalidValue, TypeMismatch + { + focused().insert_ushort(a_x); + valueChanged(); + } + + /** {@inheritDoc} */ + public void insert_val(Serializable a_x) + throws InvalidValue, TypeMismatch + { + if (pos >= 0 && pos < array.length) + { + if (array [ pos ] instanceof DynValueCommon) + array [ pos ].insert_val(a_x); + else + throw new TypeMismatch(); + } + else + throw new InvalidValue("Out of bounds at " + pos + " valid 0.." + + (array.length - 1) + ); + valueChanged(); + } + + /** {@inheritDoc} */ + public void insert_wchar(char a_x) + throws InvalidValue, TypeMismatch + { + focused().insert_wchar(a_x); + valueChanged(); + } + + /** {@inheritDoc} */ + public void insert_wstring(String a_x) + throws InvalidValue, TypeMismatch + { + focused().insert_wstring(a_x); + valueChanged(); + } + + /** {@inheritDoc} */ + public DynAny get_dyn_any() + throws TypeMismatch, InvalidValue + { + return focused().get_dyn_any(); + } + + /** {@inheritDoc} */ + public void insert_dyn_any(DynAny insert_it) + throws TypeMismatch, InvalidValue + { + focused().insert_dyn_any(insert_it); + } + + /** + * Get current component. + * + * @return current component or <code>null</code> if the pointer is out of + * bounds. + */ + public DynAny current_component() + throws TypeMismatch + { + if (array.length == 0) + throw new TypeMismatch("empty"); + return (pos >= 0 && pos < array.length) ? array [ pos ] : null; + } + + /** + * No action, cleanup is done by garbage collector in java. + */ + public void destroy() + { + } + + /** + * Involved in equal(DynAny). + */ + public abstract Any to_any() + throws TypeMismatch; + + /** + * Compares with other DynAny for equality. The final_type, array size and + * array members must match. + */ + public boolean equal(DynAny other) + { + try + { + if (!official_type.equal(other.type())) + return false; + else if (other instanceof anyDivideable) + { + anyDivideable x = (anyDivideable) other; + if (x.array.length != array.length) + return false; + + for (int i = 0; i < array.length; i++) + { + if (!array [ i ].equal(x.array [ i ])) + return false; + } + return true; + } + else if (other == null || other instanceof abstractDynAny) + return false; + else + return other.to_any().equal(to_any()); + } + catch (TypeMismatch e) + { + UNKNOWN u = new UNKNOWN(MINOR, CompletionStatus.COMPLETED_NO); + u.initCause(e); + throw u; + } + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/DynAn/anyUndivideable.java b/libjava/classpath/gnu/CORBA/DynAn/anyUndivideable.java new file mode 100644 index 00000000000..b31a6b357f9 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/DynAn/anyUndivideable.java @@ -0,0 +1,493 @@ +/* Undivideable.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.DynAn; + +import java.io.Serializable; + +import org.omg.CORBA.Any; +import org.omg.CORBA.ORB; +import org.omg.CORBA.Object; +import org.omg.CORBA.TypeCode; +import org.omg.DynamicAny.DynAny; +import org.omg.DynamicAny.DynAnyPackage.InvalidValue; +import org.omg.DynamicAny.DynAnyPackage.TypeMismatch; + +/** + * Represent DynAny that has no internal components (DynEnum and so on). The + * methods, related to internal components, throw exceptions or return agreed + * values like null. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public abstract class anyUndivideable + extends abstractDynAny + implements Serializable +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * Create a new instance with the given typecode. + */ + public anyUndivideable(TypeCode oType, TypeCode aType, + gnuDynAnyFactory aFactory, ORB anOrb) + { + super(oType, aType, aFactory, anOrb); + } + + /** + * There are no components. + * + * @return 0, always. + */ + public int component_count() + { + return 0; + } + + /** + * There is no current component. + * + * @throws TypeMismatch, always. + */ + public DynAny current_component() + throws TypeMismatch + { + throw new TypeMismatch("Not applicable"); + } + + /** + * Returns without action. + */ + public void destroy() + { + } + + /** + * Not in use. + */ + public Any get_any() + throws TypeMismatch, InvalidValue + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public boolean get_boolean() + throws TypeMismatch, InvalidValue + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public char get_char() + throws TypeMismatch, InvalidValue + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public double get_double() + throws TypeMismatch, InvalidValue + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public DynAny get_dyn_any() + throws TypeMismatch, InvalidValue + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public float get_float() + throws TypeMismatch, InvalidValue + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public int get_long() + throws TypeMismatch, InvalidValue + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public long get_longlong() + throws TypeMismatch, InvalidValue + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public byte get_octet() + throws TypeMismatch, InvalidValue + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public Object get_reference() + throws TypeMismatch, InvalidValue + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public short get_short() + throws TypeMismatch, InvalidValue + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public String get_string() + throws TypeMismatch, InvalidValue + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public TypeCode get_typecode() + throws TypeMismatch, InvalidValue + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public int get_ulong() + throws TypeMismatch, InvalidValue + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public long get_ulonglong() + throws TypeMismatch, InvalidValue + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public short get_ushort() + throws TypeMismatch, InvalidValue + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public Serializable get_val() + throws TypeMismatch, InvalidValue + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public char get_wchar() + throws TypeMismatch, InvalidValue + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public String get_wstring() + throws TypeMismatch, InvalidValue + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public void insert_any(Any an_any) + throws TypeMismatch, InvalidValue + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public void insert_boolean(boolean a_x) + throws InvalidValue, TypeMismatch + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public void insert_char(char a_x) + throws InvalidValue, TypeMismatch + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public void insert_double(double a_x) + throws InvalidValue, TypeMismatch + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public void insert_dyn_any(DynAny insert_it) + throws TypeMismatch, InvalidValue + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public void insert_float(float a_x) + throws InvalidValue, TypeMismatch + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public void insert_long(int a_x) + throws InvalidValue, TypeMismatch + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public void insert_longlong(long a_x) + throws InvalidValue, TypeMismatch + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public void insert_octet(byte a_x) + throws InvalidValue, TypeMismatch + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public void insert_reference(Object a_x) + throws InvalidValue, TypeMismatch + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public void insert_short(short a_x) + throws InvalidValue, TypeMismatch + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public void insert_string(String a_x) + throws InvalidValue, TypeMismatch + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public void insert_typecode(TypeCode a_x) + throws InvalidValue, TypeMismatch + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public void insert_ulong(int a_x) + throws InvalidValue, TypeMismatch + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public void insert_ulonglong(long a_x) + throws InvalidValue, TypeMismatch + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public void insert_ushort(short a_x) + throws InvalidValue, TypeMismatch + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public void insert_val(Serializable a_x) + throws InvalidValue, TypeMismatch + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public void insert_wchar(char a_x) + throws InvalidValue, TypeMismatch + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public void insert_wstring(String a_x) + throws InvalidValue, TypeMismatch + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public boolean next() + { + return false; + } + + /** + * Not in use. + */ + public void rewind() + { + } + + /** + * Not in use. + */ + public boolean seek(int p) + { + return false; + } + + /** + * Get the typecode of this enumeration. + */ + public TypeCode type() + { + return official_type; + } + + /** + * Compares with other DynAny for equality. + */ + public boolean equals(java.lang.Object other) + { + if (other instanceof DynAny) + return equal((DynAny) other); + else + return false; + } + + /** + * This depends on an object. + */ + public abstract boolean equal(DynAny other); + +} diff --git a/libjava/classpath/gnu/CORBA/DynAn/gnuDynAny.java b/libjava/classpath/gnu/CORBA/DynAn/gnuDynAny.java new file mode 100644 index 00000000000..015628ebf90 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/DynAn/gnuDynAny.java @@ -0,0 +1,945 @@ +/* gnuDynAny.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.DynAn; + +import gnu.CORBA.CDR.cdrBufOutput; +import gnu.CORBA.OctetHolder; +import gnu.CORBA.Unexpected; +import gnu.CORBA.WCharHolder; +import gnu.CORBA.WStringHolder; +import gnu.CORBA.holderFactory; +import gnu.CORBA.typeNamer; +import gnu.CORBA.universalHolder; + +import org.omg.CORBA.Any; +import org.omg.CORBA.AnyHolder; +import org.omg.CORBA.BooleanHolder; +import org.omg.CORBA.CharHolder; +import org.omg.CORBA.DoubleHolder; +import org.omg.CORBA.FloatHolder; +import org.omg.CORBA.IntHolder; +import org.omg.CORBA.LongHolder; +import org.omg.CORBA.MARSHAL; +import org.omg.CORBA.ORB; +import org.omg.CORBA.Object; +import org.omg.CORBA.ObjectHolder; +import org.omg.CORBA.ShortHolder; +import org.omg.CORBA.StringHolder; +import org.omg.CORBA.TCKind; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.TypeCodeHolder; +import org.omg.CORBA.TypeCodePackage.BadKind; +import org.omg.CORBA.ValueBaseHolder; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.Streamable; +import org.omg.DynamicAny.DynAny; +import org.omg.DynamicAny.DynAnyPackage.InvalidValue; +import org.omg.DynamicAny.DynAnyPackage.TypeMismatch; + +import java.io.IOException; +import java.io.Serializable; + +import java.util.Arrays; + +/** + * The primitive dynamic Any holds the value basic final_type that cannot be + * traversed. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuDynAny extends abstractDynAny implements DynAny, Serializable +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * The enclosed Streamable, holding the actual value. + */ + protected Streamable holder; + + /** + * Create DynAny providing the holder. + * + * @param a_holder + */ + public gnuDynAny(Streamable aHolder, TypeCode oType, TypeCode aType, + gnuDynAnyFactory aFactory, ORB anOrb + ) + { + super(oType, aType, aFactory, anOrb); + holder = aHolder; + } + + /** + * Assign the contents of the given {@link DynAny} to this DynAny. + * + * @param from the source to assign from. + */ + public void assign(DynAny from) throws TypeMismatch + { + checkType(official_type, from.type()); + + if (from instanceof gnuDynAny) + holder = ((gnuDynAny) from).holder; + else + holder = from.to_any().extract_Streamable(); + valueChanged(); + } + + /** + * Create a copy of this {@link DynAny} via buffer read/write. + */ + public DynAny copy() + { + if (holder != null) + { + cdrBufOutput buffer = new cdrBufOutput(); + holder._write(buffer); + + gnuDynAny other; + try + { + other = + new gnuDynAny((Streamable) (holder.getClass().newInstance()), + official_type, final_type, factory, orb + ); + } + catch (Exception e) + { + // Holder must have parameterless constructor. + throw new Unexpected(e); + } + other.holder._read(buffer.create_input_stream()); + return other; + } + else + { + return new gnuDynAny(null, official_type, final_type, factory, orb); + } + } + + /** + * Always returns <code>null</code>. + * + * @return <code>null</code>, always. + */ + public DynAny current_component() throws TypeMismatch + { + throw new TypeMismatch("Not applicable for " + + typeNamer.nameIt(final_type) + ); + } + + /** + * Returns without action, leaving all work to the garbage collector. + */ + public void destroy() + { + } + + /** + * Takes the passed parameter as the enclosed {@link Any} reference. + * + * @param an_any the {@link Any} that will be used as an enclosed reference. + * + * @throws TypeMismatch if the final_type of the passed Any is not the same as + * the final_type, currently stored in this Any. + */ + public void from_any(Any an_any) throws TypeMismatch, InvalidValue + { + checkType(official_type, an_any.type()); + + Streamable a_holder = an_any.extract_Streamable(); + if (a_holder == null) + { + throw new InvalidValue(ISNULL); + } + else if (a_holder instanceof universalHolder) + { + holder = holderFactory.createHolder(official_type); + if (holder == null) + holder = holderFactory.createHolder(final_type); + + if (holder == null) + holder = ((universalHolder) a_holder).Clone(); + else + { + InputStream in = an_any.create_input_stream(); + holder._read(in); + try + { + in.close(); + } + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + } + else + { + try + { + InputStream in = an_any.create_input_stream(); + holder = (Streamable) a_holder.getClass().newInstance(); + holder._read(in); + in.close(); + } + catch (Exception ex) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(ex); + throw t; + } + } + valueChanged(); + } + + /** + * Return the second (enclosed any) that is stored in the wrapped Any. + */ + public Any get_any() throws TypeMismatch + { + try + { + return ((AnyHolder) holder).value; + } + catch (ClassCastException cex) + { + TypeMismatch m = new TypeMismatch(); + m.initCause(cex); + throw m; + } + } + + /** {@inheritDoc} */ + public boolean get_boolean() throws TypeMismatch + { + try + { + return ((BooleanHolder) holder).value; + } + catch (ClassCastException cex) + { + TypeMismatch m = new TypeMismatch(); + m.initCause(cex); + throw m; + } + } + + /** {@inheritDoc} */ + public char get_char() throws TypeMismatch + { + try + { + return ((CharHolder) holder).value; + } + catch (ClassCastException cex) + { + TypeMismatch m = new TypeMismatch(); + m.initCause(cex); + throw m; + } + } + + /** {@inheritDoc} */ + public double get_double() throws TypeMismatch + { + try + { + return ((DoubleHolder) holder).value; + } + catch (ClassCastException cex) + { + TypeMismatch m = new TypeMismatch(); + m.initCause(cex); + throw m; + } + } + + /** {@inheritDoc} */ + public float get_float() throws TypeMismatch + { + try + { + return ((FloatHolder) holder).value; + } + catch (ClassCastException cex) + { + TypeMismatch m = new TypeMismatch(); + m.initCause(cex); + throw m; + } + } + + /** {@inheritDoc} */ + public int get_long() throws TypeMismatch + { + try + { + return ((IntHolder) holder).value; + } + catch (ClassCastException cex) + { + TypeMismatch m = new TypeMismatch(); + m.initCause(cex); + throw m; + } + } + + /** {@inheritDoc} */ + public long get_longlong() throws TypeMismatch + { + try + { + return ((LongHolder) holder).value; + } + catch (ClassCastException cex) + { + TypeMismatch m = new TypeMismatch(); + m.initCause(cex); + throw m; + } + } + + /** {@inheritDoc} */ + public byte get_octet() throws TypeMismatch + { + try + { + return ((OctetHolder) holder).value; + } + catch (ClassCastException cex) + { + TypeMismatch m = new TypeMismatch(); + m.initCause(cex); + throw m; + } + } + + /** {@inheritDoc} */ + public Object get_reference() throws TypeMismatch + { + try + { + return ((ObjectHolder) holder).value; + } + catch (ClassCastException cex) + { + TypeMismatch m = new TypeMismatch(); + m.initCause(cex); + throw m; + } + } + + /** {@inheritDoc} */ + public short get_short() throws TypeMismatch + { + try + { + return ((ShortHolder) holder).value; + } + catch (ClassCastException cex) + { + TypeMismatch m = new TypeMismatch(); + m.initCause(cex); + throw m; + } + } + + /** {@inheritDoc} */ + public String get_string() throws TypeMismatch + { + try + { + return ((StringHolder) holder).value; + } + catch (ClassCastException cex) + { + TypeMismatch m = new TypeMismatch(); + m.initCause(cex); + throw m; + } + } + + /** {@inheritDoc} */ + public TypeCode get_typecode() throws TypeMismatch + { + try + { + return ((TypeCodeHolder) holder).value; + } + catch (ClassCastException cex) + { + TypeMismatch m = new TypeMismatch(); + m.initCause(cex); + throw m; + } + } + + /** {@inheritDoc} */ + public int get_ulong() throws TypeMismatch + { + check(TCKind.tk_ulong); + return get_long(); + } + + /** {@inheritDoc} */ + public long get_ulonglong() throws TypeMismatch + { + check(TCKind.tk_ulonglong); + return get_longlong(); + } + + /** {@inheritDoc} */ + public short get_ushort() throws TypeMismatch + { + check(TCKind.tk_ushort); + return get_short(); + } + + /** {@inheritDoc} */ + public Serializable get_val() throws TypeMismatch + { + try + { + return ((ValueBaseHolder) holder).value; + } + catch (ClassCastException cex) + { + TypeMismatch m = new TypeMismatch(); + m.initCause(cex); + throw m; + } + } + + /** {@inheritDoc} */ + public char get_wchar() throws TypeMismatch + { + try + { + return ((WCharHolder) holder).value; + } + catch (ClassCastException cex) + { + TypeMismatch m = new TypeMismatch(); + m.initCause(cex); + throw m; + } + } + + /** {@inheritDoc} */ + public String get_wstring() throws TypeMismatch + { + try + { + return ((WStringHolder) holder).value; + } + catch (ClassCastException cex) + { + TypeMismatch m = new TypeMismatch(); + m.initCause(cex); + throw m; + } + } + + /** {@inheritDoc} */ + public void insert_any(Any a_x) throws TypeMismatch, InvalidValue + { + try + { + if (a_x.type().kind().value() == TCKind._tk_null) + ((AnyHolder) holder).value = a_x; + else + { + OutputStream buf = a_x.create_output_stream(); + buf.write_any(a_x); + holder._read(buf.create_input_stream()); + buf.close(); + } + valueChanged(); + } + catch (ClassCastException cex) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(cex); + throw t; + } + catch (MARSHAL m) + { + InvalidValue v = new InvalidValue(); + v.initCause(m); + throw v; + } + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** {@inheritDoc} */ + public void insert_boolean(boolean a_x) throws InvalidValue, TypeMismatch + { + try + { + ((BooleanHolder) holder).value = a_x; + valueChanged(); + } + catch (ClassCastException cex) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(cex); + throw t; + } + } + + /** {@inheritDoc} */ + public void insert_char(char a_x) throws InvalidValue, TypeMismatch + { + try + { + ((CharHolder) holder).value = a_x; + valueChanged(); + } + catch (ClassCastException cex) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(cex); + throw t; + } + } + + /** {@inheritDoc} */ + public void insert_double(double a_x) throws InvalidValue, TypeMismatch + { + try + { + ((DoubleHolder) holder).value = a_x; + valueChanged(); + } + catch (ClassCastException cex) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(cex); + throw t; + } + } + + /** {@inheritDoc} */ + public void insert_float(float a_x) throws InvalidValue, TypeMismatch + { + try + { + ((FloatHolder) holder).value = a_x; + valueChanged(); + } + catch (ClassCastException cex) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(cex); + throw t; + } + } + + /** {@inheritDoc} */ + public void insert_long(int a_x) throws InvalidValue, TypeMismatch + { + try + { + ((IntHolder) holder).value = a_x; + valueChanged(); + } + catch (ClassCastException cex) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(cex); + throw t; + } + } + + /** {@inheritDoc} */ + public void insert_longlong(long a_x) throws InvalidValue, TypeMismatch + { + try + { + ((LongHolder) holder).value = a_x; + valueChanged(); + } + catch (ClassCastException cex) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(cex); + throw t; + } + } + + /** {@inheritDoc} */ + public void insert_octet(byte a_x) throws InvalidValue, TypeMismatch + { + try + { + ((OctetHolder) holder).value = a_x; + valueChanged(); + } + catch (ClassCastException cex) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(cex); + throw t; + } + } + + /** {@inheritDoc} */ + public void insert_reference(Object a_x) throws InvalidValue, TypeMismatch + { + try + { + ((ObjectHolder) holder).value = a_x; + valueChanged(); + } + catch (ClassCastException cex) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(cex); + throw t; + } + } + + /** {@inheritDoc} */ + public void insert_short(short a_x) throws InvalidValue, TypeMismatch + { + try + { + ((ShortHolder) holder).value = a_x; + valueChanged(); + } + catch (ClassCastException cex) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(cex); + throw t; + } + } + + /** {@inheritDoc} */ + public void insert_string(String a_x) throws InvalidValue, TypeMismatch + { + try + { + if (a_x != null && + final_type.length() > 0 && + a_x.length() > final_type.length() + ) + throw new InvalidValue(a_x.length() + " exceeds bound, " + + final_type.length() + ); + ((StringHolder) holder).value = a_x; + valueChanged(); + } + catch (ClassCastException cex) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(cex); + throw t; + } + catch (BadKind e) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(e); + throw t; + } + } + + /** {@inheritDoc} */ + public void insert_typecode(TypeCode a_x) throws InvalidValue, TypeMismatch + { + try + { + ((TypeCodeHolder) holder).value = a_x; + valueChanged(); + } + catch (ClassCastException cex) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(cex); + throw t; + } + } + + /** {@inheritDoc} */ + public void insert_ulong(int a_x) throws InvalidValue, TypeMismatch + { + try + { + ((IntHolder) holder).value = a_x; + valueChanged(); + } + catch (ClassCastException cex) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(cex); + throw t; + } + } + + /** {@inheritDoc} */ + public void insert_ulonglong(long a_x) throws InvalidValue, TypeMismatch + { + try + { + ((LongHolder) holder).value = a_x; + valueChanged(); + } + catch (ClassCastException cex) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(cex); + throw t; + } + } + + /** {@inheritDoc} */ + public void insert_ushort(short a_x) throws InvalidValue, TypeMismatch + { + try + { + ((ShortHolder) holder).value = a_x; + valueChanged(); + } + catch (ClassCastException cex) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(cex); + throw t; + } + } + + /** {@inheritDoc} */ + public void insert_val(Serializable a_x) throws InvalidValue, TypeMismatch + { + try + { + ((ValueBaseHolder) holder).value = a_x; + valueChanged(); + } + catch (ClassCastException cex) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(cex); + throw t; + } + } + + /** {@inheritDoc} */ + public void insert_wchar(char a_x) throws InvalidValue, TypeMismatch + { + try + { + ((WCharHolder) holder).value = a_x; + valueChanged(); + } + catch (ClassCastException cex) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(cex); + throw t; + } + } + + /** {@inheritDoc} */ + public void insert_wstring(String a_x) throws InvalidValue, TypeMismatch + { + try + { + if (a_x != null && + final_type.length() > 0 && + a_x.length() > type().length() + ) + throw new InvalidValue(a_x.length() + " exceeds bound, " + + final_type.length() + ); + ((WStringHolder) holder).value = a_x; + valueChanged(); + } + catch (ClassCastException cex) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(cex); + throw t; + } + catch (BadKind e) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(e); + throw t; + } + } + + /** + * The objects, enclosed inside this class, have only one component (self). + * + * @return false, always (no other action). + */ + public boolean next() + { + return false; + } + + /** + * Returns without action. + */ + public void rewind() + { + } + + /** + * This objects, stored in this wrapper, never have multiple internal + * components to seek. + * + * @return false, always (no other action). + */ + public boolean seek(int p) + { + return false; + } + + /** + * Returns the enclosed {@link Any}. + * + * @return the enclosed {@link Any}. + */ + public Any to_any() + { + Any a = createAny(); + a.insert_Streamable(holder); + a.type(official_type); + return a; + } + + /** {@inheritDoc} */ + public TypeCode type() + { + return official_type; + } + + /** + * Compute hashcode in a trivial way. + */ + protected int getHashCodeSimple(int maximum) + { + int h = super.hashCode() / 2; + if (h < 0) + h = -h; + return h % maximum; + } + + /** + * Inserts Any, contained in the parameter, into Any, contained in this + * DynAny. + */ + public void insert_dyn_any(DynAny d) throws TypeMismatch, InvalidValue + { + check(d.type().kind()); + + Any a = d.to_any(); + holder = a.extract_Streamable(); + valueChanged(); + } + + /** + * Checks for equality. The DynAnys are equal if the stored Anys are equal. + */ + public boolean equal(DynAny other) + { + if (other instanceof abstractDynAny) + { + if (other instanceof gnuDynAny) + { + gnuDynAny x = (gnuDynAny) other; + + if (!x.holder.getClass().equals(holder.getClass())) + return false; + + cdrBufOutput b1 = new cdrBufOutput(); + x.holder._write(b1); + + cdrBufOutput b2 = new cdrBufOutput(b1.buffer.size() + 10); + holder._write(b2); + + return Arrays.equals(b1.buffer.toByteArray(), + b2.buffer.toByteArray() + ); + } + else + return false; + } + if (other == null) + return false; + else if (other.component_count() != component_count() || + !official_type.equal(other.type()) + ) + return false; + else + return other.to_any().equal(to_any()); + } + + /** + * This final_type has no components. + * + * @return 0, always. + */ + public int component_count() + { + return 0; + } + + public DynAny get_dyn_any() throws TypeMismatch, InvalidValue + { + return new gnuDynAny(holder, official_type, final_type, factory, orb); + } + + private void check(TCKind t) throws TypeMismatch + { + if (t.value() != final_type.kind().value()) + throw new TypeMismatch(t.value() + "!=" + final_type.kind().value()); + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/DynAn/gnuDynAnyFactory.java b/libjava/classpath/gnu/CORBA/DynAn/gnuDynAnyFactory.java new file mode 100644 index 00000000000..dd1762890de --- /dev/null +++ b/libjava/classpath/gnu/CORBA/DynAn/gnuDynAnyFactory.java @@ -0,0 +1,356 @@ +/* gnuDynAnyFactory.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.DynAn; + +import gnu.CORBA.Poa.ORB_1_4; +import gnu.CORBA.Unexpected; +import gnu.CORBA.holderFactory; +import gnu.CORBA.typeNamer; + +import org.omg.CORBA.Any; +import org.omg.CORBA.LocalObject; +import org.omg.CORBA.TCKind; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.TypeCodePackage.BadKind; +import org.omg.CORBA.UserException; +import org.omg.CORBA.portable.Streamable; +import org.omg.DynamicAny.DynAny; +import org.omg.DynamicAny.DynAnyFactory; +import org.omg.DynamicAny.DynAnyFactoryPackage.InconsistentTypeCode; +import org.omg.DynamicAny.DynArray; +import org.omg.DynamicAny.DynEnum; +import org.omg.DynamicAny.DynFixed; +import org.omg.DynamicAny.DynSequence; +import org.omg.DynamicAny.DynStruct; +import org.omg.DynamicAny.DynUnion; +import org.omg.DynamicAny.DynValue; +import org.omg.DynamicAny.DynValueBox; + +/** + * This class is returned by ORB when resolving + * initial reference "DynAnyFactory". + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuDynAnyFactory + extends LocalObject + implements DynAnyFactory +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * The ORB, to that the factory belongs. + */ + final ORB_1_4 orb; + + /** + * Create a new factory, specifying the ORB to that the factory belongs. + * + * @param anOrb + */ + public gnuDynAnyFactory(ORB_1_4 anOrb) + { + orb = anOrb; + } + + /** + * Get the orb. + */ + public ORB_1_4 getOrb() + { + return orb; + } + + /** + * Create an initialised array. + */ + public DynArray create_array(TypeCode official, TypeCode type) + { + return new gnuDynArray(official, type, this, orb, true); + } + + /** + * Create an empty sequence. + */ + public DynSequence create_sequence(TypeCode official, TypeCode type) + { + return new gnuDynSequence(official, type, this, orb); + } + + /** + * Create structure. + * + * @param official the type that was originally passed as a parameter by user. + * May be alias of some other type. + * @param type the type into that the "official type" evaluates during alias + * resolving. Initially equal to "official type". + */ + public DynStruct create_structure(TypeCode official, TypeCode type) + { + return new gnuDynStruct(official, type, this, orb); + } + + /** + * Create union. + * + * @param official the type that was originally passed as a parameter by user. + * May be alias of some other type. + * @param type the type into that the "official type" evaluates during alias + * resolving. Initially equal to "official type". + */ + public DynUnion create_union(TypeCode official, TypeCode type) + { + try + { + return new gnuDynUnion(official, type, this, orb); + } + catch (Exception ex) + { + throw new Unexpected(ex); + } + } + + /** + * Create value. + * + * @param official the type that was originally passed as a parameter by user. + * May be alias of some other type. + * @param type the type into that the "official type" evaluates during alias + * resolving. Initially equal to "official type". + */ + public DynValue create_value(TypeCode official, TypeCode type) + { + return new gnuDynValue(official, type, this, orb); + } + + /** + * Create value box. + * + * @param official the type that was originally passed as a parameter by user. + * May be alias of some other type. + * @param type the type into that the "official type" evaluates during alias + * resolving. Initially equal to "official type". + */ + public DynValueBox create_value_box(TypeCode official, TypeCode type) + { + return new gnuDynValueBox(official, type, this, orb); + } + + /** + * Create enumeration. + * + * @param official the type that was originally passed as a parameter by user. + * May be alias of some other type. + * @param type the type into that the "official type" evaluates during alias + * resolving. Initially equal to "official type". + */ + public DynEnum create_enumeration(TypeCode official, TypeCode type) + { + return new gnuDynEnum(official, type, this, orb); + } + + /** + * Create fixed. + * + * @param official the type that was originally passed as a parameter by user. + * May be alias of some other type. + * @param type the type into that the "official type" evaluates during alias + * resolving. Initially equal to "official type". + */ + public DynFixed create_fixed(TypeCode official, TypeCode type) + { + return new gnuDynFixed(official, type, this, orb); + } + + /** + * Create alias. + * + * @param official the type that was originally passed as a parameter by user. + * May be alias of some other type. + * @param type the type into that the "official type" evaluates during alias + * resolving. Initially equal to "official type". + */ + public DynAny create_alias(TypeCode official, TypeCode type) + throws InconsistentTypeCode + { + try + { + return create_dyn_any_from_type_code(official, type.content_type()); + } + catch (BadKind e) + { + throw new Unexpected(e); + } + } + + /** + * Create the undivideable DynAny. + */ + public DynAny create_simple(TypeCode official, TypeCode type) + { + Streamable holder = holderFactory.createHolder(type); + return new gnuDynAny(holder, official, type, this, orb); + } + + /** + * Create the DynAny from typecode. + */ + public DynAny create_dyn_any_from_type_code(TypeCode type) + throws InconsistentTypeCode + { + return create_dyn_any_from_type_code(type, type); + } + + /** + * Create the DynAny from typecode. + * + * @param official the type that was originally passed as a parameter by user. + * May be alias of some other type. + * @param type the type into that the "official type" evaluates during alias + * resolving. Initially equal to "official type". + */ + public DynAny create_dyn_any_from_type_code(TypeCode official, TypeCode type) + throws InconsistentTypeCode + { + DynAny d; + try + { + switch (type.kind().value()) + { + case TCKind._tk_array : + return create_array(official, type); + + case TCKind._tk_sequence : + return create_sequence(official, type); + + case TCKind._tk_struct : + case TCKind._tk_except : + return create_structure(official, type); + + case TCKind._tk_union : + return create_union(official, type); + + case TCKind._tk_value : + return create_value(official, type); + + case TCKind._tk_value_box : + return create_value_box(official, type); + + case TCKind._tk_enum : + return create_enumeration(official, type); + + case TCKind._tk_fixed : + return create_fixed(official, type); + + case TCKind._tk_alias : + return create_alias(official, type); + + case TCKind._tk_null : + return new gnuDynAny(null, official, type, this, orb); + + case TCKind._tk_TypeCode : + d = create_simple(official, type); + d.insert_typecode(orb.get_primitive_tc(TCKind.tk_null)); + return d; + + case TCKind._tk_any : + d = create_simple(official, type); + + Any empty_any = orb.create_any(); + empty_any.type(orb.get_primitive_tc(TCKind.tk_null)); + d.insert_any(empty_any); + return d; + + case TCKind._tk_wstring : + d = create_simple(official, type); + d.insert_wstring(""); + return d; + + case TCKind._tk_string : + d = create_simple(official, type); + d.insert_string(""); + return d; + + case TCKind._tk_native : + case TCKind._tk_Principal : + case TCKind._tk_abstract_interface : + throw new InconsistentTypeCode("Following API, the " + + typeNamer.nameIt(type) + + " must not be supported." + ); + + default : + return create_simple(official, type); + } + } + catch (UserException uex) + { + InconsistentTypeCode it = new InconsistentTypeCode(); + it.initCause(uex); + throw it; + } + } + + /** + * Create the DynAny using the passed value as template and assign this value. + */ + public DynAny create_dyn_any(Any value) + throws InconsistentTypeCode + { + DynAny created = create_dyn_any_from_type_code(value.type()); + try + { + created.from_any(value); + } + catch (UserException uex) + { + InconsistentTypeCode t = new InconsistentTypeCode("Inconsistent Any"); + t.initCause(uex); + throw t; + } + catch (Exception e) + { + throw new Unexpected(e); + } + return created; + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/DynAn/gnuDynArray.java b/libjava/classpath/gnu/CORBA/DynAn/gnuDynArray.java new file mode 100644 index 00000000000..1c08496d423 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/DynAn/gnuDynArray.java @@ -0,0 +1,338 @@ +/* gnuDynArray.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.DynAn; + +import gnu.CORBA.Unexpected; +import gnu.CORBA.holderFactory; + +import org.omg.CORBA.Any; +import org.omg.CORBA.BAD_PARAM; +import org.omg.CORBA.ORB; +import org.omg.CORBA.TCKind; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.TypeCodePackage.BadKind; +import org.omg.CORBA.portable.Streamable; +import org.omg.DynamicAny.DynAny; +import org.omg.DynamicAny.DynAnyFactoryPackage.InconsistentTypeCode; +import org.omg.DynamicAny.DynAnyPackage.InvalidValue; +import org.omg.DynamicAny.DynAnyPackage.TypeMismatch; +import org.omg.DynamicAny.DynArray; + +import java.io.Serializable; + +import java.lang.reflect.Array; +import java.lang.reflect.Field; + +/** + * Provides support for dynamic array or sequence, where all members have the + * same final_type. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuDynArray + extends anyDivideable + implements DynArray, Serializable +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * The component "official" type (may be alias). + */ + final TypeCode official_components; + + /** + * The component "final" type, after resolving any aliases. + */ + final TypeCode final_components; + + /** + * Creates new array. + * + * @param aType the final_type of array. + * @param aFactory the factory, used to initialise default values. + * @param orb the ORB to that this DynAny belongs. + * @param initialise_array if false, the array is not initialised in + * constructor. + * + * + * @throws BAD_PARAM if the passed typecode does not provide the length(). + */ + public gnuDynArray(TypeCode oType, TypeCode aType, gnuDynAnyFactory aFactory, + ORB anOrb, boolean initialise_array + ) + throws BAD_PARAM + { + super(oType, aType, aFactory, anOrb); + + try + { + official_components = final_type.content_type(); + + TypeCode component = official_components; + while (component.kind().value() == TCKind._tk_alias) + component = component.content_type(); + final_components = component; + + if (initialise_array) + { + array = new DynAny[ aType.length() ]; + for (int i = 0; i < array.length; i++) + { + array [ i ] = + factory.create_dyn_any_from_type_code(official_components); + } + } + } + catch (Exception e) + { + BAD_PARAM bad = new BAD_PARAM("Unable to initialise array"); + bad.initCause(e); + throw bad; + } + } + + /** + * Copy one DynAny into another. + */ + public void assign(DynAny from) + throws TypeMismatch + { + checkType(official_type, from.type()); + if (from instanceof DynArray && from.component_count() == array.length) + { + DynArray dyn = (DynArray) from; + array = dyn.get_elements_as_dyn_any(); + } + else + throw new TypeMismatch(); + } + + /** + * Create a copy. + */ + public DynAny copy() + { + DynAny[] c = new DynAny[ array.length ]; + for (int i = 0; i < c.length; i++) + { + c [ i ] = array [ i ].copy(); + } + + gnuDynArray d = + new gnuDynArray(official_type, final_type, factory, orb, false); + d.array = c; + return d; + } + + /** + * Get elements as array of anys. + */ + public Any[] get_elements() + { + Any[] r = new Any[ array.length ]; + for (int i = 0; i < r.length; i++) + r [ i ] = array [ i ].to_any(); + return r; + } + + /** {@inheritDoc} */ + public DynAny[] get_elements_as_dyn_any() + { + DynAny[] a = new DynAny[ array.length ]; + for (int i = 0; i < a.length; i++) + { + a [ i ] = array [ i ].copy(); + } + return a; + } + + /** + * Set elements when array of dyn anys is provided. This method can set nested + * data structures as an array components. + */ + public void set_elements_as_dyn_any(DynAny[] value) + throws InvalidValue, TypeMismatch + { + if (value.length != array.length) + throw new InvalidValue(sizeMismatch(array.length, value.length)); + for (int i = 0; i < value.length; i++) + { + checkType(official_components, value [ i ].type()); + array [ i ].assign(value [ i ]); + } + pos = 0; + valueChanged(); + } + + /** + * Set elements when array of ordinary anys is provided. + */ + public void set_elements(Any[] value) + throws InvalidValue, TypeMismatch + { + if (value.length != array.length) + throw new InvalidValue(sizeMismatch(array.length, value.length)); + + for (int i = 0; i < value.length; i++) + { + checkType(official_components, value [ i ].type()); + try + { + array [ i ] = factory.create_dyn_any(value [ i ]); + } + catch (InconsistentTypeCode e) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(e); + throw t; + } + } + pos = 0; + valueChanged(); + } + + /** + * Done via reflection. + */ + public Any to_any() + { + try + { + Streamable memberHolder = + holderFactory.createHolder(official_components); + + if (memberHolder == null) + memberHolder = holderFactory.createHolder(final_components); + + Class memberHolderClass = memberHolder.getClass(); + Class memberClass = memberHolderClass.getField("value").getType(); + + Object members = Array.newInstance(memberClass, array.length); + Object member; + Any am; + Field value = memberHolder.getClass().getField("value"); + + for (int i = 0; i < array.length; i++) + { + // Recursive call should support multidimensional arrays. + am = array [ i ].to_any(); + memberHolder = am.extract_Streamable(); + member = value.get(memberHolder); + Array.set(members, i, member); + } + + Streamable arrayHolder = holderFactory.createHolder(official_type); + arrayHolder.getClass().getField("value").set(arrayHolder, members); + + Any g = createAny(); + g.insert_Streamable(arrayHolder); + g.type(official_type); + return g; + } + catch (Exception e) + { + throw new Unexpected(e); + } + } + + /** + * Done via reflection. + */ + public void from_any(Any an_any) + throws TypeMismatch, InvalidValue + { + checkType(official_type, an_any.type()); + try + { + Streamable s = an_any.extract_Streamable(); + Object members = s.getClass().getField("value").get(s); + + checkArrayValid(members); + + Any member; + Streamable holder; + Class holderClass = null; + + for (int i = 0; i < array.length; i++) + { + if (holderClass == null) + { + holder = holderFactory.createHolder(official_components); + if (holder == null) + holder = holderFactory.createHolder(final_components); + holderClass = holder.getClass(); + } + else + holder = (Streamable) holderClass.newInstance(); + + member = createAny(); + holder.getClass().getField("value").set(holder, + Array.get(members, i) + ); + member.insert_Streamable(holder); + member.type(official_components); + + // This may lead to recursion, supporting multidimensional + // arrays. + array [ i ].from_any(member); + } + } + catch (Exception ex) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(ex); + throw t; + } + valueChanged(); + } + + /** + * Check if array size is valid and (for sequences) resized + * if required. Called from from_any. + */ + protected void checkArrayValid(Object members) + throws TypeMismatch, InvalidValue + { + if (array.length != Array.getLength(members)) + throw new InvalidValue(sizeMismatch(array.length, Array.getLength(members))); + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/DynAn/gnuDynEnum.java b/libjava/classpath/gnu/CORBA/DynAn/gnuDynEnum.java new file mode 100644 index 00000000000..2fccc85c59d --- /dev/null +++ b/libjava/classpath/gnu/CORBA/DynAn/gnuDynEnum.java @@ -0,0 +1,244 @@ +/* gnuDynEnum.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.DynAn; + +import gnu.CORBA.Unexpected; + +import org.omg.CORBA.Any; +import org.omg.CORBA.BAD_PARAM; +import org.omg.CORBA.MARSHAL; +import org.omg.CORBA.ORB; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.portable.InputStream; +import org.omg.DynamicAny.DynAny; +import org.omg.DynamicAny.DynAnyPackage.InvalidValue; +import org.omg.DynamicAny.DynAnyPackage.TypeMismatch; +import org.omg.DynamicAny.DynEnum; + +import java.io.IOException; + +import java.util.Arrays; + +/** + * Our implementation of dynamic enumeration. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuDynEnum extends anyUndivideable implements DynEnum +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * The valid string values of the enumeration. Most of enumerations are short, + * counting 2-5 memebers. With so small number of memebers, it seems not + * reasonable to use hashtables. + */ + final String[] values; + + /** + * The current value of enum. + */ + int current; + + /** + * Create a new dyn enum from the given typecode. + */ + public gnuDynEnum(TypeCode oType, TypeCode aType, gnuDynAnyFactory aFactory, + ORB anOrb + ) + { + super(oType, aType, aFactory, anOrb); + try + { + values = new String[ final_type.member_count() ]; + + for (int i = 0; i < values.length; i++) + { + values [ i ] = final_type.member_name(i); + } + } + catch (Exception e) + { + throw new BAD_PARAM("Not enum"); + } + } + + /** + * Create a clone of the given enum, sharing values and final_type. + */ + public gnuDynEnum(gnuDynEnum from) + { + super(from.official_type, from.final_type, from.factory, from.orb); + values = from.values; + } + + /** + * Assign the Enum from the passed value. The passed DynAny must hold the + * enumeration of exactly the same final_type. + */ + public void assign(DynAny from) throws TypeMismatch + { + checkType(official_type, from.type()); + if (!(from instanceof DynEnum)) + throw new TypeMismatch("Not a DynEnum"); + try + { + set_as_ulong(((DynEnum) from).get_as_ulong()); + } + catch (InvalidValue e) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(e); + throw t; + } + } + + /** + * Copy this DynEnum. + */ + public DynAny copy() + { + gnuDynEnum other = new gnuDynEnum(this); + other.current = current; + return other; + } + + /** + * Compares for equality. + */ + public boolean equal(DynAny other) + { + if (other instanceof gnuDynEnum) + { + gnuDynEnum oe = (gnuDynEnum) other; + return current == oe.current && + (oe.values == values || Arrays.equals(values, oe.values)); + } + else if (other instanceof DynEnum) + { + DynEnum oe = (DynEnum) other; + return current == oe.get_as_ulong() && official_type.equal(oe.type()); + } + else + return false; + } + + /** + * Set value from any that must contain enumeration. + */ + public void from_any(Any an_any) throws TypeMismatch, InvalidValue + { + checkType(official_type, an_any.type()); + try + { + InputStream in = an_any.create_input_stream(); + set_as_ulong(in.read_long()); + in.close(); + } + catch (MARSHAL eof) + { + throw new InvalidValue(); + } + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Get the value of this enumeration as string. + */ + public String get_as_string() + { + return values [ current ]; + } + + /** + * Get the value of this enumeration as int. + */ + public int get_as_ulong() + { + return current; + } + + /** + * Set the value of this enumeration as string. + */ + public void set_as_string(String value) throws InvalidValue + { + for (int i = 0; i < values.length; i++) + { + if (values [ i ].equals(value)) + { + current = i; + valueChanged(); + return; + } + } + throw new InvalidValue(value); + } + + /** + * Set the value of this enumeration as int. + */ + public void set_as_ulong(int value) throws InvalidValue + { + if (value < 0 || value >= values.length) + throw new InvalidValue(value + " not in [0.." + values.length); + else + { + current = value; + valueChanged(); + } + } + + /** + * Wrap the enumeration value into any. + */ + public Any to_any() + { + Any a = createAny(); + a.insert_long(current); + a.type(official_type); + return a; + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/DynAn/gnuDynFixed.java b/libjava/classpath/gnu/CORBA/DynAn/gnuDynFixed.java new file mode 100644 index 00000000000..39b00226245 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/DynAn/gnuDynFixed.java @@ -0,0 +1,252 @@ +/* gnuDynFixed.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.DynAn; + +import org.omg.CORBA.Any; +import org.omg.CORBA.BAD_OPERATION; +import org.omg.CORBA.BAD_PARAM; +import org.omg.CORBA.ORB; +import org.omg.CORBA.TypeCode; +import org.omg.DynamicAny.DynAny; +import org.omg.DynamicAny.DynAnyPackage.InvalidValue; +import org.omg.DynamicAny.DynAnyPackage.TypeMismatch; +import org.omg.DynamicAny.DynFixed; +import org.omg.DynamicAny.DynFixedOperations; + +import java.math.BigDecimal; + +/** + * Implements DynAny, holding CORBA <code>fixed</code>. This class is derived + * from gnuDynEnm to avoid repetetive inclusion of unused DynAny methods. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuDynFixed extends anyUndivideable implements DynFixed +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * The default value, assigned in the new instance. + */ + static final BigDecimal ZERO = new BigDecimal("0.0"); + + /** + * The content of the dyn fixed, wrapped in this DynAny. + */ + BigDecimal value; + + /** + * The number of digits after the decimal point. + */ + final int scale; + + /** + * The number of digits. + */ + final int digits; + + /** + * Create a new instance of the dyn fixed. + */ + public gnuDynFixed(TypeCode oType, TypeCode aType, + gnuDynAnyFactory aFactory, ORB anOrb + ) + { + super(oType, aType, aFactory, anOrb); + try + { + digits = final_type.fixed_digits(); + scale = final_type.fixed_scale(); + } + catch (Exception e) + { + throw new BAD_PARAM("Not a fixed"); + } + value = ZERO; + } + + /** + * Clone the current instance. + */ + public gnuDynFixed(gnuDynFixed from) + { + super(from.official_type, from.final_type, from.factory, from.orb); + digits = from.digits; + scale = from.scale; + value = from.value; + } + + /** + * Get the value of the wrapped dyn fixed, as string. + */ + public String get_value() + { + return value.toString(); + } + + /** + * Set the value. + */ + public boolean set_value(String fixed_value) + throws TypeMismatch, InvalidValue + { + // Count the digits till decimal point. + int digs = 0; + char c; + boolean leading0 = true; + Digs: + for (int i = 0; i < fixed_value.length(); i++) + { + c = fixed_value.charAt(i); + if (Character.isDigit(c)) + { + if (!(c == '0' && leading0)) + digs++; + if (c != '0') + leading0 = false; + } + else if (c == '.') + break Digs; + } + if (digs > (digits - scale)) + throw new InvalidValue("Too many digits: " + digs + " for " + digits + + "." + scale + ); + + try + { + value = new BigDecimal(fixed_value); + } + catch (NumberFormatException ex) + { + if (fixed_value.trim().length() == 0) + throw new InvalidValue("Empty string passed"); + + TypeMismatch inva = + new TypeMismatch("Not a number: '" + fixed_value + "'"); + inva.initCause(ex); + throw inva; + } + + valueChanged(); + return value.scale() <= scale; + } + + /** + * Assign the value from another BigDecimal. + */ + public void assign(DynAny from) throws TypeMismatch + { + checkType(official_type, from.type()); + + if (from instanceof gnuDynFixed) + { + gnuDynFixed other = (gnuDynFixed) from; + value = other.value; + } + else if (from instanceof DynFixedOperations) + { + value = new BigDecimal(((DynFixedOperations) from).get_value()); + } + else + throw new TypeMismatch("Not a DynFixed"); + valueChanged(); + } + + /** + * Create a copy. + */ + public DynAny copy() + { + return new gnuDynFixed(this); + } + + /** + * Compare for equality. + */ + public boolean equal(DynAny other) + { + if (other instanceof gnuDynFixed) + { + // Normally, this code would be executed. + return value.equals(((gnuDynFixed) other).value); + } + if (other instanceof DynFixedOperations) + { + // This may be involved when mixing implementations. + return ((DynFixedOperations) other).get_value().equals(get_value()); + } + else + return false; + } + + /** + * Set the value from Any (must hold <code>fixed</code> with the matching + * typecode.). + */ + public void from_any(Any an_any) throws TypeMismatch, InvalidValue + { + try + { + checkType(official_type, an_any.type()); + + value = an_any.extract_fixed(); + valueChanged(); + } + catch (BAD_OPERATION e) + { + InvalidValue t = new InvalidValue(); + t.initCause(e); + throw t; + } + } + + /** + * Create and return Any, holding this DynFixed value. + */ + public Any to_any() + { + Any g = createAny(); + g.insert_fixed(value, official_type); + return g; + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/DynAn/gnuDynSequence.java b/libjava/classpath/gnu/CORBA/DynAn/gnuDynSequence.java new file mode 100644 index 00000000000..cfa122f07d7 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/DynAn/gnuDynSequence.java @@ -0,0 +1,254 @@ +/* gnuDynSequence.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.DynAn; + +import gnu.CORBA.Unexpected; + +import org.omg.CORBA.Any; +import org.omg.CORBA.BAD_PARAM; +import org.omg.CORBA.ORB; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.TypeCodePackage.BadKind; +import org.omg.DynamicAny.DynAny; +import org.omg.DynamicAny.DynAnyFactoryPackage.InconsistentTypeCode; +import org.omg.DynamicAny.DynAnyPackage.InvalidValue; +import org.omg.DynamicAny.DynAnyPackage.TypeMismatch; +import org.omg.DynamicAny.DynSequence; + +import java.io.Serializable; + +import java.lang.reflect.*; + +public class gnuDynSequence + extends gnuDynArray + implements DynSequence, Serializable +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * The bound of the sequence, as defined in typecode. + */ + final int bound; + + /** + * Create a new gnuDynSequence with the given typecode. + * + * @throws BAD_PARAM if the passed typecode is probably not a sequence + * typecode. + */ + public gnuDynSequence(TypeCode oType, TypeCode aType, + gnuDynAnyFactory aFactory, ORB anOrb + ) + throws BAD_PARAM + { + super(oType, aType, aFactory, anOrb, false); + array = new DynAny[ 0 ]; + try + { + bound = final_type.length(); + } + catch (BadKind ex) + { + throw new Unexpected(ex); + } + } + + /** + * Get the length of the sequence. + */ + public int get_length() + { + return array.length; + } + + /** + * Resize the sequence, preserving components. + */ + public void set_length(int length) + throws InvalidValue + { + checkBound(length); + if (length == array.length) + return; // Nothing to do. + else if (length < array.length) + { + // Truncate. + DynAny[] d = new DynAny[ length ]; + for (int i = 0; i < d.length; i++) + d [ i ] = array [ i ]; + array = d; + } + else + { + // Expand. + DynAny[] d = new DynAny[ length ]; + for (int i = 0; i < array.length; i++) + d [ i ] = array [ i ]; + + for (int i = array.length; i < d.length; i++) + { + try + { + d [ i ] = + factory.create_dyn_any_from_type_code(official_components); + } + catch (InconsistentTypeCode e) + { + throw new Unexpected(e); + } + } + array = d; + } + valueChanged(); + } + + /** + * Copy one DynAny into another. + */ + public void assign(DynAny from) + throws TypeMismatch + { + checkType(official_type, from.type()); + if (from instanceof DynSequence) + { + DynSequence dyn = (DynSequence) from; + array = dyn.get_elements_as_dyn_any(); + } + else + throw new TypeMismatch(); + } + + /* + * Set the contenst of the sequence, resizing if required. + */ + public void set_elements_as_dyn_any(DynAny[] value) + throws InvalidValue, TypeMismatch + { + checkBound(value.length); + if (array.length != value.length) + set_length(value.length); + + for (int i = 0; i < value.length; i++) + { + checkType(official_components, value [ i ].type()); + array [ i ].assign(value [ i ]); + } + valueChanged(); + } + + /** + * Set the elements from array of Any's. + */ + public void set_elements(Any[] value) + throws InvalidValue, TypeMismatch + { + checkBound(value.length); + + DynAny[] prev = array; + + array = new DynAny[ value.length ]; + try + { + super.set_elements(value); + + // valueChanged() is called in super.set_elements(value). + } + + // On the problem, value does not change. + catch (TypeMismatch ex) + { + array = prev; + throw ex; + } + catch (InvalidValue ex) + { + array = prev; + throw ex; + } + catch (RuntimeException rex) + { + array = prev; + throw rex; + } + } + + /** + * Create a copy. + */ + public DynAny copy() + { + DynAny[] c = new DynAny[ array.length ]; + for (int i = 0; i < c.length; i++) + { + c [ i ] = array [ i ].copy(); + } + + gnuDynSequence d = + new gnuDynSequence(official_type, final_type, factory, orb); + d.array = c; + return d; + } + + /** + * Check the bound. + * + * @param x the value to check. + */ + void checkBound(int x) + throws InvalidValue + { + if (bound != 0) + if (x < 0 || x > bound) + throw new InvalidValue(x + " out of bounds, valid [0.." + bound + "]"); + } + + /** + * Check if array size is valid. Called from from_any. + */ + protected void checkArrayValid(Object members) + throws TypeMismatch, InvalidValue + { + checkBound(Array.getLength(members)); + if (get_length() != Array.getLength(members)) + set_length(Array.getLength(members)); + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/DynAn/gnuDynStruct.java b/libjava/classpath/gnu/CORBA/DynAn/gnuDynStruct.java new file mode 100644 index 00000000000..b086d6478cc --- /dev/null +++ b/libjava/classpath/gnu/CORBA/DynAn/gnuDynStruct.java @@ -0,0 +1,109 @@ +/* gnuDynStruct.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.DynAn; + +import java.io.Serializable; + +import org.omg.CORBA.ORB; +import org.omg.CORBA.TypeCode; +import org.omg.DynamicAny.DynStruct; +import org.omg.DynamicAny.NameDynAnyPair; +import org.omg.DynamicAny.NameValuePair; +import gnu.CORBA.Unexpected; +import org.omg.DynamicAny.DynAny; + +/** + * Implementation of the DynStruct. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuDynStruct + extends abstractRecord + implements DynStruct, Serializable +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * Create an instance. + */ + public gnuDynStruct(TypeCode oType, TypeCode aType, + gnuDynAnyFactory aFactory, ORB anOrb) + { + super(oType, aType, aFactory, anOrb); + + // Initialise fields. + try + { + array = new DynAny[ final_type.member_count() ]; + fNames = new String[ array.length ]; + for (int i = 0; i < array.length; i++) + { + array [ i ] = + factory.create_dyn_any_from_type_code(final_type.member_type(i)); + fNames [ i ] = final_type.member_name(i); + } + } + catch (Exception e) + { + throw new Unexpected(e); + } + } + + /** @inheritDoc */ + protected abstractRecord newInstance(TypeCode oType, TypeCode aType, + gnuDynAnyFactory aFactory, ORB anOrb) + { + return new gnuDynStruct(oType, aType, aFactory, anOrb); + } + + /** @inheritDoc */ + public NameDynAnyPair[] get_members_as_dyn_any() + { + return super.gnu_get_members_as_dyn_any(); + } + + /** @inheritDoc */ + public NameValuePair[] get_members() + { + return super.gnu_get_members(); + } +} diff --git a/libjava/classpath/gnu/CORBA/DynAn/gnuDynUnion.java b/libjava/classpath/gnu/CORBA/DynAn/gnuDynUnion.java new file mode 100644 index 00000000000..ad41e24b6ae --- /dev/null +++ b/libjava/classpath/gnu/CORBA/DynAn/gnuDynUnion.java @@ -0,0 +1,439 @@ +/* gnuDynUnion.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.DynAn; + +import gnu.CORBA.Unexpected; + +import org.omg.CORBA.Any; +import org.omg.CORBA.MARSHAL; +import org.omg.CORBA.ORB; +import org.omg.CORBA.TCKind; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.TypeCodePackage.BadKind; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; +import org.omg.DynamicAny.DynAny; +import org.omg.DynamicAny.DynAnyFactoryPackage.InconsistentTypeCode; +import org.omg.DynamicAny.DynAnyPackage.InvalidValue; +import org.omg.DynamicAny.DynAnyPackage.TypeMismatch; +import org.omg.DynamicAny.DynUnion; + +import java.io.Serializable; + +/** + * Implementation of DynUnion. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuDynUnion + extends anyDivideable + implements DynUnion, Serializable, valueChangedListener +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * The discrimintor of this union. + */ + DynAny discriminator; + + /** + * The message string that occurs several times throwing exception. + */ + static String NOAM = "No active member"; + + /** + * Create a new instance with the given typecode. + * + * @param aType the final_type, must be final_type of the union. + */ + public gnuDynUnion(TypeCode oType, TypeCode aType, gnuDynAnyFactory aFactory, + ORB anOrb + ) + throws InconsistentTypeCode + { + super(oType, aType, aFactory, anOrb); + try + { + discriminator = + factory.create_dyn_any_from_type_code(final_type.discriminator_type()); + + ((abstractDynAny) discriminator).listener = this; + + if (final_type.default_index() >= 0) + set_to_default_member(); + else + set_to_no_active_member(); + } + catch (Exception ex) + { + InconsistentTypeCode inc = new InconsistentTypeCode("discriminator"); + inc.initCause(ex); + throw inc; + } + } + + /* + * (non-Javadoc) + * + * @see gnu.CORBA.DynAn.anyDivideable#to_any() + */ + public Any to_any() + { + Any a = createAny(); + OutputStream ou = a.create_output_stream(); + discriminator.to_any().write_value(ou); + if (array.length == 2) + array [ 1 ].to_any().write_value(ou); + a.read_value(ou.create_input_stream(), final_type); + return a; + } + + /** + * Assign from another identical structure. + */ + public void assign(DynAny from) + throws TypeMismatch + { + checkType(official_type, from.type()); + if (!(from instanceof DynUnion)) + throw new TypeMismatch("DynUnion required"); + else + { + try + { + DynUnion u = (DynUnion) from; + discriminator.assign(u.get_discriminator()); + if (u.has_no_active_member()) + { + if (array.length != 1) + array = new DynAny[] { discriminator }; + } + else + { + if (array.length != 2) + array = new DynAny[] { discriminator, u.member().copy() }; + else + array [ 1 ] = u.member().copy(); + } + } + catch (InvalidValue e) + { + throw new Unexpected(e); + } + } + valueChanged(); + } + + /** @inheritDoc */ + public DynAny copy() + { + try + { + gnuDynUnion other = + new gnuDynUnion(official_type, final_type, factory, orb); + other.discriminator = discriminator.copy(); + ((abstractDynAny) other.discriminator).listener = other; + if (array.length == 1) + { + other.array = new DynAny[] { other.discriminator }; + } + else + { + other.array = + new DynAny[] { other.discriminator, array [ 1 ].copy() }; + } + return other; + } + catch (InconsistentTypeCode ex) + { + throw new Unexpected(ex); + } + } + + /** + * Done via reading from stream. + */ + public void from_any(Any an_any) + throws TypeMismatch, InvalidValue + { + checkType(official_type, an_any.type()); + + Any adis = createAny(); + try + { + InputStream stream = an_any.create_input_stream(); + adis.read_value(stream, final_type.discriminator_type()); + + DynAny nd = factory.create_dyn_any(adis); + + set_discriminator(nd); + if (array.length == 2) + { + // Reusing the same Any <code>adis</code>. + adis.read_value(stream, array [ 1 ].type()); + array [ 1 ].from_any(adis); + } + } + catch (InconsistentTypeCode it) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(it); + throw t; + } + catch (MARSHAL m) + { + InvalidValue t = new InvalidValue(); + t.initCause(m); + throw t; + } + catch (BadKind b) + { + throw new Unexpected(b); + } + valueChanged(); + } + + /** @inheritDoc */ + public TCKind discriminator_kind() + { + return discriminator.type().kind(); + } + + /** @inheritDoc */ + public DynAny get_discriminator() + { + return discriminator; + } + + /** @inheritDoc */ + public boolean has_no_active_member() + { + return array.length == 1; + } + + /** @inheritDoc */ + public TCKind member_kind() + throws InvalidValue + { + return member().type().kind(); + } + + /** + * Get the name of the current variant of the union. + */ + public String member_name() + throws InvalidValue + { + if (array.length == 1) + throw new InvalidValue(NOAM); + try + { + Any da = discriminator.to_any(); + + + // Get the discriminator variant. + Variants: + for (int i = 0; i < final_type.member_count(); i++) + { + if (final_type.member_label(i).equal(da)) + return final_type.member_name(i); + } + throw new InvalidValue(NOAM); + } + catch (Exception e) + { + InvalidValue t = new InvalidValue("Err"); + t.initCause(e); + throw t; + } + } + + /** @inheritDoc */ + public DynAny member() + throws InvalidValue + { + if (array.length < 2) + throw new InvalidValue(NOAM); + else + return array [ 1 ]; + } + + /** + * Set the union discriminator. + */ + public void set_discriminator(DynAny aDiscriminator) + throws TypeMismatch + { + try + { + if (!aDiscriminator.type().equal(final_type.discriminator_type())) + throw new TypeMismatch("Wrong discriminator final_type for " + + final_type.name() + ); + + // Seting the same discriminator value again should not change + // the fields of the current member. + if (!discriminator.equal(aDiscriminator)) + { + discriminator.assign(aDiscriminator); + updateMember(); + } + else + { + pos = array.length == 2 ? 1 : 0; + } + } + catch (Exception e) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(e); + throw t; + } + } + + /** + * Set to default member, if one exists. + */ + public void set_to_default_member() + throws TypeMismatch + { + try + { + int di = final_type.default_index(); + if (di < 0) + throw new TypeMismatch("Union " + final_type.name() + + "has no default index" + ); + + Any da = final_type.member_label(di); + discriminator.from_any(da); + updateMember(); + } + catch (TypeMismatch m) + { + // This one OK. + throw m; + } + catch (Exception e) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(e); + throw t; + } + } + + /** @inheritDoc */ + public void set_to_no_active_member() + throws TypeMismatch + { + try + { + if (final_type.default_index() >= 0) + { + throw new TypeMismatch("Explicit default case defined."); + } + } + catch (BadKind ex) + { + // The default index is not set. + } + array = new DynAny[] { discriminator }; + valueChanged(); + } + + /** + * Update member, in accordance with discriminator value. + */ + public void updateMember() + throws TypeMismatch + { + try + { + Any da = discriminator.to_any(); + + + // Get the discriminator variant. + Variants: + for (int i = 0; i < final_type.member_count(); i++) + { + if (final_type.member_label(i).equal(da)) + { + array = + new DynAny[] + { + discriminator, + factory.create_dyn_any_from_type_code(final_type.member_type(i)) + }; + pos = 1; + valueChanged(); + return; + } + } + } + catch (Exception e) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(e); + throw t; + } + + // Discrimintator does not point to valid member. + array = new DynAny[] { discriminator }; + pos = 0; + valueChanged(); + } + + /** + * Called when the discriminator is changed. + */ + public void changed() + { + try + { + updateMember(); + } + catch (TypeMismatch ex) + { + throw new Unexpected(ex); + } + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/DynAn/gnuDynValue.java b/libjava/classpath/gnu/CORBA/DynAn/gnuDynValue.java new file mode 100644 index 00000000000..c2db9479785 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/DynAn/gnuDynValue.java @@ -0,0 +1,382 @@ +/* gnuDynValue.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.DynAn; + +import gnu.CORBA.Unexpected; + +import org.omg.CORBA.Any; +import org.omg.CORBA.BAD_PARAM; +import org.omg.CORBA.MARSHAL; +import org.omg.CORBA.ORB; +import org.omg.CORBA.TCKind; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.VM_TRUNCATABLE; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.ValueFactory; +import org.omg.DynamicAny.DynAny; +import org.omg.DynamicAny.DynAnyPackage.InvalidValue; +import org.omg.DynamicAny.DynAnyPackage.TypeMismatch; +import org.omg.DynamicAny.DynStruct; +import org.omg.DynamicAny.DynValue; +import org.omg.DynamicAny.DynValueCommon; +import org.omg.DynamicAny.DynValueOperations; +import org.omg.DynamicAny.NameDynAnyPair; +import org.omg.DynamicAny.NameValuePair; + +import java.io.Serializable; + +/** + * Implementation of DynValue. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuDynValue extends abstractRecord implements DynValue, + Serializable +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * If true, the value of this ValueType is set to null. + */ + boolean isNull; + + /** + * Create an instance. + */ + public gnuDynValue(TypeCode oType, TypeCode aType, + gnuDynAnyFactory aFactory, ORB anOrb + ) + { + super(oType, aType, aFactory, anOrb); + + // Initialise fields. The array of fields also includes all inherited + // fields. + try + { + array = new DynAny[ final_type.member_count() ]; + fNames = new String[ array.length ]; + for (int i = 0; i < array.length; i++) + { + array [ i ] = + factory.create_dyn_any_from_type_code(final_type.member_type(i)); + fNames [ i ] = final_type.member_name(i); + } + + // Search of inherited members. + if (final_type.type_modifier() == VM_TRUNCATABLE.value) + { + TypeCode parent = final_type.concrete_base_type(); + DynAny ancestor = factory.create_dyn_any_from_type_code(parent); + + if (ancestor instanceof DynValue) + { + // Add members of ancestor in front of the curren members. + DynValue anc = (DynValue) ancestor; + anc.set_to_value(); + + NameDynAnyPair[] aar = anc.get_members_as_dyn_any(); + inheritFields(aar); + } + else if (ancestor instanceof DynStruct) + { + // Add members of ancestor in front of the curren members. + DynStruct anc = (DynStruct) ancestor; + NameDynAnyPair[] aar = anc.get_members_as_dyn_any(); + inheritFields(aar); + } + else + throw new BAD_PARAM("The parent of " + final_type.id() + ", " + + parent.id() + ", is not structure nor value." + ); + } + } + catch (Exception e) + { + throw new Unexpected(e); + } + + set_to_null(); + } + + /** + * Inherit the provided fields. + */ + private void inheritFields(NameDynAnyPair[] aar) + { + DynAny[] nArray = new DynAny[ array.length + aar.length ]; + String[] nNames = new String[ array.length + aar.length ]; + int p = 0; + for (int i = 0; i < aar.length; i++) + { + nArray [ p ] = aar [ i ].value; + nNames [ p ] = aar [ i ].id; + p++; + } + + for (int i = 0; i < array.length; i++) + { + nArray [ p ] = array [ i ]; + nNames [ p ] = fNames [ i ]; + p++; + } + + array = nArray; + fNames = nNames; + } + + /** @inheritDoc */ + public TCKind current_member_kind() throws TypeMismatch, InvalidValue + { + if (isNull) + throw new TypeMismatch(ISNULL); + else + return super.current_member_kind(); + } + ; + + /** @inheritDoc */ + public String current_member_name() throws TypeMismatch, InvalidValue + { + if (isNull) + throw new TypeMismatch(ISNULL); + else + return super.current_member_name(); + } + ; + + /** @inheritDoc */ + public NameDynAnyPair[] get_members_as_dyn_any() throws InvalidValue + { + if (isNull) + throw new InvalidValue(ISNULL); + return super.gnu_get_members_as_dyn_any(); + } + ; + + /** @inheritDoc */ + public NameValuePair[] get_members() throws InvalidValue + { + if (isNull) + throw new InvalidValue(ISNULL); + else + return super.gnu_get_members(); + } + ; + + /** @inheritDoc */ + public void set_members_as_dyn_any(NameDynAnyPair[] value) + throws TypeMismatch, InvalidValue + { + super.set_members_as_dyn_any(value); + isNull = false; + } + ; + + /** @inheritDoc */ + public void set_members(NameValuePair[] value) + throws TypeMismatch, InvalidValue + { + super.set_members(value); + isNull = false; + } + ; + + /** @inheritDoc */ + public boolean is_null() + { + return isNull; + } + + /** @inheritDoc */ + public void set_to_null() + { + isNull = true; + valueChanged(); + } + + /** @inheritDoc */ + public void set_to_value() + { + isNull = false; + valueChanged(); + } + + /** + * Create a new instance. + */ + protected abstractRecord newInstance(TypeCode oType, TypeCode aType, + gnuDynAnyFactory aFactory, ORB anOrb + ) + { + gnuDynValue v = new gnuDynValue(oType, aType, aFactory, anOrb); + if (isNull) + v.set_to_null(); + else + v.set_to_value(); + return v; + } + + /** + * Compare for equality, minding null values. + */ + public boolean equal(DynAny other) + { + if (other instanceof DynValueOperations) + { + DynValueCommon o = (DynValueCommon) other; + if (isNull) + return o.is_null() && o.type().equal(official_type); + else + return !o.is_null() && super.equal(other); + } + else + return false; + } + + /** + * Get the focused component, throwing exception if the current value is null. + */ + protected DynAny focused() throws InvalidValue, TypeMismatch + { + if (isNull) + throw new TypeMismatch(ISNULL); + else + return super.focused(); + } + + /** + * Convert into Any. + */ + public Any to_any() + { + if (isNull) + { + Any a0 = createAny(); + a0.type(orb.get_primitive_tc(TCKind.tk_null)); + return a0; + } + else + { + try + { + ValueFactory factory = + ((org.omg.CORBA_2_3.ORB) orb).lookup_value_factory(official_type.id()); + if (factory == null) + throw new MARSHAL("Factory for " + official_type.id() + + " not registered." + ); + + OutputStream out = orb.create_output_stream(); + + for (int i = 0; i < array.length; i++) + array [ i ].to_any().write_value(out); + + org.omg.CORBA_2_3.portable.InputStream in = + (org.omg.CORBA_2_3.portable.InputStream) out.create_input_stream(); + Serializable v = factory.read_value(in); + + Any g = createAny(); + g.type(official_type); + g.insert_Value(v, official_type); + + return g; + } + catch (Exception e) + { + throw new Unexpected(e); + } + } + } + + /** @inheritDoc */ + public void assign(DynAny from) throws TypeMismatch + { + checkType(official_type, from.type()); + + if (from instanceof DynValue) + { + DynValue other = (DynValue) from; + if (other.is_null()) + set_to_null(); + else + { + set_to_value(); + try + { + DynValueOperations src = (DynValueOperations) from; + set_members_as_dyn_any(src.get_members_as_dyn_any()); + } + catch (InvalidValue e) + { + TypeMismatch t = new TypeMismatch("Invalid value"); + t.initCause(e); + throw t; + } + } + } + else + throw new TypeMismatch("Not a DynValue"); + } + + /** + * Get the number of components. + */ + public int component_count() + { + return isNull ? 0 : super.component_count(); + } + + /** {@inheritDoc} */ + public Serializable get_val() throws TypeMismatch, InvalidValue + { + return to_any().extract_Value(); + } + + /** {@inheritDoc} */ + public void insert_val(Serializable a_x) throws InvalidValue, TypeMismatch + { + Any a = to_any(); + a.insert_Value(a_x); + from_any(a); + valueChanged(); + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/DynAn/gnuDynValueBox.java b/libjava/classpath/gnu/CORBA/DynAn/gnuDynValueBox.java new file mode 100644 index 00000000000..66e18f3b2fe --- /dev/null +++ b/libjava/classpath/gnu/CORBA/DynAn/gnuDynValueBox.java @@ -0,0 +1,389 @@ +/* gnuDynValueBox.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.DynAn; + +import gnu.CORBA.Unexpected; +import gnu.CORBA.holderFactory; + +import org.omg.CORBA.Any; +import org.omg.CORBA.ORB; +import org.omg.CORBA.TCKind; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.TypeCodePackage.BadKind; +import org.omg.CORBA.portable.Streamable; +import org.omg.DynamicAny.DynAny; +import org.omg.DynamicAny.DynAnyFactoryPackage.InconsistentTypeCode; +import org.omg.DynamicAny.DynAnyPackage.InvalidValue; +import org.omg.DynamicAny.DynAnyPackage.TypeMismatch; +import org.omg.DynamicAny.DynValueBox; +import org.omg.DynamicAny.DynValueBoxOperations; +import org.omg.DynamicAny.DynValueCommon; + +import java.io.Serializable; + +import java.lang.reflect.Field; + +/** + * Implementation of the DynValueBox. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuDynValueBox + extends anyDivideable + implements DynValueBox, Serializable +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * The final_type of contents of this value box. + */ + final TypeCode content; + + /** + * The string for some TypeMismatch exceptions. + */ + String CONTENT = "Box content final_type mismatch"; + + /** + * Create a new instance of gnuDynValueBox. + */ + public gnuDynValueBox(TypeCode oType, TypeCode aType, + gnuDynAnyFactory aFactory, ORB anOrb + ) + { + super(oType, aType, aFactory, anOrb); + try + { + content = final_type.content_type(); + array = new DynAny[] { factory.create_dyn_any_from_type_code(content) }; + set_to_null(); + } + catch (Exception e) + { + throw new Unexpected(e); + } + } + + /** @inheritDoc */ + public void assign(DynAny from) + throws TypeMismatch + { + checkType(official_type, from.type()); + if (from instanceof DynValueBoxOperations) + { + DynValueBoxOperations other = (DynValueBoxOperations) from; + if (other.is_null()) + set_to_null(); + else + { + DynAny inBox; + try + { + inBox = other.get_boxed_value_as_dyn_any(); + } + catch (InvalidValue e) + { + TypeMismatch t = new TypeMismatch("Invalid value"); + t.initCause(e); + throw t; + } + if (!content.equal(inBox.type())) + throw new TypeMismatch(CONTENT); + array = new DynAny[] { inBox.copy() }; + } + } + valueChanged(); + } + + /** @inheritDoc */ + public DynAny copy() + { + gnuDynValueBox other = + new gnuDynValueBox(official_type, final_type, factory, orb); + if (is_null()) + other.set_to_null(); + else + { + try + { + other.array = new DynAny[] { array [ 0 ].copy() }; + } + catch (Exception e) + { + throw new Unexpected(e); + } + } + return other; + } + + /** + * Returns null for null value, delegates to super. otherwise. + */ + public DynAny current_component() + throws TypeMismatch + { + if (is_null()) + return null; + else + return super.current_component(); + } + + /** + * Compare for equality, minding null values. + */ + public boolean equal(DynAny other) + { + if (other instanceof DynValueCommon) + { + DynValueCommon o = (DynValueCommon) other; + if (is_null()) + return o.is_null() && o.type().equal(official_type); + else + return !o.is_null() && super.equal(other); + } + else + return false; + } + + /** @inheritDoc */ + public void from_any(Any an_any) + throws TypeMismatch, InvalidValue + { + checkType(official_type, an_any.type()); + try + { + if (!an_any.type().content_type().equal(content)) + throw new InvalidValue(CONTENT); + } + catch (BadKind e) + { + TypeMismatch t = new TypeMismatch("Not a box"); + t.initCause(e); + throw t; + } + + Serializable s = an_any.extract_Value(); + if (s == null) + set_to_null(); + else + { + try + { + Streamable holder = holderFactory.createHolder(content); + Field v = holder.getClass().getField("value"); + v.set(holder, s); + + Any cont = createAny(); + cont.insert_Streamable(holder); + + array = new DynAny[] { factory.create_dyn_any(cont) }; + } + catch (Exception ex) + { + throw new Unexpected(ex); + } + } + valueChanged(); + } + + /** @inheritDoc */ + public Any get_boxed_value() + throws InvalidValue + { + try + { + if (is_null()) + throw new InvalidValue(ISNULL); + else + return array [ 0 ].to_any(); + } + catch (Exception e) + { + InvalidValue t = new InvalidValue(); + t.initCause(e); + throw t; + } + } + + /** @inheritDoc */ + public DynAny get_boxed_value_as_dyn_any() + throws InvalidValue + { + if (is_null()) + throw new InvalidValue(ISNULL); + else + return array [ 0 ].copy(); + } + + /** {@inheritDoc} */ + public Serializable get_val() + throws TypeMismatch, InvalidValue + { + return to_any().extract_Value(); + } + + /** {@inheritDoc} */ + public void insert_val(Serializable a_x) + throws InvalidValue, TypeMismatch + { + Any a = to_any(); + a.insert_Value(a_x); + from_any(a); + valueChanged(); + } + + /** @inheritDoc */ + public boolean is_null() + { + return array.length == 0; + } + + /** @inheritDoc */ + public void set_boxed_value(Any boxIt) + throws TypeMismatch + { + if (!content.equal(boxIt.type())) + throw new TypeMismatch(CONTENT); + try + { + if (is_null()) + { + array = new DynAny[] { factory.create_dyn_any(boxIt) }; + } + else + { + array [ 0 ].from_any(boxIt); + } + } + catch (Exception e) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(e); + throw t; + } + valueChanged(); + } + + /** @inheritDoc */ + public void set_boxed_value_as_dyn_any(DynAny boxIt) + throws TypeMismatch + { + if (!content.equal(boxIt.type())) + throw new TypeMismatch(CONTENT); + try + { + if (is_null()) + { + array = new DynAny[] { boxIt.copy() }; + } + else + { + array [ 0 ].assign(boxIt); + } + } + catch (Exception e) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(e); + throw t; + } + valueChanged(); + } + + /** @inheritDoc */ + public void set_to_null() + { + array = new DynAny[ 0 ]; + valueChanged(); + } + + /** @inheritDoc */ + public void set_to_value() + { + try + { + if (array.length == 0) + { + array = + new DynAny[] { factory.create_dyn_any_from_type_code(content) }; + } + } + catch (InconsistentTypeCode e) + { + throw new Unexpected(e); + } + valueChanged(); + } + + /** @inheritDoc */ + public Any to_any() + { + Any a = createAny(); + + if (!is_null()) + { + try + { + Streamable holder; + if (array [ 0 ] instanceof gnuDynAny) + holder = ((gnuDynAny) array [ 0 ]).holder; + else + { + Any uan = array [ 0 ].to_any(); + holder = uan.extract_Streamable(); + } + + Field v = holder.getClass().getField("value"); + Serializable value = (Serializable) v.get(holder); + a.type(official_type); + a.insert_Value(value, content); + } + catch (Exception ex) + { + throw new Unexpected(ex); + } + } + else + a.type(orb.get_primitive_tc(TCKind.tk_null)); + return a; + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/DynAn/valueChangedListener.java b/libjava/classpath/gnu/CORBA/DynAn/valueChangedListener.java new file mode 100644 index 00000000000..94ddffbecf7 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/DynAn/valueChangedListener.java @@ -0,0 +1,50 @@ +/* valueChangedListener.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.DynAn; + +/** + * An interface, able to receive notification about the change of value + * of some DynAny. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public interface valueChangedListener +{ + void changed(); +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/DynAnySeqHolder.java b/libjava/classpath/gnu/CORBA/DynAnySeqHolder.java new file mode 100644 index 00000000000..52d66d9e924 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/DynAnySeqHolder.java @@ -0,0 +1,116 @@ +/* DynAnySeqHolder.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.Streamable; +import org.omg.DynamicAny.DynAny; +import org.omg.DynamicAny.DynAnySeqHelper; + +/** + * A holder for the sequence of {@link DynAny} + * ({@link DynAnySeq}). + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class DynAnySeqHolder + implements Streamable +{ + /** + * The stored array of <code>DynAny</code>. + */ + public DynAny[] value; + + /** + * Create the unitialised instance, leaving the value array + * with default <code>null</code> value. + */ + public DynAnySeqHolder() + { + } + + /** + * Create the initialised instance. + * @param initialValue the array that will be assigned to + * the <code>value</code> array. + */ + public DynAnySeqHolder(DynAny[] initialValue) + { + value = initialValue; + } + + /** + * The method should read this object from the CDR input stream, but + * (following the JDK 1.5 API) it does not. + * + * @param input a org.omg.CORBA.portable stream to read from. + * + * @specenote Sun throws the same exception. + * + * @throws MARSHAL always. + */ + public void _read(InputStream input) + { + value = DynAnySeqHelper.read(input); + } + + /** + * The method should write this object to the CDR input stream, but + * (following the JDK 1.5 API) it does not. + * + * @param input a org.omg.CORBA.portable stream to read from. + * + * @specenote Sun throws the same exception. + * + * @throws MARSHAL always. + */ + public void _write(OutputStream output) + { + DynAnySeqHelper.write(output, value); + } + + /** + * Get the typecode of the DynAny. + */ + public org.omg.CORBA.TypeCode _type() + { + return DynAnySeqHelper.type(); + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/ForwardRequestHelper.java b/libjava/classpath/gnu/CORBA/ForwardRequestHelper.java new file mode 100644 index 00000000000..c7fae5b061b --- /dev/null +++ b/libjava/classpath/gnu/CORBA/ForwardRequestHelper.java @@ -0,0 +1,160 @@ +/* ForwardRequestHelper.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import gnu.CORBA.Poa.ForwardRequestHolder; + +import org.omg.CORBA.Any; +import org.omg.CORBA.BAD_OPERATION; +import org.omg.CORBA.ORB; +import org.omg.CORBA.ObjectHelper; +import org.omg.CORBA.StructMember; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; +import org.omg.PortableServer.ForwardRequest; + +/** + * The helper operations for the exception {@link ForwardRequest}. + * + * @specnote The helper must be here and not in POA subpackage as it must + * be discovered by the {@link ObjectCreator} when reading this remote + * exception. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public abstract class ForwardRequestHelper +{ + /** + * The cached typecode value, computed only once. + */ + private static TypeCode typeCode; + + /** + * Extract the ForwardRequest from given Any. + * This method uses the ForwardRequestHolder. + * + * @throws BAD_OPERATION if the passed Any does not contain ForwardRequest. + */ + public static ForwardRequest extract(Any any) + { + try + { + return ((ForwardRequestHolder) any.extract_Streamable()).value; + } + catch (ClassCastException cex) + { + BAD_OPERATION bad = new BAD_OPERATION("ForwardRequest expected"); + bad.initCause(cex); + throw bad; + } + } + + /** + * Get the ForwardRequest repository id. + * + * @return "ForwardRequest", always. + */ + public static String id() + { + return "ForwardRequest"; + } + + /** + * Insert the ForwardRequest into the given Any. + * This method uses the ForwardRequestHolder. + * + * @param any the Any to insert into. + * @param that the ForwardRequest to insert. + */ + public static void insert(Any any, ForwardRequest that) + { + any.insert_Streamable(new ForwardRequestHolder(that)); + } + + /** + * Read the exception from the CDR intput stream. + * + * @param input a org.omg.CORBA.portable stream to read from. + */ + public static ForwardRequest read(InputStream input) + { + // Read the exception repository id. + String id = input.read_string(); + ForwardRequest value = new ForwardRequest(); + + value.forward_reference = input.read_Object(); + return value; + } + + /** + * Create the ForwardRequest typecode (structure, + * named "ForwardRequest"). + * The typecode states that the structure contains the + * following fields: forward_reference. + */ + public static TypeCode type() + { + if (typeCode == null) + { + ORB orb = ORB.init(); + StructMember[] members = new StructMember[ 1 ]; + + TypeCode field; + + field = ObjectHelper.type(); + members [ 0 ] = new StructMember("forward_reference", field, null); + typeCode = orb.create_exception_tc(id(), "ForwardRequest", members); + } + return typeCode; + } + + /** + * Write the exception to the CDR output stream. + * + * @param output a org.omg.CORBA.portable stream stream to write into. + * @param value a value to write. + */ + public static void write(OutputStream output, ForwardRequest value) + { + // Write the exception repository id. + output.write_string(id()); + output.write_Object(value.forward_reference); + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/GIOP/contextSupportingHeader.java b/libjava/classpath/gnu/CORBA/GIOP/contextSupportingHeader.java new file mode 100644 index 00000000000..ba6c1f88d8f --- /dev/null +++ b/libjava/classpath/gnu/CORBA/GIOP/contextSupportingHeader.java @@ -0,0 +1,76 @@ +/* contextSupportingHeader.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.GIOP; + +import org.omg.CORBA.BAD_INV_ORDER; + +/** + * A header, supporting the service contexts. Such header has a context field + * and methods for adding the new contexts. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public abstract class contextSupportingHeader +{ + + /** + * Empty array, indicating that no service context is available. + */ + protected static final ServiceContext[] NO_CONTEXT = new ServiceContext[0]; + + /** + * The context data. + */ + public ServiceContext[] service_context = NO_CONTEXT; + + /** + * Add service context to this header. + * + * @param context_to_add context to add. + * @param replace if true, the existing context with this ID is replaced. + * Otherwise, BAD_INV_ORDER is throwsn. + */ + public void addContext(org.omg.IOP.ServiceContext context_to_add, + boolean replace) + throws BAD_INV_ORDER + { + service_context = ServiceContext.add(service_context, context_to_add, + replace); + } +} diff --git a/libjava/classpath/gnu/CORBA/Interceptor/ClientRequestInterceptors.java b/libjava/classpath/gnu/CORBA/Interceptor/ClientRequestInterceptors.java new file mode 100644 index 00000000000..5c15e121d29 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Interceptor/ClientRequestInterceptors.java @@ -0,0 +1,139 @@ +/* ClientRequestInterceptors.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Interceptor; + +import org.omg.PortableInterceptor.ClientRequestInfo; +import org.omg.PortableInterceptor.ClientRequestInterceptor; +import org.omg.PortableInterceptor.ClientRequestInterceptorOperations; +import org.omg.PortableInterceptor.ForwardRequest; + +/** + * A block of the all registered ClientRequest interceptors. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class ClientRequestInterceptors + implements ClientRequestInterceptorOperations +{ + /** + * The array of all registered ClientRequest interceptors. + */ + private final ClientRequestInterceptor[] interceptors; + + /** + * Create the interceptor pack with the registerend interceptor array, + * obtained from the registrator. + */ + public ClientRequestInterceptors(Registrator registrator) + { + interceptors = registrator.getClientRequestInterceptors(); + } + + /** @inheritDoc */ + public void receive_exception(ClientRequestInfo info) + throws ForwardRequest + { + for (int i = 0; i < interceptors.length; i++) + { + interceptors [ i ].receive_exception(info); + } + } + + /** @inheritDoc */ + public void receive_other(ClientRequestInfo info) throws ForwardRequest + { + for (int i = 0; i < interceptors.length; i++) + { + interceptors [ i ].receive_other(info); + } + } + + /** @inheritDoc */ + public void receive_reply(ClientRequestInfo info) + { + for (int i = 0; i < interceptors.length; i++) + { + interceptors [ i ].receive_reply(info); + } + } + + /** @inheritDoc */ + public void send_poll(ClientRequestInfo info) + { + for (int i = 0; i < interceptors.length; i++) + { + interceptors [ i ].send_poll(info); + } + } + + /** @inheritDoc */ + public void send_request(ClientRequestInfo info) throws ForwardRequest + { + for (int i = 0; i < interceptors.length; i++) + { + interceptors [ i ].send_request(info); + } + } + + /** + * Call destroy on all registered interceptors. + */ + public void destroy() + { + for (int i = 0; i < interceptors.length; i++) + { + try + { + interceptors [ i ].destroy(); + } + catch (Exception exc) + { + // OMG states we should ignore. + } + } + } + + /** + * Get the class name. + */ + public String name() + { + return getClass().getName(); + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/Interceptor/ForwardRequestHolder.java b/libjava/classpath/gnu/CORBA/Interceptor/ForwardRequestHolder.java new file mode 100644 index 00000000000..d9ced03a332 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Interceptor/ForwardRequestHolder.java @@ -0,0 +1,106 @@ +/* ForwardRequestHolder.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Interceptor; + +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.Streamable; +import org.omg.PortableInterceptor.ForwardRequest; +import org.omg.PortableInterceptor.ForwardRequestHelper; + +/** + * A holder for the exception {@link ForwardRequest}. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class ForwardRequestHolder implements Streamable +{ + /** + * The stored ForwardRequest value. + */ + public ForwardRequest value; + + /** + * Create the unitialised instance, leaving the value field with default + * <code>null</code> value. + */ + public ForwardRequestHolder() + { + } + + /** + * Create the initialised instance. + * + * @param initialValue the value that will be assigned to the + * <code>value</code> field. + */ + public ForwardRequestHolder(ForwardRequest initialValue) + { + value = initialValue; + } + + /** + * Fill in the {@link value} by data from the CDR stream. + * + * @param input the org.omg.CORBA.portable stream to read. + */ + public void _read(InputStream input) + { + value = ForwardRequestHelper.read(input); + } + + /** + * Write the stored value into the CDR stream. + * + * @param output the org.omg.CORBA.portable stream to write. + */ + public void _write(OutputStream output) + { + ForwardRequestHelper.write(output, value); + } + + /** + * Get the typecode of the ForwardRequest. + */ + public TypeCode _type() + { + return ForwardRequestHelper.type(); + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/Interceptor/IORInterceptors.java b/libjava/classpath/gnu/CORBA/Interceptor/IORInterceptors.java new file mode 100644 index 00000000000..88756988c92 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Interceptor/IORInterceptors.java @@ -0,0 +1,109 @@ +/* IORInterceptors.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Interceptor; + +import org.omg.PortableInterceptor.IORInfo; +import org.omg.PortableInterceptor.IORInterceptor; +import org.omg.PortableInterceptor.IORInterceptorOperations; + +/** + * A block of the all registered IOR interceptors. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class IORInterceptors implements IORInterceptorOperations +{ + /** + * The array of all registered IOR interceptors. + */ + private final IORInterceptor[] interceptors; + + /** + * Create the interceptor pack with the registerend interceptor array, + * obtained from the registrator. + */ + public IORInterceptors(Registrator registrator) + { + interceptors = registrator.getIORInterceptors(); + } + + /** + * Call this method for all registered interceptors. + */ + public void establish_components(IORInfo info) + { + for (int i = 0; i < interceptors.length; i++) + { + try + { + interceptors [ i ].establish_components(info); + } + catch (Exception exc) + { + // OMG states we should ignore. + } + } + } + + /** + * Call destroy on all registered interceptors. + */ + public void destroy() + { + for (int i = 0; i < interceptors.length; i++) + { + try + { + interceptors [ i ].destroy(); + } + catch (Exception exc) + { + // OMG states we should ignore. + } + } + } + + /** + * Get the class name. + */ + public String name() + { + return getClass().getName(); + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/Interceptor/Registrator.java b/libjava/classpath/gnu/CORBA/Interceptor/Registrator.java new file mode 100644 index 00000000000..ff35cd0c85e --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Interceptor/Registrator.java @@ -0,0 +1,470 @@ +/* Registrator.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Interceptor; + +import gnu.CORBA.Poa.ORB_1_4; +import gnu.CORBA.gnuCodecFactory; + +import org.omg.CORBA.BAD_INV_ORDER; +import org.omg.CORBA.CompletionStatus; +import org.omg.CORBA.LocalObject; +import org.omg.CORBA.Object; +import org.omg.IOP.CodecFactory; +import org.omg.PortableInterceptor.ClientRequestInterceptor; +import org.omg.PortableInterceptor.IORInterceptor; +import org.omg.PortableInterceptor.Interceptor; +import org.omg.PortableInterceptor.ORBInitInfo; +import org.omg.PortableInterceptor.ORBInitInfoPackage.DuplicateName; +import org.omg.PortableInterceptor.ORBInitInfoPackage.InvalidName; +import org.omg.PortableInterceptor.ORBInitializer; +import org.omg.PortableInterceptor.ORBInitializerOperations; +import org.omg.PortableInterceptor.PolicyFactory; +import org.omg.PortableInterceptor.ServerRequestInterceptor; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; + +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.Map; +import java.util.Properties; +import java.util.TreeMap; + +/** + * Collects interceptors, references and factories into arrays during + * registration. As the class is security sensitive, the most of the fields are + * private. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class Registrator extends LocalObject implements ORBInitInfo +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * The agreed properties prefix. + */ + public final static String m_prefix = + "org.omg.PortableInterceptor.ORBInitializerClass."; + + /** + * The initialization - time server request interceptors. + */ + private ArrayList m_server = new ArrayList(); + + /** + * The initialization - time client request interceptors. + */ + private ArrayList m_client = new ArrayList(); + + /** + * The initialization - time ior interceptors. + */ + private ArrayList m_ior = new ArrayList(); + + /** + * The policy factories. + */ + public Hashtable m_policyFactories = new Hashtable(); + + /** + * The registered references. To avoid exposing the ORB's references map, the + * are added by ORB from inside the ORB code. The ORB is responsible for + * taking them from this field between pre_init and post_init. + */ + public TreeMap m_references = new TreeMap(); + + /** + * The initializers. + */ + public ArrayList m_initializers = new ArrayList(); + + /** + * The ORB being intialised. + */ + final ORB_1_4 orb; + + /** + * The argument string array, passed to ORB.init. + */ + final String[] m_args; + + /** + * The codec factory. + */ + final gnuCodecFactory m_codecFactory; + + /** + * Create the interceptor collection from the given properties, using the + * agreed naming convention. + * + * @param orb the ORB being initialised. + * @param props the cumulated set of properties where the orb initializer + * pattern is searched. + * @param an_args the argument string array, passed to ORB.init. + */ + public Registrator(ORB_1_4 an_orb, Properties props, String[] an_args) + { + orb = an_orb; + m_args = an_args; + m_codecFactory = new gnuCodecFactory(orb); + checkProperties(props); + checkProperties(System.getProperties()); + checkFile("user.home", null); + checkFile("java.home", "lib"); + } + + /** + * Scan the given properties for the possible interceptors. + */ + private void checkProperties(Properties props) + { + if (props == null) + { + return; + } + + Enumeration names = props.propertyNames(); + java.lang.Object key; + String sk; + + while (names.hasMoreElements()) + { + key = names.nextElement(); + if (key != null) + { + sk = key.toString(); + if (sk.startsWith(m_prefix)) + { + try + { + String cn = sk.substring(m_prefix.length()); + Class iClass = Class.forName(cn); + ORBInitializer initializer = + (ORBInitializer) iClass.newInstance(); + m_initializers.add(initializer); + } + catch (Exception exc) + { + // OMG states we should not throw an exception, but + // this will help the user to detect his error + // in initialiser properties. Should never print during + // normal run. + System.err.println(sk + " failed"); + } + } + } + } + } + + /** + * Check if the property is defined in the existsting file orb.properties. + */ + private void checkFile(String dir, String subdir) + { + try + { + File f = new File(dir); + if (!f.exists()) + { + return; + } + + if (subdir != null) + { + f = new File(f, subdir); + } + f = new File(f, "orb.properties"); + + if (!f.exists()) + { + return; + } + + Properties p = new Properties(); + p.load(new BufferedInputStream(new FileInputStream(f))); + + checkProperties(p); + } + catch (IOException ex) + { + } + } + + /** + * Called by ORB as a pre_init for all initializers. + */ + public void pre_init() + { + Iterator iter = m_initializers.iterator(); + while (iter.hasNext()) + { + ORBInitializerOperations initializer = + (ORBInitializerOperations) iter.next(); + initializer.pre_init(this); + } + } + + /** + * Get the map of the registered references. The ORB calls this method to + * import the references into its references map. + */ + public Map getRegisteredReferences() + { + return m_references; + } + + /** + * Called by ORB as a post-init for all initializers. After this call, the + * interceptor sets are fixed and redundant information is discarded. + */ + public void post_init() + { + Iterator iter = m_initializers.iterator(); + while (iter.hasNext()) + { + ORBInitializerOperations initializer = + (ORBInitializerOperations) iter.next(); + initializer.post_init(this); + } + } + + public ServerRequestInterceptor[] getServerRequestInterceptors() + { + ServerRequestInterceptor[] iServer = + new ServerRequestInterceptor[ m_server.size() ]; + for (int i = 0; i < iServer.length; i++) + { + iServer [ i ] = (ServerRequestInterceptor) m_server.get(i); + } + return iServer; + } + + public ClientRequestInterceptor[] getClientRequestInterceptors() + { + ClientRequestInterceptor[] iClient = + new ClientRequestInterceptor[ m_client.size() ]; + for (int i = 0; i < iClient.length; i++) + { + iClient [ i ] = (ClientRequestInterceptor) m_client.get(i); + } + return iClient; + } + + public IORInterceptor[] getIORInterceptors() + { + IORInterceptor[] iIor = new IORInterceptor[ m_ior.size() ]; + for (int i = 0; i < iIor.length; i++) + { + iIor [ i ] = (IORInterceptor) m_ior.get(i); + } + return iIor; + } + + public void add_client_request_interceptor( + ClientRequestInterceptor interceptor + ) throws DuplicateName + { + add(m_client, interceptor); + } + + public void add_ior_interceptor(IORInterceptor interceptor) + throws DuplicateName + { + add(m_ior, interceptor); + } + + public void add_server_request_interceptor( + ServerRequestInterceptor interceptor + ) throws DuplicateName + { + add(m_server, interceptor); + } + + /** + * Allocate a new slot for request - specific records. + */ + public int allocate_slot_id() + { + return orb.icSlotSize++; + } + + /** + * Add the interceptor to the given collection. + * + * @param list the collection to add. + * @param interceptor the interceptor to add. + */ + private void add(ArrayList list, Interceptor interceptor) + throws DuplicateName + { + if (interceptor.name().length() > 0) + { + Iterator iter = list.iterator(); + Interceptor ic; + + while (iter.hasNext()) + { + ic = (Interceptor) iter.next(); + if (ic.name().equals(interceptor.name())) + { + throw new DuplicateName(interceptor.name()); + } + } + } + list.add(interceptor); + } + + /** + * Get string array, passed to ORB.init. + */ + public String[] arguments() + { + return m_args; + } + + /** + * Get the codec factory. + */ + public CodecFactory codec_factory() + { + return m_codecFactory; + } + + /** + * Get the ORB's id, currently using .toString. + */ + public String orb_id() + { + return "orb_" + orb; + } + + /** + * Register reference. + */ + public void register_initial_reference(String object_name, Object object) + throws InvalidName + { + if (object_name == null) + { + throw new InvalidName("null"); + } + else if (object_name.length() == 0) + { + throw new InvalidName("Empty string"); + } + else if (m_references.containsKey(object_name)) + { + throw new InvalidName(object_name); + } + else + { + m_references.put(object_name, object); + } + } + + /** + * Accumulates the policy factory map. + */ + public void register_policy_factory(int policy_type, + PolicyFactory policy_factory + ) + { + Integer it = new Integer(policy_type); + if (m_policyFactories.containsKey(it)) + { + throw new BAD_INV_ORDER( + "Repetetive registration of the policy factory for type " + + policy_type, + 16, + CompletionStatus.COMPLETED_NO + ); + } + m_policyFactories.put(it, policy_factory); + } + + /** + * Delegates to ORB. + */ + public org.omg.CORBA.Object resolve_initial_references(String object_name) + throws InvalidName + { + try + { + return orb.resolve_initial_references(object_name); + } + catch (org.omg.CORBA.ORBPackage.InvalidName e) + { + InvalidName in = new InvalidName(e.getMessage()); + in.initCause(e); + throw in; + } + } + + /** + * Check if any interceptors of this type were registered. + */ + public boolean hasClientRequestInterceptors() + { + return m_client.size() > 0; + } + + /** + * Check if any interceptors of this type were registered. + */ + public boolean hasServerRequestInterceptors() + { + return m_server.size() > 0; + } + + /** + * Check if any interceptors of this type were registered. + */ + public boolean hasIorInterceptors() + { + return m_ior.size() > 0; + } +} diff --git a/libjava/classpath/gnu/CORBA/Interceptor/ServerRequestInterceptors.java b/libjava/classpath/gnu/CORBA/Interceptor/ServerRequestInterceptors.java new file mode 100644 index 00000000000..4b9bede98eb --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Interceptor/ServerRequestInterceptors.java @@ -0,0 +1,139 @@ +/* ServerRequestInterceptors.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Interceptor; + +import org.omg.PortableInterceptor.ForwardRequest; +import org.omg.PortableInterceptor.ServerRequestInfo; +import org.omg.PortableInterceptor.ServerRequestInterceptor; +import org.omg.PortableInterceptor.ServerRequestInterceptorOperations; + +/** + * A block of the all registered ServerRequest interceptors. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class ServerRequestInterceptors + implements ServerRequestInterceptorOperations +{ + /** + * The array of all registered ServerRequest interceptors. + */ + private final ServerRequestInterceptor[] interceptors; + + /** + * Create the interceptor pack with the registerend interceptor array, + * obtained from the registrator. + */ + public ServerRequestInterceptors(Registrator registrator) + { + interceptors = registrator.getServerRequestInterceptors(); + } + + /** @inheritDoc */ + public void receive_request_service_contexts(ServerRequestInfo info) + throws ForwardRequest + { + for (int i = 0; i < interceptors.length; i++) + { + interceptors [ i ].receive_request_service_contexts(info); + } + } + + /** @inheritDoc */ + public void receive_request(ServerRequestInfo info) throws ForwardRequest + { + for (int i = 0; i < interceptors.length; i++) + { + interceptors [ i ].receive_request(info); + } + } + + /** @inheritDoc */ + public void send_exception(ServerRequestInfo info) throws ForwardRequest + { + for (int i = 0; i < interceptors.length; i++) + { + interceptors [ i ].send_exception(info); + } + } + + /** @inheritDoc */ + public void send_other(ServerRequestInfo info) throws ForwardRequest + { + for (int i = 0; i < interceptors.length; i++) + { + interceptors [ i ].send_other(info); + } + } + + /** @inheritDoc */ + public void send_reply(ServerRequestInfo info) + { + for (int i = 0; i < interceptors.length; i++) + { + interceptors [ i ].send_reply(info); + } + } + + /** + * Call destroy on all registered interceptors. + */ + public void destroy() + { + for (int i = 0; i < interceptors.length; i++) + { + try + { + interceptors [ i ].destroy(); + } + catch (Exception exc) + { + // OMG states we should ignore. + } + } + } + + /** + * Get the class name. + */ + public String name() + { + return getClass().getName(); + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/Interceptor/gnuClientRequestInfo.java b/libjava/classpath/gnu/CORBA/Interceptor/gnuClientRequestInfo.java new file mode 100644 index 00000000000..beb81c81f6c --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Interceptor/gnuClientRequestInfo.java @@ -0,0 +1,337 @@ +/* gnuClientRequestInfo.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Interceptor; + +import gnu.CORBA.Unexpected; +import gnu.CORBA.gnuRequest; + +import org.omg.CORBA.ARG_IN; +import org.omg.CORBA.ARG_INOUT; +import org.omg.CORBA.ARG_OUT; +import org.omg.CORBA.Any; +import org.omg.CORBA.BAD_PARAM; +import org.omg.CORBA.Bounds; +import org.omg.CORBA.ExceptionList; +import org.omg.CORBA.INV_POLICY; +import org.omg.CORBA.LocalObject; +import org.omg.CORBA.NVList; +import org.omg.CORBA.ORB; +import org.omg.CORBA.ParameterMode; +import org.omg.CORBA.Policy; +import org.omg.CORBA.TCKind; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.TypeCodePackage.BadKind; +import org.omg.Dynamic.Parameter; +import org.omg.IOP.ServiceContext; +import org.omg.IOP.TaggedComponent; +import org.omg.IOP.TaggedProfile; +import org.omg.PortableInterceptor.ClientRequestInfo; +import org.omg.PortableInterceptor.InvalidSlot; + +/** + * Client request info. All requests on the client side in Classpath + * implementations are handled via gnuRequest class. This class holds the + * instance of the gnuRequest, accessing the request info this way. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuClientRequestInfo extends LocalObject + implements ClientRequestInfo +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * The request structure, from that some methods take the needed information + * directly. The same request structure cannot be reused in parallel threads, + * the submission methods are synchronized. + */ + private final gnuRequest request; + + /** + * Provides possibility to set the wrapped thrown exception explicitly, where + * applicable. + */ + public Any m_wrapped_exception; + + /** + * Create the info on the given request. + */ + public gnuClientRequestInfo(gnuRequest a_request) + { + request = a_request; + } + + /** @inheritDoc */ + public void add_request_service_context(ServiceContext service_context, + boolean replace + ) + { + request.add_request_service_context(service_context, replace); + } + + /** @inheritDoc */ + public TaggedProfile effective_profile() + { + return request.effective_profile(); + } + + /** @inheritDoc */ + public org.omg.CORBA.Object effective_target() + { + return request.effective_target(); + } + + /** @inheritDoc */ + public TaggedComponent get_effective_component(int id) + throws BAD_PARAM + { + return request.get_effective_component(id); + } + + /** @inheritDoc */ + public TaggedComponent[] get_effective_components(int id) + throws BAD_PARAM + { + return request.get_effective_components(id); + } + + /** @inheritDoc */ + public Policy get_request_policy(int type) throws INV_POLICY + { + return request.get_request_policy(type); + } + + /** @inheritDoc */ + public String received_exception_id() + { + try + { + if (m_wrapped_exception != null) + { + return m_wrapped_exception.type().id(); + } + else + { + return request.received_exception_id(); + } + } + catch (BadKind e) + { + throw new Unexpected(e); + } + } + + /** @inheritDoc */ + public Any received_exception() + { + if (m_wrapped_exception != null) + { + return m_wrapped_exception; + } + else + { + return request.received_exception(); + } + } + + /** @inheritDoc */ + public org.omg.CORBA.Object target() + { + return request.target(); + } + + /** @inheritDoc */ + public Parameter[] arguments() + { + request.checkDii(); + + NVList args = request.arguments(); + Parameter[] p = new Parameter[ args.count() ]; + try + { + for (int i = 0; i < p.length; i++) + { + ParameterMode mode; + + switch (args.item(i).flags()) + { + case ARG_IN.value : + mode = ParameterMode.PARAM_IN; + break; + + case ARG_OUT.value : + mode = ParameterMode.PARAM_OUT; + break; + + case ARG_INOUT.value : + mode = ParameterMode.PARAM_INOUT; + break; + + default : + throw new Unexpected(); + } + + p [ i ] = new Parameter(args.item(i).value(), mode); + } + } + catch (Bounds e) + { + throw new Unexpected(e); + } + return p; + } + + /** @inheritDoc */ + public Any result() + { + request.checkDii(); + + Any rt = request.return_value(); + + if (rt == null) + { + ORB orb = request.orb(); + rt = orb.create_any(); + rt.type(orb.get_primitive_tc(TCKind.tk_void)); + return rt; + } + + return request.return_value(); + } + + /** @inheritDoc */ + public String[] contexts() + { + return request.ice_contexts(); + } + + /** @inheritDoc */ + public TypeCode[] exceptions() + { + request.checkDii(); + + ExceptionList ex = request.exceptions(); + TypeCode[] et = new TypeCode[ ex.count() ]; + try + { + for (int i = 0; i < et.length; i++) + { + et [ i ] = ex.item(i); + } + } + catch (Bounds e) + { + throw new Unexpected(e); + } + return et; + } + + /** @inheritDoc */ + public org.omg.CORBA.Object forward_reference() + { + return request.forward_reference(); + } + + /** @inheritDoc */ + public String[] operation_context() + { + return request.operation_context(); + } + + /** @inheritDoc */ + public Any get_slot(int id) throws InvalidSlot + { + return request.get_slot(id); + } + + /** @inheritDoc */ + public String operation() + { + return request.operation(); + } + + /** @inheritDoc */ + public short reply_status() + { + return request.reply_status(); + } + + /** @inheritDoc */ + public int request_id() + { + return request.request_id(); + } + + /** @inheritDoc */ + public boolean response_expected() + { + return request.response_expected(); + } + + /** + * Determines how far the request shall progress before control is returned to + * the client. However up till JDK 1.5 inclusive this method always returns + * SYNC_WITH_TRANSPORT. + * + * @return {@link org.omg.Messaging.SYNC_WITH_TRANSPORT.value (1), always. + * + * @specnote as defined in the Suns 1.5 JDK API. + */ + public short sync_scope() + { + return request.sync_scope(); + } + + /** @inheritDoc */ + public ServiceContext get_reply_service_context(int ctx_name) + throws BAD_PARAM + { + return request.get_reply_service_context(ctx_name); + } + + /** @inheritDoc */ + public ServiceContext get_request_service_context(int ctx_name) + throws BAD_PARAM + { + return request.get_request_service_context(ctx_name); + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/Interceptor/gnuIcCurrent.java b/libjava/classpath/gnu/CORBA/Interceptor/gnuIcCurrent.java new file mode 100644 index 00000000000..ee8af7fc0b4 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Interceptor/gnuIcCurrent.java @@ -0,0 +1,255 @@ +/* gnuIcCurrent.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Interceptor; + +import gnu.CORBA.CDR.cdrBufOutput; +import gnu.CORBA.Poa.ORB_1_4; + +import org.omg.CORBA.Any; +import org.omg.CORBA.BAD_INV_ORDER; +import org.omg.CORBA.TCKind; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.ObjectImpl; +import org.omg.PortableInterceptor.Current; +import org.omg.PortableInterceptor.CurrentHelper; +import org.omg.PortableInterceptor.InvalidSlot; + +import java.util.Hashtable; +import java.util.Iterator; +import java.util.Map; + +/** + * Supports the "Interceptor current" concept, providing the slot value + * information for the current thread. When making the invocation, this + * information is copied to the Current, returned by ClientRequestInfo. + * + * There is only one instance of this class per ORB. It maintains a thread to + * information map. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuIcCurrent extends ObjectImpl implements Current +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * The ORB, controllin this Current. It provides data about the required size + * of the slot array. + */ + final ORB_1_4 orb; + + /** + * The table, mapping threads to records. + */ + private Hashtable threads = new Hashtable(); + + /** + * An empty array when no slots are defined, computed once. + */ + static final Any[] NO_SLOTS = new Any[ 0 ]; + + /** + * Create the IC current. + */ + public gnuIcCurrent(ORB_1_4 an_orb) + { + orb = an_orb; + } + + /** + * Get the array of POA current repository ids. + * + * @return a single member array, containing value, returned by the + * {@link CurrentHelper#id}, normally + * "IDL:omg.org/PortableInterceptor/Current:1.0". + */ + public String[] _ids() + { + return new String[] { CurrentHelper.id() }; + } + + /** + * Add the entry to the map. + */ + public void put(Thread t, Any[] record) + { + synchronized (threads) + { + threads.put(t, record); + + // Remove non-running threads, avoiding memory leak. + if (threads.size() > 12) + { + Iterator it = threads.entrySet().iterator(); + while (it.hasNext()) + { + Map.Entry e = (Map.Entry) it.next(); + Thread tx = (Thread) e.getKey(); + if (!tx.isAlive()) + { + it.remove(); + } + } + } + } + } + + /** + * Check if this thread is registered. + */ + public boolean has(Thread t) + { + synchronized (threads) + { + return threads.containsKey(t); + } + } + + /** + * Remove the entry from the map. + */ + public void remove(Thread t) + { + synchronized (threads) + { + threads.remove(t); + } + } + + /** + * Get array of all slots, as it is applicable for the current thread. If the + * slots were not previously allocated, they are allocated during this call. + */ + Any[] get_slots() + { + Any[] r; + synchronized (threads) + { + r = (Any[]) threads.get(Thread.currentThread()); + if (r == null) + { + r = new Any[ orb.icSlotSize ]; + + for (int i = 0; i < r.length; i++) + { + Any a = orb.create_any(); + a.type(orb.get_primitive_tc(TCKind.tk_null)); + r [ i ] = a; + } + + put(Thread.currentThread(), r); + } + return r; + } + } + + /** + * Get copu array of all slots, as it is applicable for the current thread. If + * the slots were not previously allocated, they are allocated during this + * call. + */ + public Any[] clone_slots() + { + if (orb.icSlotSize == 0) + { + return NO_SLOTS; + } + else + { + Any[] r = get_slots(); + Any[] copy = new Any[ r.length ]; + + cdrBufOutput buf = new cdrBufOutput(); + buf.setOrb(orb); + + for (int i = 0; i < copy.length; i++) + { + r [ i ].write_value(buf); + } + + InputStream input = buf.create_input_stream(); + + for (int i = 0; i < copy.length; i++) + { + copy [ i ] = orb.create_any(); + copy [ i ].read_value(input, r [ i ].type()); + } + + return copy; + } + } + + /** + * Get value for the slot with the given id. If the array of Currents has not + * been yet allocated for the current thread, it is allocated during the + * invocation of this method. + */ + public Any get_slot(int slot_id) throws InvalidSlot, BAD_INV_ORDER + { + try + { + return get_slots() [ slot_id ]; + } + catch (ArrayIndexOutOfBoundsException e) + { + throw new InvalidSlot("Slot " + slot_id); + } + } + + /** + * Set value for the slot with the given id. If the array of Currents has not + * been yet allocated for the current thread, it is allocated during the + * invocation of this method. + */ + public void set_slot(int slot_id, Any data) + throws InvalidSlot, BAD_INV_ORDER + { + try + { + get_slots() [ slot_id ] = data; + } + catch (ArrayIndexOutOfBoundsException e) + { + throw new InvalidSlot("Slot " + slot_id); + } + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/Interceptor/gnuIorInfo.java b/libjava/classpath/gnu/CORBA/Interceptor/gnuIorInfo.java new file mode 100644 index 00000000000..1c406cb5e46 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Interceptor/gnuIorInfo.java @@ -0,0 +1,120 @@ +/* gnuIorInfo.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Interceptor; + +import gnu.CORBA.IOR; +import gnu.CORBA.Poa.ORB_1_4; + +import org.omg.CORBA.LocalObject; +import org.omg.CORBA.Policy; +import org.omg.IOP.TaggedComponent; +import org.omg.PortableInterceptor.IORInfo; +import org.omg.PortableServer.POA; + +/** + * Implements IORInfo. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuIorInfo extends LocalObject implements IORInfo +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * The ORB, to that the IOR is related. + */ + public final ORB_1_4 orb; + + /** + * The POA, to that IOR is related. + */ + public final POA poa; + + /** + * The IOR itself. + */ + private final IOR ior; + + /** + * Create an instance. + */ + public gnuIorInfo(ORB_1_4 an_orb, POA a_poa, IOR an_ior) + { + orb = an_orb; + poa = a_poa; + ior = an_ior; + } + + /** + * Add component to tje specified profile of this IOR. + */ + public void add_ior_component_to_profile(TaggedComponent tagged_component, + int profile_id + ) + { + ior.add_ior_component_to_profile(tagged_component, profile_id); + } + + /** + * Add component to all found profiles in this IOR. + */ + public void add_ior_component(TaggedComponent tagged_component) + { + ior.add_ior_component(tagged_component); + } + + /** + * Get the POA policy. + */ + public Policy get_effective_policy(int policy_type) + { + return poa._get_policy(policy_type); + } + + /** + * Return the state of the object POA. + */ + short state() + { + return (short) poa.the_POAManager().get_state().value(); + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/Interceptor/gnuServerRequestInfo.java b/libjava/classpath/gnu/CORBA/Interceptor/gnuServerRequestInfo.java new file mode 100644 index 00000000000..5f75f76878a --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Interceptor/gnuServerRequestInfo.java @@ -0,0 +1,456 @@ +/* gnuServerRequestInfo.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Interceptor; + +import gnu.CORBA.GIOP.ReplyHeader; +import gnu.CORBA.GIOP.RequestHeader; +import gnu.CORBA.ObjectCreator; +import gnu.CORBA.Poa.gnuServantObject; +import gnu.CORBA.Unexpected; +import gnu.CORBA.gnuRequest; + +import org.omg.CORBA.ARG_IN; +import org.omg.CORBA.ARG_INOUT; +import org.omg.CORBA.ARG_OUT; +import org.omg.CORBA.Any; +import org.omg.CORBA.BAD_PARAM; +import org.omg.CORBA.Bounds; +import org.omg.CORBA.CompletionStatus; +import org.omg.CORBA.ExceptionList; +import org.omg.CORBA.INV_POLICY; +import org.omg.CORBA.LocalObject; +import org.omg.CORBA.NO_RESOURCES; +import org.omg.CORBA.NVList; +import org.omg.CORBA.Object; +import org.omg.CORBA.ParameterMode; +import org.omg.CORBA.Policy; +import org.omg.CORBA.TCKind; +import org.omg.CORBA.TypeCode; +import org.omg.Dynamic.Parameter; +import org.omg.IOP.ServiceContext; +import org.omg.Messaging.SYNC_WITH_TRANSPORT; +import org.omg.PortableInterceptor.InvalidSlot; +import org.omg.PortableInterceptor.ServerRequestInfo; + +/** + * Implementation of the ServerRequestInfo, associacted with gnuServantObject. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuServerRequestInfo extends LocalObject + implements ServerRequestInfo +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * A local object that will serve the invocation. + */ + final gnuServantObject m_object; + + /** + * A message that the given resource is not available using this metod of + * invocation. + */ + static final String not_available = + "The used invocation method provides" + "no access to this resource."; + + /** + * An array of slots. + */ + Any[] m_slots; + + /** + * The request header. + */ + public final RequestHeader m_request_header; + + /** + * The reply header. + */ + public final ReplyHeader m_reply_header; + + /** + * The forward reference, if applicable. + */ + public Object m_forward_reference; + + /** + * The thrown systen exception. + */ + public Exception m_sys_exception; + + /** + * The Any, containing the thrown user exception. + */ + public Any m_usr_exception; + + /** + * The associated request, if any. + */ + public gnuRequest m_request; + + /** + * Create a new instance at the time when it is known which object will serve + * the invocation. + * + * @param an_object a local object, connected to the local servant that will + * serve the invocation. + */ + public gnuServerRequestInfo(gnuServantObject an_object, + RequestHeader a_request_header, ReplyHeader a_reply_header + ) + { + m_object = an_object; + m_request_header = a_request_header; + m_reply_header = a_reply_header; + m_slots = new Any[ m_object.orb.icSlotSize ]; + reset(); + } + + /** + * Set the give slot. + */ + public void set_slot(int id, Any data) throws InvalidSlot + { + try + { + m_slots [ id ] = data; + } + catch (Exception e) + { + InvalidSlot ex = new InvalidSlot("Cannot set slot " + id); + ex.initCause(e); + throw ex; + } + } + + /** + * Get the given slot. + */ + public Any get_slot(int id) throws InvalidSlot + { + try + { + return m_slots [ id ]; + } + catch (Exception e) + { + InvalidSlot ex = new InvalidSlot("Cannot get slot " + id); + ex.initCause(e); + throw ex; + } + } + + /** + * Reset slot data. + */ + public void reset() + { + TypeCode tkNull = m_object.orb.get_primitive_tc(TCKind.tk_null); + for (int i = 0; i < m_slots.length; i++) + { + Any a = m_object.orb.create_any(); + a.type(tkNull); + m_slots [ i ] = a; + } + m_sys_exception = null; + m_usr_exception = null; + } + + /** + * Get the object id (not the object IOR key). + */ + public byte[] object_id() + { + return m_object.Id; + } + + /** + * Check if the target is an instance of the type, represented by the given + * repository Id. + */ + public boolean target_is_a(String id) + { + return m_object._is_a(id); + } + + /** + * Get the POA id. + */ + public byte[] adapter_id() + { + return m_object.poa.id(); + } + + /** + * Get the POA policy of the given type that applies to the object being + * served (request being handled). + */ + public Policy get_server_policy(int type) throws INV_POLICY + { + return m_object.poa._get_policy(type); + } + + /** + * Get the first member of the object repository id array. + */ + public String target_most_derived_interface() + { + return m_object._ids() [ 0 ]; + } + + /** + * Get the name of the operation being performed. + */ + public String operation() + { + if (m_request != null) + { + return m_request.operation(); + } + else + { + return m_request_header.operation; + } + } + + /** + * Not available. + */ + public TypeCode[] exceptions() + { + if (m_request == null) + { + throw new NO_RESOURCES(not_available, 1, + CompletionStatus.COMPLETED_MAYBE + ); + } + + m_request.checkDii(); + + ExceptionList ex = m_request.exceptions(); + TypeCode[] et = new TypeCode[ ex.count() ]; + try + { + for (int i = 0; i < et.length; i++) + { + et [ i ] = ex.item(i); + } + } + catch (Bounds e) + { + throw new Unexpected(e); + } + return et; + } + + /** + * Get reply status. + */ + public short reply_status() + { + return (short) m_reply_header.reply_status; + } + + /** + * Get request id. All local requests have request id = -1. + */ + public int request_id() + { + return m_request_header.request_id; + } + + /** + * Check if the client expected any response. + */ + public boolean response_expected() + { + return m_request_header.isResponseExpected(); + } + + /** @inheritDoc */ + public void add_reply_service_context(ServiceContext service_context, + boolean replace + ) + { + m_reply_header.addContext(service_context, replace); + } + + /** + * Get an exception, wrapped into Any. + */ + public Any sending_exception() + { + if (m_usr_exception != null) + { + return m_usr_exception; + } + else if (m_sys_exception != null) + { + Any a = m_object.orb.create_any(); + ObjectCreator.insertException(a, m_sys_exception); + return a; + } + else + { + return null; + } + } + + public org.omg.CORBA.Object forward_reference() + { + return m_forward_reference; + } + + /** @inheritDoc */ + public ServiceContext get_reply_service_context(int ctx_name) + throws BAD_PARAM + { + return gnu.CORBA.GIOP.ServiceContext.findContext(ctx_name, + m_reply_header.service_context + ); + } + + /** @inheritDoc */ + public ServiceContext get_request_service_context(int ctx_name) + throws BAD_PARAM + { + return gnu.CORBA.GIOP.ServiceContext.findContext(ctx_name, + m_request_header.service_context + ); + } + + /** + * Not available + */ + public String[] operation_context() + { + if (m_request == null) + { + throw new NO_RESOURCES(not_available); + } + else + { + return m_request.operation_context(); + } + } + + /** @inheritDoc */ + public Any result() + { + if (m_request == null) + { + throw new NO_RESOURCES(not_available); + } + else + { + return m_request.return_value(); + } + } + + /** @inheritDoc */ + public String[] contexts() + { + if (m_request == null) + { + throw new NO_RESOURCES(not_available); + } + else + { + return m_request.ice_contexts(); + } + } + + /** + * Always returns "with transport". + */ + public short sync_scope() + { + return SYNC_WITH_TRANSPORT.value; + } + + /** @inheritDoc */ + public Parameter[] arguments() + { + if (m_request == null) + { + throw new NO_RESOURCES(not_available); + } + + m_request.checkDii(); + + NVList args = m_request.arguments(); + Parameter[] p = new Parameter[ args.count() ]; + try + { + for (int i = 0; i < p.length; i++) + { + ParameterMode mode; + + switch (args.item(i).flags()) + { + case ARG_IN.value : + mode = ParameterMode.PARAM_IN; + break; + + case ARG_OUT.value : + mode = ParameterMode.PARAM_OUT; + break; + + case ARG_INOUT.value : + mode = ParameterMode.PARAM_INOUT; + break; + + default : + throw new Unexpected(); + } + + p [ i ] = new Parameter(args.item(i).value(), mode); + } + } + catch (Bounds e) + { + throw new Unexpected(e); + } + return p; + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/NameDynAnyPairHolder.java b/libjava/classpath/gnu/CORBA/NameDynAnyPairHolder.java new file mode 100644 index 00000000000..6ceb9aae06f --- /dev/null +++ b/libjava/classpath/gnu/CORBA/NameDynAnyPairHolder.java @@ -0,0 +1,115 @@ +/* NameDynAnyPairHolder.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.Streamable; +import org.omg.DynamicAny.NameDynAnyPair; +import org.omg.DynamicAny.NameDynAnyPairHelper; + +/** + * A holder for the structure {@link NameDynAnyPair}. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class NameDynAnyPairHolder + implements Streamable +{ + /** + * The stored NameDynAnyPair value. + */ + public NameDynAnyPair value; + + /** + * Create the unitialised instance, leaving the value field + * with default <code>null</code> value. + */ + public NameDynAnyPairHolder() + { + } + + /** + * Create the initialised instance. + * @param initialValue the value that will be assigned to + * the <code>value</code> field. + */ + public NameDynAnyPairHolder(NameDynAnyPair initialValue) + { + value = initialValue; + } + + /** + * The method should read this object from the CDR input stream, but + * (following the JDK 1.5 API) it does not. + * + * @param input a org.omg.CORBA.portable stream to read from. + * + * @specenote Sun throws the same exception. + * + * @throws MARSHAL always. + */ + public void _read(InputStream input) + { + value = NameDynAnyPairHelper.read(input); + } + + /** + * The method should write this object to the CDR input stream, but + * (following the JDK 1.5 API) it does not. + * + * @param input a org.omg.CORBA.portable stream to read from. + * + * @specenote Sun throws the same exception. + * + * @throws MARSHAL always. + */ + public void _write(OutputStream output) + { + NameDynAnyPairHelper.write(output, value); + } + + /** + * Get the typecode of the NameDynAnyPair. + */ + public org.omg.CORBA.TypeCode _type() + { + return NameDynAnyPairHelper.type(); + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/NameDynAnyPairSeqHolder.java b/libjava/classpath/gnu/CORBA/NameDynAnyPairSeqHolder.java new file mode 100644 index 00000000000..71b6174c1ad --- /dev/null +++ b/libjava/classpath/gnu/CORBA/NameDynAnyPairSeqHolder.java @@ -0,0 +1,115 @@ +/* NameDynAnyPairSeqHolder.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.Streamable; +import org.omg.DynamicAny.NameDynAnyPair; +import org.omg.DynamicAny.NameDynAnyPairSeqHelper; + +/** + * A holder for the sequence of {@link NameDynAnyPair}. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class NameDynAnyPairSeqHolder + implements Streamable +{ + /** + * The stored array of <code>NameDynAnyPair</code>. + */ + public NameDynAnyPair[] value; + + /** + * Create the unitialised instance, leaving the value array + * with default <code>null</code> value. + */ + public NameDynAnyPairSeqHolder() + { + } + + /** + * Create the initialised instance. + * @param initialValue the array that will be assigned to + * the <code>value</code> array. + */ + public NameDynAnyPairSeqHolder(NameDynAnyPair[] initialValue) + { + value = initialValue; + } + + /** + * The method should read this object from the CDR input stream, but + * (following the JDK 1.5 API) it does not. + * + * @param input a org.omg.CORBA.portable stream to read from. + * + * @specenote Sun throws the same exception. + * + * @throws MARSHAL always. + */ + public void _read(InputStream input) + { + value = NameDynAnyPairSeqHelper.read(input); + } + + /** + * The method should write this object to the CDR input stream, but + * (following the JDK 1.5 API) it does not. + * + * @param input a org.omg.CORBA.portable stream to read from. + * + * @specenote Sun throws the same exception. + * + * @throws MARSHAL always. + */ + public void _write(OutputStream output) + { + NameDynAnyPairSeqHelper.write(output, value); + } + + /** + * Get the typecode of the NameDynAnyPair. + */ + public org.omg.CORBA.TypeCode _type() + { + return NameDynAnyPairSeqHelper.type(); + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/NameValuePairHolder.java b/libjava/classpath/gnu/CORBA/NameValuePairHolder.java new file mode 100644 index 00000000000..9a939d5e337 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/NameValuePairHolder.java @@ -0,0 +1,105 @@ +/* NameValuePairHolder.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.Streamable; +import org.omg.DynamicAny.NameValuePair; +import org.omg.DynamicAny.NameValuePairHelper; + +/** + * A holder for the structure {@link NameValuePair}. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class NameValuePairHolder + implements Streamable +{ + /** + * The stored NameValuePair value. + */ + public NameValuePair value; + + /** + * Create the unitialised instance, leaving the value field + * with default <code>null</code> value. + */ + public NameValuePairHolder() + { + } + + /** + * Create the initialised instance. + * @param initialValue the value that will be assigned to + * the <code>value</code> field. + */ + public NameValuePairHolder(NameValuePair initialValue) + { + value = initialValue; + } + + /** + * Fill in the {@link value} by data from the CDR stream. + * + * @param input the org.omg.CORBA.portable stream to read. + */ + public void _read(InputStream input) + { + value = NameValuePairHelper.read(input); + } + + /** + * Write the stored value into the CDR stream. + * + * @param output the org.omg.CORBA.portable stream to write. + */ + public void _write(OutputStream output) + { + NameValuePairHelper.write(output, value); + } + + /** + * Get the typecode of the NameValuePair. + */ + public org.omg.CORBA.TypeCode _type() + { + return NameValuePairHelper.type(); + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/NameValuePairSeqHolder.java b/libjava/classpath/gnu/CORBA/NameValuePairSeqHolder.java new file mode 100644 index 00000000000..216d78e04c8 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/NameValuePairSeqHolder.java @@ -0,0 +1,105 @@ +/* NameValuePairSeqHolder.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.Streamable; +import org.omg.DynamicAny.NameValuePair; +import org.omg.DynamicAny.NameValuePairSeqHelper; + +/** + * A holder for the sequence of {@link NameValuePair}. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class NameValuePairSeqHolder + implements Streamable +{ + /** + * The stored array of <code>NameValuePair</code>. + */ + public NameValuePair[] value; + + /** + * Create the unitialised instance, leaving the value array + * with default <code>null</code> value. + */ + public NameValuePairSeqHolder() + { + } + + /** + * Create the initialised instance. + * @param initialValue the array that will be assigned to + * the <code>value</code> array. + */ + public NameValuePairSeqHolder(NameValuePair[] initialValue) + { + value = initialValue; + } + + /** + * Read the {@link value} array from the CDR stream. + * + * @param input the org.omg.CORBA.portable stream to read. + */ + public void _read(InputStream input) + { + value = NameValuePairSeqHelper.read(input); + } + + /** + * Write the stored value into the CDR stream. + * + * @param output the org.omg.CORBA.portable stream to write. + */ + public void _write(OutputStream output) + { + NameValuePairSeqHelper.write(output, value); + } + + /** + * Get the typecode of the NameValuePair. + */ + public org.omg.CORBA.TypeCode _type() + { + return NameValuePairSeqHelper.type(); + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/NamingService/NameParser.java b/libjava/classpath/gnu/CORBA/NamingService/NameParser.java new file mode 100644 index 00000000000..f886cf93533 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/NamingService/NameParser.java @@ -0,0 +1,419 @@ +/* NameParser.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + + This file is part of GNU Classpath. + + GNU Classpath is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU Classpath is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Classpath; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. */ + + +package gnu.CORBA.NamingService; + +import gnu.CORBA.Functional_ORB; +import gnu.CORBA.IOR; +import gnu.CORBA.Unexpected; +import gnu.CORBA.Version; + +import org.omg.CORBA.BAD_PARAM; +import org.omg.CORBA.DATA_CONVERSION; +import org.omg.CORBA.ORB; +import org.omg.CORBA.Object; +import org.omg.CORBA.ORBPackage.InvalidName; +import org.omg.CORBA.portable.Delegate; +import org.omg.CORBA.portable.ObjectImpl; +import org.omg.CosNaming.NamingContext; +import org.omg.CosNaming.NamingContextExtHelper; +import org.omg.CosNaming.NamingContextHelper; +import org.omg.CosNaming._NamingContextStub; + +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.util.ArrayList; +import java.util.StringTokenizer; + +/** + * Parses the alternative IOR representations into our IOR structure. + * + * TODO This parser currently supports only one address per target string. A + * string with the multiple addresses will be accepted, but only the last + * address will be taken into consideration. The fault tolerance is not yet + * implemented. + * + * The key string is filtered using {@link java.net.URLDecoder} that replaces + * the agreed escape sequences by the corresponding non alphanumeric characters. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class NameParser + extends snConverter +{ + /** + * The corbaloc prefix. + */ + public static final String pxCORBALOC = "corbaloc"; + + /** + * The corbaname prefix. + */ + public static final String pxCORBANAME = "corbaname"; + + /** + * The IOR prefix. + */ + public static final String pxIOR = "ior"; + + /** + * Marks iiop protocol. + */ + public static final String IIOP = "iiop"; + + /** + * Marks rir protocol. + */ + public static final String RIR = "rir"; + + /** + * The default port value, as specified in OMG documentation. + */ + public static final int DEFAULT_PORT = 2809; + + /** + * The default name. + */ + public static final String DEFAULT_NAME = "NameService"; + + /** + * The string to name converter, initialized on demand. + */ + static snConverter converter; + + /** + * The current position. + */ + int p; + + /** + * The address being parsed, splitted into tokens. + */ + String[] t; + + /** + * Parse CORBALOC. + * + * The expected format is: <br> + * 1. corbaloc:[iiop][version.subversion@]:host[:port]/key <br> + * 2. corbaloc:rir:[/key] <br> + * 3. corbaname:[iiop][version.subversion@]:host[:port]/key <br> + * 4. corbaname:rir:[/key] <br> + * + * Protocol defaults to IOP, the object key defaults to the NameService. + * + * @param corbaloc the string to parse. + * @param orb the ORB, needed to create IORs and resolve rir references. + * + * @return the resolved object. + */ + public synchronized org.omg.CORBA.Object corbaloc(String corbaloc, + Functional_ORB orb) + throws BAD_PARAM + { + boolean corbaname; + + // The alternative addresses, if given. + ArrayList alt_addr = new ArrayList(); + + // The version numbers with default values. + int major = 1; + int minor = 0; + + // The host address. + String host; + + // The port. + int port = DEFAULT_PORT; + + // The object key as string. + String key; + + StringTokenizer st = new StringTokenizer(corbaloc, ":@/.,#", true); + + t = new String[st.countTokens()]; + + for (int i = 0; i < t.length; i++) + { + t[i] = st.nextToken(); + } + + p = 0; + + if (t[p].startsWith(pxCORBANAME)) + corbaname = true; + else if (t[p].equalsIgnoreCase(pxCORBALOC)) + corbaname = false; + else if (t[p].equalsIgnoreCase(pxIOR)) + { + IOR ior = IOR.parse(corbaloc); + return orb.ior_to_object(ior); + } + else + throw new DATA_CONVERSION("Unsupported protocol: '" + t[p] + "'"); + + p++; + + if (!t[p++].equals(":")) + throw new BAD_PARAM("Syntax (':' expected after name prefix)"); + + // Check for rir: + if (t[p].equals(RIR)) + { + p++; + if (!t[p++].equals(":")) + throw new BAD_PARAM("':' expected after 'rir'"); + + key = readKey("/"); + + Object object; + try + { + object = orb.resolve_initial_references(key); + return corbaname ? resolve(object) : object; + } + catch (InvalidName e) + { + throw new BAD_PARAM("Unknown initial reference '" + key + "'"); + } + } + else + // Check for iiop. + if (t[p].equals(IIOP) || t[p].equals(":")) + { + IOR ior = new IOR(); + + Addresses: do + { // Read addresses. + if (t[p].equals(":")) + { + p++; + } + else + { + p++; + if (!t[p++].equals(":")) + throw new BAD_PARAM("':' expected after 'iiop'"); + // Check if version is present. + if (t[p + 1].equals(".")) + if (t[p + 3].equals("@")) + { + // Version info present. + try + { + major = Integer.parseInt(t[p++]); + } + catch (NumberFormatException e) + { + throw new BAD_PARAM("Major version number '" + + t[p - 1] + "'"); + } + p++; // '.' at this point. + try + { + minor = Integer.parseInt(t[p++]); + } + catch (NumberFormatException e) + { + throw new BAD_PARAM("Major version number '" + + t[p - 1] + "'"); + } + p++; // '@' at this point. + } + } + + ior.Internet.version = new Version(major, minor); + + // Then host data goes till '/' or ':'. + StringBuffer bhost = new StringBuffer(corbaloc.length()); + while (!t[p].equals(":") && !t[p].equals("/") && !t[p].equals(",")) + bhost.append(t[p++]); + + host = bhost.toString(); + + ior.Internet.host = host; + + if (t[p].equals(":")) + { + // Port specified. + p++; + try + { + port = Integer.parseInt(t[p++]); + } + catch (NumberFormatException e) + { + throw new BAD_PARAM("Invalid port '" + t[p - 1] + "'"); + } + } + + ior.Internet.port = port; + + // Id is not listed. + ior.Id = ""; + + if (t[p].equals(",")) + p++; + else + break Addresses; + } + while (true); + + key = readKey("/"); + ior.key = key.getBytes(); + + org.omg.CORBA.Object object = orb.ior_to_object(ior); + return corbaname ? resolve(object) : object; + } + + else + throw new DATA_CONVERSION("Unsupported protocol '" + t[p] + "'"); + } + + private org.omg.CORBA.Object resolve(org.omg.CORBA.Object object) + { + NamingContext ns; + String key = "?"; + try + { + if (object instanceof NamingContext) + ns = (NamingContext) object; + else + { + Delegate delegate = ((ObjectImpl) object)._get_delegate(); + ns = new _NamingContextStub(delegate); + } + } + catch (Exception ex) + { + BAD_PARAM bad = new BAD_PARAM("The CORBANAME target " + object + + " is not a NamingContext"); + bad.minor = 10; + bad.initCause(ex); + throw bad; + } + + if (converter == null) + converter = new snConverter(); + + try + { + key = readKey("#"); + object = ns.resolve(converter.toName(key)); + return object; + } + catch (Exception ex) + { + BAD_PARAM bad = new BAD_PARAM("Wrong CORBANAME '" + key + "'"); + bad.minor = 10; + bad.initCause(ex); + throw bad; + } + } + + private String readKey(String delimiter) + throws BAD_PARAM + { + if (p < t.length) + if (!t[p].equals(delimiter)) + { + if (t[p].equals("#")) + return DEFAULT_NAME; + else + throw new BAD_PARAM("'" + delimiter + "String' expected '" + t[p] + + "' found"); + } + + StringBuffer bKey = new StringBuffer(); + p++; + + while (p < t.length && !t[p].equals("#")) + bKey.append(t[p++]); + + if (bKey.length() == 0) + return DEFAULT_NAME; + + try + { + return URLDecoder.decode(bKey.toString(), "UTF-8"); + } + catch (UnsupportedEncodingException e) + { + throw new Unexpected("URLDecoder does not support UTF-8", e); + } + } + + static NameParser n = new NameParser(); + + static void corbalocT(String ior, Functional_ORB orb) + { + System.out.println(ior); + System.out.println(n.corbaloc(ior, orb)); + System.out.println(); + } + + public static void main(String[] args) + { + try + { + Functional_ORB orb = (Functional_ORB) ORB.init(args, null); + corbalocT("corbaloc:iiop:1.3@155axyz.com/Prod/aTradingService", orb); + corbalocT("corbaloc:iiop:2.7@255bxyz.com/Prod/bTradingService", orb); + corbalocT("corbaloc:iiop:355cxyz.com/Prod/cTradingService", orb); + corbalocT("corbaloc:iiop:2.7@255bxyz.com/Prod/bTradingService", orb); + corbalocT("corbaloc:iiop:355cxyz.com:7777/Prod/cTradingService", orb); + + corbalocT("corbaloc::556xyz.com:80/Dev/NameService", orb); + corbalocT("corbaloc:iiop:1.2@host1:3076/0", orb); + + corbalocT("corbaloc:rir:/NameService", orb); + corbalocT("corbaloc:rir:/", orb); + corbalocT("corbaloc:rir:", orb); + + corbalocT("corbaloc:rir:/NameService", orb); + corbalocT("corbaloc:rir:/", orb); + corbalocT("corbaloc:rir:", orb); + + corbalocT("corbaloc::555xyz.com,:556xyz.com:80/Dev/NameService", orb); + } + catch (BAD_PARAM e) + { + e.printStackTrace(System.out); + } + } +} diff --git a/libjava/classpath/gnu/CORBA/Poa/ForwardRequestHolder.java b/libjava/classpath/gnu/CORBA/Poa/ForwardRequestHolder.java new file mode 100644 index 00000000000..5e2455952d2 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/ForwardRequestHolder.java @@ -0,0 +1,107 @@ +/* ForwardRequestHolder.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import gnu.CORBA.ForwardRequestHelper; + +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.Streamable; +import org.omg.PortableServer.ForwardRequest; + +/** +* A holder for the exception {@link ForwardRequest}. + +* @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) +*/ +public class ForwardRequestHolder + implements Streamable +{ + /** + * The stored ForwardRequest value. + */ + public ForwardRequest value; + + /** + * Create the unitialised instance, leaving the value field + * with default <code>null</code> value. + */ + public ForwardRequestHolder() + { + } + + /** + * Create the initialised instance. + * @param initialValue the value that will be assigned to + * the <code>value</code> field. + */ + public ForwardRequestHolder(ForwardRequest initialValue) + { + value = initialValue; + } + + /** + * Fill in the {@link value} by data from the CDR stream. + * + * @param input the org.omg.CORBA.portable stream to read. + */ + public void _read(InputStream input) + { + value = ForwardRequestHelper.read(input); + } + + /** + * Get the typecode of the ForwardRequest. + */ + public TypeCode _type() + { + return ForwardRequestHelper.type(); + } + + /** + * Write the stored value into the CDR stream. + * + * @param output the org.omg.CORBA.portable stream to write. + */ + public void _write(OutputStream output) + { + ForwardRequestHelper.write(output, value); + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/Poa/ForwardedServant.java b/libjava/classpath/gnu/CORBA/Poa/ForwardedServant.java new file mode 100644 index 00000000000..2df378df6a4 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/ForwardedServant.java @@ -0,0 +1,207 @@ +/* ForwardedServant.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import gnu.CORBA.IOR; +import gnu.CORBA.IOR_Delegate; +import gnu.CORBA.IOR_contructed_object; + +import org.omg.CORBA.BAD_PARAM; +import org.omg.CORBA.CompletionStatus; +import org.omg.CORBA.MARSHAL; +import org.omg.CORBA.ORB; +import org.omg.CORBA.SystemException; +import org.omg.CORBA.portable.ApplicationException; +import org.omg.CORBA.portable.Delegate; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.InvokeHandler; +import org.omg.CORBA.portable.ObjectImpl; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.RemarshalException; +import org.omg.CORBA.portable.ResponseHandler; +import org.omg.PortableServer.POA; +import org.omg.PortableServer.Servant; + +import java.io.IOException; + +/** + * A "virtual servant", delegating all invocation to the wrapped + * object (usually remote). Used in cases when it is necessary to + * handle the request forwarding. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class ForwardedServant + extends Servant + implements InvokeHandler +{ + /** + * The reference object, handling requests. + */ + public final ObjectImpl ref; + + /** + * Create an instance, forwarding requests to the given object. + */ + ForwardedServant(ObjectImpl a_ref) + { + ref = a_ref; + } + + /** + * Create an instance of the forwarded servant. + * + * @param a_ref a reference where request should be forwarded. + * + * @return a created forwarded servant or null if the parameter + * forwards request to itself. Returning null will force to find + * a right servant in one of many possible ways, depending on + * policies. + */ + public static Servant create(org.omg.CORBA.Object a_ref) + { + try + { + ObjectImpl fto = (ObjectImpl) a_ref; + + // Check maybe the remote side forwarded back to our local object. + if (fto instanceof IOR_contructed_object) + { + IOR_contructed_object iref = (IOR_contructed_object) fto; + + // Check maybe the IOR is local. + ORB t_orb = iref._orb(); + if (t_orb instanceof ORB_1_4) + { + ORB_1_4 orb = (ORB_1_4) t_orb; + Delegate d = iref._get_delegate(); + if (d instanceof IOR_Delegate) + { + IOR_Delegate ird = (IOR_Delegate) iref._get_delegate(); + IOR ior = ird.getIor(); + if (orb.LOCAL_HOST.equalsIgnoreCase(ior.Internet.host)) + { + activeObjectMap.Obj rx = orb.rootPOA.findIorKey(ior.key); + if (rx != null) + { + if (rx.object == fto || + rx.object._is_equivalent(fto) + ) + return rx.primary_servant; + else + fto = (ObjectImpl) rx.object; + } + } + } + } + } + return new ForwardedServant(fto); + } + catch (ClassCastException ex) + { + throw new BAD_PARAM("ObjectImpl required but " + a_ref + " passed ", + 0x5005, CompletionStatus.COMPLETED_NO + ); + } + } + + /** + * Forward the call to the wrapped object. + */ + public OutputStream _invoke(String method, InputStream input, + ResponseHandler handler + ) + throws SystemException + { + org.omg.CORBA.portable.InputStream in = null; + org.omg.CORBA.portable.OutputStream out = null; + try + { + try + { + out = ref._request(method, true); + + // Transfer request information. + int b; + while ((b = input.read()) >= 0) + { + out.write(b); + } + in = ref._invoke(out); + + // Read the returned data. + out = handler.createReply(); + while ((b = in.read()) >= 0) + { + out.write(b); + } + } + catch (IOException io_ex) + { + MARSHAL m = new MARSHAL(); + m.initCause(io_ex); + throw m; + } + } + catch (ApplicationException ex) + { + in = ex.getInputStream(); + + String _id = ex.getId(); + throw new MARSHAL(_id, 5101, CompletionStatus.COMPLETED_NO); + } + catch (RemarshalException remarsh) + { + _invoke(method, input, handler); + } + finally + { + ref._releaseReply(in); + } + return out; + } + + /** + * Delegates to the wrapped object. + */ + public String[] _all_interfaces(POA poa, byte[] key) + { + return ref._ids(); + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/Poa/LocalDelegate.java b/libjava/classpath/gnu/CORBA/Poa/LocalDelegate.java new file mode 100644 index 00000000000..7af3369d2e8 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/LocalDelegate.java @@ -0,0 +1,382 @@ +/* LocalDelegate.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import gnu.CORBA.CDR.cdrOutput; +import gnu.CORBA.streamRequest; + +import org.omg.CORBA.ARG_INOUT; +import org.omg.CORBA.Bounds; +import org.omg.CORBA.Context; +import org.omg.CORBA.ContextList; +import org.omg.CORBA.ExceptionList; +import org.omg.CORBA.NO_IMPLEMENT; +import org.omg.CORBA.NVList; +import org.omg.CORBA.NamedValue; +import org.omg.CORBA.OBJECT_NOT_EXIST; +import org.omg.CORBA.ORB; +import org.omg.CORBA.Request; +import org.omg.CORBA.TypeCodePackage.BadKind; +import org.omg.CORBA.UnknownUserException; +import org.omg.CORBA.portable.ApplicationException; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.InvokeHandler; +import org.omg.CORBA.portable.ObjectImpl; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.RemarshalException; +import org.omg.PortableServer.ServantLocatorPackage.CookieHolder; + +import java.util.Arrays; + +/** + * A local delegate, transferring all object requests to the locally available + * servant. This class is involved in handling the method invocations on the + * local object, obtained by POA.create_reference_with_id. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class LocalDelegate extends org.omg.CORBA_2_3.portable.Delegate +{ + /** + * The same servant as an invocation handler. + */ + gnuServantObject object; + String operation; + final gnuPOA poa; + final byte[] Id; + + /** + * Create a local delegate, forwarding requests to the servant that must also + * be an invocation handler. + */ + public LocalDelegate(gnuServantObject an_object, gnuPOA a_poa, byte[] an_id) + { + object = an_object; + poa = a_poa; + Id = an_id; + } + + public Request request(org.omg.CORBA.Object target, String method) + { + operation = method; + + LocalRequest rq = new LocalRequest(object, poa, Id); + rq.setOperation(method); + rq.setORB(orb(target)); + return rq; + } + + public void release(org.omg.CORBA.Object target) + { + } + + public boolean is_equivalent(org.omg.CORBA.Object target, + org.omg.CORBA.Object other + ) + { + if (target == other) + return true; + else if (target instanceof ObjectImpl && other instanceof ObjectImpl) + { + org.omg.CORBA.portable.Delegate a = null; + org.omg.CORBA.portable.Delegate b = null; + try + { + a = ((ObjectImpl) target)._get_delegate(); + b = ((ObjectImpl) other)._get_delegate(); + } + catch (Exception ex) + { + // Unable to get one of the delegates. + return false; + } + if (a instanceof LocalDelegate && b instanceof LocalDelegate) + { + byte[] k1 = ((LocalDelegate) a).Id; + byte[] k2 = ((LocalDelegate) b).Id; + return Arrays.equals(k1, k2); + } + else + return false; + } + else + return false; + } + + /** + * Always return false. + */ + public boolean non_existent(org.omg.CORBA.Object target) + { + return false; + } + + /** + * Get hash code. + */ + public int hash(org.omg.CORBA.Object target, int maximum) + { + return hashCode() % maximum; + } + + /** + * Check if this object could be named by the given repository id. + * + * @param idl_id the repository id to check. + * + * @return true if it is one of the possible repository ids of this object. + */ + public boolean is_a(org.omg.CORBA.Object a_servant, String idl_id) + { + String[] maybe = object._ids(); + for (int i = 0; i < maybe.length; i++) + { + if (maybe [ i ].equals(idl_id)) + return true; + } + return false; + } + + /** + * Return <code>this</code>. + */ + public org.omg.CORBA.Object duplicate(org.omg.CORBA.Object target) + { + return target; + } + + /** + * Create request for using with DII. + */ + public Request create_request(org.omg.CORBA.Object target, Context context, + String method, NVList parameters, NamedValue returns, + ExceptionList exceptions, ContextList ctx_list + ) + { + operation = method; + + LocalRequest rq = new LocalRequest(object, poa, Id); + rq.setOperation(method); + rq.set_args(parameters); + rq.set_result(returns); + rq.set_exceptions(exceptions); + rq.set_context_list(ctx_list); + return rq; + } + + /** + * Create request for using with DII. + */ + public Request create_request(org.omg.CORBA.Object target, Context context, + String method, NVList parameters, NamedValue returns + ) + { + operation = method; + + LocalRequest rq = new LocalRequest(object, poa, Id); + rq.setOperation(method); + rq.set_args(parameters); + rq.set_result(returns); + return rq; + } + + /** + * Not in use. + */ + public org.omg.CORBA.Object get_interface_def(org.omg.CORBA.Object target) + { + throw new NO_IMPLEMENT(); + } + + /** + * Create a request to invoke the method of this CORBA object. + * + * @param operation the name of the method to invoke. + * @param response_expected specifies if this is one way message or the + * response to the message is expected. + * + * @return the stream where the method arguments should be written. + */ + public org.omg.CORBA.portable.OutputStream request( + org.omg.CORBA.Object target, + String method, + boolean response_expected + ) + { + operation = method; + + // Check if the object is not explicitly deactivated. + activeObjectMap.Obj e = poa.aom.get(Id); + if (e != null && e.isDeactiveted()) + { + if (poa.servant_activator != null || poa.servant_locator != null) + { + // This will force the subsequent activation. + object.setServant(null); + e.setServant(null); + e.setDeactivated(false); + } + else + throw new OBJECT_NOT_EXIST("Deactivated"); + } + + LocalRequest rq = new LocalRequest(object, poa, Id); + rq.setOperation(method); + rq.setORB(orb(target)); + return rq.getParameterStream(); + } + + /** + * Return the associated invocation handler. + */ + public InvokeHandler getHandler(String method, CookieHolder cookie) + { + return object.getHandler(method, cookie, false); + } + + /** + * Return the ORB of the associated POA. The parameter is not in use. + */ + public ORB orb(org.omg.CORBA.Object target) + { + return poa.orb(); + } + + /** + * Make an invocation. + * + * @param target not in use. + * @param output the stream request that should be returned by + * {@link #m_request} in this method. + * @throws ApplicationException if the use exception is thrown by the servant + * method. + */ + public InputStream invoke(org.omg.CORBA.Object target, OutputStream output) + throws ApplicationException + { + try + { + streamRequest sr = (streamRequest) output; + + LocalRequest lr = (LocalRequest) sr.request; + InvokeHandler handler = + lr.object.getHandler(lr.operation(), lr.cookie, false); + + if (handler instanceof dynImpHandler) + { + // The local request known how to handle it, but the different + // method must be called. + lr.invoke(); + + // The encapsulation will inherit orb, endian, charsets, etc. + cdrOutput buf = sr.createEncapsulation(); + + // Write all request parameters to the buffer stream. + if (lr.env().exception() != null) + { + try + { + UnknownUserException uex = + (UnknownUserException) lr.env().exception(); + throw new ApplicationException(uex.except.type().id(), + uex.except.create_input_stream() + ); + } + catch (BadKind ex) + { + InternalError ierr = new InternalError(); + ierr.initCause(ex); + throw ierr; + } + } + if (lr.return_value() != null) + lr.return_value().write_value(buf); + + NamedValue a; + try + { + for (int i = 0; i < lr.arguments().count(); i++) + { + a = lr.arguments().item(i); + if (a.flags() == ARG_INOUT.value || + a.flags() == ARG_INOUT.value + ) + { + a.value().write_value(buf); + } + } + } + catch (Bounds ex) + { + InternalError ierr = new InternalError(); + ierr.initCause(ex); + throw ierr; + } + + return buf.create_input_stream(); + } + else + { + LocalRequest lrq = (LocalRequest) sr.request; + return lrq.s_invoke(handler); + } + } + catch (gnuForwardRequest f) + { + try + { + return ((ObjectImpl) f.forward_reference)._invoke(f.forward_reference._request( + operation, + true + ) + ); + } + catch (RemarshalException e) + { + // Never thrown in this place by Classpath implementation. + throw new NO_IMPLEMENT(); + } + } + } + + public void releaseReply(org.omg.CORBA.Object target, InputStream input) + { + release(target); + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/Poa/LocalRequest.java b/libjava/classpath/gnu/CORBA/Poa/LocalRequest.java new file mode 100644 index 00000000000..a727499fce5 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/LocalRequest.java @@ -0,0 +1,684 @@ +/* LocalRequest.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import gnu.CORBA.CDR.cdrBufOutput; +import gnu.CORBA.GIOP.MessageHeader; +import gnu.CORBA.GIOP.v1_2.ReplyHeader; +import gnu.CORBA.GIOP.v1_2.RequestHeader; +import gnu.CORBA.Interceptor.gnuClientRequestInfo; +import gnu.CORBA.Interceptor.gnuServerRequestInfo; +import gnu.CORBA.ObjectCreator; +import gnu.CORBA.Unexpected; +import gnu.CORBA.gnuAny; +import gnu.CORBA.gnuRequest; +import gnu.CORBA.recordTypeCode; +import gnu.CORBA.streamReadyHolder; +import gnu.CORBA.streamRequest; + +import org.omg.CORBA.ARG_OUT; +import org.omg.CORBA.Any; +import org.omg.CORBA.BAD_INV_ORDER; +import org.omg.CORBA.BAD_OPERATION; +import org.omg.CORBA.Bounds; +import org.omg.CORBA.NamedValue; +import org.omg.CORBA.ORB; +import org.omg.CORBA.SystemException; +import org.omg.CORBA.TCKind; +import org.omg.CORBA.UnknownUserException; +import org.omg.CORBA.UserException; +import org.omg.CORBA.portable.ApplicationException; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.InvokeHandler; +import org.omg.CORBA.portable.ObjectImpl; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.ResponseHandler; +import org.omg.PortableInterceptor.ClientRequestInterceptorOperations; +import org.omg.PortableInterceptor.ForwardRequest; +import org.omg.PortableInterceptor.ServerRequestInterceptorOperations; +import org.omg.PortableServer.CurrentOperations; +import org.omg.PortableServer.CurrentPackage.NoContext; +import org.omg.PortableServer.DynamicImplementation; +import org.omg.PortableServer.POA; +import org.omg.PortableServer.Servant; +import org.omg.PortableServer.ServantLocatorPackage.CookieHolder; +import org.omg.PortableServer.portable.Delegate; + +import java.io.IOException; + +/** + * Directs the invocation to the locally available servant. The POA servant does + * not longer implement the CORBA object and cannot be substituted directly. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class LocalRequest extends gnuRequest implements ResponseHandler, + CurrentOperations +{ + /** + * Used by servant locator, if involved. + */ + CookieHolder cookie; + + /** + * The object Id. + */ + final byte[] Id; + + /** + * The message header (singleton is sufficient). + */ + private static final MessageHeader header = new MessageHeader(); + + /** + * True if the stream was obtained by invoking {@link #createExceptionReply()}, + * false otherwise. + */ + boolean exceptionReply; + + /** + * The buffer to write into. + */ + cdrBufOutput buffer; + + /** + * The responsible POA. + */ + final gnuPOA poa; + + /** + * The servant delegate to obtain the handler. + */ + gnuServantObject object; + + /** + * Used (reused) with dynamic implementation. + */ + LocalServerRequest serverRequest; + + /** + * Create an instance of the local request. + */ + public LocalRequest(gnuServantObject local_object, gnuPOA a_poa, byte[] an_id) + { + Id = an_id; + poa = a_poa; + + // Instantiate the cookie holder only if required. + if (poa.servant_locator != null) + { + cookie = new CookieHolder(); + } + object = local_object; + prepareStream(); + } + + /** + * Make an invocation and return a stream from where the results can be read + * and throw ApplicationException, where applicable. + */ + org.omg.CORBA.portable.InputStream s_invoke(InvokeHandler handler) + throws ApplicationException + { + try + { + poa.m_orb.currents.put(Thread.currentThread(), this); + + org.omg.CORBA.portable.InputStream input = v_invoke(handler); + + if (!exceptionReply) + { + return input; + } + else + { + input.mark(500); + + String id = input.read_string(); + try + { + input.reset(); + } + catch (IOException ex) + { + InternalError ierr = new InternalError(); + ierr.initCause(ex); + throw ierr; + } + throw new ApplicationException(id, input); + } + } + finally + { + poa.m_orb.currents.remove(Thread.currentThread()); + } + } + + /** + * Make an invocation and return a stream from where the results can be read. + * + * @param the invoke handler (can be null, then it is obtained self + * dependently). + */ + public org.omg.CORBA.portable.InputStream v_invoke(InvokeHandler handler) + { + // Local request must be intercepted both by server and request + // interceptors. + boolean s_intercept = false; + ServerRequestInterceptorOperations s_interceptor = null; + gnuServerRequestInfo s_info = null; + + boolean c_intercept = false; + ClientRequestInterceptorOperations c_interceptor = null; + gnuClientRequestInfo c_info = null; + + try + { + if (poa.m_orb.iServer != null || poa.m_orb.iClient != null) + { + setORB(poa.m_orb); + + // These two are only needed with interceptors. + m_rqh = new RequestHeader(); + m_rqh.operation = m_operation; + m_rph = new ReplyHeader(); + + m_rqh.object_key = object.Id; + m_rph.request_id = m_rqh.request_id; + } + + if (poa.m_orb.iClient != null) + { + c_interceptor = poa.m_orb.iClient; + + c_info = new gnuClientRequestInfo(this); + c_intercept = true; + + c_interceptor.send_request(c_info); + + m_target = object; + } + + if (poa.m_orb.iServer != null) + { + s_interceptor = poa.m_orb.iServer; + + s_info = new gnuServerRequestInfo(object, m_rqh, m_rph); + s_info.m_request = this; + + s_intercept = true; + + s_interceptor.receive_request_service_contexts(s_info); + } + + if (handler == null) + { + handler = object.getHandler(operation(), cookie, false); + } + + cdrBufOutput request_part = new cdrBufOutput(); + + request_part.setOrb(orb()); + + if (m_args != null && m_args.count() > 0) + { + write_parameters(header, request_part); + + if (m_parameter_buffer != null) + { + throw new BAD_INV_ORDER("Please either add parameters or " + + "write them into stream, but not both " + "at once." + ); + } + } + + if (m_parameter_buffer != null) + { + write_parameter_buffer(header, request_part); + } + + Servant servant; + + if (handler instanceof Servant) + { + servant = (Servant) handler; + } + else + { + throw new BAD_OPERATION("Unexpected handler type " + handler); + } + + org.omg.CORBA.portable.InputStream input = + request_part.create_input_stream(); + + // Ensure the servant (handler) has a delegate set. + servantDelegate sd = null; + + Delegate d = null; + + try + { + d = servant._get_delegate(); + } + catch (Exception ex) + { + // In some cases exception is thrown if the delegate is not set. + } + if (d instanceof servantDelegate) + { + // If the delegate is already set, try to reuse the existing + // instance. + sd = (servantDelegate) d; + if (sd.object != object) + { + sd = new servantDelegate(servant, poa, Id); + } + } + else + { + sd = new servantDelegate(servant, poa, Id); + } + servant._set_delegate(sd); + + try + { + ORB o = orb(); + if (o instanceof ORB_1_4) + { + ((ORB_1_4) o).currents.put(Thread.currentThread(), this); + } + + try + { + if (s_intercept) + { + s_interceptor.receive_request(s_info); + } + handler._invoke(m_operation, input, this); + + // Handler is casted into i_handler. + if ((s_intercept || c_intercept) && isExceptionReply()) + { + s_info.m_reply_header.reply_status = + ReplyHeader.USER_EXCEPTION; + m_rph.reply_status = ReplyHeader.USER_EXCEPTION; + + // Make Any, holding the user exception. + Any a = new gnuAny(); + OutputStream buf = getBuffer(); + InputStream in = buf.create_input_stream(); + String uex_idl = "unknown"; + try + { + in.mark(Integer.MAX_VALUE); + uex_idl = in.read_string(); + m_exception_id = uex_idl; + in.reset(); + } + catch (IOException e) + { + throw new Unexpected(e); + } + + try + { + UserException exception = + ObjectCreator.readUserException(uex_idl, in); + + m_environment.exception(exception); + ObjectCreator.insertWithHelper(a, exception); + } + catch (Exception e) + { + // Failed due any reason, insert without + // helper. + a.insert_Streamable(new streamReadyHolder( + buf.create_input_stream() + ) + ); + + recordTypeCode r = + new recordTypeCode(TCKind.tk_except); + r.setId(uex_idl); + r.setName(ObjectCreator.getDefaultName(uex_idl)); + } + + s_info.m_usr_exception = a; + c_info.m_wrapped_exception = a; + s_interceptor.send_exception(s_info); + c_interceptor.receive_exception(c_info); + } + else + { + if (s_intercept) + { + s_info.m_reply_header.reply_status = + ReplyHeader.NO_EXCEPTION; + s_interceptor.send_reply(s_info); + } + if (c_intercept) + { + m_rph.reply_status = ReplyHeader.NO_EXCEPTION; + c_interceptor.receive_reply(c_info); + } + } + } + catch (SystemException sys_ex) + { + if (s_intercept) + { + s_info.m_reply_header.reply_status = + ReplyHeader.SYSTEM_EXCEPTION; + s_info.m_sys_exception = sys_ex; + s_interceptor.send_exception(s_info); + } + + if (c_intercept) + { + m_rph.reply_status = ReplyHeader.SYSTEM_EXCEPTION; + + Any a = new gnuAny(); + if (ObjectCreator.insertSysException(a, sys_ex)) + { + c_info.m_wrapped_exception = a; + } + c_interceptor.receive_exception(c_info); + } + + throw sys_ex; + } + } + finally + { + ORB o = orb(); + if (o instanceof ORB_1_4) + { + ((ORB_1_4) o).currents.remove(Thread.currentThread()); + } + } + + if (poa.servant_locator != null) + { + poa.servant_locator.postinvoke(object.Id, poa, operation(), + cookie.value, object.getServant() + ); + } + return buffer.create_input_stream(); + } + + catch (ForwardRequest fex) + { + // May be thrown by interceptor. + if (s_intercept) + { + Forwarding: + while (true) + { + s_info.m_reply_header.reply_status = + ReplyHeader.LOCATION_FORWARD; + s_info.m_forward_reference = fex.forward; + try + { + s_interceptor.send_other(s_info); + break Forwarding; + } + catch (ForwardRequest fex2) + { + s_info.m_forward_reference = fex2.forward; + fex.forward = s_info.m_forward_reference; + } + } + } + + if (c_intercept) + { + this.m_rph.reply_status = ReplyHeader.LOCATION_FORWARD; + this.m_forwarding_target = fex.forward; + try + { + c_interceptor.receive_other(c_info); + } + catch (ForwardRequest fex2) + { + fex.forward = fex2.forward; + } + } + throw new gnuForwardRequest(fex.forward); + } + catch (gnuForwardRequest fex) + { + // May be thrown during activation. + // May be thrown during activation. + if (s_intercept) + { + Forwarding: + while (true) + { + s_info.m_reply_header.reply_status = + ReplyHeader.LOCATION_FORWARD; + s_info.m_forward_reference = fex.forward_reference; + try + { + s_interceptor.send_other(s_info); + break Forwarding; + } + catch (ForwardRequest fex2) + { + s_info.m_forward_reference = fex2.forward; + fex.forward_reference = (ObjectImpl) fex2.forward; + } + } + } + + if (c_intercept) + { + this.m_rph.reply_status = ReplyHeader.LOCATION_FORWARD; + this.m_forwarding_target = fex.forward_reference; + try + { + c_interceptor.receive_other(c_info); + } + catch (ForwardRequest fex2) + { + fex.forward_reference = (ObjectImpl) fex2.forward; + } + } + throw fex; + } + } + + /** + * Make an invocation and store the result in the fields of this Request. Used + * with DII only. + */ + public void invoke() + { + InvokeHandler handler = object.getHandler(operation(), cookie, false); + + if (handler instanceof dynImpHandler) + { + DynamicImplementation dyn = ((dynImpHandler) handler).servant; + if (serverRequest == null) + { + serverRequest = new LocalServerRequest(this); + } + try + { + poa.m_orb.currents.put(Thread.currentThread(), this); + dyn.invoke(serverRequest); + } + finally + { + poa.m_orb.currents.remove(Thread.currentThread()); + } + } + else + { + org.omg.CORBA.portable.InputStream input = v_invoke(handler); + + if (!exceptionReply) + { + NamedValue arg; + + // Read return value, if set. + if (m_result != null) + { + m_result.value().read_value(input, m_result.value().type()); + } + + // Read returned parameters, if set. + if (m_args != null) + { + for (int i = 0; i < m_args.count(); i++) + { + try + { + arg = m_args.item(i); + + // Both ARG_INOUT and ARG_OUT have this binary flag set. + if ((arg.flags() & ARG_OUT.value) != 0) + { + arg.value().read_value(input, arg.value().type()); + } + } + catch (Bounds ex) + { + Unexpected.error(ex); + } + } + } + } + else// User exception reply + { + // Prepare an Any that will hold the exception. + gnuAny exc = new gnuAny(); + + exc.insert_Streamable(new streamReadyHolder(input)); + + UnknownUserException unuex = new UnknownUserException(exc); + m_environment.exception(unuex); + } + } + } + + /** + * Get an output stream for providing details about the exception. Before + * returning the stream, the handler automatically writes the message header + * and the reply about exception header, but not the message header. + * + * @return the stream to write exception details into. + */ + public OutputStream createExceptionReply() + { + exceptionReply = true; + prepareStream(); + return buffer; + } + + /** + * Get an output stream for writing a regular reply (not an exception). + * + * Before returning the stream, the handler automatically writes the regular + * reply header, but not the message header. + * + * @return the output stream for writing a regular reply. + */ + public OutputStream createReply() + { + exceptionReply = false; + prepareStream(); + return buffer; + } + + /** + * Get the buffer, normally containing the written reply. The reply includes + * the reply header (or the exception header) but does not include the message + * header. + * + * The stream buffer can also be empty if no data have been written into + * streams, returned by {@link #createReply()} or + * {@link #createExceptionReply()}. + * + * @return the CDR output stream, containing the written output. + */ + cdrBufOutput getBuffer() + { + return buffer; + } + + /** + * True if the stream was obtained by invoking {@link #createExceptionReply()}, + * false otherwise (usually no-exception reply). + */ + boolean isExceptionReply() + { + return exceptionReply; + } + + /** + * Compute the header offset, set the correct version number and codeset. + */ + private void prepareStream() + { + buffer = new cdrBufOutput(); + buffer.setOrb(orb()); + } + + /** + * Get the parameter stream, where the invocation arguments should be written + * if they are written into the stream directly. + */ + public streamRequest getParameterStream() + { + m_parameter_buffer = new streamRequest(); + m_parameter_buffer.request = this; + m_parameter_buffer.setOrb(poa.orb()); + return m_parameter_buffer; + } + + public byte[] get_object_id() throws NoContext + { + return Id; + } + + public POA get_POA() throws NoContext + { + return poa; + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/Poa/LocalServerRequest.java b/libjava/classpath/gnu/CORBA/Poa/LocalServerRequest.java new file mode 100644 index 00000000000..6d0b39650c1 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/LocalServerRequest.java @@ -0,0 +1,199 @@ +/* LocalServerRequest.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import gnu.CORBA.gnuNamedValue; + +import org.omg.CORBA.ARG_INOUT; +import org.omg.CORBA.ARG_OUT; +import org.omg.CORBA.Any; +import org.omg.CORBA.BAD_PARAM; +import org.omg.CORBA.Bounds; +import org.omg.CORBA.Context; +import org.omg.CORBA.NVList; +import org.omg.CORBA.NamedValue; +import org.omg.CORBA.ServerRequest; +import org.omg.CORBA.UnknownUserException; + +/** + * Used to make local invocations via LocalRequest. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class LocalServerRequest + extends ServerRequest +{ + /** + * The local request, on the base of that this instance is created. + */ + final LocalRequest request; + + /** + * Create a new instance. + */ + public LocalServerRequest(LocalRequest _request) + { + request = _request; + } + + /** + * Get the argument list that can be modified. + */ + public void params(NVList args) + { + arguments(args); + } + + /** + * Get contexts. + */ + public Context ctx() + { + return request.ctx(); + } + + /** + * Get the operatin being performed. + */ + public String operation() + { + return request.operation(); + } + + /** + * Get the argument list that can be modified. + * The direction depends on the size of the passed list. + * The empty list is filled with the request arguments. + * The non-empty list is used to set the request arguments. + */ + public void arguments(NVList args) + { + NVList l = request.arguments(); + NamedValue a; + + try + { + if (args.count() == 0) + { + // Transfer to the passed parameter. + for (int i = 0; i < l.count(); i++) + { + a = l.item(i); + args.add_value(a.name(), a.value(), a.flags()); + } + } + else + { + // Transfer from the passed parameter. + if (l.count() != args.count()) + throw new BAD_PARAM("Argument number mismatch, current " + + l.count() + ", passed " + args.count() + ); + try + { + for (int i = 0; i < l.count(); i++) + { + a = l.item(i); + if (a.flags() == ARG_INOUT.value || + a.flags() == ARG_OUT.value + ) + { + ((gnuNamedValue) a).setValue(args.item(i).value()); + } + } + } + catch (ClassCastException cex) + { + InternalError ierr = new InternalError(); + ierr.initCause(cex); + throw ierr; + } + } + } + catch (Bounds ex) + { + InternalError ierr = new InternalError(); + ierr.initCause(ex); + throw ierr; + } + } + + /** + * Set the result. + */ + public void set_result(Any result) + { + gnuNamedValue g = new gnuNamedValue(); + g.setValue(result); + g.setFlags(ARG_OUT.value); + request.set_result(g); + } + + /** + * Get the name of the method being called. + */ + public String op_name() + { + return request.operation(); + } + + /** + * Set the exception that has been thrown. + */ + public void set_exception(Any exc) + { + request.env().exception(new UnknownUserException(exc)); + } + + /** + * Set the result. + */ + public void result(Any r) + { + set_result(r); + } + + /** + * Set the exception. + */ + public void except(Any exc) + { + set_exception(exc); + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/Poa/ORB_1_4.java b/libjava/classpath/gnu/CORBA/Poa/ORB_1_4.java new file mode 100644 index 00000000000..d95bf2be8f6 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/ORB_1_4.java @@ -0,0 +1,256 @@ +/* ORB_1_4.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import gnu.CORBA.Functional_ORB; +import gnu.CORBA.IOR; +import gnu.CORBA.Connected_objects.cObject; +import gnu.CORBA.DynAn.gnuDynAnyFactory; +import gnu.CORBA.Interceptor.ClientRequestInterceptors; +import gnu.CORBA.Interceptor.IORInterceptors; +import gnu.CORBA.Interceptor.Registrator; +import gnu.CORBA.Interceptor.ServerRequestInterceptors; +import gnu.CORBA.Interceptor.gnuIcCurrent; +import gnu.CORBA.Interceptor.gnuIorInfo; + +import org.omg.CORBA.Any; +import org.omg.CORBA.BAD_OPERATION; +import org.omg.CORBA.BAD_PARAM; +import org.omg.CORBA.OBJECT_NOT_EXIST; +import org.omg.CORBA.Policy; +import org.omg.CORBA.PolicyError; +import org.omg.CORBA.portable.ObjectImpl; +import org.omg.PortableInterceptor.PolicyFactory; +import org.omg.PortableServer.POA; +import org.omg.PortableServer.POAPackage.InvalidPolicy; + +import java.applet.Applet; +import java.util.Properties; + +/** + * The ORB, supporting POAs that are the feature of jdk 1.4. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class ORB_1_4 + extends Functional_ORB +{ + /** + * The root POA. + */ + public final gnuPOA rootPOA; + + /** + * Maps the active threads to the invocation data ("POA Current's"). + */ + public gnuPoaCurrent currents = new gnuPoaCurrent(); + + /** + * Maps the active threads to the interceptor data ("Interceptor Current's"). + */ + public gnuIcCurrent ic_current = new gnuIcCurrent(this); + + /** + * Creates dynamic anys. + */ + public gnuDynAnyFactory factory = new gnuDynAnyFactory(this); + + /** + * Calls the parent constructor and additionally puts the "RootPOA", + * "RootPOAManager", "POACurrent" and "DynAnyFactory" into initial references. + */ + public ORB_1_4() + { + super(); + try + { + rootPOA = new gnuPOA(null, "RootPOA", null, policySets.rootPoa(), this); + } + catch (InvalidPolicy ex) + { + // Invalid default policy set. + InternalError ierr = new InternalError(); + ierr.initCause(ex); + throw ierr; + } + initial_references.put("RootPOA", rootPOA); + initial_references.put("RootPOAManager", rootPOA.the_POAManager()); + initial_references.put("POACurrent", currents); + initial_references.put("DynAnyFactory", factory); + initial_references.put("PICurrent", ic_current); + } + + /** + * If the super method detects that the object is not connected to this ORB, + * try to find and activate the object. + */ + public String object_to_string(org.omg.CORBA.Object forObject) + { + try + { + return super.object_to_string(forObject); + } + catch (Exception ex) + { + try + { + activeObjectMap.Obj exists = rootPOA.findObject(forObject); + if (exists == null) + throw new OBJECT_NOT_EXIST(forObject == null ? "null" + : forObject.toString()); + else if (exists.poa instanceof gnuPOA) + ((gnuPOA) exists.poa).connect_to_orb(exists.key, forObject); + else + exists.poa.create_reference_with_id(exists.key, + ((ObjectImpl) exists.object)._ids()[0]); + } + catch (Exception bex) + { + BAD_PARAM bad = new BAD_PARAM("Unable to activate " + forObject); + bad.initCause(bex); + throw bad; + } + + return super.object_to_string(forObject); + } + } + + /** + * Destroy all poas and then call the superclass method. + */ + public void destroy() + { + // This will propagate through the whole POA tree. + rootPOA.destroy(true, false); + + super.destroy(); + } + + /** + * Do interceptor registration. + * + * @param properties the properties, between those names the agreed prefix + * "org.omg.PortableInterceptor.ORBInitializerClass." is searched. + * + * @param args the string array, passed to the ORB.init + */ + protected void registerInterceptors(Properties properties, String[] args) + { + Registrator registrator = new Registrator(this, properties, args); + + policyFactories = registrator.m_policyFactories; + + registrator.pre_init(); + initial_references.putAll(registrator.getRegisteredReferences()); + registrator.post_init(); + + if (registrator.hasIorInterceptors()) + iIor = new IORInterceptors(registrator); + + if (registrator.hasServerRequestInterceptors()) + iServer = new ServerRequestInterceptors(registrator); + + if (registrator.hasClientRequestInterceptors()) + iClient = new ClientRequestInterceptors(registrator); + + policyFactories = registrator.m_policyFactories; + } + + /** + * Create IOR and allow registered interceptors to add additional components. + */ + protected IOR createIOR(cObject ref) + throws BAD_OPERATION + { + IOR ior = super.createIOR(ref); + if (iIor != null) + { + activeObjectMap.Obj obj = rootPOA.findIorKey(ior.key); + + POA poa; + + // Null means that the object was connected to the ORB directly. + if (obj == null) + poa = rootPOA; + else + poa = obj.poa; + + gnuIorInfo info = new gnuIorInfo(this, poa, ior); + + // This may modify the ior. + iIor.establish_components(info); + } + return ior; + } + + /** + * Create policy using the previously registered factory. + */ + public Policy create_policy(int type, Any value) + throws PolicyError + { + Integer policy = new Integer(type); + + PolicyFactory forge = (PolicyFactory) policyFactories.get(policy); + if (forge == null) + throw new PolicyError("No factory registered for policy " + type, + (short) type); + else + return forge.create_policy(type, value); + } + + /** + * Set the parameters and then register interceptors. + */ + protected void set_parameters(Applet app, Properties props) + { + super.set_parameters(app, props); + registerInterceptors(props, new String[0]); + } + + /** + * Set the parameters and then register interceptors. + */ + protected void set_parameters(String[] para, Properties props) + { + super.set_parameters(para, props); + registerInterceptors(props, para); + } + +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/Poa/activeObjectMap.java b/libjava/classpath/gnu/CORBA/Poa/activeObjectMap.java new file mode 100644 index 00000000000..1354ba9c5e1 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/activeObjectMap.java @@ -0,0 +1,394 @@ +/* activeObjectMap.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import gnu.CORBA.ByteArrayComparator; + +import org.omg.PortableServer.POA; +import org.omg.PortableServer.Servant; + +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; + +/** + * Implements the conception of the Active Object Map. + * If the POA supports the RETAIN policy, it maintains an Active + * Object Map, that associates Object Ids with active servants. + * Each association constitutes an active object. We use a single map + * for all POAs on the given orb. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class activeObjectMap +{ + /** + * The reference data about the object, placed on the AOM. + */ + public class Obj + { + /** + * Create an initialised instance. + */ + Obj(org.omg.CORBA.Object _object, byte[] _key, Servant _servant, POA _poa) + { + object = _object; + key = _key; + servant = _servant; + poa = _poa; + } + + /** + * The object. + */ + public final org.omg.CORBA.Object object; + + /** + * The servant, serving the given object. + */ + public Servant servant; + + /** + * The local servant that once served this object. + * This field is used by {@link ForwardedServant} when it discovers that + * the forwarding chaing returns back to the original location. + * It should not be used anywhere else. + */ + Servant primary_servant; + + /** + * The POA, where the object is connected. + */ + public final POA poa; + + /** + * The object key. + */ + public final byte[] key; + + /** + * If true, this entry is deactivated. + */ + public boolean deactivated; + + /** + * Set the servant value, preserving any non null + * value as the primary servant. + */ + public void setServant(Servant s) + { + if (primary_servant == null) + primary_servant = s; + servant = s; + } + + /** + * Get the servant. + */ + public Servant getServant() + { + return servant; + } + + /** + * Get the deactivation state. + */ + public boolean isDeactiveted() + { + return deactivated; + } + + /** + * Set the deactivation state. + */ + public void setDeactivated(boolean state) + { + deactivated = state; + } + + public boolean equals(java.lang.Object other) + { + if (other instanceof Obj) + { + Obj o = (Obj) other; + return o.object.equals(object); + } + else + return false; + } + } + + /** + * The free number to give for the next instance. + * This field is incremented each time the + * new collection of the connected objects is created. + * Each collection has its own unique instance number. + */ + private static long free_id; + + /** + * The map of the all connected objects, maps the object key to the + * object. + */ + Map objects = new TreeMap(new ByteArrayComparator()); + + /** + * Get the record of the stored object. If the object is mapped + * several times under the different keys, one of the mappings + * is used. + * + * @param object the stored object + * + * @return the record about the stored object, null if + * this object is not stored here. + */ + public Obj findObject(org.omg.CORBA.Object stored_object) + { + if (stored_object == null) + return null; + + Map.Entry item; + Iterator iter = objects.entrySet().iterator(); + Obj ref; + + while (iter.hasNext()) + { + item = (Map.Entry) iter.next(); + ref = (Obj) item.getValue(); + if (stored_object.equals(ref.object)) + return ref; + } + return null; + } + + /** + * Find the reference info for the given servant. + * If the servant is mapped to several objects, this + * returns the first found occurence. + * + * @param servant a servant to find. + * + * @return the servant/object/POA binding or null if no such found. + */ + public Obj findServant(Servant servant) + { + if (servant == null) + return null; + + Map.Entry item; + Iterator iter = objects.entrySet().iterator(); + Obj ref; + + while (iter.hasNext()) + { + item = (Map.Entry) iter.next(); + ref = (Obj) item.getValue(); + if (servant.equals(ref.servant)) + return ref; + } + return null; + } + + /** + * Find the reference info for the given servant. + * If the servant is mapped to several objects, this + * returns the first found occurence. + * + * @param servant a servant to find. + * @param speficies if to search for the inactive (true) or active + * (false) servant. A servant with unmatching activity is ignored + * by this method. + * + * @return the servant/object/POA binding or null if no such found. + */ + public Obj findServant(Servant servant, boolean inactive) + { + if (servant == null) + return null; + + Map.Entry item; + Iterator iter = objects.entrySet().iterator(); + Obj ref; + + while (iter.hasNext()) + { + item = (Map.Entry) iter.next(); + ref = (Obj) item.getValue(); + if (ref.deactivated == inactive) + if (ref.servant != null) + if (servant.equals(ref.servant)) + return ref; + } + return null; + } + + /** + * Add the new object to the repository. The object key is + * generated automatically. + * + * @param object the object to add. + * @param servant a servant, serving the given object. + * @param poa the poa, where the object is connected. + * + * @return the newly created object record. + */ + public Obj add(org.omg.CORBA.Object object, Servant servant, POA poa) + { + return add(generateObjectKey(object), object, servant, poa); + } + + /** + * Add the new object to the repository. + * + * @param key the object key. + * @param object the object to add. + * @param servant a servant, serving the given object. + * @param poa the POA, where the object is connected. + */ + public Obj add(byte[] key, org.omg.CORBA.Object object, Servant servant, + POA poa + ) + { + Obj rec = new Obj(object, key, servant, poa); + objects.put(key, rec); + return rec; + } + + /** + * Add the new object to the repository. + * + * @param delegate the delegate, providing data about the servant, key, POA + * and object. + * @param port the port that this object would take. + */ + public Obj add(servantDelegate delegate) + { + Obj rec = + new Obj(delegate.object, delegate.servant_id, delegate.servant, + delegate.poa + ); + objects.put(delegate.servant_id, rec); + return rec; + } + + /** + * Put back the definition structure that has probably been removed earlier. + */ + public void put(Obj obj) + { + objects.put(obj.key, obj); + } + + /** + * Get the stored object. + * + * @param key the key (in the byte array form). + * + * @return the matching object, null if none is matching. + */ + public Obj get(byte[] key) + { + return (Obj) objects.get(key); + } + + /** + * Get the map key set. + */ + public Set keySet() + { + return objects.keySet(); + } + + /** + * Remove the given object, indiciating it by the key. + * + * @param object the object to remove. + */ + public void remove(byte[] key) + { + objects.remove(key); + } + + /** + * Generate the object key, unique in the currently + * running java virtual machine. The passed object + * parameter is currently not in use. + * + * @return the generated key. + */ + protected byte[] generateObjectKey(org.omg.CORBA.Object object) + { + byte[] key; + + // The repetetive keys cannot be generated, but theoretically + // the same keys can be passed when calling add(byte[]...). + // Hence we check if the key is not already in the map and, + // if it is, use the subsequent value. + do + { + key = getFreeId(); + } + while (objects.containsKey(key)); + return key; + } + + /** + * Get the next free 8 byte id, surely unique between calls of this + * method for the currently running virtual machine. + */ + public static synchronized byte[] getFreeId() + { + byte[] r = new byte[ 8 ]; + + // Start from the faster-changing. + r [ 0 ] = ((byte) (0xff & free_id)); + r [ 1 ] = ((byte) (0xff & (free_id >> 8))); + r [ 2 ] = ((byte) (0xff & (free_id >> 16))); + r [ 3 ] = ((byte) (0xff & (free_id >> 24))); + r [ 4 ] = ((byte) (0xff & (free_id >> 32))); + r [ 5 ] = ((byte) (0xff & (free_id >> 40))); + r [ 6 ] = ((byte) (0xff & (free_id >> 48))); + r [ 7 ] = ((byte) (0xff & (free_id >> 56))); + + free_id++; + + return r; + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/Poa/dynImpHandler.java b/libjava/classpath/gnu/CORBA/Poa/dynImpHandler.java new file mode 100644 index 00000000000..1cc3e131cd7 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/dynImpHandler.java @@ -0,0 +1,85 @@ +/* dynImpHandler.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import org.omg.CORBA.BAD_OPERATION; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.InvokeHandler; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.ResponseHandler; +import org.omg.PortableServer.DynamicImplementation; + +/** + * The InvokeHandler, indicating, that the target is a dynamic + * implementation rather than an invoke handler. These two + * types are not substitutable, but in some methods have possibility + * just to handle them differently. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class dynImpHandler + implements InvokeHandler +{ + /** + * The servant that is a dynamic implementation rather than + * invoke handler. + */ + public final DynamicImplementation servant; + + /** + * Create a new instance, wrapping some dyn implementation. + * @param _servant + */ + public dynImpHandler(DynamicImplementation _servant) + { + servant = _servant; + } + + /** + * We cannot invoke properly without having parameter info. + * + * @throws BAD_OPERATION, always. + */ + public OutputStream _invoke(String method, InputStream input, + ResponseHandler handler + ) + { + throw new BAD_OPERATION(servant + " is not an InvokeHandler."); + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/Poa/gnuAdapterActivator.java b/libjava/classpath/gnu/CORBA/Poa/gnuAdapterActivator.java new file mode 100644 index 00000000000..3019a2ae966 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/gnuAdapterActivator.java @@ -0,0 +1,81 @@ +/* gnuAdapterActivator.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import org.omg.CORBA.LocalObject; +import org.omg.PortableServer.AdapterActivator; +import org.omg.PortableServer.POA; + +/** + * Defines a simple adapter activator. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuAdapterActivator + extends LocalObject + implements AdapterActivator +{ + /** + * Create a new POA on the parent, using the parent policy set + * from the suitable parent of grandparend and with independent + * POA manager (passing null to the createPOA). + * + * @param parent a parent. Either this parent or one of its + * grandparents must be gnuAbstractPOA, able to provide a + * policy set. + * + * @param child_name the name of the child being created. + * + * @return true on success or false if no gnuAbstractPOA + * found till the root poa. + */ + public boolean unknown_adapter(POA parent, String child_name) + { + try + { + POA n = parent.create_POA(child_name, null, policySets.rootPoa()); + n.the_POAManager().activate(); + } + catch (Exception ex) + { + return false; + } + return true; + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/Poa/gnuForwardRequest.java b/libjava/classpath/gnu/CORBA/Poa/gnuForwardRequest.java new file mode 100644 index 00000000000..02fc42470b3 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/gnuForwardRequest.java @@ -0,0 +1,90 @@ +/* gnuForwardRequest.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import gnu.CORBA.GIOP.ReplyHeader; + +import org.omg.CORBA.BAD_PARAM; +import org.omg.CORBA.portable.ObjectImpl; + +/** + * The class, indicating that the request should be forwarded to another + * target. We cannot use ForwardRequest because the exception is throws + * from methods that does not declare throwing it. Hence must be + * RuntimeException. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuForwardRequest + extends RuntimeException +{ + /** + * Use serialVersionUID (v1.4) for interoperability. + */ + private static final long serialVersionUID = -1L; + + /** + * The object reference, indicating the new location of the invocation target. + */ + public ObjectImpl forward_reference; + + /** + * This information shows if we use LOCATION_FORWARD or + * LOCATION_FORWARD_PERM in request. By defalult, LOCATION_FORWARD + * is always used. To use LOCATION_FORWARD_PERM, this exception should + * be thrown from the servant manager instead of ForwardRequest, + * with this field set to ReplyHeader.LOCATION_FORWARD_PERM. + */ + public byte forwarding_code = ReplyHeader.LOCATION_FORWARD; + + /** + * Create the ForwardRequest with explaining message and + * initialising the object reference to the given value. + * + * @param why a string, explaining, why this exception has been thrown. + * @param a_forward_reference a value for forward_reference. + */ + public gnuForwardRequest(org.omg.CORBA.Object a_forward_reference) + { + if (a_forward_reference instanceof ObjectImpl) + this.forward_reference = (ObjectImpl) a_forward_reference; + else + throw new BAD_PARAM("ObjectImpl expected"); + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/Poa/gnuIdAssignmentPolicy.java b/libjava/classpath/gnu/CORBA/Poa/gnuIdAssignmentPolicy.java new file mode 100644 index 00000000000..a404486ce70 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/gnuIdAssignmentPolicy.java @@ -0,0 +1,80 @@ +/* gnuIdAssignmentPolicy.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import gnu.CORBA._PolicyImplBase; + +import org.omg.PortableServer.ID_ASSIGNMENT_POLICY_ID; +import org.omg.PortableServer.IdAssignmentPolicy; +import org.omg.PortableServer.IdAssignmentPolicyValue; + +/** + * Implementation of the id assignment policy. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuIdAssignmentPolicy + extends _PolicyImplBase + implements IdAssignmentPolicy, vPolicy +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1L; + + /** + * Create the policy. + * + * @param v a value for the policy. + */ + public gnuIdAssignmentPolicy(IdAssignmentPolicyValue v) + { + super(ID_ASSIGNMENT_POLICY_ID.value, v, v.value(), + "IDL:org.omg/PortableServer/IdAssignmentPolicy:1.0" + ); + } + + /** + * Get the value for the policy that was passed in a constructor. + */ + public IdAssignmentPolicyValue value() + { + return (IdAssignmentPolicyValue) getValue(); + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/Poa/gnuIdUniquenessPolicy.java b/libjava/classpath/gnu/CORBA/Poa/gnuIdUniquenessPolicy.java new file mode 100644 index 00000000000..2abd1f4845f --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/gnuIdUniquenessPolicy.java @@ -0,0 +1,80 @@ +/* gnuIdUniquenessPolicy.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import gnu.CORBA._PolicyImplBase; + +import org.omg.PortableServer.ID_UNIQUENESS_POLICY_ID; +import org.omg.PortableServer.IdUniquenessPolicy; +import org.omg.PortableServer.IdUniquenessPolicyValue; + +/** + * Implementation of the id uniqueness policy. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuIdUniquenessPolicy + extends _PolicyImplBase + implements IdUniquenessPolicy, vPolicy +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1L; + + /** + * Create the policy. + * + * @param v a value for the policy. + */ + public gnuIdUniquenessPolicy(IdUniquenessPolicyValue v) + { + super(ID_UNIQUENESS_POLICY_ID.value, v, v.value(), + "IDL:org.omg/PortableServer/IdUniquenessPolicy:1.0" + ); + } + + /** + * Get the value for the policy that was passed in a constructor. + */ + public IdUniquenessPolicyValue value() + { + return (IdUniquenessPolicyValue) getValue(); + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/Poa/gnuImplicitActivationPolicy.java b/libjava/classpath/gnu/CORBA/Poa/gnuImplicitActivationPolicy.java new file mode 100644 index 00000000000..1e539a2c4e0 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/gnuImplicitActivationPolicy.java @@ -0,0 +1,80 @@ +/* gnuImplicitActivationPolicy.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import gnu.CORBA._PolicyImplBase; + +import org.omg.PortableServer.IMPLICIT_ACTIVATION_POLICY_ID; +import org.omg.PortableServer.ImplicitActivationPolicy; +import org.omg.PortableServer.ImplicitActivationPolicyValue; + +/** + * Implementation of the implicit activation policy. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuImplicitActivationPolicy + extends _PolicyImplBase + implements ImplicitActivationPolicy, vPolicy +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1L; + + /** + * Create the policy. + * + * @param v a value for the policy. + */ + public gnuImplicitActivationPolicy(ImplicitActivationPolicyValue v) + { + super(IMPLICIT_ACTIVATION_POLICY_ID.value, v, v.value(), + "IDL:org.omg/PortableServer/ImplicitActivationPolicy:1.0" + ); + } + + /** + * Get the value for the policy that was passed in a constructor. + */ + public ImplicitActivationPolicyValue value() + { + return (ImplicitActivationPolicyValue) getValue(); + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/Poa/gnuLifespanPolicy.java b/libjava/classpath/gnu/CORBA/Poa/gnuLifespanPolicy.java new file mode 100644 index 00000000000..97b3f2d7a9b --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/gnuLifespanPolicy.java @@ -0,0 +1,80 @@ +/* gnuLifespanPolicy.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import gnu.CORBA._PolicyImplBase; + +import org.omg.PortableServer.LIFESPAN_POLICY_ID; +import org.omg.PortableServer.LifespanPolicy; +import org.omg.PortableServer.LifespanPolicyValue; + +/** + * The implementation of the life span policy. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuLifespanPolicy + extends _PolicyImplBase + implements LifespanPolicy, vPolicy +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1L; + + /** + * Create the policy. + * + * @param v a value for the policy. + */ + public gnuLifespanPolicy(LifespanPolicyValue v) + { + super(LIFESPAN_POLICY_ID.value, v, v.value(), + "IDL:org.omg/PortableServer/LifespanPolicy:1.0" + ); + } + + /** + * Get the value for the policy that was passed in a constructor. + */ + public LifespanPolicyValue value() + { + return (LifespanPolicyValue) getValue(); + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/Poa/gnuPOA.java b/libjava/classpath/gnu/CORBA/Poa/gnuPOA.java new file mode 100644 index 00000000000..1d9e838532a --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/gnuPOA.java @@ -0,0 +1,1615 @@ +/* gnuAbstractPOA.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; + +import org.omg.CORBA.BAD_INV_ORDER; +import org.omg.CORBA.BAD_PARAM; +import org.omg.CORBA.CompletionStatus; +import org.omg.CORBA.LocalObject; +import org.omg.CORBA.NO_IMPLEMENT; +import org.omg.CORBA.OBJ_ADAPTER; +import org.omg.CORBA.ORB; +import org.omg.CORBA.Policy; +import org.omg.CORBA.SetOverrideType; +import org.omg.CORBA.TRANSIENT; +import org.omg.CORBA.portable.ObjectImpl; +import org.omg.PortableServer.AdapterActivator; +import org.omg.PortableServer.ForwardRequest; +import org.omg.PortableServer.IdAssignmentPolicy; +import org.omg.PortableServer.IdAssignmentPolicyValue; +import org.omg.PortableServer.IdUniquenessPolicy; +import org.omg.PortableServer.IdUniquenessPolicyValue; +import org.omg.PortableServer.ImplicitActivationPolicy; +import org.omg.PortableServer.ImplicitActivationPolicyValue; +import org.omg.PortableServer.LifespanPolicy; +import org.omg.PortableServer.LifespanPolicyValue; +import org.omg.PortableServer.POA; +import org.omg.PortableServer.POAManager; +import org.omg.PortableServer.RequestProcessingPolicy; +import org.omg.PortableServer.RequestProcessingPolicyValue; +import org.omg.PortableServer.SERVANT_RETENTION_POLICY_ID; +import org.omg.PortableServer.Servant; +import org.omg.PortableServer.ServantActivator; +import org.omg.PortableServer.ServantLocator; +import org.omg.PortableServer.ServantManager; +import org.omg.PortableServer.ServantRetentionPolicy; +import org.omg.PortableServer.ServantRetentionPolicyValue; +import org.omg.PortableServer.ThreadPolicy; +import org.omg.PortableServer.ThreadPolicyValue; +import org.omg.PortableServer.POAManagerPackage.State; +import org.omg.PortableServer.POAPackage.AdapterAlreadyExists; +import org.omg.PortableServer.POAPackage.AdapterNonExistent; +import org.omg.PortableServer.POAPackage.InvalidPolicy; +import org.omg.PortableServer.POAPackage.NoServant; +import org.omg.PortableServer.POAPackage.ObjectAlreadyActive; +import org.omg.PortableServer.POAPackage.ObjectNotActive; +import org.omg.PortableServer.POAPackage.ServantAlreadyActive; +import org.omg.PortableServer.POAPackage.ServantNotActive; +import org.omg.PortableServer.POAPackage.WrongAdapter; +import org.omg.PortableServer.POAPackage.WrongPolicy; +import gnu.CORBA.CDR.cdrBufInput; +import gnu.CORBA.CDR.cdrBufOutput; + +/** + * Our POA implementation. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuPOA + extends LocalObject + implements POA +{ + /** + * The active object map, mapping between object keys, objects and servants. + */ + public final activeObjectMap aom = new activeObjectMap(); + + /** + * The children of this POA. + */ + final ArrayList children = new ArrayList(); + + /** + * The name of this POA. + */ + final String name; + + /** + * The parent of this POA (null for the root POA). + */ + final POA parent; + + /** + * The ior key signature, indicating, that the ior key is encoded using + * internal agreements of this implementation (0x'free'). + */ + static final int SIGNATURE = 0x66726565; + + /** + * The adapter activator for this POA, null if no activator is set. + */ + AdapterActivator m_activator; + + /** + * The POA manager for this POA. + */ + POAManager m_manager; + + /** + * The servant manager (servant activator) for this POA. + */ + ServantActivator servant_activator; + + /** + * The servant manager (servant locator) for this POA. + */ + ServantLocator servant_locator; + + /** + * The default servant, if on is in use. + */ + Servant default_servant; + + /** + * The cached poa id value, computed once. + */ + private byte[] m_poa_id; + + /** + * The all policy values that apply to this POA. + * The used policy values are singletons, unique between policies. + */ + private final HashSet m_policies; + + /** + * An array of the set policies. + */ + Policy[] s_policies; + + /** + * The ORB, where the POA is connected. + */ + final ORB_1_4 m_orb; + + /** + * When true, the POA is being destroyed or is destroyed. + */ + boolean m_inDestruction; + + /** + * True if the active object map is used by this POA. + * The value is moved into separate boolean value due + * necessity of the frequent checks. + */ + public final boolean retain_servant; + + /** + * Create a new abstract POA. + * + * @param a_parent the parent of this POA. + * @param a_name a name for this POA. + * @param a_manager a manager for this POA. If null, a new + * {@link gnuPOAManager} will be instantiated. + * @param a_policies an array of policies that apply to this POA. + * @param an_orb an ORB for this POA. + */ + public gnuPOA(gnuPOA a_parent, String a_name, POAManager a_manager, + Policy[] a_policies, ORB_1_4 an_orb + ) + throws InvalidPolicy + { + // Add default policies. + Policy[] all_policies = policySets.withDefault(a_policies); + + name = a_name; + parent = a_parent; + m_orb = an_orb; + + if (a_manager != null) + m_manager = a_manager; + else + m_manager = new gnuPOAManager(); + + if (m_manager instanceof gnuPOAManager) + { + gnuPOAManager g = (gnuPOAManager) m_manager; + g.addPoa(this); + } + + m_policies = new HashSet(all_policies.length); + + s_policies = new Policy[ all_policies.length ]; + for (int i = 0; i < s_policies.length; i++) + { + s_policies [ i ] = all_policies [ i ].copy(); + m_policies.add(((vPolicy) s_policies [ i ]).getValue()); + } + + retain_servant = applies(ServantRetentionPolicyValue.RETAIN); + + validatePolicies(a_policies); + } + + /** + * Wait while at least one of the threads in this POA is actively + * processing one of requests. + */ + public void waitWhileRunning() + { + // First pause. + long time = 1; + + // Maximal duration between checks. + long max = 500; + + boolean runs; + + do + { + runs = m_orb.currents.has(this); + + if (runs) + { + // Avoid taking CPU resources + // from the thread that is running. + try + { + Thread.sleep(time); + time = time * 2; + if (time > max) + time = max; + } + catch (InterruptedException ex) + { + } + } + } + while (runs); + } + + /** + * Etherealize all objects, associated with this POA. Invoked from the + * {@link gnuPOAManager} only if it is known that the servant_activator + * holds non-null value. + */ + protected void etherealizeAll() + { + if (servant_activator == null) + return; + + ArrayList keys = new ArrayList(); + keys.addAll(aom.keySet()); + + byte[] key; + activeObjectMap.Obj obj; + boolean last; + for (int i = 0; i < keys.size(); i++) + { + key = (byte[]) keys.get(i); + obj = aom.get(key); + + if (obj.poa == this) + { + aom.remove(key); + + if (!obj.isDeactiveted()) + { + // Check if the servant still stays under the other key. + last = aom.findServant(obj.servant) == null; + servant_activator.etherealize(obj.key, this, obj.servant, true, + last + ); + } + } + } + } + + /** + * Create an instance of the POA with the given features. + * This method is not responsible for duplicate checking + * or adding the returned instance to any possible table. + * + * @param child_name the name of the poa being created. + * @param manager the poa manager (never null). + * @param policies the array of policies. + * @param an_orb the ORB for this POA. + * + * @return the created POA. + * + * @throws InvalidPolicy for conflicting or otherwise invalid policies.| + */ + protected POA createPoaInstance(String child_name, POAManager a_manager, + Policy[] policies, ORB_1_4 an_orb + ) + throws InvalidPolicy + { + POAManager some_manager = + a_manager == null ? new gnuPOAManager() : a_manager; + + if (some_manager instanceof gnuPOAManager) + { + ((gnuPOAManager) some_manager).addPoa(this); + } + + return new gnuPOA(this, child_name, some_manager, policies, an_orb); + } + + /** + * Check if the given policy value applies to this POA. + * + * @param policy_value a policy value to check. The policy values are + * singletons and unique between the different policies, so the policy + * type is not passed. + * + * @return true if the policy value applies, false otherwise. + */ + public final boolean applies(java.lang.Object policy_value) + { + return m_policies.contains(policy_value); + } + + /** + * Check for the presence of the required policy. + * + * @param policy_value a policy value to check. + * + * @throws WrongPolicy if the required policy value is not applicable. + */ + public final void required(java.lang.Object policy_value) + throws WrongPolicy + { + if (!applies(policy_value)) + throw new WrongPolicy(policy_value + " policy required."); + } + + /** + * Check for the absence of the given policy. + * + * @param policy_value a policy value to check. + * + * @throws WrongPolicy if the passed policy value is applicable. + */ + public final void excluding(java.lang.Object policy_value) + throws WrongPolicy + { + if (applies(policy_value)) + throw new WrongPolicy(policy_value + " policy applies."); + } + + /** + * Find and optionally activate the child POA with the given name. + * + * @param poa_name the name of the POA to find. + * @param activate_it if the child with the specified name is not found + * or inactive and this parameter is true, the target POA activator is + * invoked to activate that child. If this succeeds, that child POA + * is returned. + * + * @throws AdapterNonExistent if no active child with the given name + * is found and one of the following is true: + * a) the target POA has no associated + * {@link AdapterActivator}. b) that activator fails to activate the + * child POA. c) <code>activate_id</code> = false. + */ + public POA find_POA(String poa_name, boolean activate_it) + throws AdapterNonExistent + { + POA child; + for (int i = 0; i < children.size(); i++) + { + child = (POA) children.get(i); + if (child.the_name().equals(poa_name)) + return child; + } + + if (activate_it && m_activator != null) + { + boolean activated = m_activator.unknown_adapter(this, poa_name); + if (!activated) + throw new AdapterNonExistent(poa_name + " activation failed."); + + // Tha activator should add the child to the childrent table. + for (int i = 0; i < children.size(); i++) + { + child = (POA) children.get(i); + if (child.the_name().equals(poa_name)) + return child; + } + throw new AdapterNonExistent(poa_name + " not created. "); + } + else + throw new AdapterNonExistent(poa_name); + } + + /** + * Generate the Object Id for the given servant and add the servant to + * the Active Object Map using this Id a a key. If the servant + * activator is set, its incarnate method will be called. + * + * @param a_servant a servant that would serve the object with the + * returned Object Id. If null is passed, under apporoprate policies the + * servant activator is invoked. + * + * @return the generated objert Id for the given servant. + * + * @throws ServantAlreadyActive if this servant is already in the + * Active Object Map and the UNIQUE_ID policy applies. + * + * @throws WrongPolicy if the required policies SYSTEM_ID and RETAIN + * do not apply to this POA. + */ + public byte[] activate_object(Servant a_servant) + throws ServantAlreadyActive, WrongPolicy + { + checkDiscarding(); + required(ServantRetentionPolicyValue.RETAIN); + required(IdAssignmentPolicyValue.SYSTEM_ID); + + activeObjectMap.Obj exists = aom.findServant(a_servant); + + if (exists != null) + { + if (exists.isDeactiveted()) + { + // If exists but deactivated, activate and return + // the existing key. + exists.setDeactivated(false); + incarnate(exists, exists.key, a_servant, false); + return exists.key; + } + else if (applies(IdUniquenessPolicyValue.UNIQUE_ID)) + throw new ServantAlreadyActive(); + + // It multiple ids are allowed, exit block allowing repetetive + // activations. + } + + byte[] object_key = activeObjectMap.getFreeId(); + servantDelegate delegate = new servantDelegate(a_servant, this, object_key); + connectDelegate(object_key, delegate); + return object_key; + } + + /** + * Add the given servant to the Active Object Map as a servant for the + * object with the provided Object Id. If the servant activator is + * set, its incarnate method will be called. + * + * @param an_Object_Id an object id for the given object. + * @param a_servant a servant that will serve the object with the given + * Object Id. If null is passed, under apporoprate policies the + * servant activator is invoked. + * + * @throws ObjectAlreadyActive if the given object id is already in the + * Active Object Map. + * @throws ServantAlreadyActive if the UNIQUE_ID policy applies and + * this servant is already in use. + * @throws WrongPolicy if the required RETAIN policy does not apply to + * this POA. + * @throws BAD_PARAM if the passed object id is invalid due any reason. + */ + public void activate_object_with_id(byte[] an_Object_Id, Servant a_servant) + throws ServantAlreadyActive, ObjectAlreadyActive, + WrongPolicy + { + activate_object_with_id(an_Object_Id, a_servant, false); + } + + /** + * Same as activate_object_with_id, but permits gnuForwardRequest + * forwarding exception. This is used when the activation is called + * from the remote invocation context and we have possibility + * to return the forwarding message. + */ + public void activate_object_with_id(byte[] an_Object_Id, Servant a_servant, + boolean use_forwarding + ) + throws ServantAlreadyActive, ObjectAlreadyActive, + WrongPolicy + { + checkDiscarding(); + required(ServantRetentionPolicyValue.RETAIN); + + // If the UNIQUE_ID applies, the servant being passed must not be + // already active. + if (applies(IdUniquenessPolicyValue.UNIQUE_ID)) + { + activeObjectMap.Obj sx = aom.findServant(a_servant, false); + if (sx != null) + throw new ServantAlreadyActive(); + } + + activeObjectMap.Obj exists = aom.get(an_Object_Id); + if (exists != null) + { + if (exists.servant == null) + { + locateServant(an_Object_Id, a_servant, exists, use_forwarding); + exists.setDeactivated(false); + } + else if (exists.isDeactiveted()) + { + exists.setDeactivated(false); + incarnate(exists, an_Object_Id, a_servant, use_forwarding); + } + else + throw new ObjectAlreadyActive(); + } + else + { + servantDelegate delegate = + new servantDelegate(a_servant, this, an_Object_Id); + connectDelegate(an_Object_Id, delegate); + } + } + + /** + * Locate the servant for this object Id and connect it to ORB. + * + * @param an_Object_Id the object id. + * @param a_servant the servant (may be null). + * @param exists an existing active object map entry. + * @param use_forwarding allow to throw the gnuForwardRequest + * if the activator throws ForwardRequest. + * + * @throws OBJ_ADAPTER minor 4 if the servant cannot be located + * (the required servant manager may be missing). + */ + private void locateServant(byte[] an_Object_Id, Servant a_servant, + activeObjectMap.Obj exists, boolean use_forwarding + ) + throws InternalError + { + // An object was created with create_reference. + gnuServantObject object = (gnuServantObject) exists.object; + if (servant_activator != null) + { + exists.setServant(incarnate(exists, an_Object_Id, a_servant, + use_forwarding + ) + ); + } + else if (default_servant != null) + { + exists.setServant(default_servant); + } + if (exists.servant == null) + { + exists.setServant(a_servant); + } + if (exists.servant == null) + { + throw new OBJ_ADAPTER("no servant", 4, CompletionStatus.COMPLETED_NO); + } + + servantDelegate delegate = + new servantDelegate(exists.servant, this, an_Object_Id); + exists.servant._set_delegate(delegate); + object.setServant(exists.servant); + connect_to_orb(an_Object_Id, delegate.object); + } + + /** + * Deactivate object with the given id. + * + * The deactivated object will continue to process requests that arrived + * before decativation. If this POA has the associated + * servant manager, a {@link ServantActivatorOperations#etherealize} is + * immediately invoked on the passed id. + * + * @throws WrongPolicy if the required RETAIN policy does not apply to + * this POA. + */ + public void deactivate_object(byte[] the_Object_Id) + throws ObjectNotActive, WrongPolicy + { + required(ServantRetentionPolicyValue.RETAIN); + + activeObjectMap.Obj exists = aom.get(the_Object_Id); + + if (exists == null || exists.isDeactiveted()) + throw new ObjectNotActive(); + + exists.setDeactivated(true); + + // Check if this servant is serving something else. + aom.remove(the_Object_Id); + + activeObjectMap.Obj other = aom.findServant(exists.servant, false); + + boolean remaining = other != null; + + aom.put(exists); + + if (servant_activator != null) + servant_activator.etherealize(the_Object_Id, this, exists.servant, false, + remaining + ); + } + + /** + * Create the object reference, encapsulating the given repository Id and + * the Object Id, generated by this POA. The returned object will not be + * activated by default and may be activated on the first invocation by + * the servant manager (if it is set and if policies are applicable). + * + * @param a_repository_id the repository id for the given object, can + * be null if to be requested from the servant later. + * + * @throws WrongPolicy if the required SYSTEM_ID policy does not apply to + * this POA. + */ + public org.omg.CORBA.Object create_reference(String a_repository_id) + throws WrongPolicy + { + required(IdAssignmentPolicyValue.SYSTEM_ID); + return create_reference_with_id(activeObjectMap.getFreeId(), a_repository_id); + } + + /** + * <p> + * Create the object reference, encapsulating the given repository Id and + * the given Object Id. The returned object will <i>not</i> be + * activated by default and may be activated on the first invocation by + * the servant manager (if the IMPLICIT_ACTIVATION policy applies). + * + * @param an_object_id the object id for the object being created. If this + * POA uses the SYSTEM_ID policy, the portable application should only + * pass the ids, generated by this POA. + * + * @param a_repository_id the repository id for the object being created, + * can be null if this information should be later requested from the + * servant. + */ + public org.omg.CORBA.Object create_reference_with_id(byte[] an_object_id, + String a_repository_id + ) + { + String[] ids; + if (a_repository_id == null) + ids = null; + else + ids = new String[] { a_repository_id }; + + // Check maybe such object is already activated. + activeObjectMap.Obj e = aom.get(an_object_id); + + Servant servant; + if (e == null) + { + servant = null; + } + else + { + servant = e.servant; + e.setDeactivated(false); + } + + gnuServantObject object = + new gnuServantObject(ids, an_object_id, this, m_orb); + object._set_delegate(new LocalDelegate(object, this, an_object_id)); + aom.add(object.Id, object, servant, this); + connect_to_orb(an_object_id, object); + + return object; + } + + /** + * Creates a new POA as a child of the target POA. + * + * @param child_name the name of the child POA being created. + * @param manager the manager that will control the new POA. If this parameter + * is null, a new POA manager is created and associated with the new POA. + * + * @param policies the policies, applicable for the parent POA. Policies + * are <i>not</i> inherited from the parent POA. + * + * @return an newly created POA. The POA will be intially in the holding + * state and must be activated to start processing requests. + * + * @throws AdapterAlreadyExists if the child with the given child_name + * already exists for the current POA. + * @throws InvalidPolicy if the policies conflict with each other or are + * otherwise inappropriate. + * + * @see #the_children() + */ + public POA create_POA(String child_name, POAManager manager, Policy[] policies) + throws AdapterAlreadyExists, InvalidPolicy + { + POA child; + for (int i = 0; i < children.size(); i++) + { + child = (POA) children.get(i); + if (child.the_name().equals(child_name)) + throw new AdapterAlreadyExists(name + "/" + child_name); + } + + POA poa = createPoaInstance(child_name, manager, policies, m_orb); + children.add(poa); + return poa; + } + + /** + * Returns a default servant for this POA. + * + * @return a servant that will be used for requests for + * which no servant is found in the Active Object Map. + * + * @throws NoServant if there is no default servant associated with this POA. + * @throws WrongPolicy if the USE_DEFAULT_SERVANT policy is not active. + */ + public Servant get_servant() + throws NoServant, WrongPolicy + { + required(RequestProcessingPolicyValue.USE_DEFAULT_SERVANT); + if (default_servant == null) + throw new NoServant(); + return default_servant; + } + + /** + * Sets the default servant for this POA. + * + * @param a_servant a servant that will be used for requests for + * which no servant is found in the Active Object Map. + * + * @throws WrongPolicy if the USE_DEFAULT_SERVANT policy is not active. + */ + public void set_servant(Servant a_servant) + throws WrongPolicy + { + required(RequestProcessingPolicyValue.USE_DEFAULT_SERVANT); + default_servant = a_servant; + } + + /** + * Set a servant manager for this POA. + * + * @param a servant manager being set. If the RETAIN policy applies, the + * manager must implement a {@link ServantActivator}. If the NON_RETAIN + * policy applies, the manager must implement a {@link ServantLocator}. + * + * @throws WrongPolicy if the required USE_SERVANT_MANAGER policy does not + * apply to this POA. + * + * @throws OBJ_ADAPTER minor code 4 if the passed manager does not + * implement the required interface ({@link ServantActivator}, + * {@link ServantLocator}). The POA, that has the RETAIN policy uses + * servant managers that are ServantActivators. When the POA has the + * NON_RETAIN policy it uses servant managers that are ServantLoacators. + * + * @throws BAD_INV_ORDER minor code 6 if the method is called more than once + * on the same POA. The manager can be set only once. + */ + public void set_servant_manager(ServantManager a_manager) + throws WrongPolicy + { + required(RequestProcessingPolicyValue.USE_SERVANT_MANAGER); + if (servant_activator != null || servant_locator != null) + throw new BAD_INV_ORDER("Setting manager twice for " + name, 6, + CompletionStatus.COMPLETED_NO + ); + + if (applies(ServantRetentionPolicyValue.RETAIN)) + { + if (a_manager instanceof ServantActivator) + servant_activator = (ServantActivator) a_manager; + else + throw new OBJ_ADAPTER("RETAIN requires ServantActivator", 4, + CompletionStatus.COMPLETED_NO + ); + } + else if (applies(ServantRetentionPolicyValue.NON_RETAIN)) + { + if (a_manager instanceof ServantLocator) + servant_locator = (ServantLocator) a_manager; + else + throw new OBJ_ADAPTER("NON_RETAIN requires ServantLocator", 4, + CompletionStatus.COMPLETED_NO + ); + } + else + throw new WrongPolicy("No servant retention policy is specified."); + } + + /** + * Get the servant manager, associated with this POA. + * + * @return the associated servant manager or null if it has + * been previously set. + * + * @throws WrongPolicy if the required USE_SERVANT_MANAGER policy does not + * apply to this POA. + */ + public ServantManager get_servant_manager() + throws WrongPolicy + { + required(RequestProcessingPolicyValue.USE_SERVANT_MANAGER); + + if (servant_activator != null) + return servant_activator; + else + return servant_locator; + } + + /** + * Get the unique Id of the POA in the process in which it is created. + * This Id is needed by portable interceptors. The id is unique + * for the life span of the POA in the process. For persistent + * POAs, if a POA is created in the same path with the same name as + * another POA, these POAs are identical have the same id. All transient + * POAs are assumed unique. + */ + public byte[] id() + { + if (m_poa_id != null) + return m_poa_id; + else + { + cdrBufOutput buffer = new cdrBufOutput(); + POA p = this; + while (p != null) + { + buffer.write_string(p.the_name()); + p = p.the_parent(); + } + m_poa_id = buffer.buffer.toByteArray(); + return m_poa_id; + } + } + + /** + * Returns the reference to the active object with the given Id. + * + * @param the_Object_Id the object id. + * + * @throws ObjectNotActive if there is no active object with such Id + * in the scope of this POA. + * @throws WrongPolicy if the required RETAIN policy does not apply to + * this POA. + */ + public org.omg.CORBA.Object id_to_reference(byte[] the_Object_Id) + throws ObjectNotActive, WrongPolicy + { + required(ServantRetentionPolicyValue.RETAIN); + + activeObjectMap.Obj ref = aom.get(the_Object_Id); + if (ref == null) + throw new ObjectNotActive(); + else + return ref.object; + } + + /** + * Returns the servant that serves the active object with the given Id. + * + * @param the_Object_Id the object id. + * + * @throws ObjectNotActive if there is no active object with such Id or + * it is not currently active. + * @throws WrongPolicy. This method requires either RETAIN or + * USE_DEFAULT_SERVANT policies and reaises the WrongPolicy if none of them + * apply to this POA. + */ + public Servant id_to_servant(byte[] the_Object_Id) + throws ObjectNotActive, WrongPolicy + { + if (applies(ServantRetentionPolicyValue.RETAIN)) + { + activeObjectMap.Obj ref = aom.get(the_Object_Id); + if (ref == null || ref.isDeactiveted()) + { + if (default_servant != null) + return default_servant; + else + throw new ObjectNotActive(); + } + else if (ref.servant != null) + return ref.servant; + else if (default_servant != null) + return default_servant; + else + throw new ObjectNotActive(); + } + else if (default_servant != null) + { + return default_servant; + } + else + throw new WrongPolicy("Either RETAIN or USE_DEFAULT_SERVANT required."); + } + + /** + * Returns the Object Id, encapsulated in the given object reference. + * + * @param the_Object the object that has been previously created with this + * POA. It need not be active. + * + * @throws WrongAdapter if the passed object is not known for this POA. + * @throws WrongPolicy never (declared for the future extensions only). + */ + public byte[] reference_to_id(org.omg.CORBA.Object the_Object) + throws WrongAdapter, WrongPolicy + { + activeObjectMap.Obj ref = aom.findObject(the_Object); + if (ref == null) + throw new WrongAdapter(); + return ref.key; + } + + /** + * Returns the servant that is serving this object. + * + * @return if the RETAIN policy applies and the object is in the Active + * Object Map, the method returns the servant, associated with this object. + * Otherwise, if the USE_DEFAULT_SERVANT policy applies, the method returns + * the default servant (if one was set). + * + * @throws ObjectNotActive if none of the conditions above are satisfied. + * @throws WrongAdapter if the object reference was not created with this POA. + * @throws WrongPolicy. This method requires either RETAIN or + * USE_DEFAULT_SERVANT policies and reaises the WrongPolicy if none of them + * apply to this POA. + */ + public Servant reference_to_servant(org.omg.CORBA.Object the_Object) + throws ObjectNotActive, WrongPolicy, + WrongAdapter + { + if (applies(ServantRetentionPolicyValue.RETAIN)) + { + activeObjectMap.Obj ref = aom.findObject(the_Object); + if (ref == null) + throw new WrongAdapter(); + else if (ref.isDeactiveted() || ref.servant == null) + { + if (default_servant != null) + return default_servant; + else + throw new ObjectNotActive(); + } + else + return ref.servant; + } + else if (default_servant != null) + { + return default_servant; + } + else + throw new WrongPolicy("Either RETAIN or USE_DEFAULT_SERVANT required."); + } + + /** + * Returns the id of the object, served by the given servant + * (assuming that the servant serves only one object). + * The id is found in one of the following ways. + * <ul> + * <li>If the POA has both the RETAIN and the UNIQUE_ID policy and + * the specified servant is active, the method return the Object Id associated + * with that servant. + * </li><li> + * If the POA has both the RETAIN and the IMPLICIT_ACTIVATION policy and + * either the POA has the MULTIPLE_ID policy or the specified servant is + * inactive, the method activates the servant using a POA-generated Object Id + * and the Interface Id associated with the servant, and returns that + * Object Id. + * </li> + * <li>If the POA has the USE_DEFAULT_SERVANT policy, the servant specified + * is the default servant, and the method is being invoked in the context of + * executing a request on the default servant, the method returns the + * ObjectId associated with the current invocation. + * </li> + * </ul> + * @throws ServantNotActive in all cases, not listed in the list above. + * @throws WrongPolicy The method requres USE_DEFAULT_SERVANT policy or + * a combination of the RETAIN policy and either the UNIQUE_ID or + * IMPLICIT_ACTIVATION policies and throws the WrongPolicy if these conditions + * are not satisfied. + */ + public byte[] servant_to_id(Servant the_Servant) + throws ServantNotActive, WrongPolicy + { + if (applies(RequestProcessingPolicyValue.USE_DEFAULT_SERVANT) || + applies(ServantRetentionPolicyValue.RETAIN) && + ( + applies(IdUniquenessPolicyValue.UNIQUE_ID) || + applies(ImplicitActivationPolicyValue.IMPLICIT_ACTIVATION) + ) + ) + { + activeObjectMap.Obj ref = null; + if (!applies(IdUniquenessPolicyValue.MULTIPLE_ID)) + ref = aom.findServant(the_Servant); + if (ref == null && + applies(ImplicitActivationPolicyValue.IMPLICIT_ACTIVATION) + ) + { + // Try to activate. + try + { + return activate_object(the_Servant); + } + catch (ServantAlreadyActive ex) + { + // Either it shuld not be or the policy allows multiple ids. + throw new InternalError(); + } + } + if (ref == null) + throw new ServantNotActive(); + else + return ref.key; + } + else + throw new WrongPolicy("(RETAIN and UNIQUE ID) " + + "or USE_DEFAULT_SERVANT required." + ); + } + + /** + * <p>Converts the given servant to the object reference. + * The servant will serve all methods, invoked on the returned object. + * The returned object reference can be passed to the remote client, + * enabling remote invocations. + * </p><p> + * If the specified servant is active, it is returned. Otherwise, + * if the POA has the IMPLICIT_ACTIVATION policy the method activates + * the servant. In this case, if the servant activator is set, + * the {@link ServantActivatorOperations#incarnate} method will be called. + * </p> + * + * @throws ServantNotActive if the servant is inactive and no + * IMPLICIT_ACTIVATION policy applies. + * @throws WrongPolicy This method needs the RETAIN policy and either the + * UNIQUE_ID or IMPLICIT_ACTIVATION policies. + * + * @return the object, exposing the given servant in the context of this POA. + */ + public org.omg.CORBA.Object servant_to_reference(Servant the_Servant) + throws ServantNotActive, + WrongPolicy + { + required(ServantRetentionPolicyValue.RETAIN); + + activeObjectMap.Obj exists = null; + + if (!applies(IdUniquenessPolicyValue.MULTIPLE_ID)) + exists = aom.findServant(the_Servant); + + if (exists != null) + { + if (exists.isDeactiveted()) + { + if (applies(ImplicitActivationPolicyValue.IMPLICIT_ACTIVATION)) + { + checkDiscarding(); + exists.setDeactivated(false); + incarnate(exists, exists.key, the_Servant, false); + } + else + throw new ServantNotActive(); + } + else + return exists.object; + } + if (exists == null && + applies(ImplicitActivationPolicyValue.IMPLICIT_ACTIVATION) + ) + { + checkDiscarding(); + + byte[] object_key = activeObjectMap.getFreeId(); + + servantDelegate delegate = + new servantDelegate(the_Servant, this, object_key); + connectDelegate(object_key, delegate); + + return delegate.object; + } + else + throw new ServantNotActive(); + } + + /** + * Incarnate in cases when request forwarding is not expected + * because the servant must be provided by the servant activator. + * + * @param x the aom entry, where the object is replaced by + * value, returned by servant activator (if not null). + * + * @param key the object key. + * + * @param a_servant the servant that was passed as a parameter in the + * activation method. + * + * @param use_forwarding if true, the gnuForwardRequest is throw + * under the forwarding exception (for remote client). Otherwise, the + * request is internally redirected (for local invocation). + */ + private Servant incarnate(activeObjectMap.Obj x, byte[] object_key, + Servant a_servant, boolean use_forwarding + ) + { + if (servant_activator != null) + { + Servant servant; + try + { + servant = servant_activator.incarnate(object_key, this); + } + catch (ForwardRequest ex) + { + if (use_forwarding) + throw new gnuForwardRequest(ex.forward_reference); + else + servant = + ForwardedServant.create((ObjectImpl) ex.forward_reference); + } + if (servant != null && x != null) + x.setServant(servant); + if (servant == null && x != null) + servant = x.servant; + return servant; + } + else if (a_servant != null) + { + x.setServant(a_servant); + return a_servant; + } + else if (x.servant != null) + { + return x.servant; + } + else if (default_servant != null) + { + x.setServant(default_servant); + return x.servant; + } + else + throw new BAD_INV_ORDER("No servant given and the servant activator not set"); + } + + /** + * Return the POA manager, associated with this POA. + * + * @return the associated POA manager (always available). + */ + public POAManager the_POAManager() + { + return m_manager; + } + + /** + * Returns the adapter activator, associated with this POA. + * The newly created POA has no activator (null would be + * returned). The ORB root POA also initially has no activator. + * + * @return tha adapter activator or null if this POA has no + * associated adapter activator. + */ + public AdapterActivator the_activator() + { + return m_activator; + } + + /** + * Set the adapter activator for this POA. + * + * @param the activator being set. + */ + public void the_activator(AdapterActivator an_activator) + { + m_activator = an_activator; + } + + /** + * The children of this POA. + * + * @return the array of all childs for this POA. + */ + public POA[] the_children() + { + POA[] poas = new POA[ children.size() ]; + for (int i = 0; i < poas.length; i++) + { + poas [ i ] = (POA) children.get(i); + } + return poas; + } + + /** + * Return the name of this POA. + * + * @return the name of POA, relative to its parent. + */ + public String the_name() + { + return name; + } + ; + + /** + * Return the parent of this POA. + * + * @return the parent POA or <code>null</code> if this is a root POA. + */ + public POA the_parent() + { + return parent; + } + + /** {@inheritDoc} */ + public IdAssignmentPolicy create_id_assignment_policy(IdAssignmentPolicyValue a_value) + { + return new gnuIdAssignmentPolicy(a_value); + } + + /** {@inheritDoc} */ + public IdUniquenessPolicy create_id_uniqueness_policy(IdUniquenessPolicyValue a_value) + { + return new gnuIdUniquenessPolicy(a_value); + } + + /** {@inheritDoc} */ + public ImplicitActivationPolicy create_implicit_activation_policy(ImplicitActivationPolicyValue a_value) + { + return new gnuImplicitActivationPolicy(a_value); + } + + /** {@inheritDoc} */ + public LifespanPolicy create_lifespan_policy(LifespanPolicyValue a_value) + { + return new gnuLifespanPolicy(a_value); + } + + /** {@inheritDoc} */ + public RequestProcessingPolicy create_request_processing_policy(RequestProcessingPolicyValue a_value) + { + return new gnuRequestProcessingPolicy(a_value); + } + + /** {@inheritDoc} */ + public ServantRetentionPolicy create_servant_retention_policy(ServantRetentionPolicyValue a_value) + { + return new gnuServantRetentionPolicy(a_value); + } + + /** {@inheritDoc} */ + public ThreadPolicy create_thread_policy(ThreadPolicyValue a_value) + { + return new gnuThreadPolicy(a_value); + } + + /** + * <p> Destroy this POA and all descendant POAs. The destroyed POAs can be + * later re-created via {@link AdapterActivator} or by invoking + * {@link #create_POA}. + * This differs from {@link PoaManagerOperations#deactivate} that does + * not allow recreation of the deactivated POAs. After deactivation, + * recreation is only possible if the POAs were later destroyed. + * </p><p> + * The remote invocation on the target, belonging to the POA that is + * currently destroyed return the remote exception ({@link TRANSIENT}, + * minor code 4). + * </p> + * @param etherealize_objects if true, and POA has RETAIN policy, and the + * servant manager is available, the servant manager method + * {@link ServantActivatorOperations#etherealize} is called for each + * <i>active</i> object in the Active Object Map. This method should not + * try to access POA being destroyed. If <code>destroy</code> is called + * multiple times before the destruction completes, + * the etherialization should be invoked only once. + * + * @param wait_for_completion if true, the method waits till the POA being + * destroyed completes all current requests and etherialization. If false, + * the method returns immediately. + */ + public void destroy(boolean etherealize_objects, boolean wait_for_completion) + { + if (wait_for_completion) + waitWhileRunning(); + + // Put the brake instead of manager, preventing the subsequent + // requests. + gnuPOAManager g = new gnuPOAManager(); + g.state = State.INACTIVE; + m_manager = g; + + // Disconnect from parent. + if (parent instanceof gnuPOA) + { + ((gnuPOA) parent).children.remove(this); + } + + unregisterFromManager(); + + // Disconnect from the ORB all objects, registered with this POA. + ArrayList keys = new ArrayList(); + keys.addAll(aom.keySet()); + + byte[] key; + activeObjectMap.Obj obj; + for (int i = 0; i < keys.size(); i++) + { + key = (byte[]) keys.get(i); + obj = aom.get(key); + if (obj.poa == this) + m_orb.disconnect(obj.object); + } + + m_orb.identityDestroyed(this); + + if (etherealize_objects && servant_activator != null && !m_inDestruction) + { + etherealizeAll(); + } + m_inDestruction = true; + + POA[] ch = the_children(); + for (int i = 0; i < ch.length; i++) + { + ch [ i ].destroy(etherealize_objects, wait_for_completion); + } + } + + /** + * Destroy this POA if it has not been destroyed, destroys it. + */ + protected void finalize() + throws java.lang.Throwable + { + if (!m_inDestruction) + destroy(false, false); + } + + /** + * Remove self from the manager list. + */ + private void unregisterFromManager() + { + if (m_manager instanceof gnuPOAManager) + { + gnuPOAManager p = (gnuPOAManager) m_manager; + p.removePOA(this); + } + } + + /** + * Get the policy of the given type, associated with this POA. + * + * @param a_policy_type a type of the requested policy. + * @return a policy of the given type, applyting to this POA. + * + * @throws org.omg.CORBA.BAD_PARAM if the policy of this type has not + * been specified for this POA. + */ + public Policy _get_policy(int a_policy_type) + throws org.omg.CORBA.BAD_PARAM + { + for (int i = 0; i < s_policies.length; i++) + { + if (s_policies [ i ].policy_type() == a_policy_type) + return s_policies [ i ].copy(); + } + throw new BAD_PARAM("No policy type " + a_policy_type); + } + + /** + * Get the copy of the policy array. + */ + public Policy[] getPolicyArray() + { + Policy[] r = new Policy[ s_policies.length ]; + for (int i = 0; i < s_policies.length; i++) + { + r [ i ] = s_policies [ i ].copy(); + } + return r; + } + + /** + * The POAs cannot be created by this method. + * + * @specnote this is also not possible in Suns jdk at least till 1.4. + * + * @throws NO_IMPLEMENT always. + */ + public org.omg.CORBA.Object _set_policy_override(Policy[] policies, + SetOverrideType how + ) + { + throw new NO_IMPLEMENT("Use createPOA instead."); + } + + /** + * Get the ORB, where this POA is connected. + */ + public ORB orb() + { + return m_orb; + } + + /** + * Connect the given delegate under the given key, also calling + * incarnate. + */ + private void connectDelegate(byte[] object_key, servantDelegate delegate) + { + aom.add(delegate); + connect_to_orb(object_key, delegate.object); + if (servant_activator != null) + incarnate(null, object_key, delegate.servant, false); + } + + /** + * Check if the POA is not in a discarding mode. The activation + * operations are forbidded in discarding mode. + * + * @throws TRANSIENT if the POA is in discarding mode. + */ + private void checkDiscarding() + throws TRANSIENT + { + if (m_manager.get_state() == State.DISCARDING) + throw new TRANSIENT("Discarding mode", 1, CompletionStatus.COMPLETED_MAYBE); + } + + /** + * Connect the given delegate object to orb. + */ + protected void connect_to_orb(byte[] an_Object_Id, org.omg.CORBA.Object object) + { + if (applies(ThreadPolicyValue.SINGLE_THREAD_MODEL)) + m_orb.connect_1_thread(object, toIORKey(an_Object_Id), this); + else + m_orb.connect(object, toIORKey(an_Object_Id)); + } + + /** + * Returns the representation of this POA tree. + */ + public String toString() + { + StringBuffer b = new StringBuffer(name); + + if (children.size() != 0) + { + b.append(" ("); + + for (int i = 0; i < children.size(); i++) + { + b.append(children.get(i)); + if (i < children.size() - 2) + b.append(", "); + } + b.append(")"); + } + return b.toString(); + } + + /** + * Check if the policy set is valid. + */ + protected boolean validatePolicies(Policy[] a) + throws InvalidPolicy + { + if (applies(ServantRetentionPolicyValue.NON_RETAIN)) + { + if (!applies(RequestProcessingPolicyValue.USE_DEFAULT_SERVANT) && + !applies(RequestProcessingPolicyValue.USE_SERVANT_MANAGER) + ) + { + short p = 0; + for (short i = 0; i < a.length; i++) + { + if (a [ i ].policy_type() == SERVANT_RETENTION_POLICY_ID.value) + p = i; + } + throw new InvalidPolicy("NON_RETAIN requires either " + + "USE_DEFAULT_SERVANT or USE_SERVANT_MANAGER", + p + ); + } + } + return true; + } + + /** + * Recursively searches for the given object in the POA tree. + */ + public activeObjectMap.Obj findObject(org.omg.CORBA.Object object) + { + activeObjectMap.Obj h = aom.findObject(object); + if (h != null) + return h; + else + { + for (int i = 0; i < children.size(); i++) + { + h = ((gnuPOA) children.get(i)).findObject(object); + if (h != null) + return h; + } + } + return h; + } + + /** + * Recursively searches for the given key in the POA tree. + * @param ior_key the key, ecapsulating both object + * and poa ids. + * @return + */ + public activeObjectMap.Obj findKey(byte[] object_id, byte[] poa_id) + { + activeObjectMap.Obj h = null; + if (Arrays.equals(poa_id, id())) + h = aom.get(object_id); + if (h != null) + return h; + else + { + for (int i = 0; i < children.size(); i++) + { + h = ((gnuPOA) children.get(i)).findKey(object_id, poa_id); + if (h != null) + return h; + } + } + return h; + } + + /** + * Parses the given key, extracts poa and object id and searches + * for such reference. + */ + public activeObjectMap.Obj findIorKey(byte[] ior_key) + { + cdrBufInput in = new cdrBufInput(ior_key); + int signature = in.read_long(); + if (signature != SIGNATURE) + return null; + + byte[] id = in.read_sequence(); + byte[] poa = in.read_sequence(); + return findKey(id, poa); + } + + /** + * Converts the object Id into the IOR key. IOR key must be + * unique in the scope of the ORB, and Ids only in the scope of POA. + * Hence the IOR key includes the POA identifiers. + */ + public byte[] toIORKey(byte[] object_id) + { + cdrBufOutput buffer = new cdrBufOutput(); + buffer.write_long(SIGNATURE); + buffer.write_sequence(object_id); + buffer.write_sequence(id()); + return buffer.buffer.toByteArray(); + } + + /** + * Extracts the object id from the ior key. + * + * @param ior_key + * + * @return the encapsulated object ior key or null if + * this ior key either refers a different POA or encoding signature + * mismatch. + */ + public byte[] idFormIor(byte[] ior_key) + { + cdrBufInput in = new cdrBufInput(ior_key); + int signature = in.read_long(); + if (signature != SIGNATURE) + return null; + + byte[] object_id = in.read_sequence(); + byte[] poa_id = in.read_sequence(); + if (Arrays.equals(poa_id, id())) + return object_id; + else + return null; + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/Poa/gnuPOAManager.java b/libjava/classpath/gnu/CORBA/Poa/gnuPOAManager.java new file mode 100644 index 00000000000..6c1b5644f36 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/gnuPOAManager.java @@ -0,0 +1,225 @@ +/* gnuPOAManager.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import org.omg.CORBA.BAD_INV_ORDER; +import org.omg.CORBA.LocalObject; +import org.omg.PortableServer.POAManager; +import org.omg.PortableServer.POAManagerPackage.AdapterInactive; +import org.omg.PortableServer.POAManagerPackage.State; + +import java.util.HashSet; +import java.util.Iterator; + +/** + * The implementation of the POA manager. The manager is a controlled + * switch that can change its states in response to the method calls + * and throw exceptions if the requested change is invalid. It is possible + * to check the state this switch. It does not do anything else. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuPOAManager + extends LocalObject + implements POAManager +{ + /** + * The POAs, controlled by this manager. The members must be instances of + * the gnuAbstractPOA. + */ + HashSet POAs = new HashSet(); + + /** + * The state of the manager. The newly created manager is always + * in the holding state. + */ + State state = State.HOLDING; + + /** + * Get the state of the POA manager. + */ + public State get_state() + { + return state; + } + + /** + * Turns the associated POAs into active state, allowing them to receive + * and process requests. + * + * @throws if the POAs are in the inactive state. If once inactivated, + * the POA cannot be activated again. This method can only be called + * to leave the holding or discarding state. + */ + public void activate() + throws AdapterInactive + { + if (state != State.INACTIVE) + state = State.ACTIVE; + else + throw new AdapterInactive(); + } + + /** + * Turns the associated POAs into holding state. In this state, the POAs + * queue incoming requests but do not process them. + * + * @param wait_for_completion if true, the method call suspends the current + * thread till POAs complete the requests they are currently processing. If + * false, the method returns immediately. + + * @throws AdapterInactive if the POAs are in the inactive state. + */ + public void hold_requests(boolean wait_for_completion) + throws AdapterInactive + { + if (state != State.INACTIVE) + state = State.HOLDING; + else + throw new AdapterInactive(); + if (wait_for_completion) + waitForIdle(); + } + + /** + * + * Turns the asociated POAs into inactive state. The POAs in the incative + * state will reject new requests. If the POA is once inactivated, it + * cannot be activated again. The operation is used when + * the associated POAs are to be shut down. + * + * @param etherealize_objects if true, the servant managers of the + * associated POAs, having RETAIN and USE_SERVANT_MANAGER policies, + * will receive a call of {@link ServantActivatorOperations#etherealize}. + * + * @param wait_for_completion if true, the method call suspends the current + * thread till POAs complete the requests they are currently processing. If + * false, the method returns immediately. + * + * @throws AdapterInactive if the POAs are already in the inactive state. + * + * @see POAOperations#destroy + */ + public void deactivate(boolean etherealize_objects, + boolean wait_for_completion + ) + throws AdapterInactive + { + if (state == State.INACTIVE) + throw new AdapterInactive("Repetetive inactivation"); + state = State.INACTIVE; + if (wait_for_completion) + waitForIdle(); + + Iterator iter = POAs.iterator(); + while (iter.hasNext()) + { + gnuPOA poa = (gnuPOA) iter.next(); + + // If the servant activator is non null, this means it has been + // set - hence the policies are appropriate. + if (poa.servant_activator != null) + poa.etherealizeAll(); + } + } + + /** + * Turns the associated POAs into discaring state. In this state, the POAs + * discard the incoming requests. This mode is used in situations when + * the server is flooded with requests. The client receives remote exception + * ({@link org.omg.CORBA.TRANSIENT}, minor code 1). + * + * @param wait_for_completion if true, the method call suspends the current + * thread till POAs complete the requests they are currently processing. If + * false, the method returns immediately. + + * @throws AdapterInactive if the POAs are in the inactive state. + */ + public void discard_requests(boolean wait_for_completion) + throws AdapterInactive + { + if (state != State.INACTIVE) + state = State.DISCARDING; + else + throw new AdapterInactive(); + if (wait_for_completion) + waitForIdle(); + } + + /** + * Suspend the current thread while at least one of the associated POA is + * actively processing some requests. The method assumes that the POAs + * are not accepting the <i>new</i> requests due manager state. + * + * @throws BAD_INV_ORDER if the POAs are in the active state. + */ + public void waitForIdle() + { + if (state == State.ACTIVE) + throw new BAD_INV_ORDER("The state is active"); + + Iterator iter = POAs.iterator(); + while (iter.hasNext()) + { + gnuPOA poa = (gnuPOA) iter.next(); + poa.waitWhileRunning(); + } + } + + /** + * Add the POA that will be controlled by this manager. + * + * @param poa the POA. + */ + public void addPoa(gnuPOA poa) + { + POAs.add(poa); + } + + /** + * Remove the POA, releasing it from the control of this manager. + * Called in POA finaliser. + * + * @param poa the POA to remove. + */ + public void removePOA(gnuPOA poa) + { + POAs.remove(poa); + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/Poa/gnuPoaCurrent.java b/libjava/classpath/gnu/CORBA/Poa/gnuPoaCurrent.java new file mode 100644 index 00000000000..927d02fe3d2 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/gnuPoaCurrent.java @@ -0,0 +1,179 @@ +/* gnuPoaCurrent.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import org.omg.CORBA.CurrentHelper; +import org.omg.CORBA.portable.ObjectImpl; +import org.omg.PortableServer.Current; +import org.omg.PortableServer.CurrentOperations; +import org.omg.PortableServer.CurrentPackage.NoContext; +import org.omg.PortableServer.POA; + +import java.util.Iterator; +import java.util.Map; +import java.util.TreeMap; + +/** + * Supports the "Poa current" concept, providing the id and poa of + * the object currently being served. There is only one instance + * of this class per ORB. It maintains a thread to information map. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuPoaCurrent + extends ObjectImpl + implements Current +{ + /** + * The table, mapping threads to records. + */ + private TreeMap threads = new TreeMap(); + + /** + * Get the array of POA current repository ids. + * + * @return a single member array, containing value, returned + * by the {@link CurrentHelper#id}, normally + * "IDL:omg.org/PortableServer/Current:2.3". + */ + public String[] _ids() + { + return new String[] { CurrentHelper.id() }; + } + + /** + * Get the object id, associated with the thread currently being served. + * + * @throws NoContext if the current thread is not associated with any + * object. + */ + public byte[] get_object_id() + throws NoContext + { + CurrentOperations r; + synchronized (threads) + { + r = (CurrentOperations) threads.get(Thread.currentThread().getName()); + } + if (r != null) + return r.get_object_id(); + else + throw new NoContext(Thread.currentThread().getName()); + } + + /** + * Get the object POA, associated with the thread currently being served. + * + * @throws NoContext if the current thread is not associated with any + * object. + */ + public POA get_POA() + throws NoContext + { + CurrentOperations r; + synchronized (threads) + { + r = (CurrentOperations) threads.get(Thread.currentThread().getName()); + } + if (r != null) + return r.get_POA(); + else + throw new NoContext(Thread.currentThread().getName()); + } + + /** + * Add the entry to the map. + */ + public void put(Thread t, CurrentOperations record) + { + synchronized (threads) + { + threads.put(t.getName(), record); + } + } + + /** + * Check if this Poa has some running threads. + */ + public boolean has(POA poa) + { + synchronized (threads) + { + Iterator iter = threads.entrySet().iterator(); + while (iter.hasNext()) + { + Map.Entry item = (Map.Entry) iter.next(); + try + { + if (((CurrentOperations) item.getValue()).get_POA() == poa) + { + return true; + } + } + catch (NoContext ex) + { + throw new InternalError(); + } + } + } + return false; + } + + /** + * Check if this thread is registered. + */ + public boolean has(Thread t) + { + synchronized (threads) + { + return threads.containsKey(t.getName()); + } + } + + /** + * Remove the entry from the map. + */ + public void remove(Thread t) + { + synchronized (threads) + { + threads.remove(t.getName()); + } + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/Poa/gnuRequestProcessingPolicy.java b/libjava/classpath/gnu/CORBA/Poa/gnuRequestProcessingPolicy.java new file mode 100644 index 00000000000..5bbcd1321b3 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/gnuRequestProcessingPolicy.java @@ -0,0 +1,80 @@ +/* gnuRequestProcessingPolicy.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import gnu.CORBA._PolicyImplBase; + +import org.omg.PortableServer.REQUEST_PROCESSING_POLICY_ID; +import org.omg.PortableServer.RequestProcessingPolicy; +import org.omg.PortableServer.RequestProcessingPolicyValue; + +/** + * The implementation of the request processing policy. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuRequestProcessingPolicy + extends _PolicyImplBase + implements RequestProcessingPolicy, vPolicy +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1L; + + /** + * Create the policy. + * + * @param v a value for the policy. + */ + public gnuRequestProcessingPolicy(RequestProcessingPolicyValue v) + { + super(REQUEST_PROCESSING_POLICY_ID.value, v, v.value(), + "IDL:org.omg/PortableServer/RequestProcessingPolicy:1.0" + ); + } + + /** + * Get the value for the policy that was passed in a constructor. + */ + public RequestProcessingPolicyValue value() + { + return (RequestProcessingPolicyValue) getValue(); + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/Poa/gnuServantObject.java b/libjava/classpath/gnu/CORBA/Poa/gnuServantObject.java new file mode 100644 index 00000000000..1ad98d1cecd --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/gnuServantObject.java @@ -0,0 +1,802 @@ +/* gnuServantObject.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import gnu.CORBA.GIOP.ReplyHeader; +import gnu.CORBA.IOR_Delegate; +import gnu.CORBA.IOR_contructed_object; +import gnu.CORBA.Interceptor.gnuServerRequestInfo; +import gnu.CORBA.ObjectCreator; +import gnu.CORBA.Unexpected; +import gnu.CORBA.bufferedResponseHandler; +import gnu.CORBA.recordTypeCode; +import gnu.CORBA.streamReadyHolder; + +import org.omg.CORBA.Any; +import org.omg.CORBA.BAD_OPERATION; +import org.omg.CORBA.BAD_PARAM; +import org.omg.CORBA.CompletionStatus; +import org.omg.CORBA.OBJECT_NOT_EXIST; +import org.omg.CORBA.OBJ_ADAPTER; +import org.omg.CORBA.ORB; +import org.omg.CORBA.SystemException; +import org.omg.CORBA.TCKind; +import org.omg.CORBA.TRANSIENT; +import org.omg.CORBA.UserException; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.InvokeHandler; +import org.omg.CORBA.portable.ObjectImpl; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.ResponseHandler; +import org.omg.PortableInterceptor.ForwardRequest; +import org.omg.PortableInterceptor.ServerRequestInterceptorOperations; +import org.omg.PortableServer.CurrentOperations; +import org.omg.PortableServer.DynamicImplementation; +import org.omg.PortableServer.ImplicitActivationPolicyValue; +import org.omg.PortableServer.POA; +import org.omg.PortableServer.POAManager; +import org.omg.PortableServer.POAManagerPackage.State; +import org.omg.PortableServer.Servant; +import org.omg.PortableServer.ServantLocatorPackage.CookieHolder; +import org.omg.PortableServer.ServantRetentionPolicyValue; +import org.omg.PortableServer.portable.Delegate; + +import java.io.IOException; + +import java.util.Arrays; + +/** + * Represents a CORBA object, being locally served by the associated servant. + * The calls to the object are forwarded to the calls to the servant. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuServantObject extends ObjectImpl + implements org.omg.CORBA.Object, + InvokeHandler, + CurrentOperations +{ + /** + * The associated servant that must also implement the {@link InvokeHandler} + * interface. This value can be temporary null if the object was created using + * POA.create_reference or POA.create_reference_with_id, private to force + * always to use {@link setServant}. + */ + private Servant servant; + + /** + * The Id of this object. + */ + public final byte[] Id; + + /** + * The poa that takes care about this object. + */ + public final gnuPOA poa; + + /** + * The POA manager, used to control the work of this object. + */ + public final POAManager manager; + + /** + * The orb. + */ + public final ORB_1_4 orb; + + /** + * The object repository ids, if they were specified separately. Normally, the + * ids are requested from the servant. + */ + public final String[] repository_ids; + + /** + * Create an object with no connected servant. The servant must be set later. + * + * @param a_repository_ids an array of repository ids, can be null (then ids + * will be requested from the servant). + * @param an_id the object id. + * @param a_poa the POA. + */ + public gnuServantObject(String[] a_repository_ids, byte[] an_id, + gnuPOA a_poa, ORB_1_4 an_orb + ) + { + repository_ids = a_repository_ids; + Id = an_id; + manager = a_poa.the_POAManager(); + poa = a_poa; + orb = an_orb; + } + + /** + * Create a servant object, associated with the passed servant. + * + * @param a_servant a servant, serving this object. + * @param an_id an Object Id for this object. + * + * @throws BAD_PARAM if the passed servant is not an {@link InvokeHandler}. + */ + public gnuServantObject(Servant a_servant, byte[] an_id, ORB_1_4 an_orb, + gnuPOA a_poa + ) + { + Id = an_id; + setServant(a_servant); + poa = a_poa; + if (poa != null) + { + manager = poa.the_POAManager(); + } + else + { + manager = null; + } + repository_ids = null; + orb = an_orb; + } + + /** + * Set a servant, if it has not been previously set. + * + * @param a_servant a servant to set, can be null to indicate the necessity + * for the subsequent activation. + * + * @throws BAD_PARAM if the passed servant is not an {@link InvokeHandler} or + * {@link DynamicImplementation} and also not null. + */ + public void setServant(Servant a_servant) + { + if (a_servant != null && + !(a_servant instanceof InvokeHandler) && + !(a_servant instanceof DynamicImplementation) + ) + { + throw new BAD_PARAM("Must be either InvokeHandler or " + + "DynamicImplementation, but is " + a_servant + ); + } + servant = a_servant; + } + + /** + * Returns the associated servant. + */ + public Servant getServant() + { + return servant; + } + + /** + * Return the associated invocation handler. + */ + public InvokeHandler getHandler(String operation, CookieHolder cookie, + boolean forwarding_allowed + ) throws gnuForwardRequest + { + if (servant != null) + { + return servantToHandler(servant); + } + else + { + // Use servant locator to locate the servant. + if (poa.servant_locator != null) + { + try + { + servant = + poa.servant_locator.preinvoke(Id, poa, operation, cookie); + return servantToHandler(servant); + } + catch (org.omg.PortableServer.ForwardRequest forw_ex) + { + if (forwarding_allowed) + { + throw new gnuForwardRequest(forw_ex.forward_reference); + } + else + { + servant = + ForwardedServant.create(forw_ex.forward_reference); + return servantToHandler(servant); + } + } + } + else + // Use servant activator to locate the servant. + if (poa.applies(ImplicitActivationPolicyValue.IMPLICIT_ACTIVATION) && + poa.applies(ServantRetentionPolicyValue.RETAIN) + ) + { + try + { + poa.activate_object_with_id(Id, servant, forwarding_allowed); + servant = poa.id_to_servant(Id); + return servantToHandler(servant); + } + catch (gnuForwardRequest forwarded) + { + throw forwarded; + } + catch (Exception ex) + { + ex.printStackTrace(); + + BAD_OPERATION bad = + new BAD_OPERATION("Unable to activate", 0x5004, + CompletionStatus.COMPLETED_NO + ); + bad.initCause(ex); + throw bad; + } + } + else if (poa.default_servant != null) + { + servant = poa.default_servant; + return servantToHandler(servant); + } + + // No servant and no servant manager - throw exception. + else + { + throw new BAD_OPERATION("Unable to activate", 0x5002, + CompletionStatus.COMPLETED_NO + ); + } + } + } + + /** + * Convert the servant to invocation handler. + */ + public InvokeHandler servantToHandler(Servant a_servant) + { + if (a_servant instanceof InvokeHandler) + { + return (InvokeHandler) a_servant; + } + else if (a_servant instanceof DynamicImplementation) + { + return new dynImpHandler((DynamicImplementation) a_servant); + } + else + { + throw new BAD_OPERATION(a_servant + + " must be either InvokeHandler or " + "POA DynamicImplementation" + ); + } + } + + /** + * Create a servant object, associated with the passed servant. Requests the + * object id from the servant. Depending on the policies of the servants POA, + * the calls are eithe not synchronized or synchronized on POA or ORB. + * + * @param a_servant a servant, serving this object. + * @param an_id an Object Id for this object. + */ + public gnuServantObject(Servant a_servant, gnuPOA a_poa) + { + this(a_servant, a_servant._object_id(), (ORB_1_4) a_servant._orb(), a_poa); + } + + /** + * Delegates call to servant, passing the poa and Id. + */ + public String[] _ids() + { + if (repository_ids == null) + { + return getServant()._all_interfaces(poa, Id); + } + else + { + return repository_ids; + } + } + + /** + * Gets a string representation. + */ + public String toString() + { + StringBuffer b = new StringBuffer("Servant object ("); + for (int i = 0; i < Id.length; i++) + { + b.append(Integer.toHexString(Id [ i ] & 0xFF)); + b.append(' '); + } + b.append(')'); + return b.toString(); + } + + /** + * Always returns true. + */ + public boolean _is_local() + { + return true; + } + + /** + * Check if this object could be named by the given repository id. + * + * @param idl_id the repository id to check. + * + * @return true if it is one of the possible repository ids of this object. + */ + public boolean _is_a(String idl_id) + { + String[] maybe = _ids(); + for (int i = 0; i < maybe.length; i++) + { + if (maybe [ i ].equals(idl_id)) + { + return true; + } + } + return false; + } + + /** + * Get an ORB, associated with the servant of this object. + * + * @return + */ + public ORB _orb() + { + return getServant()._orb(); + } + + /** + * Handle the invocation (delegates to servant). + * + * @throws TRANSIENT minor 0x535503e9 if the POA is in discarding mode. + * @throws OBJ_ADAPTER minor 0x535503ea if the POA is inactivated. + * @throws OBJECT_NOT_EXISTS minor 0x535503ec if this object is inactivated. + * + * @specnote see {@link POAManagerOperations} for specnotes about the minor + * codes. + */ + public OutputStream _invoke(String method, InputStream input, + ResponseHandler r_handler + ) throws SystemException + { + boolean intercept = false; + ServerRequestInterceptorOperations interceptor = null; + gnuServerRequestInfo info = null; + bufferedResponseHandler i_handler = null; + + try + { + if (orb.iServer != null && + r_handler instanceof bufferedResponseHandler + ) + { + interceptor = orb.iServer; + + i_handler = (bufferedResponseHandler) r_handler; + + info = + new gnuServerRequestInfo(this, i_handler.request_header, + i_handler.reply_header + ); + intercept = true; + + interceptor.receive_request_service_contexts(info); + } + + try + { + CookieHolder cookie = null; + activeObjectMap.Obj self = poa.aom.get(Id); + + if (poa.servant_locator != null) + { + // If the servant locator is in use, it is always responsible + // for providing the servant. + self.servant = servant = null; + cookie = new CookieHolder(); + } + else if (self != null && self.isDeactiveted()) + { + if (poa.applies( + ImplicitActivationPolicyValue.IMPLICIT_ACTIVATION + ) && + poa.servant_activator != null + ) + { + // Reset the servant, forcing the subsequent activation. + servant = null; + } + else + { + throw new OBJECT_NOT_EXIST("Object deactivated", + 0x535503ec, CompletionStatus.COMPLETED_NO + ); + } + } + + InvokeHandler handler = getHandler(method, cookie, true); + + Delegate d = null; + + try + { + d = servant._get_delegate(); + orb.currents.put(Thread.currentThread(), this); + } + catch (Exception ex) + { + // In some cases exception is thrown if the delegate is not set. + } + if (d instanceof servantDelegate) + { + // If the delegate is already set, check maybe we can + // reuse the existing instance. + if (((servantDelegate) d).object != this) + { + servant._set_delegate(new servantDelegate(servant, poa, Id)); + } + } + else + { + servant._set_delegate(new servantDelegate(servant, poa, Id)); + } + + try + { + switch (manager.get_state().value()) + { + case State._ACTIVE : + + OutputStream rt; + try + { + if (intercept) + { + interceptor.receive_request(info); + } + + rt = handler._invoke(method, input, r_handler); + + if (intercept) + { + // Handler is casted into i_handler. + if (i_handler.isExceptionReply()) + { + info.m_reply_header.reply_status = + ReplyHeader.USER_EXCEPTION; + + // Make Any, holding the user exception. + Any a = orb.create_any(); + OutputStream buf = i_handler.getBuffer(); + InputStream in = buf.create_input_stream(); + String uex_idl = "unknown"; + try + { + in.mark(Integer.MAX_VALUE); + uex_idl = in.read_string(); + in.reset(); + } + catch (IOException e) + { + throw new Unexpected(e); + } + + try + { + UserException exception = + ObjectCreator.readUserException(uex_idl, + in + ); + + ObjectCreator.insertWithHelper(a, + exception + ); + } + catch (Exception e) + { + // Failed due any reason, insert without + // helper. + a.insert_Streamable(new streamReadyHolder( + buf.create_input_stream() + ) + ); + + recordTypeCode r = + new recordTypeCode(TCKind.tk_except); + r.setId(uex_idl); + r.setName(ObjectCreator.getDefaultName( + uex_idl + ) + ); + } + + info.m_usr_exception = a; + interceptor.send_exception(info); + } + else + { + info.m_reply_header.reply_status = + ReplyHeader.NO_EXCEPTION; + interceptor.send_reply(info); + } + } + } + catch (SystemException sys_ex) + { + if (intercept) + { + info.m_reply_header.reply_status = + ReplyHeader.SYSTEM_EXCEPTION; + info.m_sys_exception = sys_ex; + interceptor.send_exception(info); + } + throw sys_ex; + } + + return rt; + + case State._HOLDING : + + // The holding mode is implemented + // relying on the holding capabilites of the network + // support (if any). + // TODO FIXME in more recent CORBA applications, the + // client + // ORB can free the connection and wait for a server side + // notification about the completed request. Implement + // this + // as soon as JDK specification would allow bidirectional + // policy. + int sleep = 5; + int max = 500; + + // Wait till the state will be switched into some other + // mode. + while (manager.get_state().value() == State._HOLDING) + { + try + { + Thread.sleep(sleep); + if (sleep < max) + { + sleep = max; + } + } + catch (InterruptedException ex) + { + } + } + + // Handle another mode. + return _invoke(method, input, r_handler); + + case State._DISCARDING : + throw new TRANSIENT("Discarding mode", 0x535503e9, + CompletionStatus.COMPLETED_NO + ); + + case State._INACTIVE : + throw new OBJ_ADAPTER("POA deactivated", 0x535503ea, + CompletionStatus.COMPLETED_NO + ); + + default : + throw new InternalError(); // No more states. + } + } + finally + { + if (poa.servant_locator != null) + { + poa.servant_locator.postinvoke(Id, poa, method, + cookie.value, servant + ); + servant = null; + } + } + } + finally + { + orb.currents.remove(Thread.currentThread()); + } + } + catch (ForwardRequest fex) + { + // May be thrown by interceptor. + if (intercept) + { + Forwarding: + while (true) + { + info.m_reply_header.reply_status = + ReplyHeader.LOCATION_FORWARD; + info.m_forward_reference = fex.forward; + try + { + interceptor.send_other(info); + break Forwarding; + } + catch (ForwardRequest fex2) + { + info.m_forward_reference = fex2.forward; + fex.forward = info.m_forward_reference; + } + } + } + throw new gnuForwardRequest(fex.forward); + } + catch (gnuForwardRequest fex) + { + // May be thrown during activation. + if (intercept) + { + Forwarding: + while (true) + { + info.m_reply_header.reply_status = + ReplyHeader.LOCATION_FORWARD; + info.m_forward_reference = fex.forward_reference; + try + { + interceptor.send_other(info); + break Forwarding; + } + catch (ForwardRequest fex2) + { + info.m_forward_reference = fex2.forward; + fex.forward_reference = (ObjectImpl) fex2.forward; + } + } + } + throw fex; + } + } + + /** + * Compare with another object for equality, comparing the object keys. + */ + public boolean equals(java.lang.Object other) + { + if (other instanceof gnuServantObject) + { + gnuServantObject o = (gnuServantObject) other; + + return Arrays.equals(o.Id, Id); + } + else + { + return false; + } + } + + /** + * Get the hash code, based on the object key. + */ + public int hashCode() + { + long s = 0; + int v = 1; + for (int i = 0; i < Id.length; i++) + { + s += Id [ i ] * v; + if (s > Integer.MAX_VALUE) + { + s = s % Integer.MAX_VALUE; + v = 1; + } + v = v * 8; + } + return (int) (s % Integer.MAX_VALUE); + } + + /** + * Get the object id. + */ + public byte[] get_object_id() + { + return Id; + } + + /** + * Get POA. + */ + public POA get_POA() + { + return poa; + } + + /** + * Returns without action. + */ + public void _release() + { + } + + /** + * Returns without action. + */ + public void _releaseReply(InputStream stream) + { + } + + /** + * Checks if this object is equivalent to another instance. These objects are + * assumed equal if they are connected to the same orb and poa under the same + * Id, regardless of they delegates. + * + * @param another instance to check. + * @return + */ + public boolean _is_equivalent(org.omg.CORBA.Object other) + { + if (other instanceof gnuServantObject) + { + gnuServantObject g = (gnuServantObject) other; + return orb == g.orb && poa == g.poa && Arrays.equals(Id, g.Id); + } + else if (other instanceof IOR_contructed_object) + { + IOR_contructed_object ir = ((IOR_contructed_object) other); + try + { + IOR_Delegate ird = (IOR_Delegate) ir._get_delegate(); + byte[] ior_id = poa.idFormIor(ird.getIor().key); + if (ior_id != null && Arrays.equals(ior_id, Id)) + { + return true; + } + else + { + return false; + } + } + catch (Exception ex) + { + // Non - typical delegate or very specific subclass of + // IOR_constructed_object. + return super._is_equivalent(other); + } + } + return super._is_equivalent(other); + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/Poa/gnuServantRetentionPolicy.java b/libjava/classpath/gnu/CORBA/Poa/gnuServantRetentionPolicy.java new file mode 100644 index 00000000000..009e70e1b35 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/gnuServantRetentionPolicy.java @@ -0,0 +1,80 @@ +/* gnuServantRetentionPolicy.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import gnu.CORBA._PolicyImplBase; + +import org.omg.PortableServer.SERVANT_RETENTION_POLICY_ID; +import org.omg.PortableServer.ServantRetentionPolicy; +import org.omg.PortableServer.ServantRetentionPolicyValue; + +/** + * The implementation of the servant retention policy. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuServantRetentionPolicy + extends _PolicyImplBase + implements ServantRetentionPolicy, vPolicy +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1L; + + /** + * Create the policy. + * + * @param v a value for the policy. + */ + public gnuServantRetentionPolicy(ServantRetentionPolicyValue v) + { + super(SERVANT_RETENTION_POLICY_ID.value, v, v.value(), + "IDL:org.omg/PortableServer/ServantRetentionPolicy:1.0" + ); + } + + /** + * Get the value for the policy that was passed in a constructor. + */ + public ServantRetentionPolicyValue value() + { + return (ServantRetentionPolicyValue) getValue(); + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/Poa/gnuThreadPolicy.java b/libjava/classpath/gnu/CORBA/Poa/gnuThreadPolicy.java new file mode 100644 index 00000000000..f42ebefb363 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/gnuThreadPolicy.java @@ -0,0 +1,80 @@ +/* gnuThreadPolicy.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import gnu.CORBA._PolicyImplBase; + +import org.omg.PortableServer.THREAD_POLICY_ID; +import org.omg.PortableServer.ThreadPolicy; +import org.omg.PortableServer.ThreadPolicyValue; + +/** + * The implementation of the thread policy. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuThreadPolicy + extends _PolicyImplBase + implements ThreadPolicy, vPolicy +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1L; + + /** + * Create the policy. + * + * @param v a value for the policy. + */ + public gnuThreadPolicy(ThreadPolicyValue v) + { + super(THREAD_POLICY_ID.value, v, v.value(), + "IDL:org.omg/PortableServer/ThreadPolicy:1.0" + ); + } + + /** + * Get the value for the policy that was passed in a constructor. + */ + public ThreadPolicyValue value() + { + return (ThreadPolicyValue) getValue(); + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/Poa/policySets.java b/libjava/classpath/gnu/CORBA/Poa/policySets.java new file mode 100644 index 00000000000..eb688467ae7 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/policySets.java @@ -0,0 +1,128 @@ +/* policySets.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import org.omg.CORBA.Policy; +import org.omg.PortableServer.IdAssignmentPolicyValue; +import org.omg.PortableServer.IdUniquenessPolicyValue; +import org.omg.PortableServer.ImplicitActivationPolicyValue; +import org.omg.PortableServer.LifespanPolicyValue; +import org.omg.PortableServer.RequestProcessingPolicyValue; +import org.omg.PortableServer.ServantRetentionPolicyValue; +import org.omg.PortableServer.ThreadPolicyValue; + +import java.util.ArrayList; + +/** + * Contains the frequently uset POA policy sets. The policy + * arrays are package private for security reasons, the cloned + * copies are returned. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class policySets +{ + /** + * The default policy set, as defined in OMG specs. This is also + * the policy set for the root POA. + */ + private static final vPolicy[] rootPOASet = + new vPolicy[] + { + new gnuThreadPolicy(ThreadPolicyValue.ORB_CTRL_MODEL), + new gnuLifespanPolicy(LifespanPolicyValue.TRANSIENT), + new gnuIdUniquenessPolicy(IdUniquenessPolicyValue.UNIQUE_ID), + new gnuIdAssignmentPolicy(IdAssignmentPolicyValue.SYSTEM_ID), + new gnuServantRetentionPolicy(ServantRetentionPolicyValue.RETAIN), + new gnuRequestProcessingPolicy(RequestProcessingPolicyValue.USE_ACTIVE_OBJECT_MAP_ONLY), + new gnuImplicitActivationPolicy(ImplicitActivationPolicyValue.IMPLICIT_ACTIVATION) + }; + + /** + * Return the policy set, applicable for the root POA, as defined + * in OMG specs. + */ + public static Policy[] rootPoa() + { + Policy[] p = new Policy[ rootPOASet.length ]; + System.arraycopy(rootPOASet, 0, p, 0, p.length); + return p; + } + + /** + * Convert the potentially incomplete policy array into array, containing + * the complete policy set. + * + * @param policies the policy list, may be incomplete (even zero size). + * + * @return the complete policy array. The missing, but needed policies + * are added with they default values. + */ + public static Policy[] withDefault(Policy[] policies) + { + ArrayList current = new ArrayList(rootPOASet.length); + Policy p_default; + boolean specified; + + for (int i = 0; i < rootPOASet.length; i++) + { + p_default = rootPOASet [ i ]; + specified = false; + ForThis: + for (int j = 0; j < policies.length; j++) + { + if (policies [ j ].policy_type() == p_default.policy_type()) + { + specified = true; + current.add(policies [ j ]); + break ForThis; + } + } + if (!specified) + current.add(p_default.copy()); + } + + Policy[] complete = new Policy[ current.size() ]; + for (int i = 0; i < complete.length; i++) + { + complete [ i ] = (Policy) current.get(i); + } + return complete; + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/Poa/servantDelegate.java b/libjava/classpath/gnu/CORBA/Poa/servantDelegate.java new file mode 100644 index 00000000000..f59c01c6b3e --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/servantDelegate.java @@ -0,0 +1,232 @@ +/* servantDelegate.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import gnu.CORBA.Unexpected; + +import org.omg.CORBA.NO_IMPLEMENT; +import org.omg.CORBA.ORB; +import org.omg.CORBA.ORBPackage.InvalidName; +import org.omg.CORBA.Object; +import org.omg.PortableServer.CurrentPackage.NoContext; +import org.omg.PortableServer.POA; +import org.omg.PortableServer.POAHelper; +import org.omg.PortableServer.Servant; +import org.omg.PortableServer.portable.Delegate; + +/** + * The implementation of the servant delegate for the locally existing + * servant.The associated servant that must also implement the + * {@link InvokeHandler} interface. Each servant requires a separate + * instance of this delegate and can serve a single object only. + * Hence the fields are final, but the delegate is typically reused + * unless the same servant is connected to different objects. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class servantDelegate + implements Delegate +{ + /** + * The servant, associated with this object. + */ + final Servant servant; + + /** + * The servant (not object) id. + */ + final byte[] servant_id; + + /** + * The POA, where the servant is connected. + */ + final gnuPOA poa; + + /** + * The object, exposed as an object, served by this servant. + */ + final gnuServantObject object; + + /** + * Create the delegat for the servant that will be connected to the + * given poa. The method is normally called from inside of gnuPOA. + * The constructor sets the newly created delegate as the delegate to this + * servant by calling Servant._set_delegate. + * + * @param a_poa the poa. + * @param a_servant the servant. + * @param a_servant_id the servant id. + */ + public servantDelegate(Servant a_servant, gnuPOA a_poa, byte[] a_servant_id) + { + poa = a_poa; + servant = a_servant; + servant_id = a_servant_id; + servant._set_delegate(this); + object = + new gnuServantObject(servant, servant_id, (ORB_1_4) servant._orb(), a_poa); + object._set_delegate(new LocalDelegate(object, poa, a_servant_id)); + } + + /** + * Check if this object could be named by the given repository id. + * @param idl_id the repository id to check. + * + * @return true if it is one of the possible repository ids of this + * object. + */ + public boolean is_a(Servant a_servant, String idl_id) + { + same(a_servant); + + String[] maybe = object.repository_ids; + if (maybe == null) + maybe = servant._all_interfaces(poa, object.Id); + for (int i = 0; i < maybe.length; i++) + { + if (maybe [ i ].equals(idl_id)) + return true; + } + return false; + } + + /** + * Return the ORB's default POA. + */ + public POA default_POA(Servant a_servant) + { + same(a_servant); + try + { + return POAHelper.narrow(orb(a_servant).resolve_initial_references("RootPOA")); + } + catch (InvalidName ex) + { + throw new Unexpected(ex); + } + } + + /** + * Get ORB. + */ + public ORB orb(Servant a_servant) + { + same(a_servant); + return poa.orb(); + } + + /** + * Get the object, exposing the servant. + */ + public Object this_object(Servant a_servant) + { + same(a_servant); + try + { + return poa.aom.get(poa.m_orb.currents.get_object_id()).object; + } + catch (NoContext ex) + { + return object; + } + } + + /** + * Not supported. + * + * @specnote Same as for Sun up till 1.5 inclusive. + */ + public Object get_interface_def(Servant a_servant) + { + same(a_servant); + throw new NO_IMPLEMENT(); + } + + /** + * Get the Id of the object being currently served. + */ + public byte[] object_id(Servant a_servant) + { + same(a_servant); + try + { + byte[] id = poa.m_orb.currents.get_object_id(); + return id; + } + catch (NoContext ex) + { + return object.Id; + } + } + + /** + * Always returns false; + */ + public boolean non_existent(Servant a_servant) + { + same(a_servant); + return false; + } + + /** + * Return the associated POA. + */ + public POA poa(Servant a_servant) + { + same(a_servant); + try + { + return poa.m_orb.currents.get_POA(); + } + catch (NoContext ex) + { + return poa; + } + } + + /** + * Checks if the passed servant is the same as the servant, associated with + * this delegate. This class requires a single servant per delegate. + */ + void same(Servant some_servant) + { + if (servant != some_servant) + throw new InternalError("Only one servant per delegate is supported."); + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/Poa/vPolicy.java b/libjava/classpath/gnu/CORBA/Poa/vPolicy.java new file mode 100644 index 00000000000..9e45b56d7ee --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/vPolicy.java @@ -0,0 +1,62 @@ +/* vPolicy.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import org.omg.CORBA.Policy; + +/** + * The Classpath implementation of the policy, providing the policy + * value and the code of the policy type. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public interface vPolicy + extends Policy +{ + /** + * Get the value of this policy + */ + java.lang.Object getValue(); + + /** + * Get the integer code of this policy value. + */ + int getCode(); + +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/gnuValueHolder.java b/libjava/classpath/gnu/CORBA/gnuValueHolder.java new file mode 100644 index 00000000000..0b382648981 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/gnuValueHolder.java @@ -0,0 +1,135 @@ +/* gnuValueHolder.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import gnu.CORBA.CDR.Vio; + +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.ValueBaseHolder; +import org.omg.CORBA.portable.BoxedValueHelper; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; + +import java.io.Serializable; + +/** + * Boxed value holder that also remembers the value type and the value helper. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuValueHolder + extends ValueBaseHolder +{ + /** + * The type code of the stored value. + */ + TypeCode type; + + /** + * The helper that could read and write fields of the boxed value. + */ + transient BoxedValueHelper helper; + + /** + * If true, the helper not available. + */ + transient boolean helper_NA; + + /** + * Create a new instance for the given value and given type. + */ + public gnuValueHolder(Serializable value, TypeCode a_type) + { + super(value); + type = a_type; + } + + /** + * Get the true type, as it was passed in the constructor. + */ + public TypeCode _type() + { + return type; + } + + /** + * Write content to the output stream. Tries to locate the + * corresponding helper class. + */ + public void _write(OutputStream output) + { + findHelper(); + if (helper == null) + super._write(output); + else + Vio.write(output, value, helper); + } + + /** + * Read, trying to locate helper, if possible. + */ + public void _read(InputStream input) + { + findHelper(); + if (helper == null) + super._read(input); + else + value = Vio.read(input, helper); + } + + /** + * Set the read and write methods. + */ + void findHelper() + { + if (helper != null || helper_NA) + return; + try + { + Class helperClass = + Class.forName(ObjectCreator.toHelperName(type.id())); + + helper = (BoxedValueHelper) helperClass.newInstance(); + } + catch (Exception ex) + { + helper_NA = true; + } + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/classpath/Pointer.java b/libjava/classpath/gnu/classpath/Pointer.java new file mode 100644 index 00000000000..27634a8941b --- /dev/null +++ b/libjava/classpath/gnu/classpath/Pointer.java @@ -0,0 +1,47 @@ +/* Pointer.java -- Pointer to VM specific data + Copyright (C) 1999, 2000, 2004 Free Software Foundation + +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. */ + +/* This file is originally part of libgcj. */ + +package gnu.classpath; + +/** A type used to indicate special data used by native code that should not + be marked by the garbage collector. */ + +public abstract class Pointer +{ +} diff --git a/libjava/classpath/gnu/classpath/Pointer32.java b/libjava/classpath/gnu/classpath/Pointer32.java new file mode 100644 index 00000000000..42b6c1d2db0 --- /dev/null +++ b/libjava/classpath/gnu/classpath/Pointer32.java @@ -0,0 +1,52 @@ +/* Pointer32.java -- 32 bit Pointer + Copyright (C) 2004 Free Software Foundation + +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.classpath; + +/** + * A type used to indicate special data used by native code that should not + * be marked by the garbage collector. + */ +public final class Pointer32 extends Pointer +{ + final int data; + + public Pointer32(int data) + { + this.data = data; + } +} diff --git a/libjava/classpath/gnu/classpath/Pointer64.java b/libjava/classpath/gnu/classpath/Pointer64.java new file mode 100644 index 00000000000..6d27e1ba133 --- /dev/null +++ b/libjava/classpath/gnu/classpath/Pointer64.java @@ -0,0 +1,52 @@ +/* Pointer64.java -- 64 bit Pointer + Copyright (C) 2004 Free Software Foundation + +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.classpath; + +/** + * A type used to indicate special data used by native code that should not + * be marked by the garbage collector. + */ +public final class Pointer64 extends Pointer +{ + final long data; + + public Pointer64(long data) + { + this.data = data; + } +} diff --git a/libjava/classpath/gnu/classpath/jdwp/Jdwp.java b/libjava/classpath/gnu/classpath/jdwp/Jdwp.java new file mode 100644 index 00000000000..bb8f60224ce --- /dev/null +++ b/libjava/classpath/gnu/classpath/jdwp/Jdwp.java @@ -0,0 +1,302 @@ +/* Jdwp.java -- Virtual machine to JDWP back-end programming interface + Copyright (C) 2005 Free Software Foundation + +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 +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.classpath.jdwp; + +import gnu.classpath.jdwp.event.Event; +import gnu.classpath.jdwp.event.EventManager; +import gnu.classpath.jdwp.event.EventRequest; +import gnu.classpath.jdwp.id.ThreadId; +import gnu.classpath.jdwp.processor.PacketProcessor; +import gnu.classpath.jdwp.transport.ITransport; +import gnu.classpath.jdwp.transport.JdwpConnection; +import gnu.classpath.jdwp.transport.TransportException; +import gnu.classpath.jdwp.transport.TransportFactory; + +import java.io.IOException; +import java.security.AccessController; +import java.util.HashMap; + +/** + * Main interface from the virtual machine to the JDWP back-end. + * + * @author Keith Seitz (keiths@redhat.com) + */ +public class Jdwp + extends Thread +{ + // The single instance of the back-end + private static Jdwp _instance = null; + + /** + * Are we debugging? + */ + public static boolean isDebugging = false; + + // Packet processor + private PacketProcessor _packetProcessor; + private Thread _ppThread; + + // JDWP configuration properties + private HashMap _properties; + + // The suspend property of the configure string + // (-Xrunjdwp:..suspend=<boolean>) + private static final String _PROPERTY_SUSPEND = "suspend"; + + // User's main application thread + private Thread _mainThread; + + // Connection to debugger + private JdwpConnection _connection; + + // Are we shutting down the current session? + private boolean _shutdown; + + // A thread group for the JDWP threads + private ThreadGroup _group; + + /** + * constructor + */ + public Jdwp () + { + _shutdown = false; + isDebugging = true; + _instance = this; + } + + /** + * Returns the JDWP back-end, creating an instance of it + * if one does not already exist. + */ + public static Jdwp getDefault () + { + return _instance; + } + + /** + * Should the virtual machine suspend on startup? + */ + public static boolean suspendOnStartup () + { + Jdwp jdwp = getDefault (); + if (jdwp != null) + { + String suspend = (String) jdwp._properties.get (_PROPERTY_SUSPEND); + if (suspend != null && suspend.equals ("y")) + return true; + } + + return false; + } + + /** + * Configures the back-end + * + * @param configArgs a string of configury options + * @param mainThread the main application thread + */ + public void configure (String configArgs, Thread mainThread) + { + _mainThread = mainThread; + _processConfigury (configArgs); + } + + // A helper function to initialize the transport layer + private void _doInitialization () + throws TransportException + { + _group = new ThreadGroup ("JDWP threads"); + // initialize transport + ITransport transport = TransportFactory.newInstance (_properties); + _connection = new JdwpConnection (_group, transport); + _connection.initialize (); + _connection.start (); + + // Create processor + _packetProcessor = new PacketProcessor (_connection); + _ppThread = new Thread (_group, new Runnable () + { + public void run () + { + AccessController.doPrivileged (_packetProcessor); + } + }); + _ppThread.start (); + } + + /** + * Shutdown the JDWP back-end + * + * NOTE: This does not quite work properly. See notes in + * run() on this subject (catch of InterruptedException). + */ + public void shutdown () + { + if (!_shutdown) + { + _packetProcessor.shutdown (); + _ppThread.interrupt (); + _connection.shutdown (); + _shutdown = true; + isDebugging = false; + + /* FIXME: probably need to check state of user's + program -- if it is suspended, we need to either + resume or kill them. */ + + interrupt (); + } + } + + /** + * Notify the debugger of an event. This method should not + * be called if debugging is not active (but it would not + * cause any harm). Places where event notifications occur + * should check isDebugging before doing anything. + * + * The event is filtered through the event manager before being + * sent. + * + * FIXME: Probably need logic to send multiple events + * @param event the event to report + */ + public static void notify (Event event) + { + Jdwp jdwp = getDefault (); + if (jdwp != null) + { + EventManager em = EventManager.getDefault (); + EventRequest request = em.getEventRequest (event); + if (request != null) + sendEvent (request, event); + } + } + + /** + * Sends the event to the debugger. + * + * This method bypasses the event manager's filtering. + * + * @param request the debugger request for the event + * @param event the event to send + */ + public static void sendEvent (EventRequest request, Event event) + { + Jdwp jdwp = getDefault (); + if (jdwp != null) + { + try + { + // !! May need to implement send queue? + synchronized (jdwp._connection) + { + jdwp._connection.sendEvent (request, event); + } + + // Follow suspend policy + jdwp._enforceSuspendPolicy (request.getSuspendPolicy ()); + } + catch (IOException ie) + { + System.out.println ("Jdwp.notify: caught exception: " + ie); + } + } + } + + // Helper function to enforce suspend policies on event notification + private void _enforceSuspendPolicy (byte suspendPolicy) + { + switch (suspendPolicy) + { + case EventRequest.SUSPEND_NONE: + // do nothing + break; + + case EventRequest.SUSPEND_THREAD: + VMVirtualMachine.suspendThread (this); + break; + + case EventRequest.SUSPEND_ALL: + VMVirtualMachine.suspendAllThreads (); + break; + } + } + + public void run () + { + try + { + _doInitialization (); + + _mainThread.start (); + + _mainThread.join (); + } + catch (InterruptedException ie) + { + /* Shutting down. If we're in server mode, we should + prepare for a new connection. Otherwise, we should + simply exit. */ + // FIXME + } + catch (Throwable t) + { + System.out.println ("Exception in JDWP back-end: " + t); + System.exit (1); + } + } + + // A helper function to process the configure string "-Xrunjdwp:..." + private void _processConfigury (String configString) + { + // Loop through configuration arguments looking for a + // transport name + _properties = new HashMap (); + String[] options = configString.split (","); + for (int i = 0; i < options.length; ++i) + { + String[] property = options[i].split ("="); + if (property.length == 2) + _properties.put (property[0], property[1]); + // ignore malformed options + } + } +} diff --git a/libjava/classpath/gnu/classpath/jdwp/JdwpConstants.java b/libjava/classpath/gnu/classpath/jdwp/JdwpConstants.java new file mode 100644 index 00000000000..f38774d622e --- /dev/null +++ b/libjava/classpath/gnu/classpath/jdwp/JdwpConstants.java @@ -0,0 +1,901 @@ +/* JdwpConstants.java -- Constants defined by JDWP 1.4 specification + Copyright (C) 2005 Free Software Foundation + +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 +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.classpath.jdwp; + +/** + * Constants defined by JDWP specification. + * + * @author Keith Seitz (keiths@redhat.com) + */ +public class JdwpConstants +{ + public static final class Version + { + public static final int MAJOR = 1; + public static final int MINOR = 4; + } + + //////////////////////////////////////// + // Commands/Sets // + //////////////////////////////////////// + + public static final class CommandSet + { + public static final class VirtualMachine + { + public static final byte CS_VALUE = 1; + + // commands + public static final byte VERSION = 1; + public static final byte CLASSES_BY_SIGNATURE = 2; + public static final byte ALL_CLASSES = 3; + public static final byte ALL_THREADS = 4; + public static final byte TOP_LEVEL_THREAD_GROUPS = 5; + public static final byte DISPOSE = 6; + public static final byte IDSIZES = 7; + public static final byte SUSPEND = 8; + public static final byte RESUME = 9; + public static final byte EXIT = 10; + public static final byte CREATE_STRING = 11; + public static final byte CAPABILITIES = 12; + public static final byte CLASS_PATHS = 13; + public static final byte DISPOSE_OBJECTS = 14; + public static final byte HOLD_EVENTS = 15; + public static final byte RELEASE_EVENTS = 16; + public static final byte CAPABILITIES_NEW = 17; + public static final byte REDEFINE_CLASSES = 18; + public static final byte SET_DEFAULT_STRATUM = 19; + public static final byte ALL_CLASSES_WITH_GENERIC = 20; + } + + public static final class ReferenceType + { + public static final byte CS_VALUE = 2; + + // commands + public static final byte SIGNATURE= 1; + public static final byte CLASS_LOADER= 2; + public static final byte MODIFIERS = 3; + public static final byte FIELDS = 4; + public static final byte METHODS = 5; + public static final byte GET_VALUES = 6; + public static final byte SOURCE_FILE = 7; + public static final byte NESTED_TYPES = 8; + public static final byte STATUS = 9; + public static final byte INTERFACES= 10; + public static final byte CLASS_OBJECT = 11; + public static final byte SOURCE_DEBUG_EXTENSION = 12; + public static final byte SIGNATURE_WITH_GENERIC = 13; + public static final byte FIELDS_WITH_GENERIC = 14; + public static final byte METHODS_WITH_GENERIC = 15; + } + + public static final class ClassType + { + public static final byte CS_VALUE = 3; + + // commands + public static final byte SUPERCLASS = 1; + public static final byte SET_VALUES = 2; + public static final byte INVOKE_METHOD = 3; + public static final byte NEW_INSTANCE = 4; + } + + public static final class ArrayType + { + public static final byte CS_VALUE = 4; + + // commands + public static final byte NEW_INSTANCE = 1; + } + + public static final class InterfaceType + { + public static final byte CS_VALUE = 5; + + // commands + } + + public static final class Method + { + public static final byte CS_VALUE = 6; + + // commands + public static final byte LINE_TABLE = 1; + public static final byte VARIABLE_TABLE = 2; + public static final byte BYTE_CODES = 3; + public static final byte IS_OBSOLETE = 4; + public static final byte VARIABLE_TABLE_WITH_GENERIC = 5; + } + + public static final class Field + { + public static final byte CS_VALUE = 8; + + // commands + } + + public static final class ObjectReference + { + public static final byte CS_VALUE = 9; + + // commands + public static final byte REFERENCE_TYPE = 1; + public static final byte GET_VALUES = 2; + public static final byte SET_VALUES = 3; + public static final byte MONITOR_INFO = 5; + public static final byte INVOKE_METHOD = 6; + public static final byte DISABLE_COLLECTION = 7; + public static final byte ENABLE_COLLECTION = 8; + public static final byte IS_COLLECTED = 9; + } + + public static final class StringReference + { + public static final byte CS_VALUE = 10; + + // commands + public static final byte VALUE = 1; + } + + public static final class ThreadReference + { + public static final byte CS_VALUE = 11; + + // commands + public static final byte NAME = 1; + public static final byte SUSPEND = 2; + public static final byte RESUME = 3; + public static final byte STATUS = 4; + public static final byte THREAD_GROUP = 5; + public static final byte FRAMES = 6; + public static final byte FRAME_COUNT = 7; + public static final byte OWNED_MONITORS = 8; + public static final byte CURRENT_CONTENDED_MONITOR = 9; + public static final byte STOP = 10; + public static final byte INTERRUPT = 11; + public static final byte SUSPEND_COUNT = 12; + } + + public static final class ThreadGroupReference + { + public static final byte CS_VALUE = 12; + + // commands + public static final byte NAME = 1; + public static final byte PARENT = 2; + public static final byte CHILDREN = 3; + } + + public static final class ArrayReference + { + public static final byte CS_VALUE = 13; + + // commands + public static final byte LENGTH = 1; + public static final byte GET_VALUES = 2; + public static final byte SET_VALUES = 3; + } + + public static final class ClassLoaderReference + { + public static final byte CS_VALUE = 14; + + // commands + public static final byte VISIBLE_CLASSES = 1; + } + + public static final class EventRequest + { + public static final byte CS_VALUE = 15; + + // commands + public static final byte SET = 1; + public static final byte CLEAR = 2; + public static final byte CLEAR_ALL_BREAKPOINTS = 3; + } + + public static final class StackFrame + { + public static final byte CS_VALUE = 16; + + // commands + public static final byte GET_VALUES = 1; + public static final byte SET_VALUES = 2; + public static final byte THIS_OBJECT = 3; + public static final byte POP_FRAMES = 4; + } + + public static final class ClassObjectReference + { + public static final byte CS_VALUE = 17; + + // commands + public static final byte REFLECTED_TYPE = 1; + } + + public static final int MAXIMUM = ClassObjectReference.CS_VALUE; + + public static final class Event + { + public static final byte CS_VALUE = 64; + + // commands + public static final byte COMPOSITE = 100; + } + } + + //////////////////////////////////////// + // Constants // + //////////////////////////////////////// + + /* + * Error constants + */ + public static final class Error + { + /** + * No error has occurred + */ + public static final short NONE = 0; + + /** + * Passed thread is null, is not a valid thread or has exited + */ + public static final short INVALID_THREAD = 10; + + /** + * Thread group invalid + */ + public static final short INVALID_THREAD_GROUP = 11; + + /** + * Invalid priority + */ + public static final short INVALID_PRIORITY = 12; + + /** + * Specified thread has not been suspended by an event + */ + public static final short THREAD_NOT_SUSPENDED = 13; + + /** + * Thread already suspended + */ + public static final short THREAD_SUSPENDED = 14; + + /** + * Reference type has been unloaded and garbage collected + */ + public static final short INVALID_OBJECT = 20; + + /** + * Invalid class + */ + public static final short INVALID_CLASS = 21; + + /** + * Class has been loaded but not yet prepared + */ + public static final short CLASS_NOT_PREPARED = 22; + + /** + * Invalid method + */ + public static final short INVALID_METHODID = 23; + + /** + * Invalid location + */ + public static final short INVALID_LOCATION = 24; + + /** + * Invalid field + */ + public static final short INVALID_FIELDID = 25; + + /** + * Invaliid frame + */ + public static final short INVALID_FRAMEID = 30; + + /** + * There are no more Java or JNI frames on the call stack + */ + public static final short NO_MORE_FRAMES = 31; + + /** + * Information about the frame is not available + */ + public static final short OPAQUE_FRAME = 32; + + /** + * Operation can only be performed on current frame + */ + public static final short NOT_CURRENT_FRAME = 33; + + /** + * Variable is not an appropriate type for the function used + */ + public static final short TYPE_MISMATCH = 34; + + /** + * Invalid slot + */ + public static final short INVALID_SLOT = 35; + + /** + * Item already set + */ + public static final short DUPLICATE = 40; + + /** + * Desired element not found + */ + public static final short NOT_FOUND = 41; + + /** + * Invalid monitor + */ + public static final short INVALID_MONITOR = 50; + + /** + * Thread doesn't own the monitor + */ + public static final short NOT_MONITOR_OWNER = 51; + + /** + * Call has been interrupted before completion + */ + public static final short INTERRUPT = 52; + + /** + * Virtual machine attempted to read a class file and determined that + * the file is malformed or otherwise cannot be interpreted as a class + * file + */ + public static final short INVALID_CLASS_FORMAT = 60; + + /** + * Circularity has been detected while initializing a class + */ + public static final short CIRCULAR_CLASS_DEFINITION = 61; + + /** + * Verifier detected that a class file, though well formed, contained + * some sort of internal inconsistency or security problem + */ + public static final short FAILS_VERIFICATION = 62; + + /** + * Adding methods has not been implemented + */ + public static final short ADD_METHOD_NOT_IMPLEMENTED = 63; + + /** + * Schema change has not been implemented + */ + public static final short SCHEMA_CHANGE_NOT_IMPLEMENTED = 64; + + /** + * State of the thread has been modified and is now inconsistent + */ + public static final short INVALID_TYPESTATE = 65; + + /** + * A direct superclass is different for the new class version, or the set + * of directly implemented interfaces is different and + * <code>canUnrestrictedlyRedefineClasses</code> is false + */ + public static final short HIERARCHY_CHANGE_NOT_IMPLEMENTED = 66; + + /** + * New class version does not declare a method declared in the old + * class version and <code>canUnrestrictedlyRedefineClasses</code> + * is false + */ + public static final short DELETE_METHOD_NOT_IMPLEMENTED = 67; + + /** + * Class file has a version number not supported by this VM + */ + public static final short UNSUPPORTED_VERSION = 68; + + /** + * Class name defined in the new class file is different from the name + * in the old class object + */ + public static final short NAMES_DONT_MATCH = 69; + + /** + * New class version has different modifiers and + * <code>canUnrestrictedlyRedefineClasses</code> is false + */ + public static final short CLASS_MODIFIERS_CHANGE_NOT_IMPLEMENTED = 70; + + /** + * A method in the new class version has different modifiers than its + * counterpart in the old class version and + * <code>canUnrestrictedlyRedefineClasses</code> is false. + */ + public static final short METHOD_MODIFIERS_CHANGE_NOT_IMPLEMENTED = 71; + + /** + * Functionality is not implemented in this virtual machine + */ + public static final short NOT_IMPLEMENTED = 99; + + /** + * Invalid pointer + */ + public static final short NULL_POINTER = 100; + + /** + * Desired information is not available + */ + public static final short ABSENT_INFORMATION = 101; + + /** + * Specified event type id is not recognized + */ + public static final short INVALID_EVENT_TYPE = 102; + + /** + * Illegal argument + */ + public static final short ILLEGAL_ARGUMENT = 103; + + /** + * The function needed to allocate memory and no more memory was + * available for allocation + */ + public static final short OUT_OF_MEMORY = 110; + + /** + * Debugging has not been enabled in this virtual machine. JVMDI cannot + * be used + */ + public static final short ACCESS_DENIED = 111; + + /** + * The virtual machine is not running + */ + public static final short VM_DEAD = 112; + + /** + * An unexpected internal error has occurred + */ + public static final short INTERNAL = 113; + + /** + * The thread being used to call this function is not attached to the + * virtual machine. Calls must be made from attached threads. + */ + public static final short UNATTACHED_THREAD = 115; + + /** + * Invalid object type id or class tag + */ + public static final short INVALID_TAG = 500; + + /** + * Previous invoke not complete + */ + public static final short ALREADY_INVOKING = 502; + + /** + * Invalid index + */ + public static final short INVALID_INDEX = 503; + + /** + * Invalid length + */ + public static final short INVALID_LENGTH = 504; + + /** + * Invalid string + */ + public static final short INVALID_STRING = 506; + + /** + * Invalid class loader + */ + public static final short INVALID_CLASS_LOADER = 507; + + /** + * Invalid array + */ + public static final short INVALID_ARRAY = 508; + + /** + * Unable to load the transport + */ + public static final short TRANSPORT_LOAD = 509; + + /** + * Unablie to initialize the transport + */ + public static final short TRANSPORT_INIT = 510; + + /** + * Method is native + */ + public static final short NATIVE_METHOD = 511; + + /** + * Invalid count + */ + public static final short INVALID_COUNT = 512; + } + + /* + * EventKind constants + */ + public static final class EventKind + { + public static final byte SINGLE_STEP = 1; + public static final byte BREAKPOINT = 2; + public static final byte FRAME_POP = 3; + public static final byte EXCEPTION = 4; + public static final byte USER_DEFINED = 5; + public static final byte THREAD_START = 6; + public static final byte THREAD_END = 7; + public static final byte CLASS_PREPARE = 8; + public static final byte CLASS_UNLOAD = 9; + public static final byte CLASS_LOAD = 10; + public static final byte FIELD_ACCESS = 20; + public static final byte FIELD_MODIFICATION = 21; + public static final byte EXCEPTION_CATCH = 30; + public static final byte METHOD_ENTRY = 40; + public static final byte METHOD_EXIT = 41; + public static final byte VM_INIT = 90; + public static final byte VM_DEATH = 99; + public static final byte VM_DISCONNECTED = 100; + + public static final byte VM_START = VM_INIT; + public static final byte THREAD_DEATH = THREAD_END; + } + + /* + * ModKind constants (event filters) + */ + public static final class ModKind + { + /** + * Limit the requested event to be reported at most once after a + * given number of occurrences. May be used with any event. + */ + public static final byte COUNT = 1; + + /** + * Conditional on expression + */ + public static final byte CONDITIONAL = 2; + + /** + * Restricts reported events to those in the given thread. + * May be used with any event except for class unload. + */ + public static final byte THREAD_ONLY = 3; + + /** + * For class prepare events, restricts generated events + * to be the preparation of the given reference type and any + * subtypes. + * + * For other events, restricts the generated events to those where + * location is in the given reference type or any of its subtypes. + * + * An event will be generated for any location in a reference type + * that can be safely cast to the given reference type. + * + * May be used with any event except class unload, thread start, + * and thread end. + */ + public static final byte CLASS_ONLY = 4; + + /** + * Restricts reported events to those for classes whose name matches + * the given restricted regular expression. + * + * For class prepare events, the prepared class name is matched. + * For class unload events, the unloaded class name is matched. + * For other events, the class name of the event's location is matched. + * + * May be used with any event except thread start and thread end. + */ + public static final byte CLASS_MATCH = 5; + + /** + * Restricts reported events to those for classes whose name does not + * match the given restricted regular expression. + * + * For class prepare events, the prepared class name is matched. + * For class unload events, the unloaded class name is matched. + * For other events, the class name of the event's location is matched. + * + * May be used with any event except thread start and thread end. + */ + public static final byte CLASS_EXCLUDE = 6; + + /** + * Restricts reported events to those that occur at the given location. + * + * May be used with breakpoint, field access, field modification, step, + * and exception event kinds. + */ + public static final byte LOCATION_ONLY = 7; + + /** + * Restricts reported exceptions by their class and whether they are + * caught or uncaught. + * + * May be used with exception event kinds only. + */ + public static final byte EXCEPTION_ONLY = 8; + + /** + * Restricts reported events to those that occur for a given field. + * + * May be used with field access and field modification event kinds only. + */ + public static final byte FIELD_ONLY = 9; + + /** + * Restricts reported step events to those which satisfy depth and + * size constraints. + * + * May be used with step event kinds only. + */ + public static final byte STEP = 10; + + /** + * Restricts reported events to those whose active 'this' object is + * the given object. Match value is the null object for static methods. + * + * May be used with any event except class prepare, class unload, + * thread start, and thread end. + */ + public static final byte INSTANCE_ONLY = 11; + } + + /* + * ThreadStatus constants + */ + public static final class ThreadStatus + { + public static final int ZOMBIE = 0; + public static final int RUNNING = 1; + public static final int SLEEPING = 2; + public static final int MONITOR = 3; + public static final int WAIT = 4; + } + + /* + * SuspendStatus constants + */ + public static final class SuspendStatus + { + public static final byte SUSPENDED = 1; + } + + /* + * ClassStatus constants + */ + public static final class ClassStatus + { + public static final int VERIFIED = 1; + public static final int PREPARED = 2; + public static final int INITIALIZED = 4; + public static final int ERROR = 8; + } + + /* + * TypeTag constants + */ + public static final class TypeTag + { + public static final byte CLASS = 1; + public static final byte INTERFACE = 2; + public static final byte ARRAY = 3; + } + + /* + * Tag constants + */ + public static final class Tag + { + /** + * Array object (objectID size) + */ + public static final byte ARRAY = '['; + + /** + * Byte value (1 byte) + */ + public static final byte BYTE = 'B'; + + /** + * Character value (2 bytes) + */ + public static final byte CHAR = 'C'; + + /** + * Object (objectID size) + */ + public static final byte OBJECT = 'L'; + + /** + * Float value (4 bytes) + */ + public static final byte FLOAT = 'F'; + + /** + * Double value (8 bytes) + */ + public static final byte DOUBLE = 'D'; + + /** + * Int value (4 bytes) + */ + public static final byte INT = 'I'; + + /** + * Long value (8 bytes) + */ + public static final byte LONG = 'J'; + + /** + * Short value (2 bytes) + */ + public static final byte SHORT = 'S'; + + /** + * Void value (no bytes) + */ + public static final byte VOID = 'V'; + + /** + * Boolean value (1 byte) + */ + public static final byte BOOLEAN = 'Z'; + + /** + * String object (objectID size) + */ + public static final byte STRING = 's'; + + /** + * Thread object (objectID size) + */ + public static final byte THREAD = 't'; + + /** + * ThreadGroup object (objectID size) + */ + public static final byte THREAD_GROUP = 'g'; + + /** + * ClassLoader object (objectID size) + */ + public static final byte CLASS_LOADER = 'l'; + + /** + * Class object object (objectID size) + */ + public static final byte CLASS_OBJECT = 'c'; + } + + /* + * StepDepth constants + */ + public static final class StepDepth + { + /** + * Step into any method calls that occur before the end of the step + */ + public static final int INTO = 0; + + /** + * Step over any method calls that occur before the end of the step + */ + public static final int OVER = 1; + + /** + * Step out of the current method + */ + public static final int OUT = 2; + } + + /* + * StepSize constants + */ + public static final class StepSize + { + /** + * Step by the minimum possible amount (often a bytecode instruction) + */ + public static final int MIN = 0; + + /** + * Step to the next source line unless there is no line number information, + * in which case MIN step is done instead + */ + public static final int LINE = 1; + } + + /* + * SuspendPolicy constants + */ + public static final class SuspendPolicy + { + /** + * Suspend no threads when this event is encountered + */ + public static final byte NONE = 0; + + /** + * Suspend the event thread when this event is encountered + */ + public static final byte EVENT_THREAD = 1; + + /** + * Suspend all threads when this event is encountered + */ + public static final byte ALL = 2; + } + + /* + * InvokeOptions flag constants + */ + public static final class InvokeOptions + { + /** + * otherwise, all threads started + */ + public static final int INVOKE_SINGLE_THREADED = 0x1; + + /** + * otherwise, normal virtual invoke (instance methods only) + */ + public static final int INVOKE_NONVIRTUAL = 0x2; + } +} diff --git a/libjava/classpath/gnu/classpath/jdwp/event/ClassPrepareEvent.java b/libjava/classpath/gnu/classpath/jdwp/event/ClassPrepareEvent.java new file mode 100644 index 00000000000..22cede0c50a --- /dev/null +++ b/libjava/classpath/gnu/classpath/jdwp/event/ClassPrepareEvent.java @@ -0,0 +1,147 @@ +/* ClassPrepareEvent.java -- An event specifying that a class has been + prepared by the virtual machine + Copyright (C) 2005 Free Software Foundation + +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 +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.classpath.jdwp.event; + +import gnu.classpath.jdwp.JdwpConstants; +import gnu.classpath.jdwp.VMIdManager; +import gnu.classpath.jdwp.id.ReferenceTypeId; +import gnu.classpath.jdwp.id.ThreadId; +import gnu.classpath.jdwp.util.JdwpString; +import gnu.classpath.jdwp.util.Signature; + +import java.io.DataOutputStream; +import java.io.IOException; + +/** + * "Notification of a class prepare in the target VM. See the JVM + * specification for a definition of class preparation. Class prepare + * events are not generated for primtiive classes (for example, + * <code>java.lang.Integer.TYPE</code>)." -- JDWP 1.4.2 + * + * @author Keith Seitz (keiths@redhat.com) + */ +public class ClassPrepareEvent + extends Event +{ + // The thread in which this event occurred + private Thread _thread; + + // The class that was prepared + private Class _class; + + // Prepare flags + private int _status; + + /** + * Class has been verified + */ + public static final int STATUS_VERIFIED + = JdwpConstants.ClassStatus.VERIFIED; + + /** + * Class has been prepared + */ + public static final int STATUS_PREPARED + = JdwpConstants.ClassStatus.PREPARED; + + /** + * Class has been initialized + */ + public static final int STATUS_INITIALIZED + = JdwpConstants.ClassStatus.INITIALIZED; + + /** + * Error preparing class + */ + public static final int STATUS_ERROR + = JdwpConstants.ClassStatus.ERROR; + + /** + * Constructs a new <code>ClassPrepareEvent</code> + * + * @param thread thread in which event occurred + * @param clazz class which was prepared + * @param flags prepare status flags + */ + public ClassPrepareEvent (Thread thread, Class clazz, int flags) + { + super (JdwpConstants.EventKind.CLASS_PREPARE); + _thread = thread; + _class = clazz; + _status = flags; + } + + /** + * Returns a specific filtering parameter for this event. + * Valid types are thread and class. + * + * @param type the type of parameter desired + * @returns the desired parameter or <code>null</code> + */ + public Object getParameter (Class type) + { + if (type == ThreadId.class) + return _thread; + else if (type == ReferenceTypeId.class) + return _class; + + return null; + } + + /** + * Writes the event to the given stream + * + * @param outStream the output stream to write the event to + */ + protected void _writeData (DataOutputStream outStream) + throws IOException + { + VMIdManager idm = VMIdManager.getDefault(); + ThreadId tid = (ThreadId) idm.getObjectId (_thread); + ReferenceTypeId rid = idm.getReferenceTypeId (_class); + + tid.write (outStream); + rid.writeTagged (outStream); + JdwpString.writeString (outStream, + Signature.computeClassSignature (_class)); + outStream.writeInt (_status); + } +} diff --git a/libjava/classpath/gnu/classpath/jdwp/event/Event.java b/libjava/classpath/gnu/classpath/jdwp/event/Event.java new file mode 100644 index 00000000000..14e5b78fc14 --- /dev/null +++ b/libjava/classpath/gnu/classpath/jdwp/event/Event.java @@ -0,0 +1,130 @@ +/* Event.java -- a base class for all event types + Copyright (C) 2005 Free Software Foundation + +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 +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.classpath.jdwp.event; + +import gnu.classpath.jdwp.JdwpConstants; +import gnu.classpath.jdwp.transport.JdwpCommandPacket; +import gnu.classpath.jdwp.transport.JdwpPacket; + +import java.io.DataOutputStream; +import java.io.IOException; + +/** + * This class is a base class for all VM->debugger event + * notifications. + * + * @author Keith Seitz (keiths@redhat.com) + */ +public abstract class Event +{ + // The kind of event represented by this event + private byte _eventKind; + + /** + * Constructs an <code>Event</code> of the given kind + * + * @param kind the type of event + */ + public Event (byte kind) + { + _eventKind = kind; + } + + /** + * Returns the event type of this event + * + * @returns the event kind + */ + public byte getEventKind () + { + return _eventKind; + } + + /** + * Abstract function used by implementing classes to fill in the + * event-specific data. Note that request ID is automatically added + * by this class (since it appears in all event notifications). + * + * @param outStream the stream to which to write data + */ + protected abstract void _writeData (DataOutputStream outStream) + throws IOException; + + /** + * Returns a specific filtering parameter for this event. For example, + * most events may be filtered by thread. Consequently, a call to this + * method with <code>ThreadId.class</code> should return a + * <code>Thread</code>. + * + * @param type the type of parameter to return + * @returns the parameter (not the ID) or <code>null</code> if none is + * is defined for this event + */ + public abstract Object getParameter (Class type); + + /** + * Converts this event into to a JDWP packet + * + * @param dos the stream to which to write data + * @param request the request the wanted this notification + * @returns a <code>JdwpPacket</code> of the events + */ + public JdwpPacket toPacket (DataOutputStream dos, EventRequest request) + { + JdwpPacket pkt; + try + { + dos.writeByte (request.getSuspendPolicy ()); + dos.writeInt (1); + dos.writeByte (_eventKind); + dos.writeInt (request.getId ()); + _writeData (dos); + + pkt = new JdwpCommandPacket (JdwpConstants.CommandSet.Event.CS_VALUE, + JdwpConstants.CommandSet.Event.COMPOSITE); + } + catch (IOException ioe) + { + pkt = null; + } + + return pkt; + } +} diff --git a/libjava/classpath/gnu/classpath/jdwp/event/EventManager.java b/libjava/classpath/gnu/classpath/jdwp/event/EventManager.java new file mode 100644 index 00000000000..436a544eb3c --- /dev/null +++ b/libjava/classpath/gnu/classpath/jdwp/event/EventManager.java @@ -0,0 +1,293 @@ +/* EventManager.java -- event management and notification infrastructure + Copyright (C) 2005 Free Software Foundation + +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 +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.classpath.jdwp.event; + +import gnu.classpath.jdwp.VMVirtualMachine; +import gnu.classpath.jdwp.exception.InvalidEventTypeException; + +import java.util.Collection; +import java.util.Hashtable; +import java.util.Iterator; + +/** + * Manages event requests and filters event notifications. + * + * The purpose of this class is actually two-fold: + * + * 1) Maintain a list of event requests from the debugger + * 2) Filter event notifications from the VM + * + * If an event request arrives from the debugger, the back-end will + * call {@link #reqestEvent}, which will first check for a valid event. + * If it is valid, <code>EventManager</code> will record the request + * internally and register the event with the virtual machine, which may + * choose to handle the request itself (as is likely the case with + * breakpoints and other execution-related events), or it may decide to + * allow the <code>EventManager</code> to handle notifications and all + * filtering (which is convenient for other events such as class (un)loading). + * + * @author Keith Seitz (keiths@redhat.com) + */ +public class EventManager +{ + // Single instance + private static EventManager _instance = new EventManager (); + + // maps event (EVENT_*) to lists of EventRequests + private Hashtable _requests = null; + + /** + * Returns an instance of the event manager + * + * @return the event manager + */ + public static EventManager getDefault () + { + return _instance; + } + + // Private constructs a new <code>EventManager</code> + private EventManager () + { + _requests = new Hashtable (); + + // Add lists for all the event types + _requests.put (new Byte (EventRequest.EVENT_SINGLE_STEP), + new Hashtable ()); + _requests.put (new Byte (EventRequest.EVENT_BREAKPOINT), + new Hashtable ()); + _requests.put (new Byte (EventRequest.EVENT_FRAME_POP), + new Hashtable ()); + _requests.put (new Byte (EventRequest.EVENT_EXCEPTION), + new Hashtable ()); + _requests.put (new Byte (EventRequest.EVENT_USER_DEFINED), + new Hashtable ()); + _requests.put (new Byte (EventRequest.EVENT_THREAD_START), + new Hashtable ()); + _requests.put (new Byte (EventRequest.EVENT_THREAD_END), + new Hashtable ()); + _requests.put (new Byte (EventRequest.EVENT_CLASS_PREPARE), + new Hashtable ()); + _requests.put (new Byte (EventRequest.EVENT_CLASS_UNLOAD), + new Hashtable ()); + _requests.put (new Byte (EventRequest.EVENT_CLASS_LOAD), + new Hashtable ()); + _requests.put (new Byte (EventRequest.EVENT_FIELD_ACCESS), + new Hashtable ()); + _requests.put (new Byte (EventRequest.EVENT_FIELD_MODIFY), + new Hashtable ()); + _requests.put (new Byte (EventRequest.EVENT_METHOD_ENTRY), + new Hashtable ()); + _requests.put (new Byte (EventRequest.EVENT_METHOD_EXIT), + new Hashtable ()); + _requests.put (new Byte (EventRequest.EVENT_VM_INIT), + new Hashtable ()); + _requests.put (new Byte (EventRequest.EVENT_VM_DEATH), + new Hashtable ()); + + // Add auto-generated event notifications + // only two: VM_INIT, VM_DEATH + try + { + requestEvent (new EventRequest (0, + EventRequest.EVENT_VM_INIT, + EventRequest.SUSPEND_NONE)); + requestEvent (new EventRequest (0, + EventRequest.EVENT_VM_DEATH, + EventRequest.SUSPEND_NONE)); + } + catch (InvalidEventTypeException e) + { + // This can't happen + } + } + + /** + * Returns a request for the given event. This method will only + * be used if the <code>EventManager</code> is handling event filtering. + * + * @param event the event + * @return request that was interested in this event + * or <code>null</code> if none (and event should not be sent) + * @throws IllegalArgumentException for invalid event kind + */ + public EventRequest getEventRequest (Event event) + { + EventRequest interestedRequest = null; + Hashtable requests; + Byte kind = new Byte (event.getEventKind ()); + requests = (Hashtable) _requests.get (kind); + if (requests == null) + { + // Did not get a valid event type + throw new IllegalArgumentException ("invalid event kind: " + kind); + } + boolean match = false; + + // Loop through the requests. Must look at ALL requests in order + // to evaluate all filters (think count filter). + // TODO: What if multiple matches? Spec isn't so clear on this. + Iterator rIter = requests.values().iterator (); + while (rIter.hasNext ()) + { + EventRequest request = (EventRequest) rIter.next (); + if (request.matches (event)) + interestedRequest = request; + } + + return interestedRequest; + } + + /** + * Requests monitoring of an event. + * + * The debugger registers for event notification through + * an event filter. If no event filter is specified for an event + * in the VM, it is assumed that the debugger is not interested in + * receiving notifications of this event. + * + * The virtual machine will be notified of the request. + * + * @param request the request to monitor + * @throws InvalidEventTypeException for invalid event kind + */ + public void requestEvent (EventRequest request) + throws InvalidEventTypeException + { + // Add request to request list + Hashtable requests; + Byte kind = new Byte (request.getEventKind ()); + requests = (Hashtable) _requests.get (kind); + if (requests == null) + { + // Did not get a valid event type + throw new InvalidEventTypeException (request.getEventKind ()); + } + + // Register the event with the VM + VMVirtualMachine.registerEvent (request); + requests.put (new Integer (request.getId ()), request); + } + + /** + * Deletes the given request from the management table + * + * @param kind the event kind + * @param id the ID of the request to delete + * @throws IllegalArgumentException for invalid event kind + */ + public void deleteRequest (byte kind, int id) + { + Hashtable requests; + requests = (Hashtable) _requests.get (new Byte (kind)); + if (requests == null) + { + // Did not get a valid event type + throw new IllegalArgumentException ("invalid event kind: " + kind); + } + + Integer iid = new Integer (id); + EventRequest request = (EventRequest) requests.get (iid); + if (request != null) + { + VMVirtualMachine.unregisterEvent (request); + requests.remove (iid); + } + } + + /** + * Clears all the requests for a given event + * + * @param kind the event kind + * @throws IllegalArgumentException for invalid event kind + */ + public void clearRequests (byte kind) + { + Hashtable requests = (Hashtable) _requests.get (new Byte (kind)); + if (requests == null) + { + // Did not get a valid event type + throw new IllegalArgumentException ("invalid event kind: " + kind); + } + + VMVirtualMachine.clearEvents (kind); + requests.clear (); + } + + /** + * Returns a given event request for an event + * + * @param kind the kind of event for the request + * @param id the integer request id to return + * @return the request for the given event kind with the given id + * (or <code>null</code> if not found) + * @throws IllegalArgumentException for invalid event kind + */ + public EventRequest getRequest (byte kind, int id) + { + Hashtable requests = (Hashtable) _requests.get (new Byte (kind)); + if (requests == null) + { + // Did not get a valid event type + throw new IllegalArgumentException ("invalid event kind: " + kind); + } + + return (EventRequest) requests.get (new Integer (id)); + } + + /** + * Returns all requests of the given event kind + * + * @param kind the event kind + * @returns a <code>Collection</code> of all the registered requests + * @throws IllegalArgumentException for invalid event kind + */ + public Collection getRequests (byte kind) + { + Hashtable requests = (Hashtable) _requests.get (new Byte (kind)); + if (requests == null) + { + // Did not get a valid event type + throw new IllegalArgumentException ("invalid event kind: " + kind); + } + + return requests.values (); + } +} diff --git a/libjava/classpath/gnu/classpath/jdwp/event/EventRequest.java b/libjava/classpath/gnu/classpath/jdwp/event/EventRequest.java new file mode 100644 index 00000000000..eadad2840b6 --- /dev/null +++ b/libjava/classpath/gnu/classpath/jdwp/event/EventRequest.java @@ -0,0 +1,376 @@ +/* EventRequest.java -- an event request from the debugger + Copyright (C) 2005 Free Software Foundation + +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 +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.classpath.jdwp.event; + +import gnu.classpath.jdwp.JdwpConstants; +import gnu.classpath.jdwp.event.filters.*; +import gnu.classpath.jdwp.exception.JdwpIllegalArgumentException; +import gnu.classpath.jdwp.id.*; + +import java.util.LinkedList; +import java.util.ListIterator; + +/** + * A class which represents a request by the debugger for an event + * in the VM. <code>EventRequest</code>s usually have event filters + * associated with them, which allow the debugger to specify conditions + * under which the notification should be sent (specific thread, specific + * class, ignore count, etc). + * + * @author Keith Seitz (keiths@redhat.com) + */ +public class EventRequest +{ + /* + * Event types + */ + + /** + * Single step event + */ + public static final byte EVENT_SINGLE_STEP = + JdwpConstants.EventKind.SINGLE_STEP; + + /** + * Breakpoint event + */ + public static final byte EVENT_BREAKPOINT = + JdwpConstants.EventKind.BREAKPOINT; + + /** + * Frame pop event + */ + public static final byte EVENT_FRAME_POP = + JdwpConstants.EventKind.FRAME_POP; + + /** + * Exception event + */ + public static final byte EVENT_EXCEPTION = + JdwpConstants.EventKind.EXCEPTION; + + /** + * User-defined event + */ + public static final byte EVENT_USER_DEFINED = + JdwpConstants.EventKind.USER_DEFINED; + + /** + * Thread start event + */ + public static final byte EVENT_THREAD_START = + JdwpConstants.EventKind.THREAD_START; + + /** + * Thread end/death event + */ + public static final byte EVENT_THREAD_END = + JdwpConstants.EventKind.THREAD_END; + + /** + * Class prepare event + */ + public static final byte EVENT_CLASS_PREPARE = + JdwpConstants.EventKind.CLASS_PREPARE; + + /** + * Class unload event + */ + public static final byte EVENT_CLASS_UNLOAD = + JdwpConstants.EventKind.CLASS_UNLOAD; + + /** + * Class load event + */ + public static final byte EVENT_CLASS_LOAD = + JdwpConstants.EventKind.CLASS_LOAD; + + /** + * Field access event + */ + public static final byte EVENT_FIELD_ACCESS = + JdwpConstants.EventKind.FIELD_ACCESS; + + /** + * Field modify event + */ + public static final byte EVENT_FIELD_MODIFY = + JdwpConstants.EventKind.FIELD_MODIFICATION; + + /** + * Method entry event + */ + public static final byte EVENT_METHOD_ENTRY = + JdwpConstants.EventKind.METHOD_ENTRY; + + /** + * Method exit event + */ + public static final byte EVENT_METHOD_EXIT = + JdwpConstants.EventKind.METHOD_EXIT; + + /** + * Virtual machine initialization/start + */ + public static final byte EVENT_VM_INIT = + JdwpConstants.EventKind.VM_INIT; + + /** + * Virutal machine death + */ + public static final byte EVENT_VM_DEATH = + JdwpConstants.EventKind.VM_DEATH; + + + /* + * Suspend policies + */ + + /** + * Do not suspend any threads + */ + public static final byte SUSPEND_NONE = + JdwpConstants.SuspendPolicy.NONE; + + /** + * Suspend the thread in which the event occurred + */ + public static final byte SUSPEND_THREAD = + JdwpConstants.SuspendPolicy.EVENT_THREAD; + + /** + * Suspend all threads + */ + public static final byte SUSPEND_ALL = + JdwpConstants.SuspendPolicy.ALL; + + // ID of last EventRequest + private static int _last_id = 0; + private static Object _idLock = new Object (); + + // A list of filters + private LinkedList _filters; + + // The ID of this request + private int _id; + + // The suspend policy to enforce when this event occurs + private byte _suspendPolicy; + + // Kind of event requested + private byte _kind; + + /** + * Construct a new <code>EventRequest</code> + * + * @param kind the kind of event requested + * @param suspendPolicy how to suspend threads when event occurs + */ + public EventRequest (byte kind, byte suspendPolicy) + { + _filters = new LinkedList (); + synchronized (_idLock) + { + _id = ++_last_id; + } + _kind = kind; + _suspendPolicy = suspendPolicy; + } + + /** + * Construct a new <code>EventRequest</code> with the given ID + * + * @param id the id of the request to create + * @param kind the kind of event requested + * @param suspendPolicy how to suspend threads when event occurs + */ + public EventRequest (int id, byte kind, byte suspendPolicy) + { + _filters = new LinkedList (); + _kind = kind; + _suspendPolicy = suspendPolicy; + } + + /** + * Creates a new event filter, adding it to this request + * + * @param filter the filter to add + * @throws JdwpIllegalArgumentException if an invalid or illegal filter + * is added to the request + */ + public void addFilter (IEventFilter filter) + throws JdwpIllegalArgumentException + { + // Check validity of filter for this request + boolean valid = true; + + Class clazz = filter.getClass (); + if (clazz == ClassExcludeFilter.class) + { + if (_kind == EVENT_THREAD_START + || _kind == EVENT_THREAD_END) + valid = false; + } + else if (clazz == ClassMatchFilter.class) + { + if (_kind == EVENT_THREAD_START + || _kind == EVENT_THREAD_END) + valid = false; + } + else if (clazz == ClassOnlyFilter.class) + { + if (_kind == EVENT_CLASS_UNLOAD + || _kind == EVENT_THREAD_START + || _kind == EVENT_THREAD_END) + valid = false; + } + else if (clazz == ConditionalFilter.class) + { + // JDWP 1.4 does not say much about this + } + else if (clazz == CountFilter.class) + { + // may be used with any event + } + else if (clazz == ExceptionOnlyFilter.class) + { + if (_kind != EVENT_EXCEPTION) + valid = false; + } + else if (clazz == FieldOnlyFilter.class) + { + if (_kind != EVENT_FIELD_ACCESS + && _kind != EVENT_FIELD_MODIFY) + valid = false; + } + else if (clazz == InstanceOnlyFilter.class) + { + if (_kind == EVENT_CLASS_PREPARE + || _kind == EVENT_CLASS_UNLOAD + || _kind == EVENT_THREAD_START + || _kind == EVENT_THREAD_END) + valid = false; + } + else if (clazz == LocationOnlyFilter.class) + { + if (_kind != EVENT_BREAKPOINT + && _kind != EVENT_FIELD_ACCESS + && _kind != EVENT_FIELD_MODIFY + && _kind != EVENT_SINGLE_STEP + && _kind != EVENT_EXCEPTION) + valid = false; + } + else if (clazz == StepFilter.class) + { + if (_kind != EVENT_SINGLE_STEP) + valid = false; + } + else if (clazz == ThreadOnlyFilter.class) + { + if (_kind == EVENT_CLASS_UNLOAD) + valid = false; + } + + if (!valid) + { + String msg = ("cannot use " + filter.getClass ().getName () + + " with class unload events"); + throw new JdwpIllegalArgumentException (msg); + } + + // Add filter to list + _filters.add (filter); + } + + /** + * Returns the suspend policy for this request + */ + public byte getSuspendPolicy () + { + return _suspendPolicy; + } + + /** + * Returns the request id of this request + */ + public int getId () + { + return _id; + } + + /** + * Sets the id of the request (used for auto-generated events) + */ + public void setId (int id) + { + _id = id; + } + + /** + * Returns the kind of event for this request + */ + public byte getEventKind () + { + return _kind; + } + + /** + * Determines whether the given event matches this request + * + * @param theEvent the event to compare to + */ + public boolean matches (Event theEvent) + { + boolean matches = true; + + // Loop through filters; all must match + // Note that we must allow EVERY filter to evaluate. This way + // things like CountFilter will work. + ListIterator iter = _filters.listIterator (); + while (iter.hasNext ()) + { + IEventFilter filter = (IEventFilter) iter.next (); + if (!filter.matches (theEvent)) + matches = false; + } + + return matches; + } +} diff --git a/libjava/classpath/gnu/classpath/jdwp/event/ThreadEndEvent.java b/libjava/classpath/gnu/classpath/jdwp/event/ThreadEndEvent.java new file mode 100644 index 00000000000..768b216de0c --- /dev/null +++ b/libjava/classpath/gnu/classpath/jdwp/event/ThreadEndEvent.java @@ -0,0 +1,105 @@ +/* ThreadEndEvent.java -- An event specifying that a thread has died + Copyright (C) 2005 Free Software Foundation + +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 +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.classpath.jdwp.event; + +import gnu.classpath.jdwp.JdwpConstants; +import gnu.classpath.jdwp.VMIdManager; +import gnu.classpath.jdwp.id.ThreadId; + +import java.io.DataOutputStream; +import java.io.IOException; + +/** + * "Notification of a completed thread in the target VM. The notification + * is generated by the dying thread before it terminates. Because of this + * timing, it is possible for VirtualMachine.allThreads to return this + * thread after this event is received. + * + * <p>Note that this event gives no information about the lifetime of the + * thread object. It may or may not be collected soon depending on what + * references exist in the target VM." -- JDWP 1.4.2 + * + * @author Keith Seitz (keiths@redhat.com) + */ +public class ThreadEndEvent + extends Event +{ + private Thread _thread; + + /** + * Constructs a new <code>ThreadEndEvent</code> + * + * @param thread the deceased thread + */ + public ThreadEndEvent (Thread thread) + { + super (JdwpConstants.EventKind.THREAD_END); + _thread = thread; + } + + /** + * Returns a specific filtering parameter for this event. + * Valid types are ThreadId. + * + * @param type the type of parameter desired + * @returns the desired parameter or <code>null</code> + */ + public Object getParameter (Class type) + { + if (type == ThreadId.class) + return _thread; + + return null; + } + + /** + * Writes the event to the given stream + * + * @param outStream the output stream to write the event to + */ + protected void _writeData (DataOutputStream outStream) + throws IOException + { + VMIdManager idm = VMIdManager.getDefault(); + ThreadId tid = (ThreadId) idm.getObjectId (_thread); + tid.write (outStream); + } +} + diff --git a/libjava/classpath/gnu/classpath/jdwp/event/ThreadStartEvent.java b/libjava/classpath/gnu/classpath/jdwp/event/ThreadStartEvent.java new file mode 100644 index 00000000000..67caea97c22 --- /dev/null +++ b/libjava/classpath/gnu/classpath/jdwp/event/ThreadStartEvent.java @@ -0,0 +1,109 @@ +/* ThreadStartEvent.java -- An event specifying that a new thread + has started in the virtual machine + Copyright (C) 2005 Free Software Foundation + +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 +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.classpath.jdwp.event; + +import gnu.classpath.jdwp.JdwpConstants; +import gnu.classpath.jdwp.VMIdManager; +import gnu.classpath.jdwp.id.ThreadId; + +import java.io.DataOutputStream; +import java.io.IOException; + +/** + * "Notification of a new running thread in the target VM. The new + * thread can be the result of a call to {@link java.lang.Thread.start} or + * the result of attaching a new thread to the VM though JNI. The + * notification is generated by the new thread some time before its + * execution starts. Because of this timing, it is possible to receive + * other events for the thread before this event is received. (Notably, + * Method Entry Events and Method Exit Events might occur during thread + * initialization. It is also possible for the VirtualMachine AllThreads + * command to return a thread before its thread start event is received. + * + * <p>Note that this event gives no information about the creation of the + * thread object which may have happened much earlier, depending on the + * VM being debugged." -- JDWP 1.4.2 + * + * @author Keith Seitz (keiths@redhat.com) + */ +public class ThreadStartEvent + extends Event +{ + private Thread _thread; + + /** + * Constructs a new <code>ThreadStartEvent</code> + * + * @param tid the thread ID in which event occurred + */ + public ThreadStartEvent (Thread thread) { + super (JdwpConstants.EventKind.THREAD_END); + _thread = thread; + } + + /** + * Returns a specific filtering parameter for this event. + * Valid types are ThreadId. + * + * @param type the type of parameter desired + * @returns the desired parameter or <code>null</code> + */ + public Object getParameter (Class type) + { + if (type == ThreadId.class) + return _thread; + + return null; + } + + /** + * Writes the event to the given stream + * + * @param outStream the output stream to write the event to + */ + protected void _writeData (DataOutputStream outStream) + throws IOException + { + VMIdManager idm = VMIdManager.getDefault(); + ThreadId tid = (ThreadId) idm.getObjectId (_thread); + tid.write (outStream); + } +} diff --git a/libjava/classpath/gnu/classpath/jdwp/event/VmInitEvent.java b/libjava/classpath/gnu/classpath/jdwp/event/VmInitEvent.java new file mode 100644 index 00000000000..dd228e935cf --- /dev/null +++ b/libjava/classpath/gnu/classpath/jdwp/event/VmInitEvent.java @@ -0,0 +1,94 @@ +/* VmInitEvent.java -- An event specifying that the VM has started + Copyright (C) 2005 Free Software Foundation + +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 +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.classpath.jdwp.event; + +import gnu.classpath.jdwp.JdwpConstants; +import gnu.classpath.jdwp.VMIdManager; +import gnu.classpath.jdwp.id.ThreadId; + +import java.io.DataOutputStream; +import java.io.IOException; + +/** + * "Notification of initialization of a target VM. This event is + * received before the main thread is started and before any application + * code has been executed." -- JDWP 1.4.2 + * + * @author Keith Seitz (keiths@redhat.com) + */ +public class VmInitEvent + extends Event +{ + private Thread _initialThread; + + /** + * Constructs a <code>VmInitEvent</code> object + * + * @param thread the initial thread + */ + public VmInitEvent (Thread thread) + { + super (JdwpConstants.EventKind.VM_INIT); + _initialThread = thread; + } + + /** + * Returns a specific filtering parameter for this event. + * This event has no valid types. + * + * @param type the type of parameter desired + * @returns the desired parameter or <code>null</code> + */ + public Object getParameter (Class type) + { + return null; + } + + /** + * Writes out event-specific data + */ + protected void _writeData (DataOutputStream outStream) + throws IOException + { + VMIdManager idm = VMIdManager.getDefault(); + ThreadId tid = (ThreadId) idm.getObjectId (_initialThread); + tid.write (outStream); + } +} diff --git a/libjava/classpath/gnu/classpath/jdwp/event/filters/ClassExcludeFilter.java b/libjava/classpath/gnu/classpath/jdwp/event/filters/ClassExcludeFilter.java new file mode 100644 index 00000000000..c8ec51c756b --- /dev/null +++ b/libjava/classpath/gnu/classpath/jdwp/event/filters/ClassExcludeFilter.java @@ -0,0 +1,75 @@ +/* ClassExcludeFilter.java -- filter on class name (exclusive) + Copyright (C) 2005 Free Software Foundation + +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 +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.classpath.jdwp.event.filters; + +import gnu.classpath.jdwp.event.Event; +import gnu.classpath.jdwp.exception.InvalidStringException; + +/** + * An event filter which excludes events matching a + * specified class pattern (exact match or start/end with "*"). + * + * @author Keith Seitz (keiths@redhat.com) + */ +public class ClassExcludeFilter + extends ClassMatchFilter +{ + /** + * Constructs a new <code>ClassExcludeFilter</code> + * + * @param pattern the pattern to use + * @throws InvalidStringException if pattern is invalid + */ + public ClassExcludeFilter (String pattern) + throws InvalidStringException + { + super (pattern); + } + + /** + * Does the given event match the filter? + * + * @param event the <code>Event</code> to scrutinize + */ + public boolean matches (Event event) + { + return !super.matches (event); + } +} diff --git a/libjava/classpath/gnu/classpath/jdwp/event/filters/ClassMatchFilter.java b/libjava/classpath/gnu/classpath/jdwp/event/filters/ClassMatchFilter.java new file mode 100644 index 00000000000..4ee92bbf5e1 --- /dev/null +++ b/libjava/classpath/gnu/classpath/jdwp/event/filters/ClassMatchFilter.java @@ -0,0 +1,114 @@ +/* ClassMatchFilter.java -- filter on class name (inclusive) + Copyright (C) 2005 Free Software Foundation + +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 +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.classpath.jdwp.event.filters; + +import gnu.classpath.jdwp.event.Event; +import gnu.classpath.jdwp.exception.InvalidStringException; +import gnu.classpath.jdwp.exception.InvalidClassException; +import gnu.classpath.jdwp.id.ReferenceTypeId; + +/** + * An event filter which includes events matching a + * specified class pattern (exact match or start/end with "*"). + * + * @author Keith Seitz (keiths@redhat.com) + */ +public class ClassMatchFilter + implements IEventFilter +{ + // Pattern to match + private String _pattern; + + /** + * Constructs a new <code>ClassMatchFilter</code> + * + * @param pattern the pattern to use + * @throws InvalidStringException if pattern is invalid + */ + public ClassMatchFilter (String pattern) + throws InvalidStringException + { + int index = pattern.indexOf ('*'); + if (index != -1 && index != 0 && index != (pattern.length () - 1)) + { + // '*' must be first char or last char + throw new InvalidStringException ("pattern may be an exact match or " + + "start/end with \"*\""); + } + _pattern = pattern; + } + + /** + * Returns the pattern to be matched + * + * @return the pattern + */ + public String getPattern () + { + return _pattern; + } + + /** + * Does the given event match the filter? + * + * @param event the <code>Event</code> to scrutinize + */ + public boolean matches (Event event) + { + Object type = event.getParameter (ReferenceTypeId.class); + if (type != null) + { + Class eventClass = (Class) type; + String name = eventClass.getName (); + + if (_pattern.startsWith ("*")) + return name.endsWith (_pattern.substring (1)); + else if (_pattern.endsWith ("*")) + { + int end = _pattern.length () - 1; + return name.startsWith (_pattern.substring (0, end)); + } + else + return name.matches (_pattern); + } + + return false; + } +} diff --git a/libjava/classpath/gnu/classpath/jdwp/event/filters/ClassOnlyFilter.java b/libjava/classpath/gnu/classpath/jdwp/event/filters/ClassOnlyFilter.java new file mode 100644 index 00000000000..e4bf06cf961 --- /dev/null +++ b/libjava/classpath/gnu/classpath/jdwp/event/filters/ClassOnlyFilter.java @@ -0,0 +1,109 @@ +/* ClassOnlyFilter.java -- filter on specific class + Copyright (C) 2005 Free Software Foundation + +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 +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.classpath.jdwp.event.filters; + +import gnu.classpath.jdwp.event.Event; +import gnu.classpath.jdwp.exception.InvalidClassException; +import gnu.classpath.jdwp.id.ReferenceTypeId; + +/** + * An event filter which filters out events in uninteresting + * classes. + * + * @author Keith Seitz (keiths@redhat.com) + */ +public class ClassOnlyFilter + implements IEventFilter +{ + // Class ID for which to filter + private ReferenceTypeId _id; + + /** + * Constructs a new <code>ClassOnlyFilter</code> + * + * @param refId the reference type id for a class for which events + * will be reported + * @throws InvalidClassException if the ID is no longer valid + */ + public ClassOnlyFilter (ReferenceTypeId refId) + throws InvalidClassException + { + // validity check + refId.getType (); + _id = refId; + } + + /** + * Returns the class to which to restrict events + * + * @return the class's ID + */ + public ReferenceTypeId getType () + { + return _id; + } + + /** + * Does the given event match the filter? + * + * @param event the <code>Event</code> to scrutinize + */ + public boolean matches (Event event) + { + Object type = event.getParameter (ReferenceTypeId.class); + if (type != null) + { + try + { + Class clazz = _id.getType (); + Class eventClass = (Class) type; + if (clazz.isAssignableFrom (eventClass)) + return true; + } + catch (InvalidClassException ice) + { + // class is no longer valid + return false; + } + } + + return false; + } +} diff --git a/libjava/classpath/gnu/classpath/jdwp/event/filters/ConditionalFilter.java b/libjava/classpath/gnu/classpath/jdwp/event/filters/ConditionalFilter.java new file mode 100644 index 00000000000..1fab693eee7 --- /dev/null +++ b/libjava/classpath/gnu/classpath/jdwp/event/filters/ConditionalFilter.java @@ -0,0 +1,82 @@ +/* ConditionalFilter.java -- conditional expression filter + Copyright (C) 2005 Free Software Foundation + +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 +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.classpath.jdwp.event.filters; + +import gnu.classpath.jdwp.event.Event; +import gnu.classpath.jdwp.exception.NotImplementedException; + +/** + * An event filter which allows expression conditionals. + * Note that in JDWP 1.4, this class is marked "for the + * future". + * + * @author Keith Seitz (keiths@redhat.com) + */ +public class ConditionalFilter + implements IEventFilter +{ + // private ConditionalId _exprId; + + /** + * Constructs a new <code>ConditionalFilter</code> with the + * given conditional. + * + * <p><b>NOTE:</b> This filter is marked "for the future", + * i.e, there is no way to actually use this yet. + * + * @param cond the conditional expression + * @throws NotImplementedException if used + */ + public ConditionalFilter (Object conditional) + throws NotImplementedException + { + throw new NotImplementedException ("conditional filters"); + } + + /** + * Does the given event match the filter? + * + * @param event the <code>Event</code> to scrutinize + */ + public boolean matches (Event event) + { + return false; + } +} diff --git a/libjava/classpath/gnu/classpath/jdwp/event/filters/CountFilter.java b/libjava/classpath/gnu/classpath/jdwp/event/filters/CountFilter.java new file mode 100644 index 00000000000..46148a504bc --- /dev/null +++ b/libjava/classpath/gnu/classpath/jdwp/event/filters/CountFilter.java @@ -0,0 +1,95 @@ +/* CountFilter.java -- a step filter + Copyright (C) 2005 Free Software Foundation + +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 +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.classpath.jdwp.event.filters; + +import gnu.classpath.jdwp.event.Event; +import gnu.classpath.jdwp.exception.InvalidCountException; + +/** + * An ignore count filter. + * + * @author Keith Seitz (keiths@redhat.com) + */ +public class CountFilter + implements IEventFilter +{ + // the count + private int _count; + + /** + * Constructs a new <code>CountFilter</code> with the given count. + * + * @param count the number of times the event will be ignored + * @throws InvalidCountException if count is invalid (< 1) + */ + public CountFilter (int count) + throws InvalidCountException + { + // Check for valid count + if (count < 1) + throw new InvalidCountException (count); + + _count = count; + } + + /** + * Returns the ignore count + * + * @return the number of times the event should be ignored + */ + public int getCount () + { + return _count; + } + + /** + * Does the given event match the filter? + * + * @param event the <code>Event</code> to scrutinize + */ + public boolean matches (Event event) + { + // This filter only relies on its count + if (--_count == 0) + return true; + + return false; + } +} diff --git a/libjava/classpath/gnu/classpath/jdwp/event/filters/ExceptionOnlyFilter.java b/libjava/classpath/gnu/classpath/jdwp/event/filters/ExceptionOnlyFilter.java new file mode 100644 index 00000000000..cc4919de6ab --- /dev/null +++ b/libjava/classpath/gnu/classpath/jdwp/event/filters/ExceptionOnlyFilter.java @@ -0,0 +1,121 @@ +/* ExceptionOnlyFilter.java -- + Copyright (C) 2005 Free Software Foundation + +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 +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.classpath.jdwp.event.filters; + +import gnu.classpath.jdwp.event.Event; +import gnu.classpath.jdwp.exception.InvalidClassException; +import gnu.classpath.jdwp.id.ReferenceTypeId; + +/** + * Restricts reported exceptions by their class and whether they are caught + * or uncaught. + * + * This modifier can be used with exception event kinds only. + * + * @author Keith Seitz (keiths@redhat.com) + */ +public class ExceptionOnlyFilter + implements IEventFilter +{ + private ReferenceTypeId _refId; + private boolean _caught; + private boolean _uncaught; + + /** + * Constructs a new <code>ExceptionOnlyFilter</code> + * + * @param refid + * @param caught + * @param uncaught + * @throws InvalidClassException if refid is invalid + */ + public ExceptionOnlyFilter (ReferenceTypeId refId, boolean caught, + boolean uncaught) + throws InvalidClassException + { + if (refId == null || refId.getReference().get () == null) + throw new InvalidClassException (refId.getId ()); + + _refId = refId; + _caught = caught; + _uncaught = uncaught; + } + + /** + * Returns the exception class to report (<code>null</code> for all) + * + * @return the class's ID + */ + public ReferenceTypeId getType () + { + return _refId; + } + + /** + * Report caught exceptions? + * + * @return whether to report caught exceptions + */ + public boolean forCaught () + { + return _caught; + } + + /** + * Report uncaught exceptions? + * + * @return whether to report uncaught exceptions + */ + public boolean forUncaught () + { + return _uncaught; + } + + /** + * Does the given event match the filter? + * + * @param event the <code>Event</code> to scrutinize + */ + public boolean matches (Event event) + { + // FIXME + throw new RuntimeException ("ExceptionOnlyFilter.matches not implemented"); + } +} diff --git a/libjava/classpath/gnu/classpath/jdwp/event/filters/FieldOnlyFilter.java b/libjava/classpath/gnu/classpath/jdwp/event/filters/FieldOnlyFilter.java new file mode 100644 index 00000000000..19c5b8a9ba1 --- /dev/null +++ b/libjava/classpath/gnu/classpath/jdwp/event/filters/FieldOnlyFilter.java @@ -0,0 +1,112 @@ +/* FieldOnlyFilter.java -- filter on field + Copyright (C) 2005 Free Software Foundation + +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 +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.classpath.jdwp.event.filters; + +import gnu.classpath.jdwp.event.Event; +import gnu.classpath.jdwp.exception.InvalidClassException; +import gnu.classpath.jdwp.exception.InvalidFieldException; +import gnu.classpath.jdwp.id.ReferenceTypeId; + +/** + * Restricts reported events to those that occur for a given field. + * + * This modifier can be used with field access and field modification event + * kinds only. + * + * @author Keith Seitz (keiths@redhat.com) + */ +public class FieldOnlyFilter + implements IEventFilter +{ + private ReferenceTypeId _refId; + private ReferenceTypeId _fieldId; + + /** + * Constructs a new <code>FieldOnlyFilter</code>. + * + * @param refId class for field + * @param fid field + * @throws InvalidClassException if class is invalid + * @throws InvalidFieldExcpetion if field is invalid + */ + public FieldOnlyFilter (ReferenceTypeId refId, /*Field*/ReferenceTypeId fid) + throws InvalidClassException, InvalidFieldException + { + if (refId == null || refId.getReference().get () == null) + throw new InvalidClassException (refId.getId ()); + + if (fid == null) + throw new InvalidFieldException (fid.getId ()); + + _refId = refId; + _fieldId = fid; + } + + /** + * Returns the class in which the field is declared + * + * @return the class's id + */ + public ReferenceTypeId getType () + { + return _refId; + } + + /** + * Returns the field for which to restrict events + * + * @return the field's id + */ + public ReferenceTypeId getField () + { + return _fieldId; + } + + /** + * Does the given event match the filter? + * + * @param event the <code>Event</code> to scrutinize + */ + public boolean matches (Event event) + { + // FIXME + throw new RuntimeException ("FieldOnlyFilter.matches not implemented"); + } +} diff --git a/libjava/classpath/gnu/classpath/jdwp/event/filters/IEventFilter.java b/libjava/classpath/gnu/classpath/jdwp/event/filters/IEventFilter.java new file mode 100644 index 00000000000..4a2b5431bc9 --- /dev/null +++ b/libjava/classpath/gnu/classpath/jdwp/event/filters/IEventFilter.java @@ -0,0 +1,65 @@ +/* IEventFilter.java -- an interface for event filters + Copyright (C) 2005 Free Software Foundation + +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 +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.classpath.jdwp.event.filters; + +import gnu.classpath.jdwp.event.Event; + +/** + * An interface for event filters. The debugger registers an event + * filter for a given event when it is interested in receiving + * notifications about that event from the VM. + * + * <p>Filters are attached to {@link gnu.classpath.jdwp.event.EventRequest}s + * in order to allow the debugger to specify that an event should be sent + * only when the filters for the event request all match. + * + * <p>No filters means "send all notifications". + * + * @author Keith Seitz (keiths@redhat.com) + */ +public interface IEventFilter +{ + /** + * Does the given event match the filter? + * + * @param event the <code>Event</code> to scrutinize + */ + public boolean matches (Event event); +} diff --git a/libjava/classpath/gnu/classpath/jdwp/event/filters/InstanceOnlyFilter.java b/libjava/classpath/gnu/classpath/jdwp/event/filters/InstanceOnlyFilter.java new file mode 100644 index 00000000000..130749b4b8a --- /dev/null +++ b/libjava/classpath/gnu/classpath/jdwp/event/filters/InstanceOnlyFilter.java @@ -0,0 +1,101 @@ +/* InstanceOnlyFilter.java -- filter on instance + Copyright (C) 2005 Free Software Foundation + +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 +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.classpath.jdwp.event.filters; + +import gnu.classpath.jdwp.event.Event; +import gnu.classpath.jdwp.exception.InvalidObjectException; +import gnu.classpath.jdwp.id.ObjectId; + +/** + * Restricts reported events to those whose active 'this' object is the + * given object. Match value is the null object for static methods. + * + * This modifier can be used with any event kind except class prepare, + * class unload, thread start, and thread end. Introduced in JDWP version 1.4. + * + * @author Keith Seitz (keiths@redhat.com) + */ +public class InstanceOnlyFilter + implements IEventFilter +{ + private ObjectId _instance; + + /** + * Constructs a new <code>InstanceOnlyFilter</code>. + * + * @param oid the object to which to restrict events (may be null) + * @throws InvalidObjectException if Object is invalid + */ + public InstanceOnlyFilter (ObjectId oid) + throws InvalidObjectException + { + if (oid != null && oid.getReference().get () == null) + throw new InvalidObjectException (oid.getId ()); + + _instance = oid; + } + + /** + * Returns the instance to which to restrict events + * + * @return the object's ID + */ + public ObjectId getInstance () + { + return _instance; + } + + /** + * Does the given event match the filter? + * + * @param event the <code>Event</code> to scrutinize + */ + public boolean matches (Event event) + { + Object eventInstance = event.getParameter (ObjectId.class); + if (eventInstance != null) + { + Object myInstance = _instance.getReference().get (); + return ((myInstance != null) && (myInstance == eventInstance)); + } + + return false; + } +} diff --git a/libjava/classpath/gnu/classpath/jdwp/event/filters/LocationOnlyFilter.java b/libjava/classpath/gnu/classpath/jdwp/event/filters/LocationOnlyFilter.java new file mode 100644 index 00000000000..e9102fa0303 --- /dev/null +++ b/libjava/classpath/gnu/classpath/jdwp/event/filters/LocationOnlyFilter.java @@ -0,0 +1,91 @@ +/* LocationOnlyFilter.java -- filter on location + Copyright (C) 2005 Free Software Foundation + +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 +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.classpath.jdwp.event.filters; + +import gnu.classpath.jdwp.event.Event; +import gnu.classpath.jdwp.exception.InvalidLocationException; +import gnu.classpath.jdwp.util.Location; + +/** + * Restricts reported events to those that occur at the given location. + * + * May be used with breakpoint, field access, field modification, step, + * and exception event kinds. + * + * @author Keith Seitz (keiths@redhat.com) + */ +public class LocationOnlyFilter + implements IEventFilter +{ + private Location _location; + + /** + * Constructs a new <code>LocationOnlyFilter</code>. + * + * @param loc the location for which to report events + * @throws InvalidLocationException if location is invalid + */ + public LocationOnlyFilter (Location loc) + throws InvalidLocationException + { + _location = loc; + } + + /** + * Returns the location at which to restrict events + * + * @return the location + */ + public Location getLocation () + { + return _location; + } + + /** + * Does the given event match the filter? + * + * @param event the <code>Event</code> to scrutinize + */ + public boolean matches (Event event) + { + // FIXME + throw new RuntimeException ("LocationOnlyFilter.matches not implemented"); + } +} diff --git a/libjava/classpath/gnu/classpath/jdwp/event/filters/StepFilter.java b/libjava/classpath/gnu/classpath/jdwp/event/filters/StepFilter.java new file mode 100644 index 00000000000..75753cda095 --- /dev/null +++ b/libjava/classpath/gnu/classpath/jdwp/event/filters/StepFilter.java @@ -0,0 +1,119 @@ +/* StepFilter.java -- a step filter + Copyright (C) 2005 Free Software Foundation + +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 +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.classpath.jdwp.event.filters; + +import gnu.classpath.jdwp.event.Event; +import gnu.classpath.jdwp.exception.InvalidThreadException; +import gnu.classpath.jdwp.id.ThreadId; + +/** + * An event filter which restricts reported step events to those which + * satisfy depth and size constraints. This modifier can only be used with + * step event kinds. + * + * @author Keith Seitz (keiths@redhat.com) + */ +public class StepFilter + implements IEventFilter +{ + private ThreadId _tid; + private int _size; + private int _depth; + + /** + * Constructs a new <code>StepFilter</code> with the given count. + * + * @param count the number of times the event will be ignored + * @throws InvalidThreadException if thread is invalid + */ + public StepFilter (ThreadId tid, int size, int depth) + throws InvalidThreadException + { + if (tid == null | tid.getReference().get () == null) + throw new InvalidThreadException (tid.getId ()); + + _tid = tid; + _size = size; + _depth = depth; + } + + /** + * Returns the thread in which to step + * + * @return the thread's ID + */ + public ThreadId getThread () + { + return _tid; + } + + /** + * Returns the size of each step (insn, line) + * + * @return the step size + * @see JdwpConstants.StepSize + */ + public int getSize () + { + return _size; + } + + /** + * Returns the relative call stack limit (into, over, out) + * + * @return how to step + * @see JdwpConstants.StepDepth + */ + public int getDepth () + { + return _depth; + } + + /** + * Does the given event match the filter? + * + * @param event the <code>Event</code> to scrutinize + */ + public boolean matches (Event event) + { + // FIXME + throw new RuntimeException ("StepFilter.matches not implemented"); + } +} diff --git a/libjava/classpath/gnu/classpath/jdwp/event/filters/ThreadOnlyFilter.java b/libjava/classpath/gnu/classpath/jdwp/event/filters/ThreadOnlyFilter.java new file mode 100644 index 00000000000..039b4372125 --- /dev/null +++ b/libjava/classpath/gnu/classpath/jdwp/event/filters/ThreadOnlyFilter.java @@ -0,0 +1,102 @@ +/* ThreadOnlyFilter.java -- a thread filter + Copyright (C) 2005 Free Software Foundation + +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 +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.classpath.jdwp.event.filters; + +import gnu.classpath.jdwp.Jdwp; +import gnu.classpath.jdwp.event.Event; +import gnu.classpath.jdwp.exception.InvalidThreadException; +import gnu.classpath.jdwp.id.ThreadId; + +/** + * An event filter which allows only events within a specific + * thread + * + * @author Keith Seitz (keiths@redhat.com) + */ +public class ThreadOnlyFilter + implements IEventFilter +{ + // the thread + private ThreadId _tid; + + /** + * Constructs a new <code>ThreadOnlyFilter</code> for the given + * thread id + * + * @param tid ID of the thread on which to filter + * @throws InvalidThreadException if the thread is not valid + */ + public ThreadOnlyFilter (ThreadId tid) + throws InvalidThreadException + { + if (tid == null | tid.getReference().get () == null) + throw new InvalidThreadException (tid.getId ()); + + _tid = tid; + } + + /** + * Returns the thread in which to restrict events + * + * @return the thread's ID + */ + public ThreadId getThread () + { + return _tid; + } + + /** + * Does the given event match the filter? + * + * @param event the <code>Event</code> to scrutinize + */ + public boolean matches (Event event) + { + Object thread = event.getParameter (ThreadId.class); + if (thread != null) + { + Thread eventThread = (Thread) thread; + Thread myThread = (Thread) _tid.getReference().get (); + return (eventThread == myThread); + } + + return false; + } +} diff --git a/libjava/classpath/gnu/classpath/jdwp/exception/InvalidClassLoaderException.java b/libjava/classpath/gnu/classpath/jdwp/exception/InvalidClassLoaderException.java new file mode 100644 index 00000000000..17bbfb34a34 --- /dev/null +++ b/libjava/classpath/gnu/classpath/jdwp/exception/InvalidClassLoaderException.java @@ -0,0 +1,62 @@ +/* InvalidClassLoaderException.java -- an invalid class loader exception + Copyright (C) 2005 Free Software Foundation + +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 +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.classpath.jdwp.exception; + +import gnu.classpath.jdwp.JdwpConstants; + +/** + * An exception thrown when the debugger uses an invalid class loader + * + * @author Keith Seitz (keiths@redhat.com) + */ +public class InvalidClassLoaderException + extends JdwpException +{ + public InvalidClassLoaderException (long id) + { + super (JdwpConstants.Error.INVALID_CLASS_LOADER, + "invalid class loader (" + id + ")"); + } + + public InvalidClassLoaderException (Throwable t) + { + super (JdwpConstants.Error.INVALID_CLASS_LOADER, t); + } +} diff --git a/libjava/classpath/gnu/classpath/jdwp/exception/InvalidFieldException.java b/libjava/classpath/gnu/classpath/jdwp/exception/InvalidFieldException.java new file mode 100644 index 00000000000..f088c73db1c --- /dev/null +++ b/libjava/classpath/gnu/classpath/jdwp/exception/InvalidFieldException.java @@ -0,0 +1,63 @@ +/* InvalidFieldException.java -- an invalid field id exception + Copyright (C) 2005 Free Software Foundation + +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 +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.classpath.jdwp.exception; + +import gnu.classpath.jdwp.JdwpConstants; + +/** + * An exception thrown when an invalid field id is used by the + * debugger + * + * @author Keith Seitz (keiths@redhat.com) + */ +public class InvalidFieldException + extends JdwpException +{ + public InvalidFieldException (long id) + { + super (JdwpConstants.Error.INVALID_FIELDID, + "invalid field id (" + id + ")"); + } + + public InvalidFieldException (Throwable t) + { + super (JdwpConstants.Error.INVALID_FIELDID, t); + } +} diff --git a/libjava/classpath/gnu/classpath/jdwp/exception/InvalidLocationException.java b/libjava/classpath/gnu/classpath/jdwp/exception/InvalidLocationException.java new file mode 100644 index 00000000000..c67951fa2b3 --- /dev/null +++ b/libjava/classpath/gnu/classpath/jdwp/exception/InvalidLocationException.java @@ -0,0 +1,62 @@ +/* InvalidLocationException.java -- an invalid location exception + Copyright (C) 2005 Free Software Foundation + +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 +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.classpath.jdwp.exception; + +import gnu.classpath.jdwp.JdwpConstants; + +/** + * An exception thrown when the debugger specifies an invalid location + * + * @author Keith Seitz (keiths@redhat.com) + */ +public class InvalidLocationException + extends JdwpException +{ + public InvalidLocationException (/*something*/) + { + super (JdwpConstants.Error.INVALID_LOCATION, + "invalid location (" + "something" + ")"); + } + + public InvalidLocationException (Throwable t) + { + super (JdwpConstants.Error.INVALID_LOCATION, t); + } +} diff --git a/libjava/classpath/gnu/classpath/jdwp/exception/InvalidMethodException.java b/libjava/classpath/gnu/classpath/jdwp/exception/InvalidMethodException.java new file mode 100644 index 00000000000..3299915b8a5 --- /dev/null +++ b/libjava/classpath/gnu/classpath/jdwp/exception/InvalidMethodException.java @@ -0,0 +1,63 @@ +/* InvalidMethodException.java -- an invalid method id exception + Copyright (C) 2005 Free Software Foundation + +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 +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.classpath.jdwp.exception; + +import gnu.classpath.jdwp.JdwpConstants; + +/** + * An exception thrown when an invalid method id is used + * by the debugger + * + * @author Keith Seitz (keiths@redhat.com) + */ +public class InvalidMethodException + extends JdwpException +{ + public InvalidMethodException (long id) + { + super (JdwpConstants.Error.INVALID_METHODID, + "invalid method id (" + id + ")"); + } + + public InvalidMethodException (Throwable t) + { + super (JdwpConstants.Error.INVALID_METHODID, t); + } +} diff --git a/libjava/classpath/gnu/classpath/jdwp/exception/JdwpIllegalArgumentException.java b/libjava/classpath/gnu/classpath/jdwp/exception/JdwpIllegalArgumentException.java new file mode 100644 index 00000000000..1ede37f8370 --- /dev/null +++ b/libjava/classpath/gnu/classpath/jdwp/exception/JdwpIllegalArgumentException.java @@ -0,0 +1,62 @@ +/* JdwpIllegalArgumentException.java -- an illegal argument exception + Copyright (C) 2005 Free Software Foundation + +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 +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.classpath.jdwp.exception; + +import gnu.classpath.jdwp.JdwpConstants; + +/** + * An illegal argument exception for JDWP. + * + * @author Keith Seitz (keiths@redhat.com) + */ +public class JdwpIllegalArgumentException + extends JdwpException +{ + /** + * Constructs a new <code>JdwpIllegalArgumentException</code> with + * the given error code and given cause + * + * @param msg a message explaining the illegal argument + */ + public JdwpIllegalArgumentException (String msg) + { + super (JdwpConstants.Error.ILLEGAL_ARGUMENT, msg); + } +} diff --git a/libjava/classpath/gnu/classpath/jdwp/processor/ArrayReferenceCommandSet.java b/libjava/classpath/gnu/classpath/jdwp/processor/ArrayReferenceCommandSet.java new file mode 100644 index 00000000000..24702166252 --- /dev/null +++ b/libjava/classpath/gnu/classpath/jdwp/processor/ArrayReferenceCommandSet.java @@ -0,0 +1,174 @@ +/* ArrayReferenceCommandSet.java -- class to implement the Array + Reference Command Set + Copyright (C) 2005 Free Software Foundation + +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 +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.classpath.jdwp.processor; + +import gnu.classpath.jdwp.JdwpConstants; +import gnu.classpath.jdwp.exception.InvalidObjectException; +import gnu.classpath.jdwp.exception.JdwpException; +import gnu.classpath.jdwp.exception.JdwpInternalErrorException; +import gnu.classpath.jdwp.exception.NotImplementedException; +import gnu.classpath.jdwp.id.ObjectId; +import gnu.classpath.jdwp.util.Value; + +import java.io.DataOutputStream; +import java.io.IOException; +import java.lang.reflect.Array; +import java.nio.ByteBuffer; + +/** + * A class representing the ArrayReference Command Set. + * + * @author Aaron Luchko <aluchko@redhat.com> + */ +public class ArrayReferenceCommandSet + extends CommandSet +{ + public boolean runCommand(ByteBuffer bb, DataOutputStream os, byte command) + throws JdwpException + { + try + { + switch (command) + { + case JdwpConstants.CommandSet.ArrayReference.LENGTH: + executeLength(bb, os); + break; + case JdwpConstants.CommandSet.ArrayReference.GET_VALUES: + executeGetValues(bb, os); + break; + case JdwpConstants.CommandSet.ArrayReference.SET_VALUES: + executeSetValues(bb, os); + break; + default: + throw new NotImplementedException("Command " + command + + " not found in Array Reference Command Set."); + } + } + catch (IOException ex) + { + // The DataOutputStream we're using isn't talking to a socket at all + // So if we throw an IOException we're in serious trouble + throw new JdwpInternalErrorException(ex); + } + return true; + } + + private void executeLength(ByteBuffer bb, DataOutputStream os) + throws InvalidObjectException, IOException + { + ObjectId oid = idMan.readObjectId(bb); + Object array = oid.getObject(); + os.writeInt(Array.getLength(array)); + } + + private void executeGetValues(ByteBuffer bb, DataOutputStream os) + throws JdwpException, IOException + { + ObjectId oid = idMan.readObjectId(bb); + Object array = oid.getObject(); + int first = bb.getInt(); + int length = bb.getInt(); + + // We need to write out the byte signifying the type of array first + Class clazz = array.getClass().getComponentType(); + + // Uugh, this is a little ugly but it's the only time we deal with + // arrayregions + if (clazz == byte.class) + os.writeByte(JdwpConstants.Tag.BYTE); + else if (clazz == char.class) + os.writeByte(JdwpConstants.Tag.CHAR); + else if (clazz == float.class) + os.writeByte(JdwpConstants.Tag.FLOAT); + else if (clazz == double.class) + os.writeByte(JdwpConstants.Tag.DOUBLE); + else if (clazz == int.class) + os.writeByte(JdwpConstants.Tag.BYTE); + else if (clazz == long.class) + os.writeByte(JdwpConstants.Tag.LONG); + else if (clazz == short.class) + os.writeByte(JdwpConstants.Tag.SHORT); + else if (clazz == void.class) + os.writeByte(JdwpConstants.Tag.VOID); + else if (clazz == boolean.class) + os.writeByte(JdwpConstants.Tag.BOOLEAN); + else if (clazz.isArray()) + os.writeByte(JdwpConstants.Tag.ARRAY); + else if (String.class.isAssignableFrom(clazz)) + os.writeByte(JdwpConstants.Tag.STRING); + else if (Thread.class.isAssignableFrom(clazz)) + os.writeByte(JdwpConstants.Tag.THREAD); + else if (ThreadGroup.class.isAssignableFrom(clazz)) + os.writeByte(JdwpConstants.Tag.THREAD_GROUP); + else if (ClassLoader.class.isAssignableFrom(clazz)) + os.writeByte(JdwpConstants.Tag.CLASS_LOADER); + else if (Class.class.isAssignableFrom(clazz)) + os.writeByte(JdwpConstants.Tag.CLASS_OBJECT); + else + os.writeByte(JdwpConstants.Tag.OBJECT); + + // Write all the values, primitives should be untagged and Objects must be + // tagged + for (int i = first; i < first + length; i++) + { + Object value = Array.get(array, i); + if (clazz.isPrimitive()) + Value.writeUntaggedValue(os, value); + else + Value.writeTaggedValue(os, value); + } + } + + private void executeSetValues(ByteBuffer bb, DataOutputStream os) + throws IOException, JdwpException + { + ObjectId oid = idMan.readObjectId(bb); + Object array = oid.getObject(); + int first = bb.getInt(); + int length = bb.getInt(); + Class type = array.getClass().getComponentType(); + for (int i = first; i < first + length; i++) + { + Object value = Value.getUntaggedObj(bb, type); + Array.set(array, i, value); + } + } +} diff --git a/libjava/classpath/gnu/classpath/jdwp/processor/ArrayTypeCommandSet.java b/libjava/classpath/gnu/classpath/jdwp/processor/ArrayTypeCommandSet.java new file mode 100644 index 00000000000..8ae1b450862 --- /dev/null +++ b/libjava/classpath/gnu/classpath/jdwp/processor/ArrayTypeCommandSet.java @@ -0,0 +1,104 @@ +/* ArrayTypeCommandSet.java -- class to implement the ArrayType Command Set + Copyright (C) 2005 Free Software Foundation + +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.classpath.jdwp.processor; + +import gnu.classpath.jdwp.JdwpConstants; +import gnu.classpath.jdwp.exception.JdwpException; +import gnu.classpath.jdwp.exception.JdwpInternalErrorException; +import gnu.classpath.jdwp.exception.NotImplementedException; +import gnu.classpath.jdwp.id.ObjectId; +import gnu.classpath.jdwp.id.ReferenceTypeId; + +import java.io.DataOutputStream; +import java.io.IOException; +import java.lang.reflect.Array; +import java.nio.ByteBuffer; + +/** + * A class representing the ArrayType Command Set. + * + * @author Aaron Luchko <aluchko@redhat.com> + */ +public class ArrayTypeCommandSet + extends CommandSet +{ + public boolean runCommand(ByteBuffer bb, DataOutputStream os, byte command) + throws JdwpException + { + + // Although there's only a single command to choose from we still use + // a switch to maintain consistency with the rest of the CommandSets + try + { + switch (command) + { + case JdwpConstants.CommandSet.ArrayType.NEW_INSTANCE: + executeNewInstance(bb, os); + break; + default: + throw new NotImplementedException("Command " + command + + " not found in ArrayType Command Set."); + } + } + catch (IOException ex) + { + // The DataOutputStream we're using isn't talking to a socket at all + // So if we throw an IOException we're in serious trouble + throw new JdwpInternalErrorException(ex); + } + return true; + } + + public void executeNewInstance(ByteBuffer bb, DataOutputStream os) + throws JdwpException, IOException + { + ReferenceTypeId refId = idMan.readReferenceTypeId(bb); + Class arrayType = refId.getType(); + Class componentType = arrayType.getComponentType(); + + int length = bb.getInt(); + Object newArray = Array.newInstance(componentType, length); + ObjectId oid = idMan.getObjectId(newArray); + + // Since this array isn't referenced anywhere we'll disable garbage + // collection on it so it's still around when the debugger gets back to it. + oid.disableCollection(); + oid.writeTagged(os); + } +} diff --git a/libjava/classpath/gnu/classpath/jdwp/processor/ClassLoaderReferenceCommandSet.java b/libjava/classpath/gnu/classpath/jdwp/processor/ClassLoaderReferenceCommandSet.java new file mode 100644 index 00000000000..4e8e23ede23 --- /dev/null +++ b/libjava/classpath/gnu/classpath/jdwp/processor/ClassLoaderReferenceCommandSet.java @@ -0,0 +1,107 @@ +/* ClassLoaderReferenceCommandSet.java -- class to implement the + ClassLoaderReference Command Set + Copyright (C) 2005 Free Software Foundation + +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 +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.classpath.jdwp.processor; + +import gnu.classpath.jdwp.JdwpConstants; +import gnu.classpath.jdwp.VMVirtualMachine; +import gnu.classpath.jdwp.exception.JdwpException; +import gnu.classpath.jdwp.exception.JdwpInternalErrorException; +import gnu.classpath.jdwp.exception.NotImplementedException; +import gnu.classpath.jdwp.id.ObjectId; +import gnu.classpath.jdwp.id.ReferenceTypeId; + +import java.io.DataOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Iterator; + +/** + * A class representing the ClassLoaderReference Command Set. + * + * @author Aaron Luchko <aluchko@redhat.com> + */ +public class ClassLoaderReferenceCommandSet + extends CommandSet +{ + public boolean runCommand(ByteBuffer bb, DataOutputStream os, byte command) + throws JdwpException + { + + // Although there's only a single command to choose from we still use + // a switch to maintain consistency with the rest of the CommandSets + try + { + switch (command) + { + case JdwpConstants.CommandSet.ClassLoaderReference.VISIBLE_CLASSES: + executeVisibleClasses(bb, os); + break; + default: + throw new NotImplementedException("Command " + command + + " not found in ClassLoaderReference Command Set."); + } + } + catch (IOException ex) + { + // The DataOutputStream we're using isn't talking to a socket at all + // So if we throw an IOException we're in serious trouble + throw new JdwpInternalErrorException(ex); + } + return true; + } + + public void executeVisibleClasses(ByteBuffer bb, DataOutputStream os) + throws JdwpException, IOException + { + ObjectId oId = idMan.readObjectId(bb); + ClassLoader cl = (ClassLoader) oId.getObject(); + ArrayList loadRequests = VMVirtualMachine.getLoadRequests(cl); + os.writeInt(loadRequests.size()); + for (Iterator iter = loadRequests.iterator(); iter.hasNext();) + { + Class clazz = (Class)iter.next(); + ReferenceTypeId refId = idMan.getReferenceTypeId(clazz); + refId.writeTagged(os); + } + } + +} diff --git a/libjava/classpath/gnu/classpath/jdwp/processor/ClassObjectReferenceCommandSet.java b/libjava/classpath/gnu/classpath/jdwp/processor/ClassObjectReferenceCommandSet.java new file mode 100644 index 00000000000..dcafa6f84d2 --- /dev/null +++ b/libjava/classpath/gnu/classpath/jdwp/processor/ClassObjectReferenceCommandSet.java @@ -0,0 +1,96 @@ +/* ClassObjectReferenceCommandSet.java -- class to implement the + ClassObjectReference Command Set + Copyright (C) 2005 Free Software Foundation + +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.classpath.jdwp.processor; + +import gnu.classpath.jdwp.JdwpConstants; +import gnu.classpath.jdwp.exception.JdwpException; +import gnu.classpath.jdwp.exception.JdwpInternalErrorException; +import gnu.classpath.jdwp.exception.NotImplementedException; +import gnu.classpath.jdwp.id.ObjectId; +import gnu.classpath.jdwp.id.ReferenceTypeId; + +import java.io.DataOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; + +/** + * A class representing the ClassObjectReference Command Set. + * + * @author Aaron Luchko <aluchko@redhat.com> + */ +public class ClassObjectReferenceCommandSet + extends CommandSet +{ + public boolean runCommand(ByteBuffer bb, DataOutputStream os, byte command) + throws JdwpException + { + try + { + switch (command) + { + case JdwpConstants.CommandSet.ClassObjectReference.REFLECTED_TYPE: + executeReflectedType(bb, os); + break; + default: + throw new NotImplementedException("Command " + command + + " not found in ClassObject Reference Command Set."); + } + } + catch (IOException ex) + { + // The DataOutputStream we're using isn't talking to a socket at all + // So if we throw an IOException we're in serious trouble + throw new JdwpInternalErrorException(ex); + } + return true; + } + + public void executeReflectedType(ByteBuffer bb, DataOutputStream os) + throws JdwpException, IOException + { + ObjectId oid = idMan.readObjectId(bb); + Class clazz = (Class) oid.getObject(); + + // The difference between a ClassObjectId and a ReferenceTypeId is one is + // stored as an ObjectId and the other as a ReferenceTypeId. + ReferenceTypeId refId = idMan.getReferenceTypeId(clazz); + refId.writeTagged(os); + } +} diff --git a/libjava/classpath/gnu/classpath/jdwp/processor/ClassTypeCommandSet.java b/libjava/classpath/gnu/classpath/jdwp/processor/ClassTypeCommandSet.java new file mode 100644 index 00000000000..ff6010e59cb --- /dev/null +++ b/libjava/classpath/gnu/classpath/jdwp/processor/ClassTypeCommandSet.java @@ -0,0 +1,218 @@ +/* ClassTypeCommandSet.java -- class to implement the ClassType + Command Set + Copyright (C) 2005 Free Software Foundation + +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 +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.classpath.jdwp.processor; + +import gnu.classpath.jdwp.JdwpConstants; +import gnu.classpath.jdwp.VMVirtualMachine; +import gnu.classpath.jdwp.exception.InvalidFieldException; +import gnu.classpath.jdwp.exception.JdwpException; +import gnu.classpath.jdwp.exception.JdwpInternalErrorException; +import gnu.classpath.jdwp.exception.NotImplementedException; +import gnu.classpath.jdwp.id.ObjectId; +import gnu.classpath.jdwp.id.ReferenceTypeId; +import gnu.classpath.jdwp.util.MethodResult; +import gnu.classpath.jdwp.util.Value; + +import java.io.DataOutputStream; +import java.io.IOException; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.nio.ByteBuffer; + +/** + * A class representing the ClassType Command Set. + * + * @author Aaron Luchko <aluchko@redhat.com> + */ +public class ClassTypeCommandSet + extends CommandSet +{ + public boolean runCommand(ByteBuffer bb, DataOutputStream os, byte command) + throws JdwpException + { + try + { + switch (command) + { + case JdwpConstants.CommandSet.ClassType.SUPERCLASS: + executeSuperclass(bb, os); + break; + case JdwpConstants.CommandSet.ClassType.SET_VALUES: + executeSetValues(bb, os); + break; + case JdwpConstants.CommandSet.ClassType.INVOKE_METHOD: + executeInvokeMethod(bb, os); + break; + case JdwpConstants.CommandSet.ClassType.NEW_INSTANCE: + executeNewInstance(bb, os); + break; + default: + throw new NotImplementedException("Command " + command + + " not found in ClassType Command Set."); + } + } + catch (IOException ex) + { + // The DataOutputStream we're using isn't talking to a socket at all + // So if we throw an IOException we're in serious trouble + throw new JdwpInternalErrorException(ex); + } + return true; + } + + private void executeSuperclass(ByteBuffer bb, DataOutputStream os) + throws JdwpException, IOException + { + ReferenceTypeId refId = idMan.readReferenceTypeId(bb); + Class clazz = refId.getType(); + Class superClazz = clazz.getSuperclass(); + + ReferenceTypeId clazzId = idMan.getReferenceTypeId(superClazz); + clazzId.write(os); + } + + private void executeSetValues(ByteBuffer bb, DataOutputStream os) + throws JdwpException, IOException + { + ReferenceTypeId refId = idMan.readReferenceTypeId(bb); + + // We don't actually seem to need this... + Class clazz = refId.getType(); + + int numValues = bb.getInt(); + + for (int i = 0; i < numValues; i++) + { + ObjectId fieldId = idMan.readObjectId(bb); + Field field = (Field) (fieldId.getObject()); + Object value = Value.getUntaggedObj(bb, field.getType()); + try + { + field.setAccessible(true); // Might be a private field + field.set(null, value); + } + catch (IllegalArgumentException ex) + { + throw new InvalidFieldException(ex); + } + catch (IllegalAccessException ex) + { // Since we set it as accessible this really shouldn't happen + throw new JdwpInternalErrorException(ex); + } + } + } + + private void executeInvokeMethod(ByteBuffer bb, DataOutputStream os) + throws JdwpException, IOException + { + MethodResult mr = invokeMethod(bb); + + Object value = mr.getReturnedValue(); + Exception exception = mr.getThrownException(); + ObjectId eId = idMan.getObjectId(exception); + + Value.writeTaggedValue(os, value); + eId.writeTagged(os); + } + + private void executeNewInstance(ByteBuffer bb, DataOutputStream os) + throws JdwpException, IOException + { + MethodResult mr = invokeMethod(bb); + + Object obj = mr.getReturnedValue(); + ObjectId oId = idMan.getObjectId(obj); + Exception exception = mr.getThrownException(); + ObjectId eId = idMan.getObjectId(exception); + + oId.writeTagged(os); + eId.writeTagged(os); + } + + /** + * Execute the static method and return the resulting MethodResult. + */ + private MethodResult invokeMethod(ByteBuffer bb) throws JdwpException, + IOException + { + ReferenceTypeId refId = idMan.readReferenceTypeId(bb); + Class clazz = refId.getType(); + + ObjectId tId = idMan.readObjectId(bb); + Thread thread = (Thread) tId.getObject(); + + ObjectId mId = idMan.readObjectId(bb); + Method method = (Method) mId.getObject(); + + int args = bb.getInt(); + Object[] values = new Object[args]; + + for (int i = 0; i < args; i++) + { + values[i] = Value.getObj(bb); + } + + int invokeOpts = bb.getInt(); + boolean suspend = ((invokeOpts + & JdwpConstants.InvokeOptions.INVOKE_SINGLE_THREADED) + != 0); + try + { + if (suspend) + VMVirtualMachine.suspendAllThreads (); + + MethodResult mr = VMVirtualMachine.executeMethod(null, thread, + clazz, method, + values, false); + if (suspend) + VMVirtualMachine.resumeAllThreads (); + + return mr; + } + catch (Exception ex) + { + if (suspend) + VMVirtualMachine.resumeAllThreads (); + + throw new JdwpInternalErrorException(ex); + } + } +} diff --git a/libjava/classpath/gnu/classpath/jdwp/processor/EventRequestCommandSet.java b/libjava/classpath/gnu/classpath/jdwp/processor/EventRequestCommandSet.java new file mode 100644 index 00000000000..389b2d349f9 --- /dev/null +++ b/libjava/classpath/gnu/classpath/jdwp/processor/EventRequestCommandSet.java @@ -0,0 +1,196 @@ +/* EventRequestCommandSet.java -- class to implement the EventRequest Command + Set + Copyright (C) 2005 Free Software Foundation + +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.classpath.jdwp.processor; + +import gnu.classpath.jdwp.JdwpConstants; +import gnu.classpath.jdwp.event.EventManager; +import gnu.classpath.jdwp.event.EventRequest; +import gnu.classpath.jdwp.event.filters.ClassExcludeFilter; +import gnu.classpath.jdwp.event.filters.ClassMatchFilter; +import gnu.classpath.jdwp.event.filters.ClassOnlyFilter; +import gnu.classpath.jdwp.event.filters.ConditionalFilter; +import gnu.classpath.jdwp.event.filters.CountFilter; +import gnu.classpath.jdwp.event.filters.ExceptionOnlyFilter; +import gnu.classpath.jdwp.event.filters.FieldOnlyFilter; +import gnu.classpath.jdwp.event.filters.IEventFilter; +import gnu.classpath.jdwp.event.filters.InstanceOnlyFilter; +import gnu.classpath.jdwp.event.filters.LocationOnlyFilter; +import gnu.classpath.jdwp.event.filters.StepFilter; +import gnu.classpath.jdwp.event.filters.ThreadOnlyFilter; +import gnu.classpath.jdwp.exception.JdwpException; +import gnu.classpath.jdwp.exception.JdwpInternalErrorException; +import gnu.classpath.jdwp.exception.NotImplementedException; +import gnu.classpath.jdwp.id.ObjectId; +import gnu.classpath.jdwp.id.ReferenceTypeId; +import gnu.classpath.jdwp.id.ThreadId; +import gnu.classpath.jdwp.util.JdwpString; +import gnu.classpath.jdwp.util.Location; + +import java.io.DataOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; + +/** + * A class representing the EventRequest Command Set. + * + * @author Aaron Luchko <aluchko@redhat.com> + */ +public class EventRequestCommandSet + extends CommandSet +{ + public boolean runCommand(ByteBuffer bb, DataOutputStream os, byte command) + throws JdwpException + { + try + { + switch (command) + { + case JdwpConstants.CommandSet.EventRequest.SET: + executeSet(bb, os); + break; + case JdwpConstants.CommandSet.EventRequest.CLEAR: + executeClear(bb, os); + break; + case JdwpConstants.CommandSet.EventRequest.CLEAR_ALL_BREAKPOINTS: + executeClearAllBreakpoints(bb, os); + break; + default: + throw new NotImplementedException("Command " + command + + " not found in EventRequest Reference Command Set."); + } + } + catch (IOException ex) + { + // The DataOutputStream we're using isn't talking to a socket at all + // So if we throw an IOException we're in serious trouble + throw new JdwpInternalErrorException(ex); + } + return true; + } + + private void executeSet(ByteBuffer bb, DataOutputStream os) + throws JdwpException, IOException + { + byte eventKind = bb.get(); + byte suspendPolicy = bb.get(); + int modifiers = bb.getInt(); + + EventRequest eventReq = new EventRequest(eventKind, suspendPolicy); + IEventFilter filter = null; + ReferenceTypeId refId; + for (int i = 0; i < modifiers; i++) + { + byte modKind = bb.get(); + switch (modKind) + { + case JdwpConstants.ModKind.COUNT: + filter = new CountFilter(bb.getInt()); + break; + case JdwpConstants.ModKind.CONDITIONAL: + filter = new ConditionalFilter(idMan.readObjectId(bb)); + break; + case JdwpConstants.ModKind.THREAD_ONLY: + filter = new ThreadOnlyFilter((ThreadId) idMan.readObjectId(bb)); + break; + case JdwpConstants.ModKind.CLASS_ONLY: + filter = new ClassOnlyFilter(idMan.readReferenceTypeId(bb)); + break; + case JdwpConstants.ModKind.CLASS_MATCH: + filter = new ClassMatchFilter(JdwpString.readString(bb)); + break; + case JdwpConstants.ModKind.CLASS_EXCLUDE: + filter = new ClassExcludeFilter(JdwpString.readString(bb)); + break; + case JdwpConstants.ModKind.LOCATION_ONLY: + filter = new LocationOnlyFilter(new Location(bb)); + break; + case JdwpConstants.ModKind.EXCEPTION_ONLY: + long id = bb.getLong(); + if (id == 0) + refId = null; + else + refId = idMan.readReferenceTypeId(bb); + boolean caught = (bb.get() == 0) ? false : true; + boolean unCaught = (bb.get() == 0) ? false : true; + filter = new ExceptionOnlyFilter(refId, caught, unCaught); + break; + case JdwpConstants.ModKind.FIELD_ONLY: + refId = idMan.readReferenceTypeId(bb); + ReferenceTypeId fieldId = idMan.readReferenceTypeId(bb); + filter = new FieldOnlyFilter(refId, fieldId); + break; + case JdwpConstants.ModKind.STEP: + ThreadId tid = (ThreadId) idMan.readObjectId(bb); + int size = bb.getInt(); + int depth = bb.getInt(); + filter = new StepFilter(tid, size, depth); + break; + case JdwpConstants.ModKind.INSTANCE_ONLY: + ObjectId oid = idMan.readObjectId(bb); + filter = new InstanceOnlyFilter(oid); + break; + default: + throw new NotImplementedException("modKind " + modKind + + " is not implemented."); + } + eventReq.addFilter(filter); + } + + EventManager.getDefault().requestEvent(eventReq); + os.writeInt(eventReq.getId()); + + } + + private void executeClear(ByteBuffer bb, DataOutputStream os) + throws JdwpException, IOException + { + byte eventKind = bb.get(); + int requestId = bb.getInt(); + EventManager.getDefault().deleteRequest(eventKind, requestId); + } + + private void executeClearAllBreakpoints(ByteBuffer bb, DataOutputStream os) + throws JdwpException, IOException + { + byte eventKind = bb.get (); + EventManager.getDefault().clearRequests (eventKind); + } + +} diff --git a/libjava/classpath/gnu/classpath/jdwp/processor/MethodCommandSet.java b/libjava/classpath/gnu/classpath/jdwp/processor/MethodCommandSet.java new file mode 100644 index 00000000000..b5db664e4e4 --- /dev/null +++ b/libjava/classpath/gnu/classpath/jdwp/processor/MethodCommandSet.java @@ -0,0 +1,152 @@ +/* MethodCommandSet.java -- class to implement the Method Command Set + Copyright (C) 2005 Free Software Foundation + +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.classpath.jdwp.processor; + +import gnu.classpath.jdwp.JdwpConstants; +import gnu.classpath.jdwp.VMVirtualMachine; +import gnu.classpath.jdwp.exception.JdwpException; +import gnu.classpath.jdwp.exception.JdwpInternalErrorException; +import gnu.classpath.jdwp.exception.NotImplementedException; +import gnu.classpath.jdwp.id.ObjectId; +import gnu.classpath.jdwp.id.ReferenceTypeId; +import gnu.classpath.jdwp.util.LineTable; +import gnu.classpath.jdwp.util.VariableTable; + +import java.io.DataOutputStream; +import java.io.IOException; +import java.lang.reflect.Method; +import java.nio.ByteBuffer; + +/** + * A class representing the Method Command Set. + * + * @author Aaron Luchko <aluchko@redhat.com> + */ +public class MethodCommandSet + extends CommandSet +{ + public boolean runCommand(ByteBuffer bb, DataOutputStream os, byte command) + throws JdwpException + { + try + { + switch (command) + { + case JdwpConstants.CommandSet.Method.LINE_TABLE: + executeLineTable(bb, os); + break; + case JdwpConstants.CommandSet.Method.VARIABLE_TABLE: + executeVariableTable(bb, os); + break; + case JdwpConstants.CommandSet.Method.BYTE_CODES: + executeByteCodes(bb, os); + break; + case JdwpConstants.CommandSet.Method.IS_OBSOLETE: + executeIsObsolete(bb, os); + break; + case JdwpConstants.CommandSet.Method.VARIABLE_TABLE_WITH_GENERIC: + executeVariableTableWithGeneric(bb, os); + break; + default: + throw new NotImplementedException( + "Command " + command + " not found in Method Command Set."); + } + } + catch (IOException ex) + { + // The DataOutputStream we're using isn't talking to a socket at all + // So if we throw an IOException we're in serious trouble + throw new JdwpInternalErrorException(ex); + } + return true; + } + + private void executeLineTable(ByteBuffer bb, DataOutputStream os) + throws JdwpException, IOException + { + ReferenceTypeId refId = idMan.readReferenceTypeId(bb); + Class clazz = refId.getType(); + + ObjectId oid = idMan.readObjectId(bb); + Method method = (Method) oid.getObject(); + + LineTable lt = VMVirtualMachine.getLineTable(clazz, method); + lt.write(os); + } + + private void executeVariableTable(ByteBuffer bb, DataOutputStream os) + throws JdwpException, IOException + { + ReferenceTypeId refId = idMan.readReferenceTypeId(bb); + Class clazz = refId.getType(); + + ObjectId oid = idMan.readObjectId(bb); + Method method = (Method) oid.getObject(); + + VariableTable vt = VMVirtualMachine.getVarTable(clazz, method); + vt.write(os); + } + + private void executeByteCodes(ByteBuffer bb, DataOutputStream os) + throws JdwpException + { + // This command is optional, determined by VirtualMachines CapabilitiesNew + // so we'll leave it till later to implement + throw new NotImplementedException("Command ByteCodes not implemented."); + } + + private void executeIsObsolete(ByteBuffer bb, DataOutputStream os) + throws IOException + { + // The debugger is really asking if this method has been redefined using + // VirtualMachineCommandSet.RedefineClasses. Since we don't implement that + // command the answer to this will always be false. + os.writeBoolean(false); + } + + private void executeVariableTableWithGeneric(ByteBuffer bb, + DataOutputStream os) + throws JdwpException + { + // We don't have generics yet + throw new NotImplementedException( + "Command SourceDebugExtension not implemented."); + } + +} diff --git a/libjava/classpath/gnu/classpath/jdwp/processor/StackFrameCommandSet.java b/libjava/classpath/gnu/classpath/jdwp/processor/StackFrameCommandSet.java new file mode 100644 index 00000000000..480f4ca2833 --- /dev/null +++ b/libjava/classpath/gnu/classpath/jdwp/processor/StackFrameCommandSet.java @@ -0,0 +1,157 @@ +/* StackFrameCommandSet.java -- class to implement the StackFrame Command Set + Copyright (C) 2005 Free Software Foundation + +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 +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.classpath.jdwp.processor; + +import gnu.classpath.jdwp.JdwpConstants; +import gnu.classpath.jdwp.VMFrame; +import gnu.classpath.jdwp.VMVirtualMachine; +import gnu.classpath.jdwp.exception.JdwpException; +import gnu.classpath.jdwp.exception.JdwpInternalErrorException; +import gnu.classpath.jdwp.exception.NotImplementedException; +import gnu.classpath.jdwp.id.ObjectId; +import gnu.classpath.jdwp.util.Value; + +import java.io.DataOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; + +/** + * A class representing the StackFrame Command Set. + * + * @author Aaron Luchko <aluchko@redhat.com> + */ +public class StackFrameCommandSet + extends CommandSet +{ + public boolean runCommand(ByteBuffer bb, DataOutputStream os, byte command) + throws JdwpException + { + boolean keepRunning = true; + try + { + switch (command) + { + case JdwpConstants.CommandSet.StackFrame.GET_VALUES: + executeGetValues(bb, os); + break; + case JdwpConstants.CommandSet.StackFrame.SET_VALUES: + executeSetValues(bb, os); + break; + case JdwpConstants.CommandSet.StackFrame.THIS_OBJECT: + executeThisObject(bb, os); + break; + case JdwpConstants.CommandSet.StackFrame.POP_FRAMES: + executePopFrames(bb, os); + break; + default: + throw new NotImplementedException("Command " + command + + " not found in Stack Frame Command Set."); + } + } + catch (IOException ex) + { + // The DataOutputStream we're using isn't talking to a socket at all + // So if we throw an IOException we're in serious trouble + throw new JdwpInternalErrorException(ex); + } + return true; + } + + private void executeGetValues(ByteBuffer bb, DataOutputStream os) + throws JdwpException, IOException + { + ObjectId tId = idMan.readObjectId(bb); + Thread thread = (Thread) tId.getObject(); + + // Although Frames look like other ids they are not. First they are not + // ObjectIds since they don't exist in the users code. Storing them as an + // ObjectId would mean they could be garbage collected since no one else + // has a reference to them. Furthermore they are not ReferenceTypeIds since + // these are held permanently and we want these to be held only as long as + // the Thread is suspended. + VMFrame frame = VMVirtualMachine.getFrame(thread, bb); + int slots = bb.getInt(); + os.writeInt(slots); // Looks pointless but this is the protocol + for (int i = 0; i < slots; i++) + { + int slot = bb.getInt(); + byte sig = bb.get(); + Object val = frame.getValue(slot); + Value.writeTaggedValue(os, val); + } + } + + private void executeSetValues(ByteBuffer bb, DataOutputStream os) + throws JdwpException, IOException + { + ObjectId tId = idMan.readObjectId(bb); + Thread thread = (Thread) tId.getObject(); + + VMFrame frame = VMVirtualMachine.getFrame(thread, bb); + + int slots = bb.getInt(); + for (int i = 0; i < slots; i++) + { + int slot = bb.getInt(); + Object value = Value.getObj(bb); + frame.setValue(slot, value); + } + } + + private void executeThisObject(ByteBuffer bb, DataOutputStream os) + throws JdwpException, IOException + { + ObjectId tId = idMan.readObjectId(bb); + Thread thread = (Thread) tId.getObject(); + + VMFrame frame = VMVirtualMachine.getFrame(thread, bb); + + Object thisObject = frame.getObject(); + Value.writeTaggedValue(os, thisObject); + } + + private void executePopFrames(ByteBuffer bb, DataOutputStream os) + throws JdwpException + { + // This command is optional, determined by VirtualMachines CapabilitiesNew + // so we'll leave it till later to implement + throw new NotImplementedException("Command PopFrames not implemented."); + } +} diff --git a/libjava/classpath/gnu/classpath/jdwp/processor/ThreadGroupReferenceCommandSet.java b/libjava/classpath/gnu/classpath/jdwp/processor/ThreadGroupReferenceCommandSet.java new file mode 100644 index 00000000000..8a11195a708 --- /dev/null +++ b/libjava/classpath/gnu/classpath/jdwp/processor/ThreadGroupReferenceCommandSet.java @@ -0,0 +1,174 @@ +/* ThreadGroupReferenceCommandSet.java -- class to implement the + ThreadGroupReference Command Set + Copyright (C) 2005 Free Software Foundation + +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.classpath.jdwp.processor; + +import gnu.classpath.jdwp.JdwpConstants; +import gnu.classpath.jdwp.exception.JdwpException; +import gnu.classpath.jdwp.exception.JdwpInternalErrorException; +import gnu.classpath.jdwp.exception.NotImplementedException; +import gnu.classpath.jdwp.id.ObjectId; +import gnu.classpath.jdwp.util.JdwpString; + +import java.io.DataOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; + +/** + * A class representing the ThreadGroupReference Command Set. + * + * @author Aaron Luchko <aluchko@redhat.com> + */ +public class ThreadGroupReferenceCommandSet + extends CommandSet +{ + public boolean runCommand(ByteBuffer bb, DataOutputStream os, byte command) + throws JdwpException + { + try + { + switch (command) + { + case JdwpConstants.CommandSet.ThreadGroupReference.NAME: + executeName(bb, os); + break; + case JdwpConstants.CommandSet.ThreadGroupReference.PARENT: + executeParent(bb, os); + break; + case JdwpConstants.CommandSet.ThreadGroupReference.CHILDREN: + executeChildren(bb, os); + break; + default: + throw new NotImplementedException("Command " + command + + " not found in ThreadGroupReference Command Set."); + } + } + catch (IOException ex) + { + // The DataOutputStream we're using isn't talking to a socket at all + // So if we throw an IOException we're in serious trouble + throw new JdwpInternalErrorException(ex); + } + return true; + } + + private void executeName(ByteBuffer bb, DataOutputStream os) + throws JdwpException, IOException + { + ObjectId oid = idMan.readObjectId(bb); + ThreadGroup group = (ThreadGroup) oid.getObject(); + JdwpString.writeString(os, group.getName()); + } + + private void executeParent(ByteBuffer bb, DataOutputStream os) + throws JdwpException, IOException + { + ObjectId oid = idMan.readObjectId(bb); + ThreadGroup group = (ThreadGroup) oid.getObject(); + ThreadGroup parent = group.getParent(); + ObjectId parentId = idMan.getObjectId(parent); + parentId.write(os); + } + + private void executeChildren(ByteBuffer bb, DataOutputStream os) + throws JdwpException, IOException + { + ObjectId oid = idMan.readObjectId(bb); + ThreadGroup group = (ThreadGroup) oid.getObject(); + + ThreadGroup jdwpGroup = Thread.currentThread().getThreadGroup(); + int numThreads = group.activeCount(); + Thread allThreads[] = new Thread[numThreads]; + + group.enumerate(allThreads, false); + + // We need to loop through for the true count since some threads may have + // been destroyed since we got activeCount so those spots in the array will + // be null. As well we must ignore any threads that belong to jdwp + numThreads = 0; + for (int i = 0; i < allThreads.length; i++) + { + Thread thread = allThreads[i]; + if (thread == null) + break; // No threads after this point + if (!thread.getThreadGroup().equals(jdwpGroup)) + numThreads++; + } + + os.writeInt(numThreads); + + for (int i = 0; i < allThreads.length; i++) + { + Thread thread = allThreads[i]; + if (thread == null) + break; // No threads after this point + if (!thread.getThreadGroup().equals(jdwpGroup)) + idMan.getObjectId(thread).write(os); + } + + int numGroups = group.activeCount(); + ThreadGroup allGroups[] = new ThreadGroup[numGroups]; + + group.enumerate(allGroups, false); + + // We need to loop through for the true count since some ThreadGroups may + // have been destroyed since we got activeCount so those spots in the array + // will be null. As well we must ignore any threads that belong to jdwp. + numGroups = 0; + for (int i = 0; i < allGroups.length; i++) + { + ThreadGroup tgroup = allGroups[i]; + if (tgroup == null) + break; // No ThreadGroups after this point + if (!tgroup.equals(jdwpGroup)) + numGroups++; + } + + os.writeInt(numGroups); + + for (int i = 0; i < allGroups.length; i++) + { + ThreadGroup tgroup = allGroups[i]; + if (tgroup == null) + break; // No ThreadGroups after this point + if (!tgroup.equals(jdwpGroup)) + idMan.getObjectId(tgroup).write(os); + } + } +} diff --git a/libjava/classpath/gnu/classpath/jdwp/processor/ThreadReferenceCommandSet.java b/libjava/classpath/gnu/classpath/jdwp/processor/ThreadReferenceCommandSet.java new file mode 100644 index 00000000000..73643b6a83a --- /dev/null +++ b/libjava/classpath/gnu/classpath/jdwp/processor/ThreadReferenceCommandSet.java @@ -0,0 +1,245 @@ +/* ThreadReferenceCommandSet.java -- class to implement the ThreadReference + Command Set Copyright (C) 2005 Free Software Foundation + +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 +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.classpath.jdwp.processor; + +import gnu.classpath.jdwp.JdwpConstants; +import gnu.classpath.jdwp.VMFrame; +import gnu.classpath.jdwp.VMVirtualMachine; +import gnu.classpath.jdwp.exception.InvalidObjectException; +import gnu.classpath.jdwp.exception.JdwpException; +import gnu.classpath.jdwp.exception.JdwpInternalErrorException; +import gnu.classpath.jdwp.exception.NotImplementedException; +import gnu.classpath.jdwp.id.ObjectId; +import gnu.classpath.jdwp.id.ThreadId; +import gnu.classpath.jdwp.util.JdwpString; +import gnu.classpath.jdwp.util.Location; + +import java.io.DataOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.ArrayList; + +/** + * A class representing the ThreadReference Command Set. + * + * @author Aaron Luchko <aluchko@redhat.com> + */ +public class ThreadReferenceCommandSet + extends CommandSet +{ + public boolean runCommand(ByteBuffer bb, DataOutputStream os, byte command) + throws JdwpException + { + try + { + switch (command) + { + case JdwpConstants.CommandSet.ThreadReference.NAME: + executeName(bb, os); + break; + case JdwpConstants.CommandSet.ThreadReference.SUSPEND: + executeSuspend(bb, os); + break; + case JdwpConstants.CommandSet.ThreadReference.RESUME: + executeResume(bb, os); + break; + case JdwpConstants.CommandSet.ThreadReference.STATUS: + executeStatus(bb, os); + break; + case JdwpConstants.CommandSet.ThreadReference.THREAD_GROUP: + executeThreadGroup(bb, os); + break; + case JdwpConstants.CommandSet.ThreadReference.FRAMES: + executeFrames(bb, os); + break; + case JdwpConstants.CommandSet.ThreadReference.FRAME_COUNT: + executeFrameCount(bb, os); + break; + case JdwpConstants.CommandSet.ThreadReference.OWNED_MONITORS: + executeOwnedMonitors(bb, os); + break; + case JdwpConstants.CommandSet.ThreadReference.CURRENT_CONTENDED_MONITOR: + executeCurrentContendedMonitor(bb, os); + break; + case JdwpConstants.CommandSet.ThreadReference.STOP: + executeStop(bb, os); + break; + case JdwpConstants.CommandSet.ThreadReference.INTERRUPT: + executeInterrupt(bb, os); + break; + case JdwpConstants.CommandSet.ThreadReference.SUSPEND_COUNT: + executeSuspendCount(bb, os); + break; + default: + throw new NotImplementedException("Command " + command + + " not found in Thread Reference Command Set."); + } + } + catch (IOException ex) + { + // The DataOutputStream we're using isn't talking to a socket at all + // So if we throw an IOException we're in serious trouble + throw new JdwpInternalErrorException(ex); + } + return true; + } + + private void executeName(ByteBuffer bb, DataOutputStream os) + throws JdwpException, IOException + { + ThreadId tid = (ThreadId) idMan.readObjectId(bb); + Thread thread = tid.getThread(); + JdwpString.writeString(os, thread.getName()); + } + + private void executeSuspend(ByteBuffer bb, DataOutputStream os) + throws JdwpException, IOException + { + ThreadId tid = (ThreadId) idMan.readObjectId(bb); + Thread thread = tid.getThread(); + VMVirtualMachine.suspendThread(thread); + } + + private void executeResume(ByteBuffer bb, DataOutputStream os) + throws JdwpException, IOException + { + ThreadId tid = (ThreadId) idMan.readObjectId(bb); + Thread thread = tid.getThread(); + VMVirtualMachine.suspendThread(thread); + } + + private void executeStatus(ByteBuffer bb, DataOutputStream os) + throws JdwpException, IOException + { + ThreadId tid = (ThreadId) idMan.readObjectId(bb); + Thread thread = tid.getThread(); + int threadStatus = VMVirtualMachine.getThreadStatus(thread); + // There's only one possible SuspendStatus... + int suspendStatus = JdwpConstants.SuspendStatus.SUSPENDED; + + os.writeInt(threadStatus); + os.writeInt(suspendStatus); + } + + private void executeThreadGroup(ByteBuffer bb, DataOutputStream os) + throws JdwpException, IOException + { + ThreadId tid = (ThreadId) idMan.readObjectId(bb); + Thread thread = tid.getThread(); + ThreadGroup group = thread.getThreadGroup(); + ObjectId groupId = idMan.getObjectId(group); + groupId.write(os); + } + + private void executeFrames(ByteBuffer bb, DataOutputStream os) + throws JdwpException, IOException + { + ThreadId tid = (ThreadId) idMan.readObjectId(bb); + Thread thread = tid.getThread(); + int startFrame = bb.getInt(); + int length = bb.getInt(); + + ArrayList frames = VMVirtualMachine.getFrames(thread, startFrame, length); + os.writeInt(frames.size()); + for (int i = 0; i < frames.size(); i++) + { + VMFrame frame = (VMFrame) frames.get(i); + os.writeLong(frame.getId()); + Location loc = frame.getLocation(); + loc.write(os); + } + } + + private void executeFrameCount(ByteBuffer bb, DataOutputStream os) + throws JdwpException, IOException + { + ThreadId tid = (ThreadId) idMan.readObjectId(bb); + Thread thread = tid.getThread(); + + int frameCount = VMVirtualMachine.getFrameCount(thread); + os.writeInt(frameCount); + } + + private void executeOwnedMonitors(ByteBuffer bb, DataOutputStream os) + throws JdwpException + { + // This command is optional, determined by VirtualMachines CapabilitiesNew + // so we'll leave it till later to implement + throw new NotImplementedException( + "Command OwnedMonitors not implemented."); + } + + private void executeCurrentContendedMonitor(ByteBuffer bb, + DataOutputStream os) + throws JdwpException + { + // This command is optional, determined by VirtualMachines CapabilitiesNew + // so we'll leave it till later to implement + throw new NotImplementedException( + "Command CurrentContentedMonitors not implemented."); + } + + private void executeStop(ByteBuffer bb, DataOutputStream os) + throws JdwpException, IOException + { + ThreadId tid = (ThreadId) idMan.readObjectId(bb); + Thread thread = tid.getThread(); + ObjectId exception = idMan.readObjectId(bb); + Throwable throwable = (Throwable) exception.getObject(); + thread.stop (throwable); + } + + private void executeInterrupt(ByteBuffer bb, DataOutputStream os) + throws JdwpException, IOException + { + ThreadId tid = (ThreadId) idMan.readObjectId(bb); + Thread thread = tid.getThread(); + thread.interrupt(); + } + + private void executeSuspendCount(ByteBuffer bb, DataOutputStream os) + throws JdwpException, IOException + { + ThreadId tid = (ThreadId) idMan.readObjectId(bb); + Thread thread = tid.getThread(); + int suspendCount = VMVirtualMachine.getSuspendCount(thread); + os.writeInt(suspendCount); + } +} diff --git a/libjava/classpath/gnu/classpath/jdwp/util/LineTable.java b/libjava/classpath/gnu/classpath/jdwp/util/LineTable.java new file mode 100644 index 00000000000..dc4933aedeb --- /dev/null +++ b/libjava/classpath/gnu/classpath/jdwp/util/LineTable.java @@ -0,0 +1,96 @@ +/* LineTable.java -- A class representing a Line Table for a method + Copyright (C) 2005 Free Software Foundation + +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 +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.classpath.jdwp.util; + +import java.io.DataOutputStream; +import java.io.IOException; + +/** + * A class representing a Line Table for a method. + * + * @author Aaron Luchko <aluchko@redhat.com> + */ +public class LineTable +{ + + private final long start; + private final long end; + private final int[] lineNum; + private final long[] lineCI; + private final int lines; + + /** + * Construct a line table with the given parameters. + * + * @param start lowest code index for method, -1 if native + * @param end highest code index for method, -1 if native + * @param lines number of entries in line table + * @param lineCI code indexes for entries in line tables (of length lines) + * @param lineNum line numbers for in line tables (of length lines) + */ + public LineTable(long start, long end, int lines, long lineCI[], + int lineNum[]) + { + this.start = start; + this.end = end; + this.lines = lines; + this.lineCI = lineCI; + this.lineNum = lineNum; + } + + /** + * Writes this line table to the given DataOutputStream. + * + * @param os the stream to write it to + * @throws IOException + */ + public void write(DataOutputStream os) + throws IOException + { + os.writeLong(start); + os.writeLong(end); + os.writeInt(lines); + for (int i = 0; i < lines; i++) + { + os.writeLong(lineCI[i]); + os.writeInt(lineNum[i]); + } + } +} diff --git a/libjava/classpath/gnu/classpath/jdwp/util/Location.java b/libjava/classpath/gnu/classpath/jdwp/util/Location.java new file mode 100644 index 00000000000..d7a2855ce8a --- /dev/null +++ b/libjava/classpath/gnu/classpath/jdwp/util/Location.java @@ -0,0 +1,116 @@ +/* Location.java -- class to read/write JDWP locations + Copyright (C) 2005 Free Software Foundation + +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.classpath.jdwp.util; + +import gnu.classpath.jdwp.VMIdManager; +import gnu.classpath.jdwp.exception.JdwpException; +import gnu.classpath.jdwp.id.ClassReferenceTypeId; +import gnu.classpath.jdwp.id.ObjectId; + +import java.io.DataOutputStream; +import java.io.IOException; +import java.lang.reflect.Method; +import java.nio.ByteBuffer; + +/** + * A class to read/write JDWP locations. + * + * @author Aaron Luchko <aluchko@redhat.com> + */ +public class Location +{ + + private ClassReferenceTypeId crti; + + private int index; + + private byte tag; + + private ObjectId mid; + + /** + * Create a location with the given parameters. + * + * @param tag the type of construct the location is in + * @param clazz the class the location is in + * @param meth the Method + * @param index location in the method + * @throws JdwpException + */ + public Location(byte tag, Class clazz, Method meth, int index) + throws JdwpException + { + this.tag = tag; + this.crti = + (ClassReferenceTypeId) VMIdManager.getDefault().getReferenceTypeId(clazz); + this.mid = VMIdManager.getDefault().getObjectId(meth); + this.index = index; + } + + /** + * Read a location from the given bytebuffer, consists of a TAG (byte), + * followed by a ReferenceTypeId, a MethodId and an index (int). + * + * @param bb this holds the location + * @throws IOException + * @throws JdwpException + */ + public Location(ByteBuffer bb) throws IOException, JdwpException + { + this.tag = bb.get(); + this.crti = + (ClassReferenceTypeId) VMIdManager.getDefault().readReferenceTypeId(bb); + this.mid = VMIdManager.getDefault().readObjectId(bb); + this.index = bb.getInt(); + } + + /** + * Write the given location to an output stream. + * + * @param os stream to write to + * @throws IOException + */ + public void write(DataOutputStream os) throws IOException + { + os.writeByte(tag); + crti.write(os); + mid.write(os); + os.writeInt(index); + } +} diff --git a/libjava/classpath/gnu/classpath/jdwp/util/MethodResult.java b/libjava/classpath/gnu/classpath/jdwp/util/MethodResult.java new file mode 100644 index 00000000000..a9c1b330579 --- /dev/null +++ b/libjava/classpath/gnu/classpath/jdwp/util/MethodResult.java @@ -0,0 +1,76 @@ +/* MethodResult.java -- class to wrap around values returned from a Method call + in the VM + Copyright (C) 2005 Free Software Foundation + +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 +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.classpath.jdwp.util; + +/** + * A class to wrap around values returned from a Method call in the VM. + * + * @author Aaron Luchko <aluchko@redhat.com> + */ +public class MethodResult +{ + // The Object returned by the executing method + private Object returnedValue; + + // Any Exception that was thrown by the executing method + private Exception thrownException; + + public Object getReturnedValue() + { + return returnedValue; + } + + public void setReturnedValue(Object returnedValue) + { + this.returnedValue = returnedValue; + } + + public Exception getThrownException() + { + return thrownException; + } + + public void setThrownException(Exception thrownException) + { + this.thrownException = thrownException; + } + +} diff --git a/libjava/classpath/gnu/classpath/jdwp/util/Value.java b/libjava/classpath/gnu/classpath/jdwp/util/Value.java new file mode 100644 index 00000000000..759b2a99cb1 --- /dev/null +++ b/libjava/classpath/gnu/classpath/jdwp/util/Value.java @@ -0,0 +1,301 @@ +/* Value.java -- class to read/write JDWP tagged and untagged values + Copyright (C) 2005 Free Software Foundation + +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.classpath.jdwp.util; + +import gnu.classpath.jdwp.JdwpConstants; +import gnu.classpath.jdwp.VMIdManager; +import gnu.classpath.jdwp.exception.InvalidFieldException; +import gnu.classpath.jdwp.exception.JdwpException; +import gnu.classpath.jdwp.exception.JdwpInternalErrorException; +import gnu.classpath.jdwp.exception.NotImplementedException; +import gnu.classpath.jdwp.id.ObjectId; + +import java.io.DataOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; + +/** + * A class to read/write JDWP tagged and untagged values. + * + * @author Aaron Luchko <aluchko@redhat.com> + */ +public class Value +{ + /** + * Will write the given object as an untagged value to the DataOutputStream. + * + * @param os write the value here + * @param obj the Object to write + * @throws IOException + * @throws InvalidFieldException + */ + public static void writeUntaggedValue(DataOutputStream os, Object obj) + throws JdwpException, IOException + { + writeValue(os, obj, false); + } + + /** + * Will write the given object as a tagged value to the DataOutputStream. + * + * @param os write the value here + * @param obj the Object to write + * @throws IOException + * @throws InvalidFieldException + */ + public static void writeTaggedValue(DataOutputStream os, Object obj) + throws JdwpException, IOException + { + writeValue(os, obj, true); + } + + /** + * Will write the given object as either a value or an untagged value to the + * DataOutputStream. + * + * @param os write the value here + * @param obj the Object to write + * @param tagged true if the value is tagged, false otherwise + * @throws IOException + * @throws InvalidFieldException + */ + private static void writeValue(DataOutputStream os, Object obj, + boolean tagged) + throws IOException, JdwpException + { + Class clazz = obj.getClass(); + if (clazz.isPrimitive()) + { + if (clazz == byte.class) + { + if (tagged) + os.writeByte(JdwpConstants.Tag.BYTE); + os.writeByte(((Byte) obj).byteValue()); + } + else if (clazz == char.class) + { + if (tagged) + os.writeByte(JdwpConstants.Tag.CHAR); + os.writeChar(((Character) obj).charValue()); + } + else if (clazz == float.class) + { + if (tagged) + os.writeByte(JdwpConstants.Tag.FLOAT); + os.writeFloat(((Float) obj).floatValue()); + } + else if (clazz == double.class) + { + if (tagged) + os.writeByte(JdwpConstants.Tag.DOUBLE); + os.writeDouble(((Double) obj).doubleValue()); + } + else if (clazz == int.class) + { + if (tagged) + os.writeByte(JdwpConstants.Tag.BYTE); + os.writeInt(((Integer) obj).intValue()); + } + else if (clazz == long.class) + { + if (tagged) + os.writeByte(JdwpConstants.Tag.LONG); + os.writeLong(((Long) obj).longValue()); + } + else if (clazz == short.class) + { + if (tagged) + os.writeByte(JdwpConstants.Tag.SHORT); + os.writeInt(((Short) obj).shortValue()); + } + else if (clazz == void.class) + { // A 'void' has no data + if (tagged) + os.writeByte(JdwpConstants.Tag.VOID); + } + else if (clazz == boolean.class) + { + if (tagged) + os.writeByte(JdwpConstants.Tag.BOOLEAN); + os.writeBoolean(((Boolean) obj).booleanValue()); + } + else + { // This shouldn't be possible + throw new JdwpInternalErrorException( + "Field has invalid primitive!"); + } + } + else + { + // Object is an Object, not a primitive type wrapped in an object + // Write the appropriate tag + if (tagged) + { + if (clazz.isArray()) + os.writeByte(JdwpConstants.Tag.ARRAY); + else if (obj instanceof String) + os.writeByte(JdwpConstants.Tag.STRING); + else if (obj instanceof Thread) + os.writeByte(JdwpConstants.Tag.THREAD); + else if (obj instanceof ThreadGroup) + os.writeByte(JdwpConstants.Tag.THREAD_GROUP); + else if (obj instanceof ClassLoader) + os.writeByte(JdwpConstants.Tag.CLASS_LOADER); + else if (obj instanceof Class) + os.writeByte(JdwpConstants.Tag.CLASS_OBJECT); + else + os.writeByte(JdwpConstants.Tag.OBJECT); + } + ObjectId oid = VMIdManager.getDefault().getObjectId(obj); + oid.write(os); + } + } + + /** + * Reads the appropriate object for the tagged value contained in the + * ByteBuffer. + * + * @param bb contains the Object + * @return The Object referenced by the value + * @throws JdwpException + * @throws IOException + */ + public static Object getObj(ByteBuffer bb) + throws JdwpException, IOException + { + return getUntaggedObj(bb, bb.get()); + } + + /** + * Reads the an object of the given Class from the untagged value contained + * in the ByteBuffer. + * + * @param bb contains the Object + * @param type corresponds to the TAG of value to be read + * @return + * @throws JdwpException + * @throws IOException + */ + public static Object getUntaggedObj(ByteBuffer bb, Class type) + throws JdwpException, IOException + { + if (type.isPrimitive()) + { + if (type == byte.class) + return new Byte(bb.get()); + else if (type == char.class) + return new Character(bb.getChar()); + else if (type == float.class) + return new Float(bb.getFloat()); + else if (type == double.class) + return new Double(bb.getDouble()); + else if (type == int.class) + return new Integer(bb.getInt()); + else if (type == long.class) + return new Long(bb.getLong()); + else if (type == short.class) + return new Short(bb.getShort()); + else if (type == boolean.class) + return (bb.get() == 0) ? new Boolean(false) : new Boolean(true); + else if (type == void.class) + return new byte[0]; + else + { // This shouldn't be possible + throw new JdwpInternalErrorException( + "Field has invalid primitive!"); + } + } + else + { + // Field is an object + ObjectId oid = VMIdManager.getDefault().readObjectId(bb); + return oid.getObject(); + } + } + + /** + * Reads the an object of the given Class from the untagged value contained + * in the ByteBuffer. + * + * @param bb contains the Object + * @param tag TAG of the Value to be read + * @return the object + * @throws JdwpException + * @throws IOException + */ + public static Object getUntaggedObj(ByteBuffer bb, byte tag) + throws JdwpException, IOException + { + switch (tag) + { + case JdwpConstants.Tag.BYTE: + return new Byte(bb.get()); + case JdwpConstants.Tag.CHAR: + return new Character(bb.getChar()); + case JdwpConstants.Tag.FLOAT: + return new Float(bb.getFloat()); + case JdwpConstants.Tag.DOUBLE: + return new Double(bb.getDouble()); + case JdwpConstants.Tag.INT: + return new Integer(bb.getInt()); + case JdwpConstants.Tag.LONG: + return new Long(bb.getLong()); + case JdwpConstants.Tag.SHORT: + return new Short(bb.getShort()); + case JdwpConstants.Tag.VOID: + return new byte[0]; + case JdwpConstants.Tag.BOOLEAN: + return (bb.get() == 0) ? new Boolean(false) : new Boolean(true); + case JdwpConstants.Tag.STRING: + return JdwpString.readString(bb); + case JdwpConstants.Tag.ARRAY: + case JdwpConstants.Tag.THREAD: + case JdwpConstants.Tag.OBJECT: + case JdwpConstants.Tag.THREAD_GROUP: + case JdwpConstants.Tag.CLASS_LOADER: + case JdwpConstants.Tag.CLASS_OBJECT: + // All these cases are ObjectIds + ObjectId oid = VMIdManager.getDefault().readObjectId(bb); + return oid.getObject(); + default: + throw new NotImplementedException("Tag " + tag + + " is not implemented."); + } + } +} diff --git a/libjava/classpath/gnu/classpath/jdwp/util/VariableTable.java b/libjava/classpath/gnu/classpath/jdwp/util/VariableTable.java new file mode 100644 index 00000000000..22d8c7dd621 --- /dev/null +++ b/libjava/classpath/gnu/classpath/jdwp/util/VariableTable.java @@ -0,0 +1,110 @@ +/* VariableTable.java -- A class representing a Variable Table for a method + Copyright (C) 2005 Free Software Foundation + +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 +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.classpath.jdwp.util; + +import java.io.DataOutputStream; +import java.io.IOException; + +/** + * A class representing a Variable Table for a method. + * + * @author Aaron Luchko <aluchko@redhat.com> + */ +public class VariableTable +{ + + private final long argCnt; + + private final long slots; + + private final long[] lineCI; + + private int[] slot; + + private int[] lengths; + + private String[] sigs; + + private String[] names; + + /** + * Make a new variable table with the given values. + * + * @param argCnt number of words used by arguments in this frame + * @param slots number of variables + * @param lineCI first code index of given variable (size slots) + * @param names name of given variable (size slots) + * @param sigs signature of given variable (size slots) + * @param lengths size of region where variable is active (size slots) + * @param slot index of variable in this frame (size slots) + */ + public VariableTable(int argCnt, int slots, long lineCI[], String names[], + String sigs[], int lengths[], int slot[]) + { + this.argCnt = argCnt; + this.slots = slots; + this.lineCI = lineCI; + this.names = names; + this.sigs = sigs; + this.lengths = lengths; + this.slot = slot; + } + + /** + * Writes this line table to the given DataOutputStream. + * + * @param os the stream to write it to + * @throws IOException + */ + public void write(DataOutputStream os) throws IOException + { + os.writeLong(argCnt); + os.writeLong(slots); + for (int i = 0; i < slots; i++) + { + os.writeLong(lineCI[i]); + JdwpString.writeString(os, names[i]); + JdwpString.writeString(os, sigs[i]); + os.writeInt(lengths[i]); + os.writeInt(slot[i]); + } + } + +} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkClipboardNotifier.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkClipboardNotifier.java new file mode 100644 index 00000000000..a470fe171b8 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkClipboardNotifier.java @@ -0,0 +1,112 @@ +/* GtkClipboardNotifier.java -- Helper for announcing GtkSelection changes. + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.awt.peer.gtk; + +import java.awt.datatransfer.*; + +class GtkClipboardNotifier extends Thread +{ + /** Whether or not to announce a GtkSelection change. */ + private static boolean announceChange; + + /** + * The one and only instance. All operations are synchronized on + * this. + */ + private static GtkClipboardNotifier notifier = new GtkClipboardNotifier(); + + /** + * Creates a deamon thread that monitors this for change + * announcements. + */ + private GtkClipboardNotifier() + { + super("GtkClipBoardNotifier"); + setDaemon(true); + start(); + } + + /** + * Notifies that a new GtkSelection has to be announced. + */ + static void announce() + { + synchronized (notifier) + { + announceChange = true; + notifier.notifyAll(); + } + } + + public void run() + { + final GtkClipboard clipboard = GtkClipboard.getInstance(); + while (true) + { + synchronized (this) + { + while (!announceChange) + { + try + { + this.wait(); + } + catch (InterruptedException ie) + { + // ignore + } + } + announceChange = false; + } + + // Do the actual announcement without the lock held. We will + // notice a new change after this notification has finished. + try + { + clipboard.setContents(new GtkSelection(), null); + } + catch (Throwable t) + { + // should never happen, but might if we have some faulty + // listener. + t.printStackTrace(); + } + } + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkSelection.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkSelection.java new file mode 100644 index 00000000000..08b6b66dd1f --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkSelection.java @@ -0,0 +1,664 @@ +/* GtkClipboard.java - Class representing gtk+ clipboard selection. + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.awt.peer.gtk; + +import gnu.classpath.Pointer; + +import java.awt.datatransfer.*; + +import java.io.*; +import java.net.*; +import java.util.*; + +import java.awt.Image; + +/** + * Class representing the gtk+ clipboard selection. This is used when + * another program owns the clipboard. Whenever the system clipboard + * selection changes we create a new instance to notify the program + * that the available flavors might have changed. When requested it + * (lazily) caches the targets, and (text, image, or files/uris) + * clipboard contents. + * + * XXX - should only cache when + * gdk_display_supports_selection_notification is true. + */ +public class GtkSelection implements Transferable +{ + /** + * Static lock used for requests of mimetypes and contents retrieval. + */ + static private Object requestLock = new Object(); + + /** + * Whether a request for mimetypes, text, images, uris or byte[] is + * currently in progress. Should only be tested or set with + * requestLock held. When true no other requests should be made till + * it is false again. + */ + private boolean requestInProgress; + + /** + * Indicates a requestMimeTypes() call was made and the + * corresponding mimeTypesAvailable() callback was triggered. + */ + private boolean mimeTypesDelivered; + + /** + * Set and returned by getTransferDataFlavors. Only valid when + * mimeTypesDelivered is true. + */ + private DataFlavor[] dataFlavors; + + /** + * Indicates a requestText() call was made and the corresponding + * textAvailable() callback was triggered. + */ + private boolean textDelivered; + + /** + * Set as response to a requestText() call and possibly returned by + * getTransferData() for text targets. Only valid when textDelivered + * is true. + */ + private String text; + + /** + * Indicates a requestImage() call was made and the corresponding + * imageAvailable() callback was triggered. + */ + private boolean imageDelivered; + + /** + * Set as response to a requestImage() call and possibly returned by + * getTransferData() for image targets. Only valid when + * imageDelivered is true and image is null. + */ + private Pointer imagePointer; + + /** + * Cached image value. Only valid when imageDelivered is + * true. Created from imagePointer. + */ + private Image image; + + /** + * Indicates a requestUris() call was made and the corresponding + * urisAvailable() callback was triggered. + */ + private boolean urisDelivered; + + /** + * Set as response to a requestURIs() call. Only valid when + * urisDelivered is true + */ + private List uris; + + /** + * Indicates a requestBytes(String) call was made and the + * corresponding bytesAvailable() callback was triggered. + */ + private boolean bytesDelivered; + + /** + * Set as response to a requestBytes(String) call. Only valid when + * bytesDelivered is true. + */ + private byte[] bytes; + + /** + * Should only be created by the GtkClipboard class. + */ + GtkSelection() + { + } + + /** + * Gets an array of mime-type strings from the gtk+ clipboard and + * transforms them into an array of DataFlavors. + */ + public DataFlavor[] getTransferDataFlavors() + { + DataFlavor[] result; + synchronized (requestLock) + { + // Did we request already and cache the result? + if (mimeTypesDelivered) + result = (DataFlavor[]) dataFlavors.clone(); + else + { + // Wait till there are no pending requests. + while (requestInProgress) + { + try + { + requestLock.wait(); + } + catch (InterruptedException ie) + { + // ignored + } + } + + // If nobody else beat us and cached the result we try + // ourselves to get it. + if (! mimeTypesDelivered) + { + requestInProgress = true; + requestMimeTypes(); + while (! mimeTypesDelivered) + { + try + { + requestLock.wait(); + } + catch (InterruptedException ie) + { + // ignored + } + } + requestInProgress = false; + } + result = dataFlavors; + if (! GtkClipboard.canCache) + { + dataFlavors = null; + mimeTypesDelivered = false; + } + requestLock.notifyAll(); + } + } + return result; + } + + /** + * Callback that sets the available DataFlavors[]. Note that this + * should not call any code that could need the main gdk lock. + */ + private void mimeTypesAvailable(String[] mimeTypes) + { + synchronized (requestLock) + { + if (mimeTypes == null) + dataFlavors = new DataFlavor[0]; + else + { + // Most likely the mimeTypes include text in which case we add an + // extra element. + ArrayList flavorsList = new ArrayList(mimeTypes.length + 1); + for (int i = 0; i < mimeTypes.length; i++) + { + try + { + if (mimeTypes[i] == GtkClipboard.stringMimeType) + { + // XXX - Fix DataFlavor.getTextPlainUnicodeFlavor() + // and also add it to the list. + flavorsList.add(DataFlavor.stringFlavor); + flavorsList.add(DataFlavor.plainTextFlavor); + } + else if (mimeTypes[i] == GtkClipboard.imageMimeType) + flavorsList.add(DataFlavor.imageFlavor); + else if (mimeTypes[i] == GtkClipboard.filesMimeType) + flavorsList.add(DataFlavor.javaFileListFlavor); + else + { + // We check the target to prevent duplicates + // of the "magic" targets above. + DataFlavor target = new DataFlavor(mimeTypes[i]); + if (! flavorsList.contains(target)) + flavorsList.add(target); + } + } + catch (ClassNotFoundException cnfe) + { + cnfe.printStackTrace(); + } + catch (NullPointerException npe) + { + npe.printStackTrace(); + } + } + + dataFlavors = new DataFlavor[flavorsList.size()]; + flavorsList.toArray(dataFlavors); + } + + mimeTypesDelivered = true; + requestLock.notifyAll(); + } + } + + /** + * Gets the available data flavors for this selection and checks + * that at least one of them is equal to the given DataFlavor. + */ + public boolean isDataFlavorSupported(DataFlavor flavor) + { + DataFlavor[] dfs = getTransferDataFlavors(); + for (int i = 0; i < dfs.length; i++) + if (flavor.equals(dfs[i])) + return true; + + return false; + } + + /** + * Helper method that tests whether we already have the text for the + * current gtk+ selection on the clipboard and if not requests it + * and waits till it is available. + */ + private String getText() + { + String result; + synchronized (requestLock) + { + // Did we request already and cache the result? + if (textDelivered) + result = text; + else + { + // Wait till there are no pending requests. + while (requestInProgress) + { + try + { + requestLock.wait(); + } + catch (InterruptedException ie) + { + // ignored + } + } + + // If nobody else beat us we try ourselves to get and + // caching the result. + if (! textDelivered) + { + requestInProgress = true; + requestText(); + while (! textDelivered) + { + try + { + requestLock.wait(); + } + catch (InterruptedException ie) + { + // ignored + } + } + requestInProgress = false; + } + result = text; + if (! GtkClipboard.canCache) + { + text = null; + textDelivered = false; + } + requestLock.notifyAll(); + } + } + return result; + } + + /** + * Callback that sets the available text on the clipboard. Note that + * this should not call any code that could need the main gdk lock. + */ + private void textAvailable(String text) + { + synchronized (requestLock) + { + this.text = text; + textDelivered = true; + requestLock.notifyAll(); + } + } + + /** + * Helper method that tests whether we already have an image for the + * current gtk+ selection on the clipboard and if not requests it + * and waits till it is available. + */ + private Image getImage() + { + Image result; + synchronized (requestLock) + { + // Did we request already and cache the result? + if (imageDelivered) + result = image; + else + { + // Wait till there are no pending requests. + while (requestInProgress) + { + try + { + requestLock.wait(); + } + catch (InterruptedException ie) + { + // ignored + } + } + + // If nobody else beat us we try ourselves to get and + // caching the result. + if (! imageDelivered) + { + requestInProgress = true; + requestImage(); + while (! imageDelivered) + { + try + { + requestLock.wait(); + } + catch (InterruptedException ie) + { + // ignored + } + } + requestInProgress = false; + } + if (imagePointer != null) + image = new GtkImage(imagePointer); + imagePointer = null; + result = image; + if (! GtkClipboard.canCache) + { + image = null; + imageDelivered = false; + } + requestLock.notifyAll(); + } + } + return result; + } + + /** + * Callback that sets the available image on the clipboard. Note + * that this should not call any code that could need the main gdk + * lock. Note that we get a Pointer to a GdkPixbuf which we cannot + * turn into a real GtkImage at this point. That will be done on the + * "user thread" in getImage(). + */ + private void imageAvailable(Pointer pointer) + { + synchronized (requestLock) + { + this.imagePointer = pointer; + imageDelivered = true; + requestLock.notifyAll(); + } + } + + /** + * Helper method that test whether we already have a list of + * URIs/Files and if not requests them and waits till they are + * available. + */ + private List getURIs() + { + List result; + synchronized (requestLock) + { + // Did we request already and cache the result? + if (urisDelivered) + result = uris; + else + { + // Wait till there are no pending requests. + while (requestInProgress) + { + try + { + requestLock.wait(); + } + catch (InterruptedException ie) + { + // ignored + } + } + + // If nobody else beat us we try ourselves to get and + // caching the result. + if (! urisDelivered) + { + requestInProgress = true; + requestURIs(); + while (! urisDelivered) + { + try + { + requestLock.wait(); + } + catch (InterruptedException ie) + { + // ignored + } + } + requestInProgress = false; + } + result = uris; + if (! GtkClipboard.canCache) + { + uris = null; + urisDelivered = false; + } + requestLock.notifyAll(); + } + } + return result; + } + + /** + * Callback that sets the available File list. Note that this should + * not call any code that could need the main gdk lock. + */ + private void urisAvailable(String[] uris) + { + synchronized (requestLock) + { + if (uris != null && uris.length != 0) + { + ArrayList list = new ArrayList(uris.length); + for (int i = 0; i < uris.length; i++) + { + try + { + URI uri = new URI(uris[i]); + if (uri.getScheme().equals("file")) + list.add(new File(uri)); + } + catch (URISyntaxException use) + { + } + } + this.uris = list; + } + + urisDelivered = true; + requestLock.notifyAll(); + } + } + + /** + * Helper method that requests a byte[] for the given target + * mime-type flavor and waits till it is available. Note that unlike + * the other get methods this one doesn't cache the result since + * there are possibly many targets. + */ + private byte[] getBytes(String target) + { + byte[] result; + synchronized (requestLock) + { + // Wait till there are no pending requests. + while (requestInProgress) + { + try + { + requestLock.wait(); + } + catch (InterruptedException ie) + { + // ignored + } + } + + // Request bytes and wait till they are available. + requestInProgress = true; + requestBytes(target); + while (! bytesDelivered) + { + try + { + requestLock.wait(); + } + catch (InterruptedException ie) + { + // ignored + } + } + result = bytes; + bytes = null; + bytesDelivered = false; + requestInProgress = false; + + requestLock.notifyAll(); + } + return result; + } + + /** + * Callback that sets the available byte array on the + * clipboard. Note that this should not call any code that could + * need the main gdk lock. + */ + private void bytesAvailable(byte[] bytes) + { + synchronized (requestLock) + { + this.bytes = bytes; + bytesDelivered = true; + requestLock.notifyAll(); + } + } + + public Object getTransferData(DataFlavor flavor) + throws UnsupportedFlavorException + { + // Note the fall throughs for the "magic targets" if they fail we + // try one more time through getBytes(). + if (flavor.equals(DataFlavor.stringFlavor)) + { + String text = getText(); + if (text != null) + return text; + } + + if (flavor.equals(DataFlavor.plainTextFlavor)) + { + String text = getText(); + if (text != null) + return new StringBufferInputStream(text); + } + + if (flavor.equals(DataFlavor.imageFlavor)) + { + Image image = getImage(); + if (image != null) + return image; + } + + if (flavor.equals(DataFlavor.javaFileListFlavor)) + { + List uris = getURIs(); + if (uris != null) + return uris; + } + + byte[] bytes = getBytes(flavor.getMimeType()); + if (bytes == null) + throw new UnsupportedFlavorException(flavor); + + if (flavor.isMimeTypeSerializedObject()) + { + try + { + ByteArrayInputStream bais = new ByteArrayInputStream(bytes); + ObjectInputStream ois = new ObjectInputStream(bais); + return ois.readObject(); + } + catch (IOException ioe) + { + ioe.printStackTrace(); + } + catch (ClassNotFoundException cnfe) + { + cnfe.printStackTrace(); + } + } + + if (flavor.isRepresentationClassInputStream()) + return new ByteArrayInputStream(bytes); + + // XXX, need some more conversions? + + throw new UnsupportedFlavorException(flavor); + } + + /* + * Requests text, Image or an byte[] for a particular target from the + * other application. These methods return immediately. When the + * content is available the contentLock will be notified through + * textAvailable, imageAvailable, urisAvailable or bytesAvailable and the + * appropriate field is set. + */ + private native void requestText(); + private native void requestImage(); + private native void requestURIs(); + private native void requestBytes(String target); + + /* Similar to the above but for requesting the supported targets. */ + private native void requestMimeTypes(); +} diff --git a/libjava/classpath/gnu/java/awt/peer/qt/MainQtThread.java b/libjava/classpath/gnu/java/awt/peer/qt/MainQtThread.java new file mode 100644 index 00000000000..fdd6da0a639 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/qt/MainQtThread.java @@ -0,0 +1,86 @@ +/* MainQtThread.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.qt; + +/** + * This Thread is the main Qt thread. + * + * It doesn't appear to do much here, since all custom code executed by + * this thread is injected into Qt's main event loop through the (native) + * MainThreadInterface class. + */ +public class MainQtThread extends Thread +{ + long QApplicationPointer; + long mainThreadInterface; + String theme; + private boolean running; + private boolean doublebuffer; + + public MainQtThread( String theme, boolean doublebuffer ) + { + this.theme = theme; + this.doublebuffer = doublebuffer; + running = false; + } + + public boolean isRunning() + { + return running; + } + + /** + * Creates the QApplication + */ + public native long init(String theme, boolean doublebuffer); + + /** + * Runs the QApplication (doesn't return.) + */ + public native void exec(long ptr); + + public void run() + { + QApplicationPointer = init(theme, doublebuffer); + running = true; + exec(QApplicationPointer); + } + +} + + diff --git a/libjava/classpath/gnu/java/awt/peer/qt/NativeWrapper.java b/libjava/classpath/gnu/java/awt/peer/qt/NativeWrapper.java new file mode 100644 index 00000000000..706e0df6c05 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/qt/NativeWrapper.java @@ -0,0 +1,43 @@ +/* NativeWrapper.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.qt; + +public class NativeWrapper +{ + protected long nativeObject; +} diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QMatrix.java b/libjava/classpath/gnu/java/awt/peer/qt/QMatrix.java new file mode 100644 index 00000000000..428cda17308 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/qt/QMatrix.java @@ -0,0 +1,73 @@ +/* QMatrix.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.qt; + +import java.awt.geom.AffineTransform; + +/** + * A simple wrapper class for a QMatrix, + * interfacing it to an AffineTransform. + */ +public class QMatrix extends NativeWrapper +{ + + public QMatrix( AffineTransform t ) + { + double[] matrix = new double[6]; + t.getMatrix( matrix ); + init( matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5] ); + } + + private native void init(double m00, double m10, double m01, double m11, + double m02, double m12 ); + + private native double[] getMatrix(); + + public AffineTransform getTransform() + { + return new AffineTransform( getMatrix() ); + } + + public native void dispose(); + + public void finalize() + { + dispose(); + } +} + diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QPainterPath.java b/libjava/classpath/gnu/java/awt/peer/qt/QPainterPath.java new file mode 100644 index 00000000000..8d176a15698 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/qt/QPainterPath.java @@ -0,0 +1,141 @@ +/* QPainterPath.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.qt; + +import java.awt.Shape; +import java.awt.geom.AffineTransform; +import java.awt.geom.PathIterator; +import java.awt.geom.GeneralPath; + +/** + * A simple wrapper class for a QPainterPath, + * createable from an AWT Shape + */ +public class QPainterPath extends NativeWrapper +{ + QPainterPath() + { + } + + public QPainterPath( Shape s ) + { + PathIterator pi = s.getPathIterator( new AffineTransform() ); + double[] coords = new double[6]; + + init( pi.getWindingRule() ); + + while( !pi.isDone() ) + { + switch( pi.currentSegment(coords) ) + { + case PathIterator.SEG_MOVETO: + moveTo( coords[0], coords[1] ); + break; + + case PathIterator.SEG_CLOSE: + close(); + break; + + case PathIterator.SEG_LINETO: + lineTo( coords[0], coords[1] ); + break; + + case PathIterator.SEG_QUADTO: + quadTo( coords[0], coords[1], coords[2], coords[3] ); + break; + + case PathIterator.SEG_CUBICTO: + cubicTo( coords[0], coords[1], + coords[2], coords[3], + coords[4], coords[5] ); + break; + } + pi.next(); + } + } + + /** + * Constructor for rectangles. + */ + public QPainterPath( double x, double y, double w, double h ) + { + init(PathIterator.WIND_EVEN_ODD); + moveTo( x, y ); + lineTo( x + w, y ); + lineTo( x + w, y + h ); + lineTo( x , y + h ); + lineTo( x, y ); + close(); + } + + /** + * Constructor for lines. + */ + public QPainterPath( double x1, double y1, double x2, double y2, boolean s ) + { + init(PathIterator.WIND_EVEN_ODD); + moveTo( x1, y1 ); + lineTo( x2, y2 ); + } + + /** + * Returns the QPainterPath as a GeneralPath + */ + public native GeneralPath getPath(); + + private native void init(int windingRule); + + private native void moveTo(double x, double y); + + private native void close(); + + private native void lineTo(double x, double y); + + private native void quadTo(double x1, double y1, double x2, double y2); + + private native void cubicTo(double x1, double y1, double x2, double y2, + double x3, double y3); + + public native void dispose(); + + public void finalize() + { + dispose(); + } +} + diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QPen.java b/libjava/classpath/gnu/java/awt/peer/qt/QPen.java new file mode 100644 index 00000000000..ec41015ed60 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/qt/QPen.java @@ -0,0 +1,71 @@ +/* QPen.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.qt; + +import java.awt.Stroke; +import java.awt.BasicStroke; + +/** + * A simple wrapper class for a QPen, + * interfacing it to an BasicStroke. + */ +public class QPen extends NativeWrapper +{ + + public QPen( Stroke stroke ) + { + if( !( stroke instanceof BasicStroke ) ) + throw new IllegalArgumentException("Not a basic stroke."); + + BasicStroke s = (BasicStroke)stroke; + if(s.getDashArray() != null) + throw new IllegalArgumentException("Can't handle dashed strokes."); + + init(s.getLineWidth(), s.getEndCap(), s.getLineJoin(), s.getMiterLimit()); + } + + private native void init(double width, int cap, int join, double miterlimit); + + public native void dispose(); + + public void finalize() + { + dispose(); + } +} + diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtAudioClip.java b/libjava/classpath/gnu/java/awt/peer/qt/QtAudioClip.java new file mode 100644 index 00000000000..43387acf6aa --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtAudioClip.java @@ -0,0 +1,110 @@ +/* QtAudioClip.java -- Qt implementation of the applet AudioClip interface + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.qt; + +import java.applet.AudioClip; +import java.awt.Toolkit; +import java.io.File; +import java.io.IOException; +import java.net.URL; + +/** + * Implementation of the applet AudioClip interface on a Qt + * QSound object. + */ +public class QtAudioClip extends NativeWrapper implements AudioClip +{ + private static Toolkit t = null; + + public QtAudioClip(String filename) + { + checkForQt(); + File f = new File(filename); + try + { + String fn = f.getCanonicalPath(); + loadClip( fn ); + } + catch(IOException e) + { + } + } + + public QtAudioClip(URL url) + { + + } + + private native void loadClip(String filename); + + private native void play(boolean looped); + + private native boolean isAvailable(); + + /** + * Checks that Qt and sound is available. + */ + private void checkForQt() + { + if( t == null ) + t = Toolkit.getDefaultToolkit(); + if( !( t instanceof QtToolkit) ) + throw new IllegalStateException("This requires Qt peers."); + } + + // *************** Public methods ******************* + + public void loop() + { + play( true ); + } + + public void play() + { + play( false ); + } + + public native void stop(); + + public native void dispose(); + + public void finalize() + { + dispose(); + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtButtonPeer.java b/libjava/classpath/gnu/java/awt/peer/qt/QtButtonPeer.java new file mode 100644 index 00000000000..629f4591117 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtButtonPeer.java @@ -0,0 +1,79 @@ +/* QtButtonPeer.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.qt; + +import java.awt.Button; +import java.awt.event.ActionEvent; +import java.awt.peer.ButtonPeer; + +public class QtButtonPeer extends QtComponentPeer implements ButtonPeer +{ + public QtButtonPeer( QtToolkit kit, Button owner ) + { + super( kit, owner ); + } + + public native void init(); + + protected void setup() + { + super.setup(); + setLabel( ((Button)owner).getLabel() ); + } + + /** + * Callback for button click events + */ + void fireClick(int modifiers) + { + ActionEvent e = new ActionEvent(owner, + ActionEvent.ACTION_PERFORMED, + ((Button)owner).getActionCommand(), + System.currentTimeMillis(), + modifiers); + QtToolkit.eventQueue.postEvent(e); + } + + // ************ Public methods ********************* + + public native void setLabel( String label ); +} + + + + diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtCanvasPeer.java b/libjava/classpath/gnu/java/awt/peer/qt/QtCanvasPeer.java new file mode 100644 index 00000000000..2367cd0662a --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtCanvasPeer.java @@ -0,0 +1,65 @@ +/* QtCanvasPeer.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.qt; + +import java.awt.Canvas; +import java.awt.Dimension; +import java.awt.peer.CanvasPeer; + +public class QtCanvasPeer extends QtComponentPeer implements CanvasPeer +{ + public QtCanvasPeer( QtToolkit kit, Canvas owner ) + { + super( kit, owner ); + } + + public native void init(); + + protected void setup() + { + super.setup(); + } + + /** + * Overloaded, because a Canvas doesn't have a preferred size. + */ + public Dimension getPreferredSize() + { + return owner.getSize(); + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtCheckboxPeer.java b/libjava/classpath/gnu/java/awt/peer/qt/QtCheckboxPeer.java new file mode 100644 index 00000000000..788e08ee12a --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtCheckboxPeer.java @@ -0,0 +1,114 @@ +/* QtCheckboxPeer.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.qt; + +import java.awt.Rectangle; +import java.awt.Checkbox; +import java.awt.CheckboxGroup; +import java.awt.event.ItemEvent; +import java.awt.peer.CheckboxPeer; +import java.util.WeakHashMap; + +public class QtCheckboxPeer extends QtComponentPeer implements CheckboxPeer +{ + private CheckboxGroup group; + + // Map QButtonGroup<->CheckboxGroup + private static WeakHashMap groupMap; + + static + { + groupMap = new WeakHashMap(); + } + + public QtCheckboxPeer( QtToolkit kit, Checkbox owner ) + { + super( kit, owner ); + } + + protected native void init(); + + protected void setup() + { + super.setup(); + setCheckboxGroup( ((Checkbox)owner).getCheckboxGroup() ); + setLabel( ((Checkbox)owner).getLabel() ); + setState( ((Checkbox)owner).getState() ); + } + + private void fireToggle(boolean checked) + { + if (group == null) + ((Checkbox)owner).setState( checked ); + else + if ( checked ) + group.setSelectedCheckbox((Checkbox)owner); + + int sel = checked ? ItemEvent.SELECTED : ItemEvent.DESELECTED; + ItemEvent e = new ItemEvent((Checkbox)owner, + ItemEvent.ITEM_STATE_CHANGED, + ((Checkbox)owner).getLabel(), + sel); + QtToolkit.eventQueue.postEvent(e); + } + + // ************ Public methods ********************* + + public void setCheckboxGroup( CheckboxGroup group ) + { + if(this.group == group) + return; + + // if we change from a checkbox to a radio button or vice versa + if((this.group == null) != (group == null)) + { + this.group = group; + callInit(); + setup(); + } + + this.group = group; + } + + public native void setLabel( String label ); + + public native void setState( boolean state ); + +} + + diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtChoicePeer.java b/libjava/classpath/gnu/java/awt/peer/qt/QtChoicePeer.java new file mode 100644 index 00000000000..30674b36eca --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtChoicePeer.java @@ -0,0 +1,95 @@ +/* QtChoicePeer.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.qt; + +import java.awt.Choice; +import java.awt.event.ItemEvent; +import java.awt.peer.ChoicePeer; + +public class QtChoicePeer extends QtComponentPeer implements ChoicePeer +{ + public QtChoicePeer( QtToolkit kit, Choice owner ) + { + super( kit, owner ); + } + + protected native void init(); + + protected void setup() + { + super.setup(); + + Choice c = (Choice) owner; + int n = c.getItemCount(); + for ( int i = 0; i < n ; i++ ) + add( c.getItem( i ), i ); + select( c.getSelectedIndex() ); + } + + private void fireChoice( int index ) + { + ((Choice)owner).select( index ); + ItemEvent e = new ItemEvent((Choice)owner, + ItemEvent.ITEM_STATE_CHANGED, + ((Choice)owner).getItem(index), + ItemEvent.SELECTED); + QtToolkit.eventQueue.postEvent(e); + } + + // ************ Public methods ********************* + + public native void add( String item, int index ); + + public void addItem( String item, int index ) + { + add(item, index); + } + + public native void remove( int index ); + + public void removeAll() + { + int n = ((Choice)owner).getItemCount(); + for (int i = 0; i < n; i++) + remove( i ); + } + + public native void select( int index ); +} + + diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtComponentGraphics.java b/libjava/classpath/gnu/java/awt/peer/qt/QtComponentGraphics.java new file mode 100644 index 00000000000..7395a8e6c81 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtComponentGraphics.java @@ -0,0 +1,124 @@ +/* QtComponentGraphics.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.qt; + +import java.awt.Color; +import java.awt.GraphicsConfiguration; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.Paint; + +/** + * QtComponentPainter is a Graphics2D context for painting directly to AWT + * components. They require an existing QPainter object (the one passed into + * the native paint method), and are created there (ONLY). + * + * Since this context does direct on-screen drawing it is NOT thread-safe, + * and should NOT be used outside the thread in which it was created. + * + * In other words, + * this is intended for use by QtComponentPeer.paintEvent() only. + * + */ +public class QtComponentGraphics extends QtGraphics +{ + private QtComponentPeer peer; + + /** + * Creates a new ComponentGraphics from an *existing* QPainter object. + * + * @param ptr the pointer to the QPainter object. + */ + public QtComponentGraphics(long ptr, QtComponentPeer component, + int x, int y, int w, int h) + { + nativeObject = ptr; + peer = component; + + Rectangle r = new Rectangle(x, y, w, h); + initialClip = r; + + setAlpha( 1.0 ); + Color c = component.owner.getBackground(); + if(c == null) + setBackground(Color.white); + else + setBackground( c ); + + c = component.owner.getForeground(); + if(c == null) + setColor( Color.black ); + else + setColor( c ); + setup(); + setClip( initialClip ); + } + + /** + * Copying constructor + */ + QtComponentGraphics( QtComponentGraphics g ) + { + super( g ); // Slalom is fun + } + + public Graphics create() + { + return new QtComponentGraphics( this ); + } + + /** + * This is a tricky one + */ + public void copyArea(int x, int y, int width, int height, + int dx, int dy) + { + // FIXME + } + + /** + * Returns the GraphicsConfiguration of the context component. + */ + public GraphicsConfiguration getDeviceConfiguration() + { + return peer.getGraphicsConfiguration(); + } +} + + diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtComponentPeer.java b/libjava/classpath/gnu/java/awt/peer/qt/QtComponentPeer.java new file mode 100644 index 00000000000..d5662a86169 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtComponentPeer.java @@ -0,0 +1,825 @@ +/* QtComponentPeer.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.qt; + +import java.awt.AWTEvent; +import java.awt.AWTException; +import java.awt.BufferCapabilities; +import java.awt.Component; +import java.awt.Container; +import java.awt.Color; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Image; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.KeyboardFocusManager; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Toolkit; +import java.awt.Window; +import java.awt.peer.ComponentPeer; +import java.awt.peer.ContainerPeer; +import java.awt.image.ColorModel; +import java.awt.image.VolatileImage; +import java.awt.image.ImageObserver; +import java.awt.image.ImageProducer; +import java.awt.event.ComponentEvent; // 100% +import java.awt.event.FocusEvent; // 100% +import java.awt.event.InputEvent; // (abstract) +import java.awt.event.KeyEvent; // 2/3 +import java.awt.event.MouseEvent; // 70%? +import java.awt.event.PaintEvent; // Yup. +import java.awt.event.WindowEvent; // 2/ 12 +import java.util.Timer; +import java.util.TimerTask; + +public class QtComponentPeer extends NativeWrapper implements ComponentPeer +{ + + /** + * Popup trigger button, may differ between platforms + */ + protected static final int POPUP_TRIGGER = 3; + + /** + * The toolkit which manufactured this peer. + */ + protected QtToolkit toolkit; + + /** + * The component which owns this peer. + */ + Component owner; + + /** + * Classpath updates our eventMask. + */ + private long eventMask; + + /** + * if the thing has mouse motion listeners or not. + */ + private boolean hasMotionListeners; + + /** + * The component's double buffer for off-screen drawing. + */ + protected QtImage backBuffer; + + protected long qtApp; + + private boolean settingUp; + + private boolean ignoreResize = false; + + QtComponentPeer( QtToolkit kit, Component owner ) + { + this.owner = owner; + this.toolkit = kit; + qtApp = QtToolkit.guiThread.QApplicationPointer; + nativeObject = 0; + synchronized(this) + { + callInit(); // Calls the init method FROM THE MAIN THREAD. + try + { + wait(); // Wait for the thing to be created. + } + catch(InterruptedException e) + { + } + } + setup(); + hasMotionListeners = false; + } + + protected native void callInit(); + + /** + * Init does the creation of native widgets, it is therefore + * called from the main thread. (the constructor waits for this to happen.) + */ + protected void init() + { + } + + protected void setup() + { + settingUp = true; + if (owner != null) + { + if (owner instanceof javax.swing.JComponent) + setBackground(owner.getBackground()); + else + owner.setBackground(getNativeBackground()); + + if (owner.getForeground() != null) + setForeground(owner.getForeground()); + else + setForeground( Color.black ); + + if (owner.getCursor() != null) + if (owner.getCursor().getType() != Cursor.DEFAULT_CURSOR) + setCursor(owner.getCursor()); + + if (owner.getFont() != null) + setFont(owner.getFont()); + + setEnabled( owner.isEnabled() ); + + backBuffer = null; + updateBounds(); + + setVisible( owner.isVisible() ); + QtToolkit.repaintThread.queueComponent(this); + } + settingUp = false; + } + + native void QtUpdate(); + native void QtUpdateArea( int x, int y, int w, int h ); + private synchronized native void disposeNative(); + private native void setGround( int r, int g, int b, boolean isForeground ); + private native void setBoundsNative( int x, int y, int width, int height ); + private native void setCursor( int ctype ); + private native Color getNativeBackground(); + private native void setFontNative( QtFontPeer fp ); + private native int whichScreen(); + private native void reparentNative( QtContainerPeer parent ); + private native void getLocationOnScreenNative( Point p ); + + private boolean drawableComponent() + { + return ((this instanceof QtContainerPeer && + !(this instanceof QtScrollPanePeer)) || + (this instanceof QtCanvasPeer)); + } + + void updateBounds() + { + Rectangle r = owner.getBounds(); + setBounds( r.x, r.y, r.width, r.height ); + } + + synchronized void updateBackBuffer(int width, int height) + { + if(width <= 0 || height <= 0) + return; + + if( !drawableComponent() && backBuffer == null) + return; + + if( backBuffer != null ) + { + if( width < backBuffer.width && height < backBuffer.height ) + return; + backBuffer.dispose(); + } + backBuffer = new QtImage(width, height); + } + + + // ************ Event methods ********************* + + /** + * Window closing event + */ + protected void closeEvent() + { + if (owner instanceof Window) + { + WindowEvent e = new WindowEvent((Window)owner, + WindowEvent.WINDOW_CLOSING); + QtToolkit.eventQueue.postEvent(e); + } + } + + protected void enterEvent(int modifiers, int x, int y, int dummy) + { + MouseEvent e = new MouseEvent(owner, + MouseEvent.MOUSE_ENTERED, + System.currentTimeMillis(), + (modifiers & 0x2FF), x, y, 0, false); + QtToolkit.eventQueue.postEvent(e); + } + + protected void focusInEvent() + { + FocusEvent e = new FocusEvent(owner, FocusEvent.FOCUS_GAINED); + QtToolkit.eventQueue.postEvent(e); + } + + protected void focusOutEvent() + { + FocusEvent e = new FocusEvent(owner, FocusEvent.FOCUS_LOST); + QtToolkit.eventQueue.postEvent(e); + } + + protected void keyPressEvent(int modifiers, int code, int unicode, int dummy) + { + KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager (); + KeyEvent e = new KeyEvent(owner, + KeyEvent.KEY_PRESSED, + System.currentTimeMillis(), + modifiers, code, (char)(unicode & 0xFFFF), + KeyEvent.KEY_LOCATION_UNKNOWN); + if (!manager.dispatchEvent (e)) + QtToolkit.eventQueue.postEvent(e); + } + + protected void keyReleaseEvent(int modifiers, int code, int unicode, int dummy) + { + KeyEvent e = new KeyEvent(owner, + KeyEvent.KEY_RELEASED, + System.currentTimeMillis(), + modifiers, code, (char)(unicode & 0xFFFF), + KeyEvent.KEY_LOCATION_UNKNOWN); + QtToolkit.eventQueue.postEvent(e); + } + + protected void leaveEvent(int modifiers, int x, int y, int dummy) + { + MouseEvent e = new MouseEvent(owner, + MouseEvent.MOUSE_EXITED, + System.currentTimeMillis(), + (modifiers & 0x2FF), x, y, 0, false); + QtToolkit.eventQueue.postEvent(e); + } + + // FIXME: Coalesce press-release events into clicks. + protected void mouseDoubleClickEvent( int modifiers, int x, int y, int clickCount) + { + if( (eventMask & AWTEvent.MOUSE_EVENT_MASK) == 0 ) + return; + int button = 0; + if((modifiers & InputEvent.BUTTON1_DOWN_MASK) == + InputEvent.BUTTON1_DOWN_MASK) button = 1; + if((modifiers & InputEvent.BUTTON2_DOWN_MASK) == + InputEvent.BUTTON2_DOWN_MASK) button = 2; + if((modifiers & InputEvent.BUTTON3_DOWN_MASK) == + InputEvent.BUTTON3_DOWN_MASK) button = 3; + MouseEvent e = new MouseEvent(owner, + MouseEvent.MOUSE_CLICKED, + System.currentTimeMillis(), + (modifiers & 0x2FF), x, y, clickCount, + false, button); + QtToolkit.eventQueue.postEvent(e); + } + + protected void mouseMoveEvent( int modifiers, int x, int y, int clickCount) + { + if( (eventMask & AWTEvent.MOUSE_EVENT_MASK) == 0 ) + return; + + int button = 0; + if((modifiers & InputEvent.BUTTON1_DOWN_MASK) == + InputEvent.BUTTON1_DOWN_MASK) button = 1; + if((modifiers & InputEvent.BUTTON2_DOWN_MASK) == + InputEvent.BUTTON2_DOWN_MASK) button = 2; + if((modifiers & InputEvent.BUTTON3_DOWN_MASK) == + InputEvent.BUTTON3_DOWN_MASK) button = 3; + + int type = (button != 0) ? + MouseEvent.MOUSE_DRAGGED :MouseEvent.MOUSE_MOVED; + + MouseEvent e = new MouseEvent(owner, + type, + System.currentTimeMillis(), + (modifiers & 0x2FF), x, y, clickCount, + false, button); + QtToolkit.eventQueue.postEvent(e); + } + + protected void mousePressEvent( int modifiers, int x, int y, int clickCount) + { + if( (eventMask & AWTEvent.MOUSE_EVENT_MASK) == 0 ) + return; + int button = 0; + if((modifiers & InputEvent.BUTTON1_DOWN_MASK) == + InputEvent.BUTTON1_DOWN_MASK) button = 1; + if((modifiers & InputEvent.BUTTON2_DOWN_MASK) == + InputEvent.BUTTON2_DOWN_MASK) button = 2; + if((modifiers & InputEvent.BUTTON3_DOWN_MASK) == + InputEvent.BUTTON3_DOWN_MASK) button = 3; + MouseEvent e = new MouseEvent(owner, + MouseEvent.MOUSE_PRESSED, + System.currentTimeMillis(), + (modifiers & 0x2FF), x, y, clickCount, + ( button == POPUP_TRIGGER ), + button); + QtToolkit.eventQueue.postEvent(e); + } + + protected void mouseReleaseEvent( int modifiers, int x, int y, int clickCount) + { + if( (eventMask & AWTEvent.MOUSE_EVENT_MASK) == 0 ) + return; + int button = 0; + if((modifiers & InputEvent.BUTTON1_DOWN_MASK) == + InputEvent.BUTTON1_DOWN_MASK) button = 1; + if((modifiers & InputEvent.BUTTON2_DOWN_MASK) == + InputEvent.BUTTON2_DOWN_MASK) button = 2; + if((modifiers & InputEvent.BUTTON3_DOWN_MASK) == + InputEvent.BUTTON3_DOWN_MASK) button = 3; + + MouseEvent e = new MouseEvent(owner, + MouseEvent.MOUSE_RELEASED, + System.currentTimeMillis(), + (modifiers & 0x2FF), x, y, clickCount, + false, button); + QtToolkit.eventQueue.postEvent(e); + } + + protected void moveEvent(int x, int y, int oldx, int oldy) + { + if( !ignoreResize ) + { + // Since Component.setLocation calls back to setBounds, + // we need to ignore that. + ignoreResize = true; + owner.setLocation( x, y ); + ignoreResize = false; + } + } + + protected void resizeEvent(int oldWidth, int oldHeight, + int width, int height) + { + if(!(owner instanceof Window)) + return; + updateBackBuffer(width, height); + ignoreResize = true; + owner.setSize(width, height); + ignoreResize = false; + ComponentEvent e = new ComponentEvent(owner, + ComponentEvent.COMPONENT_RESIZED); + QtToolkit.eventQueue.postEvent(e); + QtToolkit.repaintThread.queueComponent(this); + } + + protected void showEvent() + { + if (owner instanceof Window) + { + WindowEvent e = new WindowEvent((Window)owner, + WindowEvent.WINDOW_OPENED); + QtToolkit.eventQueue.postEvent(e); + } + else + { + ComponentEvent e = new ComponentEvent(owner, + ComponentEvent.COMPONENT_SHOWN); + QtToolkit.eventQueue.postEvent(e); + } + } + + protected void hideEvent() + { + ComponentEvent e = new ComponentEvent(owner, + ComponentEvent.COMPONENT_HIDDEN); + QtToolkit.eventQueue.postEvent(e); + } + + // ************ Public methods ********************* + + /** Classpath-specific method */ + public void setEventMask(long x) + { + eventMask = x; + } + + + public boolean canDetermineObscurity() + { + return true; + } + + public int checkImage(Image img, + int w, + int h, + ImageObserver o) + { + return toolkit.checkImage(img, w, h, o); + } + + public void createBuffers(int numBuffers, BufferCapabilities caps) + throws AWTException + { + // FIXME + } + + public Image createImage(ImageProducer producer) + { + return toolkit.createImage(producer); + } + + public Image createImage(int width, int height) + { + return new QtImage(width, height); + } + + public void coalescePaintEvent(PaintEvent e) + { + // FIXME + } + + public VolatileImage createVolatileImage(int w, int h) + { + return new QtVolatileImage( w, h ); + } + + public void destroyBuffers() + { + // FIXME + } + + public void disable() + { + setEnabled(false); + } + + public void dispose() + { + disposeNative(); + if( backBuffer != null ) + backBuffer.dispose(); + } + + public void enable() + { + setEnabled(true); + } + + public void finalize() + { + dispose(); + } + + public void flip(BufferCapabilities.FlipContents contents) + { + } + + public Image getBackBuffer() + { + return backBuffer; + } + + public ColorModel getColorModel() + { + return toolkit.getColorModel(); + } + + public FontMetrics getFontMetrics(Font font) + { + return new QtFontMetrics( font, getGraphics() ); + } + + public Graphics getGraphics() + { + if( backBuffer == null ) + { + Rectangle r = owner.getBounds(); + backBuffer = new QtImage( r.width, r.height ); + } + return backBuffer.getDirectGraphics( this ); + } + + public GraphicsConfiguration getGraphicsConfiguration() + { + int id = whichScreen(); // get the ID of the screen the widget is on. + GraphicsDevice[] devs = QtToolkit.graphicsEnv.getScreenDevices(); + return devs[id].getDefaultConfiguration(); + } + + public Point getLocationOnScreen() + { + Point p = new Point(); + synchronized( p ) + { + getLocationOnScreenNative( p ); + try + { + p.wait(); // Wait for the thing to be created. + } + catch(InterruptedException e) + { + } + } + return p; + } + + private native void getSizeNative(Dimension d, boolean preferred); + + private Dimension getSize(boolean preferred) + { + Dimension d = new Dimension(); + synchronized( d ) + { + getSizeNative(d, preferred); + try + { + d.wait(); // Wait for the thing to be created. + } + catch(InterruptedException e) + { + } + } + return d; + } + + public Dimension getMinimumSize() + { + return getSize( false ); + } + + public Dimension getPreferredSize() + { + return getSize( true ); + } + + public Toolkit getToolkit() + { + return toolkit; + } + + public native boolean handlesWheelScrolling(); + + public void hide() + { + setVisible(false); + } + + public native boolean isFocusable(); + + public boolean isFocusTraversable() + { + // FIXME + return false; + } + + public native boolean isObscured(); + + public Dimension minimumSize() + { + return getMinimumSize(); + } + + public Dimension preferredSize() + { + return getPreferredSize(); + } + + public native void requestFocus(); + + public boolean requestFocus (Component source, boolean bool1, + boolean bool2, long x) + { + // FIXME + return true; + } + + public void reshape(int x, + int y, + int width, + int height) + { + setBounds( x, y, width, height ); + } + + public void setBackground(Color c) + { + if(c == null && !settingUp) + return; + setGround(c.getRed(), c.getGreen(), c.getBlue(), false); + } + + public void setBounds(int x, int y, int width, int height) + { + if( ignoreResize ) + return; + updateBackBuffer(width, height); + QtToolkit.repaintThread.queueComponent(this); + setBoundsNative(x, y, width, height); + } + + public void setCursor(Cursor cursor) + { + if (cursor != null) + setCursor(cursor.getType()); + } + + public native void setEnabled(boolean b); + + public void setFont(Font f) + { + if( f == null || f.getPeer() == null) + throw new IllegalArgumentException("Null font."); + setFontNative( (QtFontPeer)f.getPeer() ); + } + + public void setForeground(Color c) + { + if(c == null && !settingUp) + return; + setGround(c.getRed(), c.getGreen(), c.getBlue(), true); + } + + public native void setVisible(boolean b); + + public void show() + { + setVisible(true); + } + + public void handleEvent (AWTEvent e) + { + int eventID = e.getID(); + Rectangle r; + + switch (eventID) + { + case ComponentEvent.COMPONENT_SHOWN: + QtToolkit.repaintThread.queueComponent(this); + break; + case PaintEvent.PAINT: + case PaintEvent.UPDATE: + r = ((PaintEvent)e).getUpdateRect(); + QtToolkit.repaintThread.queueComponent(this, r.x, r.y, + r.width, r.height); + break; + case KeyEvent.KEY_PRESSED: + break; + case KeyEvent.KEY_RELEASED: + break; + } + } + + /** + * paint() is called back from the native side in response to a native + * repaint event. + */ + public void paint(Graphics g) + { + Rectangle r = g.getClipBounds(); + + if (backBuffer != null) + backBuffer.drawPixelsScaledFlipped ((QtGraphics) g, + 0, 0, 0, /* bg colors */ + false, false, /* no flipping */ + r.x, r.y, r.width, r.height, + r.x, r.y, r.width, r.height, + false ); /* no compositing */ + } + + public void paintBackBuffer() throws InterruptedException + { + if( backBuffer != null ) + { + backBuffer.clear(); + Graphics2D bbg = (Graphics2D)backBuffer.getGraphics(); + owner.paint(bbg); + bbg.dispose(); + } + } + + public void paintBackBuffer(int x, int y, int w, int h) + throws InterruptedException + { + if( backBuffer != null ) + { + Graphics2D bbg = (Graphics2D)backBuffer.getGraphics(); + bbg.setBackground( getNativeBackground() ); + bbg.clearRect(x, y, w, h); + bbg.setClip(x, y, w, h); + owner.paint(bbg); + bbg.dispose(); + } + } + + public boolean prepareImage(Image img, + int w, + int h, + ImageObserver o) + { + return toolkit.prepareImage(img, w, h, o); + } + + public void print(Graphics g) + { + // FIXME + } + + /** + * Schedules a timed repaint. + */ + public void repaint(long tm, + int x, + int y, + int w, + int h) + { + if( tm <= 0 ) + { + QtToolkit.repaintThread.queueComponent(this, x, y, w, h); + return; + } + Timer t = new Timer(); + t.schedule(new RepaintTimerTask(this, x, y, w, h), tm); + } + + /** + * Update the cursor (note that setCursor is usually not called) + */ + public void updateCursorImmediately() + { + if (owner.getCursor() != null) + setCursor(owner.getCursor().getType()); + } + + /** + * Timed repainter + */ + private class RepaintTimerTask extends TimerTask + { + private int x, y, w, h; + private QtComponentPeer peer; + RepaintTimerTask(QtComponentPeer peer, int x, int y, int w, int h) + { + this.x=x; + this.y=y; + this.w=w; + this.h=h; + this.peer=peer; + } + public void run() + { + QtToolkit.repaintThread.queueComponent(peer, x, y, w, h); + } + } + + public native Rectangle getBounds(); + + public void reparent(ContainerPeer parent) + { + if(!(parent instanceof QtContainerPeer)) + throw new IllegalArgumentException("Illegal peer."); + reparentNative((QtContainerPeer)parent); + } + + public void setBounds(int x, int y, int width, int height, int z) + { + // TODO Auto-generated method stub + + } + + public boolean isReparentSupported() + { + return true; + } + + // What does this do, anyway? + public void layout() + { + // TODO Auto-generated method stub + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtContainerPeer.java b/libjava/classpath/gnu/java/awt/peer/qt/QtContainerPeer.java new file mode 100644 index 00000000000..3782d781597 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtContainerPeer.java @@ -0,0 +1,116 @@ +/* QtContainerPeer.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.qt; + +import java.awt.Container; +import java.awt.Component; +import java.awt.Insets; +import java.awt.peer.ContainerPeer; + +public class QtContainerPeer extends QtComponentPeer implements ContainerPeer +{ + public QtContainerPeer( QtToolkit kit, Component owner ) + { + super( kit, owner ); + } + + protected void init() + { + } + + protected void setup() + { + super.setup(); + } + + // ************ Public methods ********************* + public void beginLayout() + { + // FIXME + } + + public void beginValidate() + { + } + + public void endLayout() + { + QtUpdate(); + } + + public void endValidate() + { + } + + public Insets getInsets() + { + return new Insets(0, 0, 0, 0); + } + + public Insets insets() + { + return getInsets(); + } + + public boolean isPaintPending() + { + // FIXME etc. + return false; + } + + public boolean isRestackSupported() + { + // TODO Auto-generated method stub + return false; + } + + public void cancelPendingPaint(int x, int y, int width, int height) + { + // TODO Auto-generated method stub + + } + + public void restack() + { + // TODO Auto-generated method stub + + } +} + + + diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtDialogPeer.java b/libjava/classpath/gnu/java/awt/peer/qt/QtDialogPeer.java new file mode 100644 index 00000000000..0da2e4ebc95 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtDialogPeer.java @@ -0,0 +1,75 @@ +/* QtDialogPeer.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.qt; + +import java.awt.Dialog; +import java.awt.MenuBar; +import java.awt.Rectangle; +import java.awt.peer.DialogPeer; + +public class QtDialogPeer extends QtWindowPeer implements DialogPeer +{ + public QtDialogPeer( QtToolkit kit, Dialog owner ) + { + super( kit, owner ); + } + + protected native void init(); + + protected void setup() + { + super.setup(); + setTitle( ((Dialog)owner).getTitle() ); + setResizable( ((Dialog)owner).isResizable() ); + setModal( ((Dialog)owner).isModal() ); + } + + native void setModal(boolean modal); + + private native void setBoundsNative(int x, int y, int width, int height, boolean fixed); + + // ************ Public methods ********************* + + public native void setResizable (boolean resizeable); + + public void setBounds(int x, int y, int width, int height) + { + setBoundsNative(x, y, width, height, + !((Dialog)owner).isResizable()); + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtEmbeddedWindowPeer.java b/libjava/classpath/gnu/java/awt/peer/qt/QtEmbeddedWindowPeer.java new file mode 100644 index 00000000000..cac12b91a99 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtEmbeddedWindowPeer.java @@ -0,0 +1,65 @@ +/* QtEmbeddedWindowPeer.java -- embedded window peer + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.qt; + +import java.awt.Component; +import java.awt.peer.WindowPeer; +import gnu.java.awt.peer.EmbeddedWindowPeer; + +/** + * Embedded window peer for applets. + * FIXME: EmbeddedWindowPeer and this class should extend Window, NOT Frame. + */ +public class QtEmbeddedWindowPeer extends QtFramePeer implements EmbeddedWindowPeer +{ + public QtEmbeddedWindowPeer( QtToolkit kit, Component owner ) + { + super( kit, owner ); + } + + protected native void init(); + + protected void setup() + { + super.setup(); + } + + // ************ Public methods ********************* + + public native void embed( long handle ); +} diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtFileDialogPeer.java b/libjava/classpath/gnu/java/awt/peer/qt/QtFileDialogPeer.java new file mode 100644 index 00000000000..4937031aa05 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtFileDialogPeer.java @@ -0,0 +1,84 @@ +/* QtFileDialogPeer.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.qt; + +import java.awt.FileDialog; +import java.io.FilenameFilter; +import java.awt.peer.FileDialogPeer; + +public class QtFileDialogPeer extends QtDialogPeer implements FileDialogPeer +{ + public QtFileDialogPeer( QtToolkit kit, FileDialog owner ) + { + super( kit, owner ); + } + + protected native void init(); + + protected void setup() + { + super.setup(); + setMode( ((FileDialog)owner).getMode() ); + } + + /** + * Sets load or save mode + */ + private native void setMode(int mode); + + private void fileDialogDone(String path, String filename) + { + } + + // ************ Public methods ********************* + public void setFile (String file) + { + // FIXME + } + + public void setDirectory (String dir) + { + // FIXME + } + + public void setFilenameFilter (FilenameFilter ff) + { + // FIXME + } +} + diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtFontMetrics.java b/libjava/classpath/gnu/java/awt/peer/qt/QtFontMetrics.java new file mode 100644 index 00000000000..e403239e9e9 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtFontMetrics.java @@ -0,0 +1,128 @@ +/* QtFontMetrics.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.qt; + +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.geom.Rectangle2D; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphVector; +import java.awt.font.LineMetrics; + +public class QtFontMetrics extends FontMetrics +{ + + private long nativeObject; + private QtFontPeer peer; + + public QtFontMetrics( Font f ) + { + super( f ); + if(f.getPeer() == null || !(f.getPeer() instanceof QtFontPeer)) + throw new IllegalArgumentException("Invalid Font object."); + peer = (QtFontPeer) f.getPeer(); + init( peer ); + } + + public QtFontMetrics( Font f, Graphics g ) + { + super( f ); + if(f.getPeer() == null || !(f.getPeer() instanceof QtFontPeer)) + throw new IllegalArgumentException("Invalid Font object."); + if( !(g instanceof QtGraphics) ) + throw new IllegalArgumentException("Invalid graphics object."); + peer = (QtFontPeer) f.getPeer(); + initGraphics(peer, (QtGraphics)g ); + } + + QtFontMetrics( QtFontPeer f, Graphics g ) + { + super( null ); + if( !(g instanceof QtGraphics) ) + throw new IllegalArgumentException("Invalid graphics object."); + peer = f; + initGraphics(peer, (QtGraphics)g ); + } + + public QtFontMetrics( QtFontPeer fp ) + { + super( (Font)null ); + peer = fp; + init( peer ); + } + + private native void init(QtFontPeer fp); + + private native void initGraphics(QtFontPeer fp, QtGraphics g); + + private native void dispose(); + + native Rectangle2D getStringBounds(String s); + + // ****************** Package private *************************** + + native boolean canDisplay( char c ); + + // ****************** Public methods **************************** + + public native int getAscent(); + + public native int getDescent(); + + public native int getHeight(); + + public native int getLeading(); + + public native int getMaxAdvance(); + + public native int charWidth(char c); + + public int charsWidth(char[] chars, int off, int len) + { + return stringWidth( new String(chars, off, len) ); + } + + public native int stringWidth(String str); + + public Rectangle2D getStringBounds(String str, Graphics context) + { + QtFontMetrics fm = new QtFontMetrics(peer, context); + return fm.getStringBounds( str ); + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtFontPeer.java b/libjava/classpath/gnu/java/awt/peer/qt/QtFontPeer.java new file mode 100644 index 00000000000..ee88c7dd5d0 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtFontPeer.java @@ -0,0 +1,209 @@ +/* QtFontPeer.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.qt; + +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.geom.Rectangle2D; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphVector; +import java.awt.font.LineMetrics; +import java.text.CharacterIterator; +import java.util.Locale; +import java.util.Map; +import java.awt.peer.FontPeer; + +import gnu.java.awt.peer.ClasspathFontPeer; + +public class QtFontPeer extends ClasspathFontPeer +{ + // Pointer to native QFont structure. + private long nativeObject; + private QtFontMetrics metrics; + + + public QtFontPeer (String name, int style) + { + this(name, style, 12); + } + + public QtFontPeer (String name, int style, int size) + { + super(name, style, size); + init(); + } + + public QtFontPeer (String name, Map attributes) + { + super(name, attributes); + init(); + } + + public void init() + { + if(this.familyName == null) + throw new IllegalArgumentException("null family name"); + if(this.familyName.equals("Helvetica")) + this.familyName = "sans serif"; + if(this.familyName.equals("Dialog")) + this.familyName = "sans serif"; + create(this.familyName, this.style, (int)this.size); + metrics = new QtFontMetrics(this); + } + + /** + * Creates the QFont object. + */ + private native void create(String name, int style, int size); + + /** + * Destroys the QFont. + */ + public native void dispose(); + + + // ****************** ClasspathFontPeer Methods. + + public boolean canDisplay (Font font, char c) + { + return metrics.canDisplay( c ); + } + + public int canDisplayUpTo (Font font, CharacterIterator i, + int start, int limit) + { + int index = start; + char c = i.setIndex( index ); + while( index <= limit ) + { + if(!canDisplay(font, c)) + return index; + index++; + c = i.next(); + } + return -1; + } + + public String getSubFamilyName (Font font, Locale locale) + { + throw new UnsupportedOperationException(); + } + + public String getPostScriptName (Font font) + { + throw new UnsupportedOperationException(); + } + + public int getNumGlyphs (Font font) + { + throw new UnsupportedOperationException(); + } + + public int getMissingGlyphCode (Font font) + { + throw new UnsupportedOperationException(); + } + + public byte getBaselineFor (Font font, char c) + { + throw new UnsupportedOperationException(); + } + + public String getGlyphName (Font font, int glyphIndex) + { + throw new UnsupportedOperationException(); + } + + public GlyphVector createGlyphVector (Font font, + FontRenderContext frc, + CharacterIterator ci) + { + throw new UnsupportedOperationException(); + } + + public GlyphVector createGlyphVector (Font font, + FontRenderContext ctx, + int[] glyphCodes) + { + throw new UnsupportedOperationException(); + } + + public GlyphVector layoutGlyphVector (Font font, + FontRenderContext frc, + char[] chars, int start, + int limit, int flags) + { + throw new UnsupportedOperationException(); + } + + public FontMetrics getFontMetrics (Font font) + { + return new QtFontMetrics( this ); + } + + public boolean hasUniformLineMetrics (Font font) + { + throw new UnsupportedOperationException(); + } + + public LineMetrics getLineMetrics (Font font, + CharacterIterator ci, + int begin, int limit, + FontRenderContext rc) + { + throw new UnsupportedOperationException(); + } + + public Rectangle2D getMaxCharBounds (Font font, + FontRenderContext rc) + { + throw new UnsupportedOperationException(); + } + + public Rectangle2D getStringBounds (Font font, + CharacterIterator ci, + int begin, int limit, + FontRenderContext frc) + { + int index = begin; + String s = "" + ci.setIndex( index ); + while( index++ <= limit ) + s = s + ci.next(); + return metrics.getStringBounds(s); + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtFramePeer.java b/libjava/classpath/gnu/java/awt/peer/qt/QtFramePeer.java new file mode 100644 index 00000000000..b2c6a5921cb --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtFramePeer.java @@ -0,0 +1,158 @@ +/* QtFramePeer.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.qt; + +import java.awt.Component; +import java.awt.Frame; +import java.awt.Image; +import java.awt.Insets; +import java.awt.MenuBar; +import java.awt.Rectangle; +import java.awt.peer.FramePeer; + +public class QtFramePeer extends QtWindowPeer implements FramePeer +{ + private int theState; // FIXME + + long frameObject; + + public QtFramePeer( QtToolkit kit, Component owner ) + { + super( kit, owner ); + } + + protected native void init(); + + protected void setup() + { + super.setup(); + setTitle( ((Frame)owner).getTitle() ); + if( ((Frame)owner).getMenuBar() != null ) + setMenuBar( ((Frame)owner).getMenuBar() ); + } + + private native void setIcon(QtImage image); + + private native void setMaximizedBounds(int w, int h); + + private native void setMenu(QtMenuBarPeer mb); + + private native int menuBarHeight(); + + // ************ Public methods ********************* + + public void destroy() + { + dispose(); + } + + public int getState() + { + // FIXME + return theState; + } + + public Insets getInsets() + { + int mbHeight = ( ((Frame)owner).getMenuBar() != null ) ? + menuBarHeight() : 0; + return new Insets(mbHeight, 0, 0, 0); + } + + public void setIconImage(Image im) + { + if (im instanceof QtImage) + setIcon( (QtImage)im ); + else + setIcon( new QtImage( im.getSource() ) ); + } + + public void setMaximizedBounds(Rectangle rect) + { + // FIXME + } + + public void setMenuBar(MenuBar mb) + { + if( mb != null ) + { + QtMenuBarPeer mbpeer = (QtMenuBarPeer)mb.getPeer(); + if( mbpeer == null ) + { + mb.addNotify(); + mbpeer = (QtMenuBarPeer)mb.getPeer(); + if( mbpeer == null ) + throw new IllegalStateException("No menu bar peer."); + } + mbpeer.addMenus(); + setMenu( mbpeer ); + } + else + setMenu( null ); + } + + public void setResizable(boolean resizeable) + { + // FIXME + } + + public void setState(int s) + { + theState = s; + // FIXME + } + + public void setBoundsPrivate(int x, int y, int width, int height) + { + // TODO Auto-generated method stub + + } + + public void updateAlwaysOnTop() + { + // TODO Auto-generated method stub + + } + + public boolean requestWindowFocus() + { + // TODO Auto-generated method stub + return false; + } + +} diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtGraphics.java b/libjava/classpath/gnu/java/awt/peer/qt/QtGraphics.java new file mode 100644 index 00000000000..f9b4f26729f --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtGraphics.java @@ -0,0 +1,706 @@ +/* QtGraphics.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.qt; + +import java.awt.AlphaComposite; +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Composite; +import java.awt.GradientPaint; +import java.awt.GraphicsConfiguration; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.RenderingHints; +import java.awt.Rectangle; +import java.awt.Paint; +import java.awt.Polygon; +import java.awt.Shape; +import java.awt.Stroke; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphVector; +import java.awt.geom.AffineTransform; +import java.awt.geom.PathIterator; +import java.awt.geom.Arc2D; +import java.awt.geom.Ellipse2D; +import java.awt.geom.Line2D; +import java.awt.geom.Rectangle2D; +import java.awt.geom.RoundRectangle2D; +import java.awt.image.BufferedImage; +import java.awt.image.BufferedImageOp; +import java.awt.image.ImageObserver; +import java.awt.image.RenderedImage; +import java.awt.image.renderable.RenderableImage; + +import java.text.AttributedCharacterIterator; +import java.text.CharacterIterator; +import java.util.Map; + +/** + * QtGraphics is an abstract implementation of Graphics2D over a QPainter + * object. This is to be subclassed for different drawing contexts, + * which may have different requirements. + */ +public abstract class QtGraphics extends Graphics2D +{ + /** + * Native QPainter pointer. + */ + protected long nativeObject; + + private static final AffineTransform identity = new AffineTransform(); + + // Graphics state + protected Font font; // Current font. + protected Color color, bgcolor; // Current color and background color. + protected Shape clip; // Current clipping area. + protected Shape initialClip; // Initial clip bounds + protected AffineTransform xform; // Current transform + protected Stroke currentStroke; // the current stroke + protected boolean nativeStroking; // whether we're using Qt's stroking or not + protected Composite composite; // current composite operator + protected double currentAlpha; // current alpha + protected Paint currentPaint; // current paint + protected RenderingHints renderingHints; // the rendering hints. + + /** + * Owner Graphics, used by subcontext created by create() + * to avoid GC of the original context. + */ + Graphics parent; + + /** + * Do-nothing constructor. + */ + QtGraphics() + { + } + + /** + * Copying constructor - used by copy() and subclasses. + */ + QtGraphics(QtGraphics parent) + { + cloneNativeContext( parent ); + setFont( parent.getFont() ); + setAlpha( parent.currentAlpha ); + setBackground( parent.getBackground() ); + setColor( parent.getColor() ); + setClip( (initialClip = parent.getClip()) ); + setTransform( parent.getTransform() ); + setStroke( parent.getStroke() ); + setComposite( parent.getComposite() ); + setPaint( parent.getPaint() ); + setRenderingHints( parent.getRenderingHints() ); + } + + /** + * Set up some generic defaults. + */ + protected void setup() + { + font = new Font ("Dialog", Font.PLAIN, 12); + setTransform( identity ); + setStroke( new BasicStroke() ); + renderingHints = new RenderingHints( null ); + } + + public synchronized native void delete(); + + public void dispose() + { + } + + // ********************** etc ******************************* + + private void resetClip() + { + AffineTransform current = getTransform(); + setTransform( identity ); + setClip( initialClip ); + setTransform( current ); + } + + protected native void initImage(QtImage image); + protected native void initVolatileImage(QtVolatileImage image); + + // Creates a new native QPainter object on the same context. + private native void cloneNativeContext( QtGraphics parent ); + private native void setColor(int r, int g, int b, int a); + private native void drawNative( QPainterPath p ); + private native void fillNative( QPainterPath p ); + private native void setClipNative( QPainterPath p ); + private native void setClipRectNative( int x, int y, int w, int h ); + private native void intersectClipNative( QPainterPath p ); + private native void intersectClipRectNative( int x, int y, int w, int h ); + private native void setQtTransform(QMatrix m); + private native void setNativeStroke(QPen p); + private native void setNativeComposite(int alphaMode); + private native void drawStringNative(String string, double x, double y); + private native void setLinearGradient(int r1, int g1, int b1, + int r2, int g2, int b2, + double x1, double y1, + double x2, double y2, boolean cyclic); + private native void setAlphaNative(double alpha); + private native void setFontNative(QtFontPeer font); + private native QPainterPath getClipNative(); + + void setAlpha(double alpha) + { + currentAlpha = alpha; + setAlphaNative(currentAlpha); + } + + // ************ Public methods ********************* + + /** + * Context-sensitive methods are declared abstract. + */ + public abstract Graphics create(); + + public abstract void copyArea(int x, int y, int width, int height, + int dx, int dy); + + public abstract GraphicsConfiguration getDeviceConfiguration(); + + + public Color getColor() + { + return new Color(color.getRed(), color.getGreen(), color.getBlue()); + } + + public void setColor(Color c) + { + if( c == null ) + c = Color.white; + this.color = c; + int alpha = (int)(c.getAlpha() * currentAlpha); + setColor(c.getRed(), c.getGreen(), c.getBlue(), alpha); + } + + public void setBackground(Color color) + { + bgcolor = new Color(color.getRed(), color.getGreen(), color.getBlue()); + } + + public Color getBackground() + { + return new Color(bgcolor.getRed(), bgcolor.getGreen(), bgcolor.getBlue()); + } + + public void setPaintMode() + { + } + + public void setXORMode(Color color) + { + // FIXME + } + + public boolean hit(Rectangle rect, Shape s, boolean onStroke) + { + if( onStroke ) + { + Shape stroked = currentStroke.createStrokedShape( s ); + return stroked.intersects( (double)rect.x, (double)rect.y, + (double)rect.width, (double)rect.height ); + } + return s.intersects( (double)rect.x, (double)rect.y, + (double)rect.width, (double)rect.height ); + } + + // ******************* Font *********************** + public Font getFont() + { + return font; + } + + public void setFont(Font font) + { + if( font == null ) + return; + this.font = font; + if(font.getPeer() != null && font.getPeer() instanceof QtFontPeer) + setFontNative( (QtFontPeer)font.getPeer() ); + } + + public FontMetrics getFontMetrics(Font font) + { + return new QtFontMetrics(font, this); + } + + // ***************** Clipping ********************* + + /** + * Intersects the current clip with the shape + */ + public void clip(Shape s) + { + intersectClipNative( new QPainterPath( s ) ); + } + + public void clipRect(int x, int y, int width, int height) + { + intersectClipRectNative( x, y, width, height ); + } + + public void setClip(int x, int y, int width, int height) + { + setClipRectNative( x, y, width, height ); + } + + public Shape getClip() + { + return getClipNative().getPath(); + } + + public native Rectangle getClipBounds(); + + /** + * Sets the clip + */ + public void setClip(Shape clip) + { + if (clip == null) + resetClip(); + else + setClipNative(new QPainterPath( clip )); + } + + // ***************** Drawing primitives ********************* + + public void draw(Shape s) + { + if( nativeStroking ) + drawNative( new QPainterPath(s) ); + else + fillNative( new QPainterPath( currentStroke.createStrokedShape( s ) ) ); + } + + public void fill(Shape s) + { + fillNative( new QPainterPath(s) ); + } + + public void drawLine(int x1, int y1, int x2, int y2) + { + if( nativeStroking ) + drawNative( new QPainterPath((double)x1, (double)y1, (double)x2, (double)y2, true) ); + else + draw( new Line2D.Double((double)x1, (double)y1, (double)x2, (double)y2) ); + } + + public void drawRect(int x, int y, int width, int height) + { + if( nativeStroking ) + drawNative( new QPainterPath((double)x, (double)y, + (double)width, (double)height) ); + else + fillNative( new QPainterPath + ( currentStroke.createStrokedShape + (new Rectangle2D.Double + ((double)x, (double)y, + (double)width, (double)height) ) ) ); + } + + public void fillRect(int x, int y, int width, int height) + { + fillNative( new QPainterPath( x, y, width, height ) ); + } + + public void clearRect(int x, int y, int width, int height) + { + Color c = color; + setColor( bgcolor ); // FIXME + fillRect( x, y, width, height ); + setColor( c ); + } + + public void drawRoundRect(int x, int y, int width, int height, + int arcWidth, int arcHeight) + { + draw( new RoundRectangle2D.Double(x, y, width, height, + arcWidth, arcHeight) ); + } + + public void fillRoundRect(int x, int y, int width, int height, + int arcWidth, int arcHeight) + { + fill( new RoundRectangle2D.Double(x, y, width, height, + arcWidth, arcHeight) ); + } + + public void drawOval(int x, int y, int width, int height) + { + draw( new Ellipse2D.Double((double)x, (double)y, + (double)width, (double)height) ); + } + + public void fillOval(int x, int y, int width, int height) + { + fill( new Ellipse2D.Double(x, y, width, height) ); + } + + public void drawArc(int x, int y, int width, int height, + int arcStart, int arcAngle) + { + draw( new Arc2D.Double(x, y, width, height, arcStart, arcAngle, + Arc2D.OPEN) ); + } + + public void fillArc(int x, int y, int width, int height, + int arcStart, int arcAngle) + { + fill( new Arc2D.Double(x, y, width, height, arcStart, arcAngle, + Arc2D.CHORD) ); + } + + public void drawPolyline(int xPoints[], int yPoints[], int npoints) + { + for( int i = 0; i < npoints - 1; i++) + drawLine(xPoints[i], yPoints[i], xPoints[i + 1], yPoints[i + 1]); + } + + public void drawPolygon(int xPoints[], int yPoints[], int npoints) + { + draw( new Polygon(xPoints, yPoints, npoints) ); + } + + public void fillPolygon(int xPoints[], int yPoints[], int npoints) + { + fill( new Polygon(xPoints, yPoints, npoints) ); + } + + public native void fill3DRect(int x, int y, int width, int height, boolean raised); + + public native void draw3DRect(int x, int y, int width, int height, boolean raised); + + // *********************** Text rendering ************************* + + public void drawString(String string, int x, int y) + { + drawStringNative(string, (double)x, (double)y); + } + + public void drawString(String string, float x, float y) + { + drawStringNative(string, (double)x, (double)y); + } + + public void drawString (AttributedCharacterIterator ci, int x, int y) + { + // FIXME - to something more correct ? + String s = ""; + for(char c = ci.first(); c != CharacterIterator.DONE; c = ci.next()) + s += c; + drawString(s, x, y); + } + + public void drawString(AttributedCharacterIterator ci, + float x, float y) + { + // FIXME - to something more correct ? + String s = ""; + for(char c = ci.first(); c != CharacterIterator.DONE; c = ci.next()) + s += c; + drawString(s, x, y); + } + + public void drawGlyphVector(GlyphVector v, float x, float y) + { + throw new RuntimeException("Not implemented"); + } + + // ******************* Image drawing ****************************** + public boolean drawImage(Image image, + AffineTransform Tx, + ImageObserver obs) + { + if (image instanceof QtImage) + return ((QtImage)image).drawImage(this, new QMatrix( Tx ), obs); + + return (new QtImage(image.getSource())).drawImage(this, + new QMatrix( Tx ), + obs); + } + + public boolean drawImage(Image image, int x, int y, Color bgcolor, + ImageObserver observer) + { + if (image instanceof QtImage) + return ((QtImage)image).drawImage (this, x, y, bgcolor, observer); + return (new QtImage(image.getSource())).drawImage (this, x, y, + bgcolor, observer); + } + + public boolean drawImage(Image image, + int dx1, int dy1, int dx2, int dy2, + int sx1, int sy1, int sx2, int sy2, + Color bgcolor, ImageObserver observer) + { + if (image instanceof QtImage) + return ((QtImage)image).drawImage(this, dx1, dy1, dx2, dy2, + sx1, sy1, sx2, sy2, bgcolor, observer); + + return (new QtImage(image.getSource())).drawImage(this, dx1, dy1, + dx2, dy2, + sx1, sy1, sx2, sy2, + bgcolor, observer); + } + + public boolean drawImage(Image image, int x, int y, + int width, int height, Color bgcolor, + ImageObserver observer) + { + if (image instanceof QtImage) + return ((QtImage)image).drawImage (this, x, y, width, height, + bgcolor, observer); + return (new QtImage(image.getSource())).drawImage (this, x, y, + width, height, + bgcolor, observer); + } + + public boolean drawImage(Image image, int x, int y, int width, int height, + ImageObserver observer) + { + return drawImage(image, x, y, width, height, null, observer); + } + + public boolean drawImage(Image image, int x, int y, ImageObserver observer) + { + return drawImage(image, x, y, null, observer); + } + + public boolean drawImage(Image image, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer) + { + return drawImage(image, dx1, dy1, dx2, dy2, + sx1, sy1, sx2, sy2, null, observer); + } + + // *********************** Transform methods ************************* + public AffineTransform getTransform() + { + return new AffineTransform( xform ); + } + + public void setTransform(AffineTransform Tx) + { + xform = new AffineTransform( Tx ); + setQtTransform( new QMatrix( xform ) ); + } + + public void rotate(double theta) + { + xform.rotate( theta ); + setQtTransform( new QMatrix( xform ) ); + } + + public void rotate(double theta, double x, double y) + { + xform.rotate(theta, x, y); + setQtTransform( new QMatrix( xform ) ); + } + + public void scale(double sx, double sy) + { + xform.scale(sx, sy); + setQtTransform( new QMatrix( xform ) ); + } + + public void shear(double shx, double shy) + { + xform.shear(shx, shy); + setQtTransform( new QMatrix( xform ) ); + } + + public void transform(AffineTransform Tx) + { + xform.concatenate( Tx ); + setQtTransform( new QMatrix( xform ) ); + } + + public void translate(double tx, double ty) + { + xform.translate( tx, ty ); + setQtTransform( new QMatrix( xform ) ); + } + + public void translate(int x, int y) + { + translate((double)x, (double)y); + } + + // *************** Stroking, Filling, Compositing ***************** + public void setStroke(Stroke s) + { + try // ..to convert the stroke into a native one. + { + QPen pen = new QPen( s ); + nativeStroking = true; + setNativeStroke( pen ); + setColor( color ); + } + catch (IllegalArgumentException e) + { + nativeStroking = false; + } + currentStroke = s; + } + + public Stroke getStroke() + { // FIXME: return copy? + return currentStroke; + } + + public void setComposite(Composite comp) + { + if( comp == null) + { + setNativeComposite( AlphaComposite.SRC_OVER ); + return; + } + + if( comp instanceof AlphaComposite ) + { + if( ((AlphaComposite)comp).getRule() != AlphaComposite.XOR ) + setAlpha( ((AlphaComposite)comp).getAlpha() ); + setNativeComposite( ((AlphaComposite)comp).getRule() ); + composite = comp; + } + else + throw new UnsupportedOperationException("We don't support custom"+ + " composites yet."); + } + + public Composite getComposite() + { + return composite; + } + + public void setPaint(Paint p) + { + if( p == null ) + return; + + // FIXME + currentPaint = p; + if( p instanceof GradientPaint ) + { + GradientPaint lg = (GradientPaint)p; + setLinearGradient(lg.getColor1().getRed(), lg.getColor1().getGreen(), + lg.getColor1().getBlue(), lg.getColor2().getRed(), + lg.getColor2().getGreen(), lg.getColor2().getBlue(), + lg.getPoint1().getX(), lg.getPoint1().getY(), + lg.getPoint2().getX(), lg.getPoint2().getY(), + lg.isCyclic() ); + return; + } + if( p instanceof Color ) + { + setColor((Color) p); + return; + } + throw new UnsupportedOperationException("We don't support custom"+ + " paints yet."); + } + + public Paint getPaint() + { + // FIXME + return currentPaint; + } + + // ********************** Rendering Hints ************************* + + public void addRenderingHints(Map hints) + { + renderingHints.putAll( hints ); + } + + public Object getRenderingHint(RenderingHints.Key hintKey) + { + return renderingHints.get( hintKey ); + } + + public RenderingHints getRenderingHints() + { + return new RenderingHints( renderingHints ); + } + + public void setRenderingHints(Map hints) + { + renderingHints = new RenderingHints( hints ); + updateRenderingHints(); + } + + public void setRenderingHint(RenderingHints.Key hintKey, Object hintValue) + { + renderingHints.put( hintKey, hintValue ); + updateRenderingHints(); + } + + private void updateRenderingHints() + { + // FIXME - update native settings. + } + + ////////////////////////////// unimplemented ///////////////////// + + public FontRenderContext getFontRenderContext() + { + throw new UnsupportedOperationException("Not implemented yet"); + } + + public void drawRenderableImage(RenderableImage image, AffineTransform xform) + { + throw new UnsupportedOperationException("Not implemented yet"); + } + + public void drawRenderedImage(RenderedImage image, AffineTransform xform) + { + throw new UnsupportedOperationException("Not implemented yet"); + } + + public void drawImage(BufferedImage image, BufferedImageOp op, int x, int y) + { + throw new UnsupportedOperationException("Not implemented yet"); + } +} + diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtGraphicsEnvironment.java b/libjava/classpath/gnu/java/awt/peer/qt/QtGraphicsEnvironment.java new file mode 100644 index 00000000000..142b140cf14 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtGraphicsEnvironment.java @@ -0,0 +1,108 @@ +/* QtGraphicsEnvironment.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.qt; + +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.HeadlessException; +import java.awt.image.BufferedImage; +import java.util.Locale; + +public class QtGraphicsEnvironment extends GraphicsEnvironment +{ + QtToolkit toolkit; + GraphicsDevice[] screens; + + public QtGraphicsEnvironment (QtToolkit tk) + { + super(); + toolkit = tk; + // Get the number of screens from Qt. + int n = toolkit.numScreens(); + + /** + * Create the screen device objects + */ + screens = new GraphicsDevice[ n ]; + for(int i = 0; i < n; i++) + screens[ i ] = new QtScreenDevice( i ); + } + + public Font[] getAllFonts () + { + String[] fonts = getAvailableFontFamilyNames(); + Font[] fontObjs = new Font[fonts.length]; + for( int i = 0; i < fonts.length; i++) + fontObjs[i] = new Font(fonts[i], Font.PLAIN, 12); + return fontObjs; + } + + public String[] getAvailableFontFamilyNames() + { + return toolkit.getFontList(); + } + + public String[] getAvailableFontFamilyNames(Locale l) + { + return getAvailableFontFamilyNames(); + } + + public GraphicsDevice getDefaultScreenDevice () + { + return screens[ toolkit.defaultScreen() ]; + } + + public Graphics2D createGraphics (BufferedImage image) + { + return (Graphics2D)image.getGraphics(); + } + + public GraphicsDevice[] getScreenDevices() + { + return screens; + } + + public QtToolkit getToolkit() + { + return toolkit; + } +} + + diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtImage.java b/libjava/classpath/gnu/java/awt/peer/qt/QtImage.java new file mode 100644 index 00000000000..90954643570 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtImage.java @@ -0,0 +1,642 @@ +/* QtImage.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.qt; + +import java.awt.Graphics; +import java.awt.Color; +import java.awt.Image; +import java.awt.image.ColorModel; +import java.awt.image.DirectColorModel; +import java.awt.image.MemoryImageSource; +import java.awt.image.ImageConsumer; +import java.awt.image.ImageObserver; +import java.awt.image.ImageProducer; +import java.io.File; +import java.io.IOException; +import java.io.ByteArrayOutputStream; +import java.io.BufferedInputStream; +import java.net.URL; +import java.util.Hashtable; +import java.util.WeakHashMap; +import java.util.Vector; + +/** + * QtImage - wraps a QImage + * + */ +public class QtImage extends Image +{ + int width = -1, height = -1; + + /** + * Properties. + */ + Hashtable props; + + /** + * Loaded or not flag, for asynchronous compatibility. + */ + boolean isLoaded; + + /** + * Pointer to the QImage + */ + long nativeObject; + + /** + * Observer queue. + */ + Vector observers; + + /** + * Error flag for loading. + */ + boolean errorLoading; + + /** + * Original source, if created from an ImageProducer. + */ + ImageProducer source; + + /* + * The 32-bit AARRGGBB format the uses. + */ + static ColorModel nativeModel = new DirectColorModel(32, + 0x00FF0000, + 0x0000FF00, + 0x000000FF, + 0xFF000000); + /** + * HashMap of Graphics objects painting on this Image. + */ + WeakHashMap painters; + + /** + * Flags if this image is to be destroyed. + */ + boolean killFlag; + + /** + * Clears the image to RGBA 0 + */ + public native void clear(); + + /** + * Returns a copy of the pixel data as a java array. + */ + private native int[] getPixels(); + + /** + * Sets the pixel data from a java array. + */ + private native void setPixels(int[] pixels); + + /** + * Loads an image + */ + private native boolean loadImage(String name); + + /** + * Loads an image from data. + */ + private native boolean loadImageFromData(byte[] data); + + /** + * Allocates a QImage + */ + private native void createImage(); + + /** + * Frees the above. + */ + private synchronized native void freeImage(); + + /** + * Sets the image to scaled copy of src image. hints are rendering hints. + */ + private native void createScaledImage(QtImage src, int hints); + + /** + * Draws the image optionally composited. + */ + native void drawPixels (QtGraphics gc, + int bg_red, int bg_green, int bg_blue, + int x, int y, + boolean composite); + /** + * Draws the image, optionally scaled and composited. + */ + private native void drawPixelsScaled (QtGraphics gc, + int bg_red, int bg_green, int bg_blue, + int x, int y, int width, int height, + boolean composite); + + /** + * Draws the image transformed. + */ + private native void drawPixelsTransformed (QtGraphics gc, QMatrix transform); + + /** + * Draws the image scaled flipped and optionally composited. + */ + native void drawPixelsScaledFlipped (QtGraphics gc, + int bg_red, int bg_green, + int bg_blue, + boolean flipX, boolean flipY, + int srcX, int srcY, + int srcWidth, int srcHeight, + int dstX, int dstY, + int dstWidth, int dstHeight, + boolean composite); + + /** + * Creates the image from an ImageProducer. May result in an error image. + */ + public QtImage (ImageProducer producer) + { + killFlag = false; + isLoaded = false; + observers = new Vector(); + source = producer; + errorLoading = false; + if( producer != null ) + source.startProduction(new QtImageConsumer(this, source)); + } + + /** + * Creates the image from a URL. May result in an error image. + */ + public QtImage (URL url) + { + killFlag = false; + isLoaded = false; + observers = new Vector(); + errorLoading = false; + if( url == null) + return; + ByteArrayOutputStream baos = new ByteArrayOutputStream( 5000 ); + try + { + BufferedInputStream bis = new BufferedInputStream(url.openStream()); + + byte[] buf = new byte[5000]; + int n = 0; + + while ( (n = bis.read( buf )) != -1 ) + baos.write(buf, 0, n); + bis.close(); + } + catch(IOException e) + { + throw new IllegalArgumentException("Couldn't load image."); + } + if ( loadImageFromData( baos.toByteArray() ) != true ) + throw new IllegalArgumentException("Couldn't load image."); + + isLoaded = true; + observers = null; + props = new Hashtable(); + } + + /** + * Constructs a QtImage by loading a given file. + * + * @throws IllegalArgumentException if the image could not be loaded. + */ + public QtImage (String filename) + { + killFlag = false; + File f = new File(filename); + observers = null; + props = new Hashtable(); + try + { + String fn = f.getCanonicalPath(); + if (loadImage( fn ) != true) + { + errorLoading = true; + isLoaded = false; + return; + } + } + catch(IOException e) + { + errorLoading = true; + isLoaded = false; + return; + } + errorLoading = false; + isLoaded = true; + } + + /** + * Constructs a QtImage from a byte array of an image file. + * + * @throws IllegalArgumentException if the image could not be loaded. + */ + public QtImage (byte[] data) + { + if (loadImageFromData(data) != true) + throw new IllegalArgumentException("Couldn't load image."); + + killFlag = false; + isLoaded = true; + observers = null; + errorLoading = false; + props = new Hashtable(); + } + + /** + * Constructs an empty QtImage. + */ + public QtImage (int width, int height) + { + this.width = width; + this.height = height; + props = new Hashtable(); + isLoaded = true; + killFlag = false; + observers = null; + errorLoading = false; + createImage(); + clear(); + } + + /** + * Constructs a scaled version of the src bitmap, using Qt + */ + private QtImage (QtImage src, int width, int height, int hints) + { + this.width = width; + this.height = height; + props = new Hashtable(); + isLoaded = true; + killFlag = false; + observers = null; + errorLoading = false; + + createScaledImage(src, hints); + } + + /** + * Callback from the image consumer. + */ + public void setImage(int width, int height, + int[] pixels, Hashtable properties) + { + this.width = width; + this.height = height; + props = (properties != null) ? properties : new Hashtable(); + + if (width <= 0 || height <= 0 || pixels == null) + { + errorLoading = true; + return; + } + + isLoaded = true; + deliver(); + createImage(); + setPixels(pixels); + } + + // java.awt.Image methods //////////////////////////////////////////////// + + public int getWidth (ImageObserver observer) + { + if (addObserver(observer)) + return -1; + + return width; + } + + public int getHeight (ImageObserver observer) + { + if (addObserver(observer)) + return -1; + + return height; + } + + public Object getProperty (String name, ImageObserver observer) + { + if (addObserver(observer)) + return UndefinedProperty; + + Object value = props.get (name); + return (value == null) ? UndefinedProperty : value; + } + + /** + * Returns the source of this image. + */ + public ImageProducer getSource () + { + if (!isLoaded) + return null; + return new MemoryImageSource(width, height, nativeModel, getPixels(), + 0, width); + } + + void putPainter(QtImageGraphics g) + { + if( painters == null ) + painters = new WeakHashMap(); + painters.put( g, "dummy" ); + } + + void removePainter(QtImageGraphics g) + { + painters.remove( g ); + if( killFlag && painters.isEmpty() ) + freeImage(); + } + + /** + * Creates a Graphics context for this image. + */ + public Graphics getGraphics () + { + if (!isLoaded || killFlag) + return null; + + return new QtImageGraphics(this); + } + + /** + * Creates a Graphics context for this image. + */ + Graphics getDirectGraphics(QtComponentPeer peer) + { + if (!isLoaded) + return null; + + return new QtImageDirectGraphics(this, peer); + } + + /** + * Returns a scaled instance of this image. + */ + public Image getScaledInstance(int width, + int height, + int hints) + { + if (width <= 0 || height <= 0) + throw new IllegalArgumentException("Width and height of scaled bitmap"+ + "must be >= 0"); + + return new QtImage(this, width, height, hints); + } + + /** + * If the image is loaded and comes from an ImageProducer, + * regenerate the image from there. + * + * I have no idea if this is ever actually used. Since QtImage can't be + * instantiated directly, how is the user to know if it was created from + * an ImageProducer or not? + */ + public synchronized void flush () + { + if (isLoaded && source != null) + { + observers = new Vector(); + isLoaded = false; + freeImage(); + source.startProduction(new QtImageConsumer(this, source)); + } + } + + public void finalize() + { + dispose(); + } + + public void dispose() + { + if (isLoaded) + { + if( painters == null || painters.isEmpty() ) + freeImage(); + else + killFlag = true; // can't destroy image yet. + // Do so when all painters are gone. + } + } + + /** + * Returns the image status, used by QtToolkit + */ + public int checkImage (ImageObserver observer) + { + if (addObserver(observer)) + { + if (errorLoading == true) + return ImageObserver.ERROR; + else + return 0; + } + + return ImageObserver.ALLBITS | ImageObserver.WIDTH | ImageObserver.HEIGHT; + } + + // Drawing methods //////////////////////////////////////////////// + + /** + * Draws an image with eventual scaling/transforming. + */ + public boolean drawImage (QtGraphics g, QMatrix matrix, + ImageObserver observer) + { + if (addObserver(observer)) + return false; + + drawPixelsTransformed (g, matrix); + + return true; + } + + /** + * Draws an image to the QtGraphics context, at (x,y) with optional + * compositing with a background color. + */ + public boolean drawImage (QtGraphics g, int x, int y, + Color bgcolor, ImageObserver observer) + { + if (addObserver(observer)) + return false; + + if(bgcolor != null) + drawPixels(g, bgcolor.getRed (), bgcolor.getGreen (), + bgcolor.getBlue (), x, y, true); + else + drawPixels(g, 0, 0, 0, x, y, false); + + return true; + } + + /** + * Draws an image to the QtGraphics context, at (x,y) scaled to + * width and height, with optional compositing with a background color. + */ + public boolean drawImage (QtGraphics g, int x, int y, int width, int height, + Color bgcolor, ImageObserver observer) + { + if (addObserver(observer)) + return false; + + if(bgcolor != null) + drawPixelsScaled(g, bgcolor.getRed (), bgcolor.getGreen (), + bgcolor.getBlue (), x, y, width, height, true); + else + drawPixelsScaled(g, 0, 0, 0, x, y, width, height, false); + + return true; + } + + /** + * Draws an image with eventual scaling/transforming. + */ + public boolean drawImage (QtGraphics g, int dx1, int dy1, int dx2, int dy2, + int sx1, int sy1, int sx2, int sy2, + Color bgcolor, ImageObserver observer) + { + if (addObserver(observer)) + return false; + + boolean flipX = (dx1 > dx2)^(sx1 > sx2); + boolean flipY = (dy1 > dy2)^(sy1 > sy2); + int dstWidth = Math.abs (dx2 - dx1); + int dstHeight = Math.abs (dy2 - dy1); + int srcWidth = Math.abs (sx2 - sx1); + int srcHeight = Math.abs (sy2 - sy1); + int srcX = (sx1 < sx2) ? sx1 : sx2; + int srcY = (sy1 < sy2) ? sy1 : sy2; + int dstX = (dx1 < dx2) ? dx1 : dx2; + int dstY = (dy1 < dy2) ? dy1 : dy2; + + // Clipping. This requires the dst to be scaled as well, + if (srcWidth > width) + { + dstWidth = (int)((double)dstWidth*((double)width/(double)srcWidth)); + srcWidth = width - srcX; + } + + if (srcHeight > height) + { + dstHeight = (int)((double)dstHeight*((double)height/(double)srcHeight)); + srcHeight = height - srcY; + } + + if (srcWidth + srcX > width) + { + dstWidth = (int)((double)dstWidth * (double)(width - srcX)/(double)srcWidth); + srcWidth = width - srcX; + } + + if (srcHeight + srcY > height) + { + dstHeight = (int)((double)dstHeight * (double)(width - srcY)/(double)srcHeight); + srcHeight = height - srcY; + } + + if ( srcWidth <= 0 || srcHeight <= 0 || dstWidth <= 0 || dstHeight <= 0) + return true; + + if(bgcolor != null) + drawPixelsScaledFlipped (g, bgcolor.getRed (), bgcolor.getGreen (), + bgcolor.getBlue (), + flipX, flipY, + srcX, srcY, + srcWidth, srcHeight, + dstX, dstY, + dstWidth, dstHeight, + true); + else + drawPixelsScaledFlipped (g, 0, 0, 0, flipX, flipY, + srcX, srcY, srcWidth, srcHeight, + dstX, dstY, dstWidth, dstHeight, + false); + return true; + } + + public native void copyArea(int x, int y, int width, int height, + int dx, int dy); + + // Private methods //////////////////////////////////////////////// + + /** + * Delivers notifications to all queued observers. + */ + private void deliver() + { + int flags = ImageObserver.HEIGHT | + ImageObserver.WIDTH | + ImageObserver.PROPERTIES | + ImageObserver.ALLBITS; + + if (observers != null) + for(int i=0; i < observers.size(); i++) + ((ImageObserver)observers.elementAt(i)). + imageUpdate(this, flags, 0, 0, width, height); + + observers = null; + } + + /** + * Adds an observer, if we need to. + * @return true if an observer was added. + */ + private boolean addObserver(ImageObserver observer) + { + if (!isLoaded) + { + if(observer != null) + if (!observers.contains (observer)) + observers.addElement (observer); + return true; + } + return false; + } + + public String toString() + { + return "QtImage [isLoaded="+isLoaded+", width="+width+", height="+height + +"]"; + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtImageConsumer.java b/libjava/classpath/gnu/java/awt/peer/qt/QtImageConsumer.java new file mode 100644 index 00000000000..aec0671f8e0 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtImageConsumer.java @@ -0,0 +1,154 @@ +/* QtImageConsumer.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.qt; + +import java.awt.Graphics; +import java.awt.Image; +import java.awt.image.ColorModel; +import java.awt.image.DirectColorModel; +import java.awt.image.ImageConsumer; +import java.awt.image.ImageObserver; +import java.awt.image.ImageProducer; +import java.util.Hashtable; +import java.util.Vector; + +/** + * Helper class to QtImage. Sits and gathers pixels for a QtImage and then + * calls QtImage.setImage(). + * + * @author Sven de Marothy + */ +public class QtImageConsumer implements ImageConsumer +{ + private QtImage target; + private int width, height; + private Hashtable properties; + private int[] pixelCache = null; + private ImageProducer source; + + public QtImageConsumer(QtImage target, ImageProducer source) + { + this.target = target; + this.source = source; + } + + public synchronized void imageComplete (int status) + { + source.removeConsumer(this); + target.setImage(width, height, pixelCache, properties); + } + + public synchronized void setColorModel (ColorModel model) + { + // This method is to inform on what the most used color model + // in the image is, for optimization reasons. We ignore this + // information. + } + + public synchronized void setDimensions (int width, int height) + { + pixelCache = new int[width*height]; + + this.width = width; + this.height = height; + } + + public synchronized void setHints (int flags) + { + // This method informs us in which order the pixels are + // delivered, for progressive-loading support, etc. + // Since we wait until it's all loaded, we can ignore the hints. + } + + public synchronized void setPixels (int x, int y, int width, int height, + ColorModel cm, byte[] pixels, + int offset, int scansize) + { + setPixels (x, y, width, height, cm, convertPixels (pixels), offset, + scansize); + } + + public synchronized void setPixels (int x, int y, int width, int height, + ColorModel cm, int[] pixels, + int offset, int scansize) + { + if (pixelCache == null) + return; // Not sure this should ever happen. + + if (cm.equals(QtImage.nativeModel)) + for (int i = 0; i < height; i++) + System.arraycopy (pixels, offset + (i * scansize), + pixelCache, (y + i) * this.width + x, + width); + else + { + for (int i = 0; i < height; i++) + for (int j = 0; j < width; j++) + { + // get in AARRGGBB and convert to AABBGGRR + int pix = cm.getRGB(pixels[offset + (i * scansize) + x + j]); + byte b = (byte)(pix & 0xFF); + byte r = (byte)(((pix & 0x00FF0000) >> 16) & 0xFF); + pix &= 0xFF00FF00; + pix |= ((b & 0xFF) << 16); + pix |= (r & 0xFF); + pixelCache[(y + i) * this.width + x + j] = pix; + } + } + } + + /** + * This is an old method, no idea if it's correct. + */ + private int[] convertPixels (byte[] pixels) + { + int ret[] = new int[pixels.length]; + + for (int i = 0; i < pixels.length; i++) + ret[i] = pixels[i] & 0xFF; + + return ret; + } + + public synchronized void setProperties (Hashtable props) + { + this.properties = props; + } +} + + diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtImageDirectGraphics.java b/libjava/classpath/gnu/java/awt/peer/qt/QtImageDirectGraphics.java new file mode 100644 index 00000000000..5a6f3189a7a --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtImageDirectGraphics.java @@ -0,0 +1,166 @@ +/* QtImageDirectGraphics.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.qt; + +import java.awt.Color; +import java.awt.GraphicsConfiguration; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.Paint; +import java.awt.Rectangle; +import java.util.Stack; +import java.awt.Shape; +import java.awt.Stroke; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphVector; +import java.awt.geom.AffineTransform; +import java.awt.geom.PathIterator; +import java.awt.geom.Arc2D; +import java.awt.geom.Ellipse2D; +import java.awt.geom.Line2D; +import java.awt.geom.Rectangle2D; +import java.awt.geom.RoundRectangle2D; +import java.awt.image.BufferedImage; +import java.awt.image.BufferedImageOp; +import java.awt.image.ImageObserver; +import java.awt.image.RenderedImage; +import java.awt.image.renderable.RenderableImage; + +/** + * A QtImagePainter that does an update after every drawing op. + */ +public class QtImageDirectGraphics extends QtImageGraphics +{ + private QtComponentPeer peer; + private boolean modified; + + public QtImageDirectGraphics(QtImage image, QtComponentPeer peer) + { + super( image ); + this.peer = peer; + modified = false; + } + + public QtImageDirectGraphics(QtImageGraphics g) + { + super( g ); + } + + private void scheduleUpdate() + { + } + + public void dispose() + { + super.dispose(); + peer.toolkit.sync(); + peer.QtUpdate(); + } + + public void draw(Shape s) + { + super.draw(s); + scheduleUpdate(); + } + + public void fill(Shape s) + { + super.fill(s); + scheduleUpdate(); + } + + public void drawString(String string, int x, int y) + { + super.drawString( string, x, y ); + scheduleUpdate(); + } + + public void drawString(String string, float x, float y) + { + super.drawString( string, x, y ); + scheduleUpdate(); + } + + public void drawLine(int x1, int y1, int x2, int y2) + { + super.drawLine(x1, y1, x2, y2); + scheduleUpdate(); + } + + public boolean drawImage(Image image, + AffineTransform Tx, + ImageObserver obs) + { + boolean r = super.drawImage(image, Tx, obs); + scheduleUpdate(); + return r; + } + + public boolean drawImage(Image image, int x, int y, Color bgcolor, + ImageObserver observer) + { + boolean r = super.drawImage(image, x, y, bgcolor, observer); + scheduleUpdate(); + return r; + } + + public boolean drawImage(Image image, + int dx1, int dy1, int dx2, int dy2, + int sx1, int sy1, int sx2, int sy2, + Color bgcolor, ImageObserver observer) + { + boolean r = super.drawImage( image, dx1, dy1, dx2, dy2, + sx1, sy1, sx2, sy2, + bgcolor, observer); + scheduleUpdate(); + return r; + } + + public boolean drawImage(Image image, int x, int y, + int width, int height, Color bgcolor, + ImageObserver observer) + { + boolean r = super.drawImage(image, x, y, width, height, bgcolor, + observer); + scheduleUpdate(); + return r; + } +} + + diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtImageGraphics.java b/libjava/classpath/gnu/java/awt/peer/qt/QtImageGraphics.java new file mode 100644 index 00000000000..f8a7e51d398 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtImageGraphics.java @@ -0,0 +1,143 @@ +/* QtImageGraphics.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.qt; + +import java.awt.Color; +import java.awt.GraphicsConfiguration; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.Paint; +import java.awt.Rectangle; +import java.util.Stack; + +/** + * QtComponentPainter is a Graphics2D context for painting to QtImage and + * QtVolatileImages. + */ +public class QtImageGraphics extends QtGraphics +{ + Image parentImage; + Stack owners; + QtImageGraphics topParent; + + public QtImageGraphics(Image image) + { + if(!( image instanceof QtVolatileImage || image instanceof QtImage)) + throw new IllegalArgumentException("Cannot create QtImageGraphics for a non-QImage context."); + + owners = new Stack(); + owners.push(this); + topParent = null; + int w, h; + if(image instanceof QtImage) + { + w = ((QtImage)image).width; + h = ((QtImage)image).height; + initImage((QtImage) image ); + ((QtImage)image).putPainter( this ); + } + else + { + w = ((QtVolatileImage)image).width; + h = ((QtVolatileImage)image).height; + initVolatileImage((QtVolatileImage) image ); + ((QtVolatileImage)image).putPainter( this ); + } + + parentImage = image; + initialClip = new Rectangle( 0, 0, w, h ); + setClip( initialClip ); + setBackground(Color.white); // fixme + currentAlpha = 1.0; + setColor(Color.black); + setup(); + } + + /** + * Copying constructor + */ + QtImageGraphics( QtImageGraphics g ) + { + super( g ); + parentImage = g.parentImage; + if(parentImage instanceof QtImage) + ((QtImage)parentImage).putPainter( this ); + else + ((QtVolatileImage)parentImage).putPainter( this ); + } + + public void dispose() + { + delete(); + if( parentImage instanceof QtImage ) + ((QtImage)parentImage).removePainter( this ); + else + ((QtVolatileImage)parentImage).removePainter( this ); + } + + /** + * Create a copy of this context. + */ + public Graphics create() + { + return new QtImageGraphics( this ); + } + + /** + * Copy an area. + */ + public void copyArea(int x, int y, int width, int height, + int dx, int dy) + { + if(parentImage instanceof QtImage) + ((QtImage)parentImage).copyArea(x, y, width, height, dx, dy); + else + ((QtVolatileImage)parentImage).copyArea(x, y, width, height, dx, dy); + } + + /** + * Returns the GraphicsConfiguration of the context component. + */ + public GraphicsConfiguration getDeviceConfiguration() + { + throw new UnsupportedOperationException("Not implemented yet"); + } +} + + diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtLabelPeer.java b/libjava/classpath/gnu/java/awt/peer/qt/QtLabelPeer.java new file mode 100644 index 00000000000..449c9b3cb58 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtLabelPeer.java @@ -0,0 +1,62 @@ +/* QtLabelPeer.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.qt; + +import java.awt.Label; +import java.awt.peer.LabelPeer; + +public class QtLabelPeer extends QtComponentPeer implements LabelPeer +{ + public QtLabelPeer( QtToolkit kit, Label owner ) + { + super( kit, owner ); + } + + protected native void init(); + + protected void setup() + { + super.setup(); + setText( ((Label)owner).getText() ); + setAlignment( ((Label)owner).getAlignment() ); + } + + public native void setAlignment( int alignment ); + + public native void setText( String label ); +} diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtListPeer.java b/libjava/classpath/gnu/java/awt/peer/qt/QtListPeer.java new file mode 100644 index 00000000000..9df250a42d3 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtListPeer.java @@ -0,0 +1,188 @@ +/* QtListPeer.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.qt; + +import java.awt.Dimension; +import java.awt.List; +import java.awt.event.ActionEvent; +import java.awt.event.ItemEvent; +import java.awt.peer.ListPeer; + +public class QtListPeer extends QtComponentPeer implements ListPeer +{ + public QtListPeer( QtToolkit kit, List owner ) + { + super( kit, owner ); + } + + public native void init(); + + protected void setup() + { + super.setup(); + List o = (List)owner; + // Multiple selection + setMultipleMode(o.isMultipleMode()); + // Add initial list items. + String[] items = o.getItems(); + for (int i = 0; i < items.length; i++) + add(items[i], i); + + // Initial selections. + int[] selected = o.getSelectedIndexes(); + for (int i = 0; i < selected.length; i++) + select(selected[i]); + + // If no initial selection, use 0. + if(selected.length == 0 && items.length > 0) + select( 0 ); + } + + private boolean ignoreNextSelect = false; + + /** + * Called back when a row is selected. -1 if no row is selected. + */ + private void fireChoice( int index ) + { + ignoreNextSelect = true; + if( index == -1) + ((List)owner).deselect( ((List)owner).getSelectedIndex() ); + else + { + ((List)owner).select( index ); + ItemEvent e = new ItemEvent((List)owner, + ItemEvent.ITEM_STATE_CHANGED, + ""+index, + ItemEvent.SELECTED); + QtToolkit.eventQueue.postEvent(e); + } + } + + /** + * Called back when an item is double-clicked. + */ + private void itemDoubleClicked( int index, int modifiers ) + { + ActionEvent e = new ActionEvent(owner, + ActionEvent.ACTION_PERFORMED, + ((List)owner).getItem( index ), + System.currentTimeMillis(), + modifiers); + QtToolkit.eventQueue.postEvent(e); + } + + private native void select(int index, boolean selected); + + // ************ Public methods ********************* + + public native void add(String item, int index); + + public void addItem(String item, int index) + { + add(item, index); + } + + public void clear() + { + removeAll(); + } + + /** + * Deletes items from the starting index to the ending index (inclusive). + */ + public native void delItems(int start_index, int end_index); + + public void deselect(int index) + { + if( ignoreNextSelect == true ) + ignoreNextSelect = false; + else + select(index, false); + } + + public native int[] getSelectedIndexes(); + + public native void makeVisible(int index); + + public Dimension minimumSize(int s) + { + return getMinimumSize(s); + } + + public Dimension preferredSize(int s) + { + return getPreferredSize(s); + } + + public void removeAll() + { + delItems(0, ((List)owner).getItemCount() - 1); + } + + public void select(int index) + { + if( ignoreNextSelect == true ) + ignoreNextSelect = false; + else + select(index, true); + } + + /** + * Sets multiple-selection mode. + * Note there's a bug in multiple selection in Qt 4.0.0, use 4.0.1. + */ + public native void setMultipleMode(boolean multi); + + public void setMultipleSelections(boolean multi) + { + setMultipleMode(multi); + } + + public Dimension getPreferredSize(int s) + { + // FIXME + return getPreferredSize(); + } + + public Dimension getMinimumSize(int s) + { + // FIXME + return getMinimumSize(); + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtMenuBarPeer.java b/libjava/classpath/gnu/java/awt/peer/qt/QtMenuBarPeer.java new file mode 100644 index 00000000000..d8f0d1f8892 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtMenuBarPeer.java @@ -0,0 +1,103 @@ +/* QtMenuBarPeer.java -- Qt peer for a menu bar. + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.qt; + +import java.awt.Menu; +import java.awt.MenuBar; +import java.awt.peer.MenuBarPeer; +import java.util.Vector; + +public class QtMenuBarPeer extends QtMenuComponentPeer implements MenuBarPeer +{ + public QtMenuBarPeer( QtToolkit kit, MenuBar owner ) + { + super( kit, owner ); + } + + protected native void init(); + + protected void setup() + { + } + + /** + * Recurses the menubar adding menus (and menu items), + * called from the Frame peer. + */ + void addMenus() + { + MenuBar o = (MenuBar)owner; + int help = (o.getHelpMenu() != null) ? 1 : 0; + for (int i = 0; i < o.getMenuCount() - help; i++) + addMenu( o.getMenu(i) ); + if(o.getHelpMenu() != null) + addHelpMenu( o.getHelpMenu() ); + } + + private native void addMenu( QtMenuPeer mp ); + + private native void addHelpMenu( QtMenuPeer mp ); + + private native void delMenu( QtMenuPeer mp ); + + // ************ Public methods ********************* + + public void addMenu( Menu m ) + { + if (m.getPeer() == null) + m.addNotify(); + ((QtMenuPeer)m.getPeer()).addItems(); + addMenu( (QtMenuPeer)m.getPeer() ); + } + + public void addHelpMenu( Menu m ) + { + if (m.getPeer() == null) + m.addNotify(); + ((QtMenuPeer)m.getPeer()).addItems(); + addHelpMenu( (QtMenuPeer)m.getPeer() ); + } + + public void delMenu( int index ) + { + Menu m = ((MenuBar)owner).getMenu( index ); + if(m != null) + delMenu( (QtMenuPeer)m.getPeer() ); + } +} + diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtMenuComponentPeer.java b/libjava/classpath/gnu/java/awt/peer/qt/QtMenuComponentPeer.java new file mode 100644 index 00000000000..7e292d00fbf --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtMenuComponentPeer.java @@ -0,0 +1,94 @@ +/* QtMenuComponentPeer.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.qt; + +import java.awt.Font; +import java.awt.MenuComponent; +import java.awt.peer.MenuComponentPeer; + +public class QtMenuComponentPeer extends NativeWrapper + implements MenuComponentPeer +{ + protected QtToolkit toolkit; + protected MenuComponent owner; + + public QtMenuComponentPeer( QtToolkit kit, MenuComponent owner ) + { + this.toolkit = kit; + this.owner = owner; + nativeObject = 0; + synchronized(this) + { + callInit(); // Calls the init method FROM THE MAIN THREAD. + try + { + wait(); // Wait for the thing to be created. + } + catch(InterruptedException e) + { + } + } + setup(); + } + + protected native void callInit(); + + protected void init() + { + } + + protected void setup() + { + } + + public void finalize() + { + dispose(); + } + + // ************ Public methods ********************* + + public native void dispose(); + + public void setFont(Font font) + { + // TODO Auto-generated method stub + + } + +} diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtMenuItemPeer.java b/libjava/classpath/gnu/java/awt/peer/qt/QtMenuItemPeer.java new file mode 100644 index 00000000000..34753cb359b --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtMenuItemPeer.java @@ -0,0 +1,108 @@ +/* QtMenuItemPeer.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.qt; + +import java.awt.Menu; +import java.awt.MenuItem; +import java.awt.CheckboxMenuItem; +import java.awt.event.ActionEvent; +import java.awt.peer.MenuItemPeer; +import java.awt.peer.CheckboxMenuItemPeer; + +public class QtMenuItemPeer extends QtMenuComponentPeer + implements MenuItemPeer, CheckboxMenuItemPeer +{ + public QtMenuItemPeer( QtToolkit toolkit, MenuItem owner ) + { + super(toolkit, owner); + } + + protected void init() + { + String label = ((MenuItem)owner).getLabel(); + create(label, label.equals("-"), (owner instanceof CheckboxMenuItem)); + } + + protected void setup() + { + } + + private native void create(String label, boolean isSeperator, boolean isCheckable); + + public void finalize() + { + dispose(); + } + + public native void dispose(); + + private void fireClick(int modifiers) + { + ActionEvent e = new ActionEvent(owner, + ActionEvent.ACTION_PERFORMED, + ((MenuItem)owner).getActionCommand(), + System.currentTimeMillis(), + (modifiers & 0x2FF)); + QtToolkit.eventQueue.postEvent(e); + } + + // ************ Public methods ********************* + + public void disable() + { + setEnabled(false); + } + + public void enable() + { + setEnabled(true); + } + + public native void setEnabled(boolean b); + + public native void setLabel(String label); + + public native void setState(boolean state); +} + + + + + + + diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtMenuPeer.java b/libjava/classpath/gnu/java/awt/peer/qt/QtMenuPeer.java new file mode 100644 index 00000000000..7457c38d2ff --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtMenuPeer.java @@ -0,0 +1,152 @@ +/* QtMenuPeer.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.qt; + +import java.awt.Menu; +import java.awt.MenuItem; +import java.awt.PopupMenu; +import java.awt.event.ActionEvent; +import java.awt.peer.MenuPeer; +import java.util.Vector; + +public class QtMenuPeer extends QtMenuComponentPeer implements MenuPeer +{ + Vector items; + boolean itemsAdded; + + public QtMenuPeer( QtToolkit kit, Menu owner ) + { + super( kit, owner ); + itemsAdded = false; + } + + protected native void init(); + + protected void setup() + { + items = new Vector(); + setLabel( ((Menu)owner).getLabel() ); + if( ((Menu)owner).isTearOff() ) + allowTearOff(); + } + + // Recurse the menu tree adding items, + // called from the MenuBar addMenus() method, called from the Frame peer. + void addItems() + { + if(!itemsAdded) + { + Menu o = (Menu)owner; + for( int i=0; i < o.getItemCount(); i++ ) + { + MenuItem ci = (MenuItem)o.getItem(i); + if (ci instanceof Menu && ci.getPeer() != null) + ((QtMenuPeer)ci.getPeer()).addItems(); + addItem( ci ); + } + itemsAdded = true; + } + } + + private void fireClick() + { + ActionEvent e = new ActionEvent(owner, + ActionEvent.ACTION_PERFORMED, + ((Menu)owner).getActionCommand()); + QtToolkit.eventQueue.postEvent(e); + } + + private native void allowTearOff(); + + private native void insertSeperator(); + + private native void insertItem(QtMenuItemPeer p); + + private native void insertMenu(QtMenuPeer menu); + + private native void delItem(long ptr); + + private void add(long ptr) + { + items.add(new Long(ptr)); + } + + // ************ Public methods ********************* + + public void addItem( MenuItem item ) + { + if( item instanceof Menu || item instanceof PopupMenu) + insertMenu((QtMenuPeer)item.getPeer()); + else + { + QtMenuItemPeer p = (QtMenuItemPeer)item.getPeer(); + insertItem(p); + } + } + + public void addSeparator() + { + insertSeperator(); + } + + public void delItem( int index ) + { + long ptr = ((Long)items.elementAt(index)).longValue(); + delItem(ptr); + items.removeElementAt(index); + } + + // Inherited methods.. + + public void disable() + { + setEnabled(false); + } + + public void enable() + { + setEnabled(true); + } + + public native void setEnabled(boolean enabled); + + public native void setLabel(String text); +} + + + diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtPanelPeer.java b/libjava/classpath/gnu/java/awt/peer/qt/QtPanelPeer.java new file mode 100644 index 00000000000..9e435233110 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtPanelPeer.java @@ -0,0 +1,56 @@ +/* QtPanelPeer.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.qt; + +import java.awt.Component; +import java.awt.peer.PanelPeer; + +public class QtPanelPeer extends QtContainerPeer implements PanelPeer +{ + public QtPanelPeer( QtToolkit kit, Component owner ) + { + super( kit, owner ); + } + + protected native void init(); + + protected void setup() + { + super.setup(); + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtPopupMenuPeer.java b/libjava/classpath/gnu/java/awt/peer/qt/QtPopupMenuPeer.java new file mode 100644 index 00000000000..81577cc6c52 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtPopupMenuPeer.java @@ -0,0 +1,82 @@ +/* QtPopupMenuPeer.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.qt; + +import java.awt.Component; +import java.awt.Menu; +import java.awt.MenuItem; +import java.awt.Point; +import java.awt.PopupMenu; +import java.awt.Event; +import java.awt.event.ActionEvent; +import java.awt.peer.PopupMenuPeer; + +public class QtPopupMenuPeer extends QtMenuPeer implements PopupMenuPeer +{ + public QtPopupMenuPeer( QtToolkit kit, PopupMenu owner ) + { + super( kit, owner ); + } + + private native void showNative(int x, int y); + + // ************ Public methods ********************* + + /** + * Part of the older API, replaced by event version instead. + */ + public void show (Component origin, int x, int y) + { + if( origin == null ) + throw new NullPointerException("Null parent component."); + addItems(); + + Point p = origin.getLocationOnScreen(); + showNative( (int)p.getX() + x, (int)p.getY() + y ); + } + + public void show (Event e) + { + if (!(e.target instanceof Component)) + throw new IllegalArgumentException("Expecting a component Event target!"); + show((Component)e.target, e.x, e.y); + } +} + + + diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtRepaintThread.java b/libjava/classpath/gnu/java/awt/peer/qt/QtRepaintThread.java new file mode 100644 index 00000000000..405505e9bc8 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtRepaintThread.java @@ -0,0 +1,156 @@ +/* QtRepaintThread.java -- Repaint thread implementation + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.qt; + +/** + * This class does repainting of Component back-buffers. It is undesirable to + * do this directly from the paint callback in QtComponentPeer, because that + * is executed from the main thread. Thus, if a call is made at the same time + * which requires execution by the main thread, and this is sharing a lock with + * paint(), then a deadlock will occur, which must be avoided. In general, + * the main Qt thread should avoid calling into java code as far as possible. + * + */ +public class QtRepaintThread extends Thread +{ + static class RepaintComponent + { + public QtComponentPeer curr; + public RepaintComponent next; + public boolean paintAll; + public int x, y, w, h; + + public RepaintComponent(QtComponentPeer p) + { + curr = p; + next = null; + paintAll = true; + } + + public RepaintComponent(QtComponentPeer p, int x, int y, int w, int h) + { + this(p); + paintAll = false; + this.x = x; + this.y = y; + this.w = w; + this.h = h; + } + } + + RepaintComponent component; + boolean busy; + + public QtRepaintThread() + { + component = null; + } + + public void run() + { + while( true ) + { + try + { + busy = false; + // Wait for a repaint + sleep(100); + busy = true; + } + catch (InterruptedException ie) + { + while( component != null ) + { + try + { + if( component.paintAll ) + { + // update the back-buffer. + component.curr.paintBackBuffer(); + component.curr.QtUpdate(); // trigger a native repaint event + } + else + { + component.curr.paintBackBuffer(component.x, component.y, + component.w, component.h); + component.curr.QtUpdateArea(component.x, component.y, + component.w, component.h); + } + } + catch (InterruptedException e) + { + } + component = component.next; + } + } + } + } + + /** + * Enqueue a component for repainting. + */ + public synchronized void queueComponent(QtComponentPeer p) + { + if( component == null ) + component = new RepaintComponent(p); + else + { + RepaintComponent r = component; + while( r.next != null ) r = r.next; + r.next = new RepaintComponent(p); + } + interrupt(); + } + + /** + * Enqueue a component for repainting. + */ + public synchronized void queueComponent(QtComponentPeer p, int x, int y, + int w, int h) + { + if( component == null ) + component = new RepaintComponent(p, x, y, w, h); + else + { + RepaintComponent r = component; + while( r.next != null ) r = r.next; + r.next = new RepaintComponent(p, x, y, w, h); + } + interrupt(); + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtScreenDevice.java b/libjava/classpath/gnu/java/awt/peer/qt/QtScreenDevice.java new file mode 100644 index 00000000000..c2d73aed1cb --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtScreenDevice.java @@ -0,0 +1,116 @@ +/* QtScreenDevice.java -- Wrapper on a Qt screen Widget + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.qt; + +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.DisplayMode; +import java.awt.GraphicsConfigTemplate; +import java.awt.Rectangle; +import java.awt.Window; + +public class QtScreenDevice extends GraphicsDevice +{ + private long nativeObject; + private int id; + private String IDstring; + QtScreenDeviceConfiguration config; + + public QtScreenDevice(int id) + { + this.id = id; + IDstring = "QtScreen" + id; + init( id ); + config = new QtScreenDeviceConfiguration(this); + } + + public native void init( int id ); + public native void dispose(); + + // Package-private methods used by QtScreenDeviceConfiguration + native Rectangle getBounds(); + native int getDpiX(); + native int getDpiY(); + native int depth(); + + // ****************** Public methods *********************** + + public GraphicsConfiguration getBestConfiguration(GraphicsConfigTemplate gct) + { + return config; + } + + public GraphicsConfiguration[] getConfigurations() + { + return new GraphicsConfiguration[]{ config }; + } + + public GraphicsConfiguration getDefaultConfiguration() + { + return config; + } + + public String getIDstring() + { + return IDstring; + } + + public int getType() + { + return TYPE_RASTER_SCREEN; + } + + public boolean isDisplayChangeSupported() + { + return false; + } + + public boolean isFullScreenSupported() + { + return false; + } + + public void setDisplayMode(DisplayMode dm) + { + } + + public void setFullScreenWindow(Window w) + { + } +} + diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtScreenDeviceConfiguration.java b/libjava/classpath/gnu/java/awt/peer/qt/QtScreenDeviceConfiguration.java new file mode 100644 index 00000000000..045cfdf3284 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtScreenDeviceConfiguration.java @@ -0,0 +1,147 @@ +/* QtScreenDeviceConfiguration.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.qt; + +import java.awt.DisplayMode; +import java.awt.ImageCapabilities; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsConfigTemplate; +import java.awt.Rectangle; +import java.awt.image.BufferedImage; +import java.awt.image.ColorModel; +import java.awt.image.VolatileImage; +import java.awt.geom.AffineTransform; + +public class QtScreenDeviceConfiguration extends GraphicsConfiguration { + + private QtScreenDevice owner; + private Rectangle bounds; + private double dpiX, dpiY; + private int depth; + + public QtScreenDeviceConfiguration(QtScreenDevice owner) + { + this.owner = owner; + bounds = owner.getBounds(); + dpiX = owner.getDpiX(); + dpiY = owner.getDpiY(); + depth = owner.depth(); + } + + public BufferedImage createCompatibleImage(int width, int height) + { + switch( depth ) + { + case 24: + return new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR); + case 16: + return new BufferedImage(width, height, + BufferedImage.TYPE_USHORT_565_RGB); + case 8: + return new BufferedImage(width, height, BufferedImage.TYPE_BYTE_INDEXED); + default: + case 32: + return new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + } + } + + public BufferedImage createCompatibleImage(int width, int height, int transparency) + { + // FIXME: Take the transpareny flag into account? + // For now, ignore it and just use an alpha channel. + if(depth == 32) + return new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); + return createCompatibleImage(width, height); + } + + public VolatileImage createCompatibleVolatileImage(int width, int height) + { + return new QtVolatileImage( width, height ); + } + + public VolatileImage createCompatibleVolatileImage(int width, int height, + ImageCapabilities caps) + { + return createCompatibleVolatileImage( width, height ); + } + + public Rectangle getBounds() + { + return bounds; + } + + public ColorModel getColorModel() + { + // FIXME? + return QtToolkit.getDefaultToolkit().getColorModel(); + } + + public ColorModel getColorModel(int transparency) + { + // FIXME? + return QtToolkit.getDefaultToolkit().getColorModel(); + } + + public AffineTransform getDefaultTransform() + { + return new AffineTransform(); + } + + public GraphicsDevice getDevice() + { + return owner; + } + + /** + * Returns the transform which transforms from this display's resolution + * to a 72 DPI resolution. + */ + public AffineTransform getNormalizingTransform() + { + AffineTransform nTrans = new AffineTransform(); + nTrans.scale( 72.0 / dpiX, 72.0 / dpiY ); + return nTrans; + } + + public VolatileImage createCompatibleVolatileImage(int width, int height, + int transparency) + { + return createCompatibleVolatileImage(width, height); + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtScrollPanePeer.java b/libjava/classpath/gnu/java/awt/peer/qt/QtScrollPanePeer.java new file mode 100644 index 00000000000..02fa8fb22cb --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtScrollPanePeer.java @@ -0,0 +1,91 @@ +/* QtScrollPanePeer.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.qt; + +import java.awt.Adjustable; +import java.awt.Dimension; +import java.awt.Insets; +import java.awt.ScrollPane; +import java.awt.peer.ScrollPanePeer; + +public class QtScrollPanePeer extends QtContainerPeer implements ScrollPanePeer +{ + public QtScrollPanePeer( QtToolkit kit, ScrollPane owner ) + { + super( kit, owner ); + } + + protected native void init(); + + protected void setup() + { + super.setup(); + setPolicy( ((ScrollPane)owner).getScrollbarDisplayPolicy() ); + } + + private native void setPolicy(int policy); + + // ************ Public methods ********************* + + public native void childResized(int width, int height); + + public native int getHScrollbarHeight(); + + public native int getVScrollbarWidth(); + + public native void setScrollPosition(int x, int y); + + public Insets getInsets() + { + // FIXME : more accurate? + return new Insets(5 + getHScrollbarHeight(), // Top + 5 + getVScrollbarWidth(), // Left + 5, // Bottom + 5); // Right + } + + public void setUnitIncrement(Adjustable item, int inc) + { + // FIXME + } + + public void setValue(Adjustable item, int value) + { + // FIXME + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtScrollbarPeer.java b/libjava/classpath/gnu/java/awt/peer/qt/QtScrollbarPeer.java new file mode 100644 index 00000000000..838cca62d20 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtScrollbarPeer.java @@ -0,0 +1,80 @@ +/* QtScrollbarPeer.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.qt; + +import java.awt.Scrollbar; +import java.awt.event.AdjustmentEvent; +import java.awt.peer.ScrollbarPeer; + +public class QtScrollbarPeer extends QtComponentPeer implements ScrollbarPeer +{ + public QtScrollbarPeer( QtToolkit kit, Scrollbar owner ) + { + super( kit, owner ); + } + + public native void init(); + + protected void setup() + { + super.setup(); + Scrollbar o = (Scrollbar)owner; + setValues(o.getValue(), o.getVisible(), o.getMinimum(), o.getMaximum()); + setOrientation(o.getOrientation()); + setLineIncrement(o.getLineIncrement()); + setPageIncrement(o.getPageIncrement()); + } + + private native void setOrientation(int orientation); + + private void fireMoved(int type, int value) + { + AdjustmentEvent e = new AdjustmentEvent((Scrollbar)owner, + AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED, + type, value); + QtToolkit.eventQueue.postEvent(e); + } + + // ************ Public methods ********************* + + public native void setLineIncrement(int inc); + + public native void setPageIncrement(int inc); + + public native void setValues(int value, int visible, int min, int max); +} diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtTextAreaPeer.java b/libjava/classpath/gnu/java/awt/peer/qt/QtTextAreaPeer.java new file mode 100644 index 00000000000..f37b9537cfa --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtTextAreaPeer.java @@ -0,0 +1,180 @@ +/* QtTextAreaPeer.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.qt; + +import java.awt.Dimension; +import java.awt.Rectangle; +import java.awt.TextArea; +import java.awt.event.TextEvent; +import java.awt.im.InputMethodRequests; +import java.awt.peer.TextAreaPeer; + +public class QtTextAreaPeer extends QtComponentPeer implements TextAreaPeer +{ + public QtTextAreaPeer( QtToolkit kit, TextArea owner ) + { + super( kit, owner ); + } + + protected native void init(); + + protected void setup() + { + super.setup(); + setText(((TextArea)owner).getText()); + setEditable(((TextArea)owner).isEditable()); + } + + /** + * Returns the start (start = true) or end (start = false) of the selection. + */ + private native int getSelection(boolean start); + + /** + * Called back on a text edit. + */ + private void textChanged() + { + TextEvent e = new TextEvent(owner, TextEvent.TEXT_VALUE_CHANGED); + QtToolkit.eventQueue.postEvent(e); + } + + // ************ Public methods ********************* + + public long filterEvents(long filter) + { + return filter; + } + + public native int getCaretPosition(); + + public Rectangle getCharacterBounds(int pos) + { + // FIXME + return new Rectangle(0,0,0,0); + } + + /** + * Implemented, but who uses it? + */ + public native int getIndexAtPoint(int x, int y); + +// public void reshape(int x, int y, +// int width, int height) +// { +// if(width != 0 || height != 0) +// super.reshape(x, y, width, height); +// else +// super.reshape(x, y, 10, 10); +// } + + public Dimension getMinimumSize(int rows, int cols) + { + // FIXME + return getMinimumSize(); + } + + public Dimension getPreferredSize(int rows, int cols) + { + // FIXME + return getPreferredSize(); + } + + public int getSelectionEnd() + { + return getSelection(false); + } + + public int getSelectionStart() + { + return getSelection(true); + } + + public native String getText(); + + public void insert(String text, int pos) + { + // Not very efficient, no. + String s = getText(); + setText(s.substring(0, pos) + text + s.substring(pos)); + } + + public void insertText(String text, int pos) + { + insert(text, pos); + } + + public Dimension minimumSize(int rows, int cols) + { + return getMinimumSize(rows, cols); + } + + public Dimension preferredSize(int rows, int cols) + { + return getPreferredSize(rows, cols); + } + + public void replaceRange(String insert, int start_pos, int end_pos) + { + // Not very efficient, no. + String text = getText(); + String right = text.substring(0, start_pos); + String left = text.substring(end_pos); + setText(right + insert + left); + } + + public void replaceText(String text, int start_pos, int end_pos) + { + replaceRange(text, start_pos, end_pos); + } + + public native void setText(String text); + + public native void select(int start_pos, int end_pos); + + public native void setEditable(boolean editable); + + public native void setCaretPosition(int pos); + + public InputMethodRequests getInputMethodRequests() + { + // TODO Auto-generated method stub + return null; + } +} + diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtTextFieldPeer.java b/libjava/classpath/gnu/java/awt/peer/qt/QtTextFieldPeer.java new file mode 100644 index 00000000000..0e3d5af7816 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtTextFieldPeer.java @@ -0,0 +1,160 @@ +/* QtTextFieldPeer.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.qt; + +import java.awt.Dimension; +import java.awt.Rectangle; +import java.awt.TextField; +import java.awt.event.TextEvent; +import java.awt.im.InputMethodRequests; +import java.awt.peer.TextFieldPeer; + +public class QtTextFieldPeer extends QtComponentPeer implements TextFieldPeer +{ + public QtTextFieldPeer( QtToolkit kit, TextField owner ) + { + super( kit, owner ); + } + + protected native void init(); + + protected void setup() + { + super.setup(); + setText(((TextField)owner).getText()); + setEditable(((TextField)owner).isEditable()); + } + + /** + * Called back on a text edit. + */ + private void textChanged() + { + TextEvent e = new TextEvent(owner, TextEvent.TEXT_VALUE_CHANGED); + QtToolkit.eventQueue.postEvent(e); + } + + /** + * Returns the start (start = true) or end (start = false) of the selection. + */ + private native int getSelection(boolean start); + + private native Dimension getMinimumSizeNative(int columns); + + private native Dimension getPreferredSizeNative(int columns); + + // ************ Public methods ********************* + + public long filterEvents(long e) + { + return e; + } + + public native int getCaretPosition(); + + public Rectangle getCharacterBounds(int i) + { + return new Rectangle(0,0,0,0); + } + + public int getIndexAtPoint(int x, int y) + { + // FIXME + return 0; + } + + public Dimension getMinimumSize(int columns) + { + Dimension d = getMinimumSizeNative( columns ); + if ( d == null ) + return new Dimension(10, 10); + return d; + } + + public Dimension getPreferredSize(int columns) + { + Dimension d = getPreferredSizeNative( columns ); + if ( d == null ) + return owner.getSize(); + return d; + } + + public int getSelectionEnd() + { + return getSelection(false); + } + + public int getSelectionStart() + { + return getSelection(true); + } + + public native String getText(); + + public Dimension minimumSize(int cols) + { + return getMinimumSize(cols); + } + + public Dimension preferredSize(int cols) + { + return getPreferredSize(cols); + } + + public native void select(int selStart, int selEnd); + + public native void setCaretPosition(int pos); + + public void setEchoCharacter(char c) + { + setEchoChar(c); + } + + public native void setEchoChar(char echoChar); + + public native void setEditable(boolean editable); + + public native void setText(String l); + + public InputMethodRequests getInputMethodRequests() + { + // TODO Auto-generated method stub + return null; + } +} + diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtToolkit.java b/libjava/classpath/gnu/java/awt/peer/qt/QtToolkit.java new file mode 100644 index 00000000000..54f4888cf8d --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtToolkit.java @@ -0,0 +1,470 @@ +/* QtToolkit.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.qt; + +import gnu.java.awt.EmbeddedWindow; +import gnu.java.awt.peer.ClasspathFontPeer; +import gnu.java.awt.peer.EmbeddedWindowPeer; +import gnu.java.awt.peer.ClasspathTextLayoutPeer; +import java.awt.AWTEvent; +import java.awt.AWTException; +import java.awt.Button; +import java.awt.Canvas; +import java.awt.Checkbox; +import java.awt.CheckboxMenuItem; +import java.awt.Choice; +import java.awt.Component; +import java.awt.Dialog; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Frame; +import java.awt.Image; +import java.awt.Label; +import java.awt.List; +import java.awt.MenuBar; +import java.awt.Menu; +import java.awt.MenuItem; +import java.awt.Panel; +import java.awt.TextArea; +import java.awt.TextField; +import java.awt.FileDialog; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.HeadlessException; +import java.awt.PopupMenu; +import java.awt.PrintJob; +import java.awt.Scrollbar; +import java.awt.ScrollPane; +import java.awt.Toolkit; +import java.awt.Window; +import java.awt.datatransfer.Clipboard; +import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragGestureRecognizer; +import java.awt.dnd.DragSource; +import java.awt.dnd.peer.DragSourceContextPeer; +import java.awt.event.AWTEventListener; +import java.awt.image.ColorModel; +import java.awt.image.DirectColorModel; +import java.awt.image.ImageObserver; +import java.awt.image.ImageProducer; +import java.awt.im.InputMethodHighlight; +import java.awt.peer.ButtonPeer; +import java.awt.peer.FontPeer; +import java.awt.peer.PanelPeer; +import java.awt.peer.CanvasPeer; +import java.awt.peer.FramePeer; +import java.awt.peer.PopupMenuPeer; +import java.awt.peer.CheckboxMenuItemPeer; +import java.awt.peer.LabelPeer; +import java.awt.peer.RobotPeer; +import java.awt.peer.CheckboxPeer; +import java.awt.peer.LightweightPeer; +import java.awt.peer.ScrollPanePeer; +import java.awt.peer.ChoicePeer; +import java.awt.peer.ListPeer; +import java.awt.peer.ScrollbarPeer; +import java.awt.peer.ComponentPeer; +import java.awt.peer.MenuBarPeer; +import java.awt.peer.TextAreaPeer; +import java.awt.peer.ContainerPeer; +import java.awt.peer.MenuComponentPeer; +import java.awt.peer.TextComponentPeer; +import java.awt.peer.DialogPeer; +import java.awt.peer.MenuItemPeer; +import java.awt.peer.TextFieldPeer; +import java.awt.peer.FileDialogPeer; +import java.awt.peer.MenuPeer; +import java.awt.peer.WindowPeer; +import java.awt.font.FontRenderContext; +import java.io.InputStream; +import java.net.URL; +import java.text.AttributedString; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import javax.imageio.spi.IIORegistry; + +import gnu.java.awt.ClasspathToolkit; + +public class QtToolkit extends ClasspathToolkit +{ + public static EventQueue eventQueue = null; // the native event queue + public static QtRepaintThread repaintThread = null; + public static MainQtThread guiThread = null; + public static QtGraphicsEnvironment graphicsEnv = null; + + private static void initToolkit() + { + eventQueue = new EventQueue(); + repaintThread = new QtRepaintThread(); + System.loadLibrary("qtpeer"); + + String theme = null; + try + { + String style = System.getProperty("qtoptions.style"); + if(style != null) + theme = style; + } + catch(SecurityException e) + { + } + catch(IllegalArgumentException e) + { + } + + boolean doublebuffer = true; + try + { + String style = System.getProperty("qtoptions.nodoublebuffer"); + if(style != null) + doublebuffer = false; + } + catch(SecurityException e) + { + } + catch(IllegalArgumentException e) + { + } + + guiThread = new MainQtThread( theme, doublebuffer ); + guiThread.start(); + repaintThread.start(); + } + + /** + * Construct the toolkit! + */ + public QtToolkit() + { + if( guiThread == null ) + initToolkit(); + + while (!guiThread.isRunning()); // make sure the GUI thread has started. + + if( graphicsEnv == null ) + graphicsEnv = new QtGraphicsEnvironment( this ); + } + + native String[] nativeFontFamilies(); + + native int numScreens(); + + native int defaultScreen(); + + // ************ Public methods ********************* + + public synchronized native void beep(); + + public int checkImage(Image image, int w, int h, ImageObserver observer) + { + if(image instanceof QtImage) + return ((QtImage)image).checkImage(observer); + + return ImageObserver.ERROR; // FIXME + } + + protected ButtonPeer createButton( Button target ) + { + return new QtButtonPeer( this, target ); + } + + protected CanvasPeer createCanvas(Canvas target) + { + return new QtCanvasPeer( this, target ); + } + + protected CheckboxPeer createCheckbox(Checkbox target) + { + return new QtCheckboxPeer( this, target ); + } + + protected ChoicePeer createChoice(Choice target) + { + return new QtChoicePeer( this, target ); + } + + protected CheckboxMenuItemPeer createCheckboxMenuItem(CheckboxMenuItem target) + { + return new QtMenuItemPeer( this, target ); + } + + public DragSourceContextPeer createDragSourceContextPeer(DragGestureEvent dge) + { + throw new RuntimeException("Not implemented"); + } + + protected FramePeer createFrame(Frame target) + { + return new QtFramePeer( this, target ); + } + + protected FileDialogPeer createFileDialog(FileDialog target) + { + return new QtFileDialogPeer( this, target ); + } + + public Image createImage(ImageProducer producer) + { + return new QtImage( producer ); + } + + public Image createImage(byte[] imageData, + int imageOffset, + int imageLength) + { + byte[] dataCopy = new byte[imageLength]; + System.arraycopy(imageData, imageOffset, dataCopy, 0, imageLength); + return new QtImage( dataCopy ); + } + + public Image createImage(String filename) + { + return new QtImage( filename ); + } + + public Image createImage(URL url) + { + return new QtImage( url ); + } + + protected TextFieldPeer createTextField(TextField target) + { + return new QtTextFieldPeer(this,target); + } + + protected LabelPeer createLabel(Label target) + { + return new QtLabelPeer( this, target ); + } + + protected ListPeer createList(List target) + { + return new QtListPeer( this, target ); + } + + protected ScrollbarPeer createScrollbar(Scrollbar target) + { + return new QtScrollbarPeer( this, target ); + } + + protected ScrollPanePeer createScrollPane(ScrollPane target) + { + return new QtScrollPanePeer( this, target ); + } + + protected TextAreaPeer createTextArea(TextArea target) + { + return new QtTextAreaPeer( this, target ); + } + + protected PanelPeer createPanel(Panel target) + { + return new QtPanelPeer( this, target); + } + + protected WindowPeer createWindow(Window target) + { + return new QtWindowPeer( this, target ); + } + + protected DialogPeer createDialog(Dialog target) + { + return new QtDialogPeer( this, target ); + } + + protected MenuBarPeer createMenuBar(MenuBar target) + { + return new QtMenuBarPeer( this, target ); + } + + protected MenuPeer createMenu(Menu target) + { + return new QtMenuPeer( this, target ); + } + + protected PopupMenuPeer createPopupMenu(PopupMenu target) + { + return new QtPopupMenuPeer( this, target ); + } + + protected MenuItemPeer createMenuItem(MenuItem target) + { + return new QtMenuItemPeer( this, target ); + } + + /** + * @since 1.4 + */ + public AWTEventListener[] getAWTEventListeners() + { + return null; // FIXME + } + + /** + * @since 1.4 + */ + public AWTEventListener[] getAWTEventListeners(long mask) + { + return null; // FIXME + } + + public ColorModel getColorModel() + { + return new DirectColorModel(32, + 0x00FF0000, + 0x0000FF00, + 0x000000FF, + 0xFF000000); + } + + /** + * Just return the defaults. + */ + public String[] getFontList() + { + String[] builtIn = new String[] { "Dialog", + "DialogInput", + "Monospaced", + "Serif", + "SansSerif" }; + String[] nat = nativeFontFamilies(); + String[] allFonts = new String[ nat.length + 5 ]; + System.arraycopy(builtIn, 0, allFonts, 0, 5); + System.arraycopy(nat, 0, allFonts, 5, nat.length); + return allFonts; + } + + public FontMetrics getFontMetrics(Font font) + { + return new QtFontMetrics(font); + } + + protected FontPeer getFontPeer(String name, + int style) + { + Map attrs = new HashMap (); + ClasspathFontPeer.copyStyleToAttrs(style, attrs); + ClasspathFontPeer.copySizeToAttrs(12, attrs); // Default size is 12. + return getClasspathFontPeer (name, attrs); + } + + public Image getImage(String filename) + { + return new QtImage(filename); + } + + public Image getImage(URL url) + { + return createImage( url ); + } + + public PrintJob getPrintJob(Frame frame, + String jobtitle, + Properties props) + { + throw new RuntimeException("Not implemented"); + } + + public Clipboard getSystemClipboard() + { + throw new RuntimeException("Not implemented"); + } + + protected EventQueue getSystemEventQueueImpl() + { + return eventQueue; + } + + public native Dimension getScreenSize(); + + public native int getScreenResolution(); + + public Map mapInputMethodHighlight(InputMethodHighlight highlight) + { + return null; // FIXME + } + + public boolean prepareImage(Image image, int w, int h, ImageObserver observer) + { + if(image instanceof QtImage) + return true; + return false; // FIXME? + } + + public native void sync(); + + // ********************** ClasspathToolkit methods + + public GraphicsEnvironment getLocalGraphicsEnvironment() + { + return graphicsEnv; + } + + public ClasspathFontPeer getClasspathFontPeer (String name, Map attrs) + { + return new QtFontPeer (name, attrs); + } + + public ClasspathTextLayoutPeer getClasspathTextLayoutPeer(AttributedString str, + FontRenderContext frc) + { + return null; + } + + // FIXME + public Font createFont(int format, InputStream stream) + { + throw new UnsupportedOperationException(); + } + + // FIXME + public RobotPeer createRobot (GraphicsDevice screen) throws AWTException + { + throw new UnsupportedOperationException(); + } + + public EmbeddedWindowPeer createEmbeddedWindow(EmbeddedWindow w) + { + // return new QtEmbeddedWindowPeer( this, w ); + return null; + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtVolatileImage.java b/libjava/classpath/gnu/java/awt/peer/qt/QtVolatileImage.java new file mode 100644 index 00000000000..0ec61deb3a6 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtVolatileImage.java @@ -0,0 +1,438 @@ +/* QtVolatileImage.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.qt; + +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Color; +import java.awt.Image; +import java.awt.ImageCapabilities; +import java.awt.GraphicsConfiguration; +import java.awt.image.BufferedImage; +import java.awt.image.ColorModel; +import java.awt.image.DirectColorModel; +import java.awt.image.MemoryImageSource; +import java.awt.image.ImageConsumer; +import java.awt.image.ImageObserver; +import java.awt.image.ImageProducer; +import java.awt.image.VolatileImage; +import java.io.File; +import java.io.IOException; +import java.util.Hashtable; +import java.util.WeakHashMap; +import java.util.Vector; + +/** + * QtVolatileImage - wraps a QImage + * + */ +public class QtVolatileImage extends VolatileImage +{ + int width = -1, height = -1; + + /** + * Properties. + */ + Hashtable props; + + /** + * Pointer to the QImage + */ + long nativeObject; + + /* + * The 32-bit AARRGGBB format the uses. + */ + static ColorModel nativeModel = new DirectColorModel(32, + 0x00FF0000, + 0x0000FF00, + 0x000000FF, + 0xFF000000); + + /** + * Clears the image to RGBA 0 + */ + public native void clear(); + + /** + * Returns a copy of the pixel data as a java array. + */ + private native int[] getPixels(); + + /** + * Allocates a QImage + */ + private native void createImage(); + + /** + * HashMap of Graphics objects painting on this Image. + */ + WeakHashMap painters; + + /** + * Flags if this image is to be destroyed. + */ + boolean killFlag; + + /** + * Frees the above. + */ + private native void freeImage(); + + /** + * Blit a QImage + */ + public native void blit(QtImage i); + public native void blit(QtImage i, int x, int y, int w, int h); + + /** + * Sets the image to scaled copy of src image. hints are rendering hints. + */ + private native void createScaledImage(QtVolatileImage src, int hints); + + /** + * Draws the image optionally composited. + */ + private native void drawPixels (QtGraphics gc, + int bg_red, int bg_green, int bg_blue, + int x, int y, + boolean composite); + /** + * Draws the image, optionally scaled and composited. + */ + private native void drawPixelsScaled (QtGraphics gc, + int bg_red, int bg_green, int bg_blue, + int x, int y, int width, int height, + boolean composite); + + /** + * Draws the image transformed. + */ + private native void drawPixelsTransformed (QtGraphics gc, QMatrix transform); + + /** + * Draws the image scaled flipped and optionally composited. + */ + native void drawPixelsScaledFlipped (QtGraphics gc, + int bg_red, int bg_green, + int bg_blue, + boolean flipX, boolean flipY, + int srcX, int srcY, + int srcWidth, int srcHeight, + int dstX, int dstY, + int dstWidth, int dstHeight, + boolean composite); + + /** + * Constructs an empty QtVolatileImage. + */ + public QtVolatileImage (int width, int height) + { + this.width = width; + this.height = height; + props = new Hashtable(); + createImage(); + clear(); + } + + /** + * Constructs a scaled version of the src bitmap, using Qt + */ + private QtVolatileImage (QtVolatileImage src, int width, int height, + int hints) + { + this.width = width; + this.height = height; + props = new Hashtable(); + + createScaledImage(src, hints); + } + + + public void finalize() + { + dispose(); + } + + public void dispose() + { + if( painters == null || painters.isEmpty() ) + freeImage(); + else + killFlag = true; // can't destroy image yet. + // Do so when all painters are gone. + } + + // java.awt.Image methods //////////////////////////////////////////////// + + public int getWidth (ImageObserver observer) + { + return getWidth(); + } + + public int getHeight (ImageObserver observer) + { + return getHeight(); + } + + public Object getProperty (String name, ImageObserver observer) + { + Object value = props.get (name); + return (value == null) ? UndefinedProperty : value; + } + + /** + * Returns the source of this image. + */ + public ImageProducer getSource () + { + return new MemoryImageSource(width, height, nativeModel, getPixels(), + 0, width); + } + + void putPainter(QtImageGraphics g) + { + if( painters == null ) + painters = new WeakHashMap(); + painters.put( g, "dummy" ); + } + + void removePainter(QtImageGraphics g) + { + painters.remove( g ); + if( killFlag && painters.isEmpty() ) + freeImage(); + } + + /** + * Creates a Graphics context for this image. + */ + public Graphics getGraphics () + { + QtImageGraphics g = new QtImageGraphics( this ); + putPainter( g ); + return g; + } + + /** + * Returns a scaled instance of this image. + */ + public Image getScaledInstance(int width, + int height, + int hints) + { + if (width <= 0 || height <= 0) + throw new IllegalArgumentException("Width and height of scaled bitmap"+ + "must be >= 0"); + + return new QtVolatileImage(this, width, height, hints); + } + + /** + */ + public void flush () + { + // FIXME ? + } + + /** + * Returns the image status, used by QtToolkit + */ + public int checkImage (ImageObserver observer) + { + return ImageObserver.ALLBITS | ImageObserver.WIDTH | ImageObserver.HEIGHT; + } + + // Drawing methods //////////////////////////////////////////////// + + /** + * Draws an image with eventual scaling/transforming. + */ + public boolean drawImage (QtGraphics g, QMatrix matrix, + ImageObserver observer) + { + drawPixelsTransformed (g, matrix); + return true; + } + + /** + * Draws an image to the QtGraphics context, at (x,y) with optional + * compositing with a background color. + */ + public boolean drawImage (QtGraphics g, int x, int y, + Color bgcolor, ImageObserver observer) + { + if(bgcolor != null) + drawPixels(g, bgcolor.getRed (), bgcolor.getGreen (), + bgcolor.getBlue (), x, y, true); + else + drawPixels(g, 0, 0, 0, x, y, false); + + return true; + } + + /** + * Draws an image to the QtGraphics context, at (x,y) scaled to + * width and height, with optional compositing with a background color. + */ + public boolean drawImage (QtGraphics g, int x, int y, int width, int height, + Color bgcolor, ImageObserver observer) + { + if(bgcolor != null) + drawPixelsScaled(g, bgcolor.getRed (), bgcolor.getGreen (), + bgcolor.getBlue (), x, y, width, height, true); + else + drawPixelsScaled(g, 0, 0, 0, x, y, width, height, false); + + return true; + } + + /** + * Draws an image with eventual scaling/transforming. + */ + public boolean drawImage (QtGraphics g, int dx1, int dy1, int dx2, int dy2, + int sx1, int sy1, int sx2, int sy2, + Color bgcolor, ImageObserver observer) + { + boolean flipX = (dx1 > dx2)^(sx1 > sx2); + boolean flipY = (dy1 > dy2)^(sy1 > sy2); + int dstWidth = Math.abs (dx2 - dx1); + int dstHeight = Math.abs (dy2 - dy1); + int srcWidth = Math.abs (sx2 - sx1); + int srcHeight = Math.abs (sy2 - sy1); + int srcX = (sx1 < sx2) ? sx1 : sx2; + int srcY = (sy1 < sy2) ? sy1 : sy2; + int dstX = (dx1 < dx2) ? dx1 : dx2; + int dstY = (dy1 < dy2) ? dy1 : dy2; + + // Clipping. This requires the dst to be scaled as well, + if (srcWidth > width) + { + dstWidth = (int)((double)dstWidth*((double)width/(double)srcWidth)); + srcWidth = width - srcX; + } + + if (srcHeight > height) + { + dstHeight = (int)((double)dstHeight*((double)height/(double)srcHeight)); + srcHeight = height - srcY; + } + + if (srcWidth + srcX > width) + { + dstWidth = (int)((double)dstWidth * (double)(width - srcX)/(double)srcWidth); + srcWidth = width - srcX; + } + + if (srcHeight + srcY > height) + { + dstHeight = (int)((double)dstHeight * (double)(width - srcY)/(double)srcHeight); + srcHeight = height - srcY; + } + + if ( srcWidth <= 0 || srcHeight <= 0 || dstWidth <= 0 || dstHeight <= 0) + return true; + + if(bgcolor != null) + drawPixelsScaledFlipped (g, bgcolor.getRed (), bgcolor.getGreen (), + bgcolor.getBlue (), + flipX, flipY, + srcX, srcY, + srcWidth, srcHeight, + dstX, dstY, + dstWidth, dstHeight, + true); + else + drawPixelsScaledFlipped (g, 0, 0, 0, flipX, flipY, + srcX, srcY, srcWidth, srcHeight, + dstX, dstY, dstWidth, dstHeight, + false); + return true; + } + + public native void copyArea(int x, int y, int width, int height, + int dx, int dy); + + //******************** VolatileImage stuff ******************** + + public boolean contentsLost() + { + return false; + } + + public Graphics2D createGraphics() + { + QtImageGraphics g = new QtImageGraphics(this); + putPainter( g ); + return g; + } + + public ImageCapabilities getCapabilities() + { + return new ImageCapabilities(false) + { + public boolean isTrueVolatile() + { + return false; + } + }; + } + + public int getHeight() + { + return height; + } + + public BufferedImage getSnapshot() + { + BufferedImage bi = new BufferedImage(width, height, + BufferedImage.TYPE_INT_ARGB_PRE); + bi.setRGB( 0, 0, width, height, getPixels(), 0, width); + return bi; + } + + public int getWidth() + { + return width; + } + + public int validate(GraphicsConfiguration gc) + { + return IMAGE_OK; + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtWindowPeer.java b/libjava/classpath/gnu/java/awt/peer/qt/QtWindowPeer.java new file mode 100644 index 00000000000..7baf8e6ebea --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtWindowPeer.java @@ -0,0 +1,80 @@ +/* QtWindowPeer.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.qt; + +import java.awt.Component; +import java.awt.peer.WindowPeer; + +public class QtWindowPeer extends QtContainerPeer implements WindowPeer +{ + public QtWindowPeer( QtToolkit kit, Component owner ) + { + super( kit, owner ); + } + + protected native void init(); + + protected void setup() + { + super.setup(); + } + + // ************ Public methods ********************* + + public native void toBack(); + + public native void toFront(); + + /* + * Belongs to Frame and Dialog, but no sense in duplicating code. + */ + public native void setTitle(String title); + + public void updateAlwaysOnTop() + { + // TODO Auto-generated method stub + + } + + public boolean requestWindowFocus() + { + // TODO Auto-generated method stub + return false; + } + +} diff --git a/libjava/classpath/gnu/xml/stream/AttributeImpl.java b/libjava/classpath/gnu/xml/stream/AttributeImpl.java new file mode 100644 index 00000000000..501575e56d8 --- /dev/null +++ b/libjava/classpath/gnu/xml/stream/AttributeImpl.java @@ -0,0 +1,124 @@ +/* AttributeImpl.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.stream; + +import java.io.IOException; +import java.io.Writer; +import javax.xml.namespace.QName; +import javax.xml.stream.events.Attribute; +import javax.xml.stream.Location; +import javax.xml.stream.XMLStreamException; + +/** + * An attribute event. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +public class AttributeImpl + extends XMLEventImpl + implements Attribute +{ + + protected final QName name; + protected final String value; + protected final QName type; + protected final boolean specified; + + protected AttributeImpl(Location location, + QName name, String value, QName type, + boolean specified) + { + super(location); + this.name = name; + this.value = value; + this.type = type; + this.specified = specified; + } + + public int getEventType() + { + return ATTRIBUTE; + } + + public QName getName() + { + return name; + } + + public String getValue() + { + return value; + } + + public QName getDTDType() + { + return type; + } + + public boolean isSpecified() + { + return specified; + } + + public void writeAsEncodedUnicode(Writer writer) + throws XMLStreamException + { + try + { + String prefix = name.getPrefix(); + if (prefix != null && !"".equals(prefix)) + { + writer.write(prefix); + writer.write(':'); + } + writer.write(name.getLocalPart()); + writer.write('='); + writer.write('"'); + writer.write(encode(value, true)); + writer.write('"'); + } + catch (IOException e) + { + XMLStreamException e2 = new XMLStreamException(e.getMessage()); + e2.initCause(e); + throw e2; + } + } + +} + diff --git a/libjava/classpath/gnu/xml/stream/CharactersImpl.java b/libjava/classpath/gnu/xml/stream/CharactersImpl.java new file mode 100644 index 00000000000..6df06582b87 --- /dev/null +++ b/libjava/classpath/gnu/xml/stream/CharactersImpl.java @@ -0,0 +1,120 @@ +/* CharactersImpl.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.stream; + +import java.io.IOException; +import java.io.Writer; +import javax.xml.stream.Location; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.events.Characters; + +/** + * A character data (text) event. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +public class CharactersImpl + extends XMLEventImpl + implements Characters +{ + + protected final String data; + protected final boolean whitespace; + protected final boolean cdata; + protected final boolean ignorableWhitespace; + + protected CharactersImpl(Location location, + String data, boolean whitespace, boolean cdata, + boolean ignorableWhitespace) + { + super(location); + this.data = data; + this.whitespace = whitespace; + this.cdata = cdata; + this.ignorableWhitespace = ignorableWhitespace; + } + + public int getEventType() + { + return cdata ? CDATA : whitespace ? SPACE : CHARACTERS; + } + + public String getData() + { + return data; + } + + public boolean isWhiteSpace() + { + return whitespace; + } + + public boolean isCData() + { + return cdata; + } + + public boolean isIgnorableWhiteSpace() + { + return ignorableWhitespace; + } + + public void writeAsEncodedUnicode(Writer writer) + throws XMLStreamException + { + try + { + if (cdata) + { + writer.write("<![CDATA["); + writer.write(data); + writer.write("]]>"); + } + else + writer.write(encode(data, false)); + } + catch (IOException e) + { + XMLStreamException e2 = new XMLStreamException(e.getMessage()); + e2.initCause(e); + throw e2; + } + } + +} + diff --git a/libjava/classpath/gnu/xml/stream/CommentImpl.java b/libjava/classpath/gnu/xml/stream/CommentImpl.java new file mode 100644 index 00000000000..5863fb05aec --- /dev/null +++ b/libjava/classpath/gnu/xml/stream/CommentImpl.java @@ -0,0 +1,92 @@ +/* CommentImpl.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.stream; + +import java.io.IOException; +import java.io.Writer; +import javax.xml.stream.Location; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.events.Comment; + +/** + * A comment event. + * + * @author <a href'mailto:dog@gnu.org'>Chris Burdess</a> + */ +public class CommentImpl + extends XMLEventImpl + implements Comment +{ + + protected final String text; + + protected CommentImpl(Location location, String text) + { + super(location); + this.text = text; + } + + public int getEventType() + { + return COMMENT; + } + + public String getText() + { + return text; + } + + public void writeAsEncodedUnicode(Writer writer) + throws XMLStreamException + { + try + { + writer.write("<!--"); + writer.write(encode(text, false)); + writer.write("-->"); + } + catch (IOException e) + { + XMLStreamException e2 = new XMLStreamException(e.getMessage()); + e2.initCause(e); + throw e2; + } + } + +} + diff --git a/libjava/classpath/gnu/xml/stream/DTDImpl.java b/libjava/classpath/gnu/xml/stream/DTDImpl.java new file mode 100644 index 00000000000..8e008aaede1 --- /dev/null +++ b/libjava/classpath/gnu/xml/stream/DTDImpl.java @@ -0,0 +1,115 @@ +/* DTDImpl.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.stream; + +import java.io.IOException; +import java.io.Writer; +import java.util.List; +import javax.xml.stream.Location; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.events.DTD; + +/** + * A DOCTYPE declaration event. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +public class DTDImpl + extends XMLEventImpl + implements DTD +{ + + protected final String body; + protected final Object impl; + protected final List notations; + protected final List entities; + + protected DTDImpl(Location location, + String body, Object impl, List notations, List entities) + { + super(location); + this.body = body; + this.impl = impl; + this.notations = notations; + this.entities = entities; + } + + public int getEventType() + { + return DTD; + } + + public String getDocumentTypeDeclaration() + { + return body; + } + + public Object getProcessedDTD() + { + return impl; + } + + public List getNotations() + { + return notations; + } + + public List getEntities() + { + return entities; + } + + public void writeAsEncodedUnicode(Writer writer) + throws XMLStreamException + { + try + { + writer.write("<!DOCTYPE "); + writer.write(body); + writer.write(">"); + } + catch (IOException e) + { + XMLStreamException e2 = new XMLStreamException(e.getMessage()); + e2.initCause(e); + throw e2; + } + } + +} + diff --git a/libjava/classpath/gnu/xml/stream/EndDocumentImpl.java b/libjava/classpath/gnu/xml/stream/EndDocumentImpl.java new file mode 100644 index 00000000000..7a5e2049e10 --- /dev/null +++ b/libjava/classpath/gnu/xml/stream/EndDocumentImpl.java @@ -0,0 +1,72 @@ +/* EndDocumentImpl.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.stream; + +import java.io.IOException; +import java.io.Writer; +import javax.xml.stream.Location; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.events.EndDocument; + +/** + * An end-document event. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +public class EndDocumentImpl + extends XMLEventImpl + implements EndDocument +{ + + protected EndDocumentImpl(Location location) + { + super(location); + } + + public int getEventType() + { + return END_DOCUMENT; + } + + public void writeAsEncodedUnicode(Writer writer) + throws XMLStreamException + { + } + +} + diff --git a/libjava/classpath/gnu/xml/stream/EndElementImpl.java b/libjava/classpath/gnu/xml/stream/EndElementImpl.java new file mode 100644 index 00000000000..7b5382ec5f3 --- /dev/null +++ b/libjava/classpath/gnu/xml/stream/EndElementImpl.java @@ -0,0 +1,108 @@ +/* EndElementImpl.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.stream; + +import java.io.IOException; +import java.io.Writer; +import java.util.Iterator; +import java.util.List; +import javax.xml.namespace.QName; +import javax.xml.stream.Location; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.events.EndElement; + +/** + * An end-element event. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +public class EndElementImpl + extends XMLEventImpl + implements EndElement +{ + + protected final QName name; + protected final List namespaces; + + protected EndElementImpl(Location location, QName name, List namespaces) + { + super(location); + this.name = name; + this.namespaces = namespaces; + } + + public int getEventType() + { + return END_ELEMENT; + } + + public QName getName() + { + return name; + } + + public Iterator getNamespaces() + { + return namespaces.iterator(); + } + + public void writeAsEncodedUnicode(Writer writer) + throws XMLStreamException + { + try + { + writer.write("</"); + String prefix = name.getPrefix(); + if (prefix != null && !"".equals(prefix)) + { + writer.write(prefix); + writer.write(':'); + } + writer.write(name.getLocalPart()); + writer.write(">"); + } + catch (IOException e) + { + XMLStreamException e2 = new XMLStreamException(e.getMessage()); + e2.initCause(e); + throw e2; + } + } + +} + diff --git a/libjava/classpath/gnu/xml/stream/EndEntityImpl.java b/libjava/classpath/gnu/xml/stream/EndEntityImpl.java new file mode 100644 index 00000000000..fd36ee267d3 --- /dev/null +++ b/libjava/classpath/gnu/xml/stream/EndEntityImpl.java @@ -0,0 +1,80 @@ +/* EndEntityImpl.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.stream; + +import java.io.IOException; +import java.io.Writer; +import javax.xml.stream.Location; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.events.EndEntity; + +/** + * An end-entity event. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +public class EndEntityImpl + extends XMLEventImpl + implements EndEntity +{ + + protected final String name; + + protected EndEntityImpl(Location location, String name) + { + super(location); + this.name = name; + } + + public int getEventType() + { + return END_ENTITY; + } + + public String getName() + { + return name; + } + + public void writeAsEncodedUnicode(Writer writer) + throws XMLStreamException + { + } + +} + diff --git a/libjava/classpath/gnu/xml/stream/EntityDeclarationImpl.java b/libjava/classpath/gnu/xml/stream/EntityDeclarationImpl.java new file mode 100644 index 00000000000..41ec2fb9b0d --- /dev/null +++ b/libjava/classpath/gnu/xml/stream/EntityDeclarationImpl.java @@ -0,0 +1,164 @@ +/* EntityDeclarationImpl.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.stream; + +import java.io.IOException; +import java.io.Writer; +import javax.xml.stream.Location; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.events.EntityDeclaration; + +/** + * An entity declaration event. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +public class EntityDeclarationImpl + extends XMLEventImpl + implements EntityDeclaration +{ + + protected final String publicId; + protected final String systemId; + protected final String name; + protected final String notationName; + protected final String replacementText; + protected final String baseUri; + + protected EntityDeclarationImpl(Location location, + String publicId, String systemId, + String name, String notationName, + String replacementText, String baseUri) + { + super(location); + this.publicId = publicId; + this.systemId = systemId; + this.name = name; + this.notationName = notationName; + this.replacementText = replacementText; + this.baseUri = baseUri; + } + + public int getEventType() + { + return ENTITY_DECLARATION; + } + + public String getPublicId() + { + return publicId; + } + + public String getSystemId() + { + return systemId; + } + + public String getName() + { + return name; + } + + public String getNotationName() + { + return notationName; + } + + public String getReplacementText() + { + return replacementText; + } + + public String getBaseURI() + { + return baseUri; + } + + public void writeAsEncodedUnicode(Writer writer) + throws XMLStreamException + { + try + { + writer.write("<!ENTITY "); + writer.write(name); + writer.write(' '); + if (systemId != null) + { + if (publicId != null) + { + writer.write(" PUBLIC "); + writer.write('"'); + writer.write(publicId); + writer.write('"'); + writer.write(' '); + writer.write('"'); + writer.write(systemId); + writer.write('"'); + } + else + { + writer.write(" SYSTEM "); + writer.write('"'); + writer.write(systemId); + writer.write('"'); + } + if (notationName != null) + { + writer.write(" NDATA "); + writer.write(notationName); + } + } + else + { + writer.write('"'); + if (replacementText != null) + writer.write(replacementText); + writer.write('"'); + } + writer.write(">"); + } + catch (IOException e) + { + XMLStreamException e2 = new XMLStreamException(e.getMessage()); + e2.initCause(e); + throw e2; + } + } + +} + diff --git a/libjava/classpath/gnu/xml/stream/EntityReferenceImpl.java b/libjava/classpath/gnu/xml/stream/EntityReferenceImpl.java new file mode 100644 index 00000000000..4b40bfa526a --- /dev/null +++ b/libjava/classpath/gnu/xml/stream/EntityReferenceImpl.java @@ -0,0 +1,132 @@ +/* EntityReferenceImpl.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.stream; + +import java.io.IOException; +import java.io.Writer; +import javax.xml.stream.Location; +import javax.xml.stream.XMLStreamException; +//import javax.xml.stream.events.EntityDeclaration; +import javax.xml.stream.events.EntityReference; + +/** + * An entity reference event. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +public class EntityReferenceImpl + extends XMLEventImpl + implements EntityReference +{ + + //protected final EntityDeclaration decl; + protected final String name; + protected final String baseUri; + protected final String publicId; + protected final String systemId; + protected final String replacementText; + + protected EntityReferenceImpl(Location location, + //EntityDeclaration decl, + String name, + String baseUri, String publicId, + String systemId, String replacementText) + { + super(location); + //this.decl = decl; + this.name = name; + this.baseUri = baseUri; + this.publicId = publicId; + this.systemId = systemId; + this.replacementText = replacementText; + } + + public int getEventType() + { + return ENTITY_REFERENCE; + } + + /*public EntityDeclaration getDeclaration() + { + return decl; + }*/ + + public String getName() + { + return name; + } + + public String getBaseUri() + { + return baseUri; + } + + public String getPublicId() + { + return publicId; + } + + public String getSystemId() + { + return systemId; + } + + public String getReplacementText() + { + return replacementText; + } + + public void writeAsEncodedUnicode(Writer writer) + throws XMLStreamException + { + try + { + writer.write('&'); + writer.write(name); + writer.write(';'); + } + catch (IOException e) + { + XMLStreamException e2 = new XMLStreamException(e.getMessage()); + e2.initCause(e); + throw e2; + } + } + +} + diff --git a/libjava/classpath/gnu/xml/stream/FilteredEventReader.java b/libjava/classpath/gnu/xml/stream/FilteredEventReader.java new file mode 100644 index 00000000000..3bf0f2518b5 --- /dev/null +++ b/libjava/classpath/gnu/xml/stream/FilteredEventReader.java @@ -0,0 +1,102 @@ +/* FilteredEventReader.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.stream; + +import javax.xml.stream.EventFilter; +import javax.xml.stream.XMLEventReader; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.events.XMLEvent; +import javax.xml.stream.util.EventReaderDelegate; + +class FilteredEventReader + extends EventReaderDelegate +{ + + final EventFilter filter; + + FilteredEventReader(XMLEventReader reader, EventFilter filter) + { + super(reader); + this.filter = filter; + } + + public boolean hasNext() + throws XMLStreamException + { + // XXX ??? + return super.hasNext(); + } + + public XMLEvent next() + throws XMLStreamException + { + XMLEvent ret; + do + { + ret = super.next(); + } + while (!filter.accept(ret)); + return ret; + } + + public XMLEvent peek() + throws XMLStreamException + { + XMLEvent ret; + do + { + ret = super.peek(); + } + while (!filter.accept(ret)); + return ret; + } + + public XMLEvent nextTag() + throws XMLStreamException + { + XMLEvent ret; + do + { + ret = super.nextTag(); + } + while (!filter.accept(ret)); + return ret; + } + +} + diff --git a/libjava/classpath/gnu/xml/stream/FilteredStreamReader.java b/libjava/classpath/gnu/xml/stream/FilteredStreamReader.java new file mode 100644 index 00000000000..1db02f6e30a --- /dev/null +++ b/libjava/classpath/gnu/xml/stream/FilteredStreamReader.java @@ -0,0 +1,91 @@ +/* FilteredStreamReader.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.stream; + +import javax.xml.stream.StreamFilter; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.util.ReaderDelegate; + +class FilteredStreamReader + extends ReaderDelegate +{ + + final XMLStreamReader reader; + final StreamFilter filter; + + FilteredStreamReader(XMLStreamReader reader, StreamFilter filter) + { + super(reader); + this.reader = reader; + this.filter = filter; + } + + public boolean hasNext() + throws XMLStreamException + { + // XXX ??? + return super.hasNext(); + } + + public int next() + throws XMLStreamException + { + int ret; + do + { + ret = super.next(); + } + while (!filter.accept(reader)); + return ret; + } + + public int nextTag() + throws XMLStreamException + { + int ret; + do + { + ret = super.nextTag(); + } + while (!filter.accept(reader)); + return ret; + } + +} + diff --git a/libjava/classpath/gnu/xml/stream/LocationImpl.java b/libjava/classpath/gnu/xml/stream/LocationImpl.java new file mode 100644 index 00000000000..1900aeb45c3 --- /dev/null +++ b/libjava/classpath/gnu/xml/stream/LocationImpl.java @@ -0,0 +1,89 @@ +/* LocationImpl.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.stream; + +import javax.xml.stream.Location; + +/** + * Information about the location of an XML event within the underlying + * stream. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +public class LocationImpl + implements Location +{ + + protected final int offset; + + protected final int col; + + protected final int line; + + protected final String systemId; + + protected LocationImpl(int offset, int col, int line, String systemId) + { + this.offset = offset; + this.col = col; + this.line = line; + this.systemId = systemId; + } + + public int getLineNumber() + { + return line; + } + + public int getColumnNumber() + { + return col; + } + + public int getCharacterOffset() + { + return offset; + } + + public String getLocationURI() + { + return systemId; + } + +} + diff --git a/libjava/classpath/gnu/xml/stream/NamespaceImpl.java b/libjava/classpath/gnu/xml/stream/NamespaceImpl.java new file mode 100644 index 00000000000..eeb57be6cac --- /dev/null +++ b/libjava/classpath/gnu/xml/stream/NamespaceImpl.java @@ -0,0 +1,111 @@ +/* NamespaceImpl.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.stream; + +import java.io.IOException; +import java.io.Writer; +import javax.xml.stream.Location; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.events.Namespace; + +/** + * A namespace declaration event. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +public class NamespaceImpl + extends XMLEventImpl + implements Namespace +{ + + protected final String prefix; + protected final String uri; + + protected NamespaceImpl(Location location, String prefix, String uri) + { + super(location); + this.prefix = prefix; + this.uri = uri; + } + + public int getEventType() + { + return NAMESPACE; + } + + public String getPrefix() + { + return prefix; + } + + public String getNamespaceURI() + { + return uri; + } + + public boolean isDefaultNamespaceDeclaration() + { + return (prefix == null || "".equals(prefix)); + } + + public void writeAsEncodedUnicode(Writer writer) + throws XMLStreamException + { + try + { + writer.write("xmlns"); + if (prefix != null && !"".equals(prefix)) + { + writer.write(':'); + writer.write(prefix); + } + writer.write('='); + writer.write('"'); + writer.write(encode(uri, true)); + writer.write('"'); + } + catch (IOException e) + { + XMLStreamException e2 = new XMLStreamException(e.getMessage()); + e2.initCause(e); + throw e2; + } + } + +} + diff --git a/libjava/classpath/gnu/xml/stream/NotationDeclarationImpl.java b/libjava/classpath/gnu/xml/stream/NotationDeclarationImpl.java new file mode 100644 index 00000000000..2d08599f577 --- /dev/null +++ b/libjava/classpath/gnu/xml/stream/NotationDeclarationImpl.java @@ -0,0 +1,126 @@ +/* NotationDeclarationImpl.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.stream; + +import java.io.IOException; +import java.io.Writer; +import javax.xml.stream.Location; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.events.NotationDeclaration; + +/** + * A notation declaration event. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +public class NotationDeclarationImpl + extends XMLEventImpl + implements NotationDeclaration +{ + + protected final String name; + protected final String publicId; + protected final String systemId; + + protected NotationDeclarationImpl(Location location, + String name, String publicId, + String systemId) + { + super(location); + this.name = name; + this.publicId = publicId; + this.systemId = systemId; + } + + public int getEventType() + { + return NOTATION_DECLARATION; + } + + public String getName() + { + return name; + } + + public String getPublicId() + { + return publicId; + } + + public String getSystemId() + { + return systemId; + } + + public void writeAsEncodedUnicode(Writer writer) + throws XMLStreamException + { + try + { + writer.write("<!NOTATION "); + writer.write(name); + if (publicId != null) + { + writer.write(" PUBLIC "); + writer.write('"'); + writer.write(publicId); + writer.write('"'); + writer.write(' '); + writer.write('"'); + writer.write(systemId); + writer.write('"'); + } + else + { + writer.write(" SYSTEM "); + writer.write('"'); + writer.write(systemId); + writer.write('"'); + } + writer.write('>'); + } + catch (IOException e) + { + XMLStreamException e2 = new XMLStreamException(e.getMessage()); + e2.initCause(e); + throw e2; + } + } + +} + diff --git a/libjava/classpath/gnu/xml/stream/ProcessingInstructionImpl.java b/libjava/classpath/gnu/xml/stream/ProcessingInstructionImpl.java new file mode 100644 index 00000000000..6a5028956ad --- /dev/null +++ b/libjava/classpath/gnu/xml/stream/ProcessingInstructionImpl.java @@ -0,0 +1,105 @@ +/* ProcessingInstructionImpl.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.stream; + +import java.io.IOException; +import java.io.Writer; +import javax.xml.stream.Location; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.events.ProcessingInstruction; + +/** + * A processing instruction event. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +public class ProcessingInstructionImpl + extends XMLEventImpl + implements ProcessingInstruction +{ + + protected final String target; + protected final String data; + + protected ProcessingInstructionImpl(Location location, + String target, String data) + { + super(location); + this.target = target; + this.data = data; + } + + public int getEventType() + { + return PROCESSING_INSTRUCTION; + } + + public String getTarget() + { + return target; + } + + public String getData() + { + return data; + } + + public void writeAsEncodedUnicode(Writer writer) + throws XMLStreamException + { + try + { + writer.write("<?"); + writer.write(target); + if (data != null) + { + writer.write(' '); + writer.write(data); + } + writer.write("?>"); + } + catch (IOException e) + { + XMLStreamException e2 = new XMLStreamException(e.getMessage()); + e2.initCause(e); + throw e2; + } + } + +} + diff --git a/libjava/classpath/gnu/xml/stream/StartDocumentImpl.java b/libjava/classpath/gnu/xml/stream/StartDocumentImpl.java new file mode 100644 index 00000000000..dc4251dd9bf --- /dev/null +++ b/libjava/classpath/gnu/xml/stream/StartDocumentImpl.java @@ -0,0 +1,144 @@ +/* StartDocumentImpl.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.stream; + +import java.io.IOException; +import java.io.Writer; +import javax.xml.stream.Location; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.events.StartDocument; + +/** + * A start-document event. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +public class StartDocumentImpl + extends XMLEventImpl + implements StartDocument +{ + + protected final String systemId; + protected final String encoding; + protected final String xmlVersion; + protected final boolean xmlStandalone; + protected final boolean standaloneDeclared; + protected final boolean encodingDeclared; + + protected StartDocumentImpl(Location location, + String systemId, String encoding, + String xmlVersion, boolean xmlStandalone, + boolean standaloneDeclared, + boolean encodingDeclared) + { + super(location); + this.systemId = systemId; + this.encoding = encoding; + this.xmlVersion = xmlVersion; + this.xmlStandalone = xmlStandalone; + this.standaloneDeclared = standaloneDeclared; + this.encodingDeclared = encodingDeclared; + } + + public int getEventType() + { + return START_DOCUMENT; + } + + public String getSystemId() + { + return systemId; + } + + public String getCharacterEncodingScheme() + { + return encoding; + } + + public boolean encodingSet() + { + return encodingDeclared; + } + + public boolean isStandalone() + { + return xmlStandalone; + } + + public boolean standaloneSet() + { + return standaloneDeclared; + } + + public String getVersion() + { + return xmlVersion; + } + + public void writeAsEncodedUnicode(Writer writer) + throws XMLStreamException + { + try + { + writer.write("<?xml version='"); + writer.write(xmlVersion); + writer.write('\''); + if (standaloneDeclared) + { + writer.write(" standalone='"); + writer.write(xmlStandalone ? "yes" : "no"); + writer.write('\''); + } + if (encodingDeclared) + { + writer.write(" encoding='"); + writer.write(encoding); + writer.write('\''); + } + writer.write("?>"); + } + catch (IOException e) + { + XMLStreamException e2 = new XMLStreamException(e.getMessage()); + e2.initCause(e); + throw e2; + } + } + +} + diff --git a/libjava/classpath/gnu/xml/stream/StartElementImpl.java b/libjava/classpath/gnu/xml/stream/StartElementImpl.java new file mode 100644 index 00000000000..48f88656046 --- /dev/null +++ b/libjava/classpath/gnu/xml/stream/StartElementImpl.java @@ -0,0 +1,153 @@ +/* StartElementImpl.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.stream; + +import java.io.IOException; +import java.io.Writer; +import java.util.Iterator; +import java.util.List; +import javax.xml.namespace.NamespaceContext; +import javax.xml.namespace.QName; +import javax.xml.stream.Location; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.events.Attribute; +import javax.xml.stream.events.Namespace; +import javax.xml.stream.events.StartElement; + +/** + * A start-element event. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +public class StartElementImpl + extends XMLEventImpl + implements StartElement +{ + + protected final QName name; + protected final List attributes; + protected final List namespaces; + protected final NamespaceContext namespaceContext; + + protected StartElementImpl(Location location, + QName name, List attributes, List namespaces, + NamespaceContext namespaceContext) + { + super(location); + this.name = name; + this.attributes = attributes; + this.namespaces = namespaces; + this.namespaceContext = namespaceContext; + } + + public int getEventType() + { + return START_ELEMENT; + } + + public QName getName() + { + return name; + } + + public Iterator getAttributes() + { + return attributes.iterator(); + } + + public Iterator getNamespaces() + { + return namespaces.iterator(); + } + + public Attribute getAttributeByName(QName name) + { + for (Iterator i = attributes.iterator(); i.hasNext(); ) + { + Attribute attr = (Attribute) i.next(); + if (name.equals(attr.getName())) + return attr; + } + return null; + } + + public NamespaceContext getNamespaceContext() + { + return namespaceContext; + } + + public String getNamespaceURI(String prefix) + { + return namespaceContext.getNamespaceURI(prefix); + } + + public void writeAsEncodedUnicode(Writer writer) + throws XMLStreamException + { + try + { + writer.write('<'); + String prefix = name.getPrefix(); + if (prefix != null && !"".equals(prefix)) + { + writer.write(prefix); + writer.write(':'); + } + writer.write(name.getLocalPart()); + for (Iterator i = namespaces.iterator(); i.hasNext(); ) + { + writer.write(' '); + ((Namespace) i.next()).writeAsEncodedUnicode(writer); + } + for (Iterator i = attributes.iterator(); i.hasNext(); ) + { + writer.write(' '); + ((Attribute) i.next()).writeAsEncodedUnicode(writer); + } + writer.write('>'); + } + catch (IOException e) + { + XMLStreamException e2 = new XMLStreamException(e.getMessage()); + e2.initCause(e); + throw e2; + } + } + +} + diff --git a/libjava/classpath/gnu/xml/stream/StartEntityImpl.java b/libjava/classpath/gnu/xml/stream/StartEntityImpl.java new file mode 100644 index 00000000000..6e4ca257a2c --- /dev/null +++ b/libjava/classpath/gnu/xml/stream/StartEntityImpl.java @@ -0,0 +1,80 @@ +/* StartEntityImpl.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.stream; + +import java.io.IOException; +import java.io.Writer; +import javax.xml.stream.Location; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.events.StartEntity; + +/** + * A start-entity event. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +public class StartEntityImpl + extends XMLEventImpl + implements StartEntity +{ + + protected final String name; + + protected StartEntityImpl(Location location, String name) + { + super(location); + this.name = name; + } + + public int getEventType() + { + return START_ENTITY; + } + + public String getName() + { + return name; + } + + public void writeAsEncodedUnicode(Writer writer) + throws XMLStreamException + { + } + +} + diff --git a/libjava/classpath/gnu/xml/stream/XMLEventAllocatorImpl.java b/libjava/classpath/gnu/xml/stream/XMLEventAllocatorImpl.java new file mode 100644 index 00000000000..4b21b6c7110 --- /dev/null +++ b/libjava/classpath/gnu/xml/stream/XMLEventAllocatorImpl.java @@ -0,0 +1,204 @@ +/* XMLEventAllocatorImpl.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.stream; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import javax.xml.namespace.QName; +import javax.xml.stream.Location; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.events.EntityDeclaration; +import javax.xml.stream.events.XMLEvent; +import javax.xml.stream.util.XMLEventAllocator; +import javax.xml.stream.util.XMLEventConsumer; + +/** + * Allocator for creating XML events based on a reader state. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +public class XMLEventAllocatorImpl + implements XMLEventAllocator +{ + + protected Map entityDeclarations; + + protected XMLEventAllocatorImpl() + { + entityDeclarations = new HashMap(); + } + + public XMLEvent allocate(XMLStreamReader reader) + throws XMLStreamException + { + String text; + boolean whitespace; + boolean ignorableWhitespace; + int len; + List namespaces; + int eventType = reader.getEventType(); + Location location = reader.getLocation(); + switch (eventType) + { + case XMLStreamConstants.CDATA: + text = reader.getText(); + whitespace = isWhitespace(text); + // TODO ignorableWhitespace + ignorableWhitespace = whitespace && false; + return new CharactersImpl(location, text, + whitespace, true, ignorableWhitespace); + case XMLStreamConstants.CHARACTERS: + text = reader.getText(); + whitespace = false; + // TODO ignorableWhitespace + ignorableWhitespace = whitespace && false; + return new CharactersImpl(location, text, + whitespace, false, ignorableWhitespace); + case XMLStreamConstants.COMMENT: + text = reader.getText(); + return new CommentImpl(location, text); + case XMLStreamConstants.DTD: + text = reader.getText(); + List notations = new LinkedList(); + List entities = new LinkedList(); + // TODO readDTDBody(notations, entities); + return new DTDImpl(location, text, null, notations, entities); + case XMLStreamConstants.END_DOCUMENT: + return new EndDocumentImpl(location); + case XMLStreamConstants.END_ELEMENT: + len = reader.getNamespaceCount(); + namespaces = new LinkedList(); + for (int i = 0; i < len; i++) + namespaces.add(new NamespaceImpl(location, + reader.getNamespacePrefix(i), + reader.getNamespaceURI(i))); + return new EndElementImpl(location, + reader.getName(), + namespaces); + case XMLStreamConstants.ENTITY_REFERENCE: + String name = reader.getLocalName(); + //EntityDeclaration decl = + // (EntityDeclaration) entityDeclarations.get(name); + //return new EntityReferenceImpl(location, decl, name); + return new EntityReferenceImpl(location, name, null, null, null, null); + case XMLStreamConstants.PROCESSING_INSTRUCTION: + return new ProcessingInstructionImpl(location, + reader.getPITarget(), + reader.getPIData()); + case XMLStreamConstants.SPACE: + text = reader.getText(); + whitespace = true; + // TODO ignorableWhitespace + ignorableWhitespace = whitespace && false; + return new CharactersImpl(location, text, + whitespace, false, ignorableWhitespace); + case XMLStreamConstants.START_DOCUMENT: + String systemId = location.getLocationURI(); + String encoding = reader.getCharacterEncodingScheme(); + boolean encodingDeclared = encoding != null; + if (encoding == null) + { + encoding = reader.getEncoding(); + if (encoding == null) + encoding = "UTF-8"; + } + String xmlVersion = reader.getVersion(); + if (xmlVersion == null) + xmlVersion = "1.0"; + boolean xmlStandalone = reader.isStandalone(); + boolean standaloneDeclared = reader.standaloneSet(); + return new StartDocumentImpl(location, + systemId, + encoding, + xmlVersion, + xmlStandalone, + standaloneDeclared, + encodingDeclared); + case XMLStreamConstants.START_ELEMENT: + len = reader.getNamespaceCount(); + namespaces = new LinkedList(); + for (int i = 0; i < len; i++) + namespaces.add(new NamespaceImpl(location, + reader.getNamespacePrefix(i), + reader.getNamespaceURI(i))); + len = reader.getAttributeCount(); + List attributes = new LinkedList(); + for (int i = 0; i < len; i++) + attributes.add(new AttributeImpl(location, + reader.getAttributeQName(i), + reader.getAttributeValue(i), + QName.valueOf(reader.getAttributeType(i)), + reader.isAttributeSpecified(i))); + return new StartElementImpl(location, + reader.getName(), + attributes, namespaces, + reader.getNamespaceContext()); + default: + throw new XMLStreamException("Unknown event type: " + eventType); + } + } + + public void allocate(XMLStreamReader reader, XMLEventConsumer consumer) + throws XMLStreamException + { + consumer.add(allocate(reader)); + } + + public XMLEventAllocator newInstance() + { + return new XMLEventAllocatorImpl(); + } + + protected boolean isWhitespace(String text) + { + int len = text.length(); + for (int i = 0; i < len; i++) + { + char c = text.charAt(i); + if (c != 0x20 && c != 0x09 && c != 0x0a && c != 0x0d) + return false; + } + return true; + } + +} + diff --git a/libjava/classpath/gnu/xml/stream/XMLEventFactoryImpl.java b/libjava/classpath/gnu/xml/stream/XMLEventFactoryImpl.java new file mode 100644 index 00000000000..a839b182c09 --- /dev/null +++ b/libjava/classpath/gnu/xml/stream/XMLEventFactoryImpl.java @@ -0,0 +1,271 @@ +/* XMLEventFactoryImpl.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.stream; + +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedList; +import javax.xml.XMLConstants; +import javax.xml.namespace.NamespaceContext; +import javax.xml.namespace.QName; +import javax.xml.stream.Location; +import javax.xml.stream.XMLEventFactory; +import javax.xml.stream.events.Attribute; +import javax.xml.stream.events.Characters; +import javax.xml.stream.events.Comment; +import javax.xml.stream.events.DTD; +import javax.xml.stream.events.EndDocument; +import javax.xml.stream.events.EndElement; +import javax.xml.stream.events.EntityDeclaration; +import javax.xml.stream.events.EntityReference; +import javax.xml.stream.events.Namespace; +import javax.xml.stream.events.ProcessingInstruction; +import javax.xml.stream.events.StartDocument; +import javax.xml.stream.events.StartElement; + +/** + * Factory for XML events. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +public class XMLEventFactoryImpl + extends XMLEventFactory +{ + + protected Location location; + + public void setLocation(Location location) + { + this.location = location; + } + + public Attribute createAttribute(String prefix, String namespaceURI, + String localName, String value) + { + return new AttributeImpl(location, + new QName(namespaceURI, localName, prefix), + value, QName.valueOf("CDATA"), true); + } + + public Attribute createAttribute(String localName, String value) + { + return new AttributeImpl(location, + new QName(localName), + value, QName.valueOf("CDATA"), true); + } + + public Attribute createAttribute(QName name, String value) + { + return new AttributeImpl(location, name, value, + QName.valueOf("CDATA"), true); + } + + public Namespace createNamespace(String namespaceURI) + { + return new NamespaceImpl(location, + XMLConstants.DEFAULT_NS_PREFIX, namespaceURI); + } + + public Namespace createNamespace(String prefix, String namespaceUri) + { + return new NamespaceImpl(location, prefix, namespaceUri); + } + + public StartElement createStartElement(QName name, + Iterator attributes, + Iterator namespaces) + { + return new StartElementImpl(location, name, + createLinkedList(attributes), + createLinkedList(namespaces), + null); + } + + public StartElement createStartElement(String prefix, + String namespaceUri, + String localName) + { + return new StartElementImpl(location, + new QName(namespaceUri, localName, prefix), + Collections.EMPTY_LIST, + Collections.EMPTY_LIST, + null); + } + + public StartElement createStartElement(String prefix, + String namespaceUri, + String localName, + Iterator attributes, + Iterator namespaces) + { + return new StartElementImpl(location, + new QName(namespaceUri, localName, prefix), + createLinkedList(attributes), + createLinkedList(namespaces), + null); + } + + public StartElement createStartElement(String prefix, + String namespaceUri, + String localName, + Iterator attributes, + Iterator namespaces, + NamespaceContext context) + { + return new StartElementImpl(location, + new QName(namespaceUri, localName, prefix), + createLinkedList(attributes), + createLinkedList(namespaces), + context); + } + + public EndElement createEndElement(QName name, + Iterator namespaces) + { + return new EndElementImpl(location, name, + createLinkedList(namespaces)); + } + + public EndElement createEndElement(String prefix, + String namespaceUri, + String localName) + { + return new EndElementImpl(location, + new QName(namespaceUri, localName, prefix), + Collections.EMPTY_LIST); + } + + public EndElement createEndElement(String prefix, + String namespaceUri, + String localName, + Iterator namespaces) + { + return new EndElementImpl(location, + new QName(namespaceUri, localName, prefix), + createLinkedList(namespaces)); + } + + public Characters createCharacters(String content) + { + return new CharactersImpl(location, content, false, false, false); + } + + public Characters createCData(String content) + { + return new CharactersImpl(location, content, false, true, false); + } + + public Characters createSpace(String content) + { + return new CharactersImpl(location, content, true, false, false); + } + + public Characters createIgnorableSpace(String content) + { + return new CharactersImpl(location, content, true, false, true); + } + + public StartDocument createStartDocument() + { + return new StartDocumentImpl(location, null, "UTF-8", "1.0", + false, false, false); + } + + public StartDocument createStartDocument(String encoding, + String version, + boolean standalone) + { + return new StartDocumentImpl(location, null, encoding, version, + standalone, true, true); + } + + public StartDocument createStartDocument(String encoding, + String version) + { + return new StartDocumentImpl(location, null, encoding, version, + false, false, true); + } + + public StartDocument createStartDocument(String encoding) + { + return new StartDocumentImpl(location, null, encoding, "1.0", + false, false, true); + } + + public EndDocument createEndDocument() + { + return new EndDocumentImpl(location); + } + + public EntityReference createEntityReference(String name, + //EntityDeclaration declaration) + String replacementText) + { + //return new EntityReferenceImpl(location, declaration, name); + return new EntityReferenceImpl(location, name, null, null, null, + replacementText); + } + + public Comment createComment(String text) + { + return new CommentImpl(location, text); + } + + public ProcessingInstruction createProcessingInstruction(String target, + String data) + { + return new ProcessingInstructionImpl(location, target, data); + } + + public DTD createDTD(String dtd) + { + return new DTDImpl(location, dtd, null, + Collections.EMPTY_LIST, + Collections.EMPTY_LIST); + } + + LinkedList createLinkedList(Iterator i) + { + LinkedList ret = new LinkedList(); + while (i.hasNext()) + ret.add(i.next()); + return ret; + } + +} + diff --git a/libjava/classpath/gnu/xml/stream/XMLEventImpl.java b/libjava/classpath/gnu/xml/stream/XMLEventImpl.java new file mode 100644 index 00000000000..a8b522f88a7 --- /dev/null +++ b/libjava/classpath/gnu/xml/stream/XMLEventImpl.java @@ -0,0 +1,208 @@ +/* XMLEventImpl.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.stream; + +import java.io.Writer; +import javax.xml.namespace.QName; +import javax.xml.stream.Location; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.events.Characters; +import javax.xml.stream.events.EndElement; +import javax.xml.stream.events.StartElement; +import javax.xml.stream.events.XMLEvent; + +/** + * An XML stream event. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +public abstract class XMLEventImpl + implements XMLEvent +{ + + protected final Location location; + + protected XMLEventImpl(Location location) + { + this.location = location; + } + + public abstract int getEventType(); + + public Location getLocation() + { + return location; + } + + public boolean isStartElement() + { + return getEventType() == START_ELEMENT; + } + + public boolean isAttribute() + { + return getEventType() == ATTRIBUTE; + } + + public boolean isNamespace() + { + return getEventType() == NAMESPACE; + } + + public boolean isEndElement() + { + return getEventType() == END_ELEMENT; + } + + public boolean isEntityReference() + { + return getEventType() == ENTITY_REFERENCE; + } + + public boolean isProcessingInstruction() + { + return getEventType() == PROCESSING_INSTRUCTION; + } + + public boolean isCharacters() + { + int et = getEventType(); + return et == CHARACTERS || et == CDATA; + } + + public boolean isStartDocument() + { + return getEventType() == START_DOCUMENT; + } + + public boolean isEndDocument() + { + return getEventType() == END_DOCUMENT; + } + + public boolean isStartEntity() + { + return getEventType() == START_ENTITY; + } + + public boolean isEndEntity() + { + return getEventType() == END_ENTITY; + } + + public StartElement asStartElement() + { + return (StartElement) this; + } + + public EndElement asEndElement() + { + return (EndElement) this; + } + + public Characters asCharacters() + { + return (Characters) this; + } + + public QName getSchemaType() + { + return null; + } + + public abstract void writeAsEncodedUnicode(Writer writer) + throws XMLStreamException; + + protected String encode(String text, boolean inAttr) + { + int len = text.length(); + StringBuffer buf = null; + for (int i = 0; i < len; i++) + { + char c = text.charAt(i); + if (c == '<') + { + if (buf == null) + { + buf = new StringBuffer(text.substring(0, i)); + } + buf.append("<"); + } + else if (c == '>') + { + if (buf == null) + { + buf = new StringBuffer(text.substring(0, i)); + } + buf.append(">"); + } + else if (c == '&') + { + if (buf == null) + { + buf = new StringBuffer(text.substring(0, i)); + } + buf.append("&"); + } + else if (c == '\'' && inAttr) + { + if (buf == null) + { + buf = new StringBuffer(text.substring(0, i)); + } + buf.append("'"); + } + else if (c == '"' && inAttr) + { + if (buf == null) + { + buf = new StringBuffer(text.substring(0, i)); + } + buf.append("""); + } + else if (buf != null) + { + buf.append(c); + } + } + return (buf == null) ? text : buf.toString(); + } + +} + diff --git a/libjava/classpath/gnu/xml/stream/XMLEventReaderImpl.java b/libjava/classpath/gnu/xml/stream/XMLEventReaderImpl.java new file mode 100644 index 00000000000..70481d7c407 --- /dev/null +++ b/libjava/classpath/gnu/xml/stream/XMLEventReaderImpl.java @@ -0,0 +1,125 @@ +/* XMLEventReaderImpl.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.stream; + +import javax.xml.stream.XMLEventReader; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.events.XMLEvent; +import javax.xml.stream.util.XMLEventAllocator; + +/** + * Parser using XML events. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +public class XMLEventReaderImpl + implements XMLEventReader +{ + + protected final XMLStreamReader reader; + protected final XMLEventAllocator allocator; + protected final String systemId; + protected XMLEvent peekEvent; + + protected XMLEventReaderImpl(XMLStreamReader reader, + XMLEventAllocator allocator, + String systemId) + { + this.reader = reader; + this.allocator = allocator; + this.systemId = systemId; + } + + public XMLEvent next() + throws XMLStreamException + { + XMLEvent ret = peek(); + peekEvent = null; + return ret; + } + + public boolean hasNext() + throws XMLStreamException + { + return peekEvent != null || reader.hasNext(); + } + + public XMLEvent peek() + throws XMLStreamException + { + if (peekEvent != null) + return peekEvent; + if (!reader.hasNext()) + return null; + reader.next(); + peekEvent = allocator.allocate(reader); + return peekEvent; + } + + public String getElementText() + throws XMLStreamException + { + return reader.getElementText(); + } + + public XMLEvent nextTag() + throws XMLStreamException + { + if (peekEvent != null) + { + int eventType = peekEvent.getEventType(); + if (eventType == XMLStreamConstants.START_ELEMENT || + eventType == XMLStreamConstants.END_ELEMENT) + return peekEvent; + else + peekEvent = null; + } + reader.nextTag(); + return allocator.allocate(reader); + } + + public Object getProperty(String name) + throws IllegalArgumentException + { + return reader.getProperty(name); + } + +} + diff --git a/libjava/classpath/gnu/xml/stream/XMLEventWriterImpl.java b/libjava/classpath/gnu/xml/stream/XMLEventWriterImpl.java new file mode 100644 index 00000000000..45024158da6 --- /dev/null +++ b/libjava/classpath/gnu/xml/stream/XMLEventWriterImpl.java @@ -0,0 +1,191 @@ +/* XMLEventWriterImpl.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.stream; + +import javax.xml.namespace.NamespaceContext; +import javax.xml.namespace.QName; +import javax.xml.stream.XMLEventReader; +import javax.xml.stream.XMLEventWriter; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamWriter; +import javax.xml.stream.events.Attribute; +import javax.xml.stream.events.Characters; +import javax.xml.stream.events.Comment; +import javax.xml.stream.events.DTD; +import javax.xml.stream.events.Namespace; +import javax.xml.stream.events.ProcessingInstruction; +import javax.xml.stream.events.StartDocument; +import javax.xml.stream.events.StartElement; +import javax.xml.stream.events.XMLEvent; + +/** + * Writer to write events to an underlying XML stream writer. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +public class XMLEventWriterImpl + implements XMLEventWriter +{ + + protected final XMLStreamWriter writer; + + protected XMLEventWriterImpl(XMLStreamWriter writer) + { + this.writer = writer; + } + + public void flush() + throws XMLStreamException + { + writer.flush(); + } + + public void close() + throws XMLStreamException + { + writer.close(); + } + + public void add(XMLEvent event) + throws XMLStreamException + { + QName name; + String uri; + switch (event.getEventType()) + { + case XMLStreamConstants.START_ELEMENT: + StartElement startElement = event.asStartElement(); + name = startElement.getName(); + uri = name.getNamespaceURI(); + if (uri != null && !"".equals(uri)) + writer.writeStartElement(name.getPrefix(), name.getLocalPart(), uri); + else + writer.writeStartElement(name.getLocalPart()); + break; + case XMLStreamConstants.END_ELEMENT: + writer.writeEndElement(); + break; + case XMLStreamConstants.ATTRIBUTE: + Attribute attribute = (Attribute) event; + name = attribute.getName(); + uri = name.getNamespaceURI(); + if (uri != null && !"".equals(uri)) + writer.writeAttribute(name.getPrefix(), uri, name.getLocalPart(), + attribute.getValue()); + else + writer.writeAttribute(name.getLocalPart(), attribute.getValue()); + break; + case XMLStreamConstants.NAMESPACE: + Namespace namespace = (Namespace) event; + uri = namespace.getNamespaceURI(); + writer.writeNamespace(namespace.getPrefix(), uri); + break; + case XMLStreamConstants.PROCESSING_INSTRUCTION: + ProcessingInstruction pi = (ProcessingInstruction) event; + String data = pi.getData(); + if (data == null) + writer.writeProcessingInstruction(pi.getTarget()); + else + writer.writeProcessingInstruction(pi.getTarget(), data); + break; + case XMLStreamConstants.COMMENT: + Comment comment = (Comment) event; + writer.writeComment(comment.getText()); + break; + case XMLStreamConstants.START_DOCUMENT: + StartDocument startDocument = (StartDocument) event; + writer.writeStartDocument(startDocument.getVersion()); + break; + case XMLStreamConstants.END_DOCUMENT: + writer.writeEndDocument(); + break; + case XMLStreamConstants.DTD: + DTD dtd = (DTD) event; + writer.writeDTD(dtd.getDocumentTypeDeclaration()); + break; + case XMLStreamConstants.CHARACTERS: + case XMLStreamConstants.SPACE: + Characters characters = event.asCharacters(); + writer.writeCharacters(characters.getData()); + break; + case XMLStreamConstants.CDATA: + Characters cdata = event.asCharacters(); + writer.writeCData(cdata.getData()); + break; + } + } + + public void add(XMLEventReader reader) + throws XMLStreamException + { + while (reader.hasNext()) + add(reader.next()); + } + + public String getPrefix(String uri) + throws XMLStreamException + { + return writer.getPrefix(uri); + } + + public void setPrefix(String prefix, String uri) + throws XMLStreamException + { + writer.setPrefix(prefix, uri); + } + + public void setDefaultNamespace(String uri) + throws XMLStreamException + { + writer.setDefaultNamespace(uri); + } + + public void setNamespaceContext(NamespaceContext context) + throws XMLStreamException + { + writer.setNamespaceContext(context); + } + + public NamespaceContext getNamespaceContext() + { + return writer.getNamespaceContext(); + } + +} + diff --git a/libjava/classpath/gnu/xml/stream/XMLInputFactoryImpl.java b/libjava/classpath/gnu/xml/stream/XMLInputFactoryImpl.java new file mode 100644 index 00000000000..c99f564b623 --- /dev/null +++ b/libjava/classpath/gnu/xml/stream/XMLInputFactoryImpl.java @@ -0,0 +1,321 @@ +/* XMLInputFactoryImpl.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.stream; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.io.IOException; +import java.io.Reader; +import java.net.MalformedURLException; +import java.net.URL; + +import javax.xml.transform.Source; +import javax.xml.transform.stream.StreamSource; +import javax.xml.stream.EventFilter; +import javax.xml.stream.StreamFilter; +import javax.xml.stream.XMLEventReader; +import javax.xml.stream.XMLReporter; +import javax.xml.stream.XMLResolver; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.util.XMLEventAllocator; + +/** + * Factory for creating parsers from various kinds of XML source. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +public class XMLInputFactoryImpl + extends XMLInputFactory +{ + + protected XMLResolver resolver; + protected XMLReporter reporter; + protected XMLEventAllocator allocator; + + protected boolean validating; + protected boolean namespaceAware = true; + protected boolean coalescing; + protected boolean replacingEntityReferences = true; + protected boolean externalEntities = true; + protected boolean supportDTD = true; + + public XMLInputFactoryImpl() + { + allocator = new XMLEventAllocatorImpl(); + } + + public XMLStreamReader createXMLStreamReader(Reader reader) + throws XMLStreamException + { + return new XMLStreamReaderImpl(reader, null, null, + resolver, reporter, + validating, namespaceAware, + coalescing, replacingEntityReferences, + externalEntities, supportDTD); + } + + public XMLStreamReader createXMLStreamReader(Source source) + throws XMLStreamException + { + String systemId = source.getSystemId(); + InputStream in = getInputStream(source); + return new XMLStreamReaderImpl(in, null, systemId, + resolver, reporter, + validating, namespaceAware, + coalescing, replacingEntityReferences, + externalEntities, supportDTD); + } + + public XMLStreamReader createXMLStreamReader(InputStream in) + throws XMLStreamException + { + return new XMLStreamReaderImpl(in, null, null, + resolver, reporter, + validating, namespaceAware, + coalescing, replacingEntityReferences, + externalEntities, supportDTD); + } + + public XMLStreamReader createXMLStreamReader(InputStream in, String encoding) + throws XMLStreamException + { + return createXMLStreamReader(in); + } + + public XMLEventReader createXMLEventReader(Reader reader) + throws XMLStreamException + { + XMLStreamReader sr = createXMLStreamReader(reader); + return new XMLEventReaderImpl(sr, allocator, null); + } + + public XMLEventReader createXMLEventReader(XMLStreamReader reader) + throws XMLStreamException + { + return new XMLEventReaderImpl(reader, allocator, null); + } + + public XMLEventReader createXMLEventReader(Source source) + throws XMLStreamException + { + XMLStreamReader sr = createXMLStreamReader(source); + return new XMLEventReaderImpl(sr, allocator, null); + } + + public XMLEventReader createXMLEventReader(InputStream in) + throws XMLStreamException + { + XMLStreamReader sr = createXMLStreamReader(in); + return new XMLEventReaderImpl(sr, allocator, null); + } + + public XMLEventReader createXMLEventReader(InputStream in, String encoding) + throws XMLStreamException + { + XMLStreamReader sr = createXMLStreamReader(in, encoding); + return new XMLEventReaderImpl(sr, allocator, null); + } + + public XMLStreamReader createFilteredReader(XMLStreamReader reader, + StreamFilter filter) + throws XMLStreamException + { + return new FilteredStreamReader(reader, filter); + } + + public XMLEventReader createFilteredReader(XMLEventReader reader, + EventFilter filter) + throws XMLStreamException + { + return new FilteredEventReader(reader, filter); + } + + public XMLResolver getXMLResolver() + { + return resolver; + } + + public void setXMLResolver(XMLResolver resolver) + { + this.resolver = resolver; + } + + public XMLReporter getXMLReporter() + { + return reporter; + } + + public void setXMLReporter(XMLReporter reporter) + { + this.reporter = reporter; + } + + public void setProperty(String name, Object value) + throws IllegalArgumentException + { + if (name.equals(IS_NAMESPACE_AWARE)) + namespaceAware = ((Boolean) value).booleanValue(); + else if (name.equals(IS_VALIDATING)) + validating = ((Boolean) value).booleanValue(); + else if (name.equals(IS_COALESCING)) + coalescing = ((Boolean) value).booleanValue(); + else if (name.equals(IS_REPLACING_ENTITY_REFERENCES)) + replacingEntityReferences = ((Boolean) value).booleanValue(); + else if (name.equals(IS_SUPPORTING_EXTERNAL_ENTITIES)) + externalEntities = ((Boolean) value).booleanValue(); + else if (name.equals(SUPPORT_DTD)) + supportDTD = ((Boolean) value).booleanValue(); + else if (name.equals(REPORTER)) + reporter = (XMLReporter) value; + else if (name.equals(RESOLVER)) + resolver = (XMLResolver) value; + else if (name.equals(ALLOCATOR)) + allocator = (XMLEventAllocator) value; + else + throw new IllegalArgumentException(name); + } + + public Object getProperty(String name) + throws IllegalArgumentException + { + if (name.equals(IS_NAMESPACE_AWARE)) + return namespaceAware ? Boolean.TRUE : Boolean.FALSE; + if (name.equals(IS_VALIDATING)) + return validating ? Boolean.TRUE : Boolean.FALSE; + if (name.equals(IS_COALESCING)) + return coalescing ? Boolean.TRUE : Boolean.FALSE; + if (name.equals(IS_REPLACING_ENTITY_REFERENCES)) + return replacingEntityReferences ? Boolean.TRUE : Boolean.FALSE; + if (name.equals(IS_SUPPORTING_EXTERNAL_ENTITIES)) + return externalEntities ? Boolean.TRUE : Boolean.FALSE; + if (name.equals(SUPPORT_DTD)) + return supportDTD ? Boolean.TRUE : Boolean.FALSE; + if (name.equals(REPORTER)) + return reporter; + if (name.equals(RESOLVER)) + return resolver; + if (name.equals(ALLOCATOR)) + return allocator; + throw new IllegalArgumentException(name); + } + + public boolean isPropertySupported(String name) + { + return name.equals(IS_NAMESPACE_AWARE) || + name.equals(IS_VALIDATING) || + name.equals(IS_COALESCING) || + name.equals(IS_REPLACING_ENTITY_REFERENCES) || + name.equals(IS_SUPPORTING_EXTERNAL_ENTITIES) || + name.equals(SUPPORT_DTD) || + name.equals(REPORTER) || + name.equals(RESOLVER) || + name.equals(ALLOCATOR); + } + + public void setEventAllocator(XMLEventAllocator allocator) + { + this.allocator = allocator; + } + + public XMLEventAllocator getEventAllocator() + { + return allocator; + } + + public void setCoalescing(boolean coalescing) + { + this.coalescing = coalescing; + } + + public boolean isCoalescing() + { + return coalescing; + } + + protected InputStream getInputStream(Source source) + throws XMLStreamException + { + InputStream in = null; + if (source instanceof StreamSource) + { + StreamSource streamSource = (StreamSource) source; + in = streamSource.getInputStream(); + } + if (in == null) + { + String systemId = source.getSystemId(); + try + { + URL url = new URL(systemId); + try + { + in = url.openStream(); + } + catch (IOException e2) + { + XMLStreamException e3 = new XMLStreamException(e2); + e3.initCause(e2); + throw e3; + } + } + catch (MalformedURLException e) + { + // Fall back to relative file + if (File.separatorChar != '/') + systemId = systemId.replace('/', File.separatorChar); + try + { + in = new FileInputStream(systemId); + } + catch (FileNotFoundException e2) + { + XMLStreamException e3 = new XMLStreamException(e2); + e3.initCause(e2); + throw e3; + } + } + } + return in; + } + +} + diff --git a/libjava/classpath/gnu/xml/stream/XMLOutputFactoryImpl.java b/libjava/classpath/gnu/xml/stream/XMLOutputFactoryImpl.java new file mode 100644 index 00000000000..25f520416e2 --- /dev/null +++ b/libjava/classpath/gnu/xml/stream/XMLOutputFactoryImpl.java @@ -0,0 +1,153 @@ +/* XMLOutputFactoryImpl.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.stream; + +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.io.UnsupportedEncodingException; + +import javax.xml.stream.XMLEventWriter; +import javax.xml.stream.XMLOutputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamWriter; + +/** + * Standard output factory. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +public class XMLOutputFactoryImpl + extends XMLOutputFactory +{ + + protected boolean prefixDefaulting = false; + + public XMLOutputFactoryImpl() + { + } + + public XMLStreamWriter createXMLStreamWriter(Writer stream) + throws XMLStreamException + { + // XXX try to determine character encoding of writer? + return new XMLStreamWriterImpl(stream, null, prefixDefaulting); + } + + public XMLStreamWriter createXMLStreamWriter(OutputStream stream) + throws XMLStreamException + { + return createXMLStreamWriter(stream, "UTF-8"); + } + + public XMLStreamWriter createXMLStreamWriter(OutputStream stream, + String encoding) + throws XMLStreamException + { + if (encoding == null) + encoding = "UTF-8"; + try + { + Writer writer = new OutputStreamWriter(stream, encoding); + return new XMLStreamWriterImpl(writer, encoding, prefixDefaulting); + } + catch (UnsupportedEncodingException e) + { + XMLStreamException e2 = new XMLStreamException(e); + e2.initCause(e); + throw e2; + } + } + + public XMLEventWriter createXMLEventWriter(OutputStream stream) + throws XMLStreamException + { + XMLStreamWriter writer = createXMLStreamWriter(stream); + return new XMLEventWriterImpl(writer); + } + + public XMLEventWriter createXMLEventWriter(OutputStream stream, + String encoding) + throws XMLStreamException + { + XMLStreamWriter writer = createXMLStreamWriter(stream, encoding); + return new XMLEventWriterImpl(writer); + } + + public XMLEventWriter createXMLEventWriter(Writer stream) + throws XMLStreamException + { + XMLStreamWriter writer = createXMLStreamWriter(stream); + return new XMLEventWriterImpl(writer); + } + + public void setProperty(String name, Object value) + throws IllegalArgumentException + { + if (IS_PREFIX_DEFAULTING.equals(name)) + prefixDefaulting = ((Boolean) value).booleanValue(); + throw new IllegalArgumentException(name); + } + + public Object getProperty(String name) + throws IllegalArgumentException + { + if (IS_PREFIX_DEFAULTING.equals(name)) + return new Boolean(prefixDefaulting); + throw new IllegalArgumentException(name); + } + + public boolean isPropertySupported(String name) + { + if (IS_PREFIX_DEFAULTING.equals(name)) + return true; + return false; + } + + public boolean isPrefixDefaulting() + { + return prefixDefaulting; + } + + public void setPrefixDefaulting(boolean value) + { + prefixDefaulting = value; + } + +} + diff --git a/libjava/classpath/gnu/xml/stream/XMLStreamReaderImpl.java b/libjava/classpath/gnu/xml/stream/XMLStreamReaderImpl.java new file mode 100644 index 00000000000..568d800ae0d --- /dev/null +++ b/libjava/classpath/gnu/xml/stream/XMLStreamReaderImpl.java @@ -0,0 +1,1037 @@ +/* XMLStreamReaderImpl.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.stream; + +import java.io.InputStream; +import java.io.IOException; +import java.io.Reader; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Map; +import javax.xml.namespace.NamespaceContext; +import javax.xml.namespace.QName; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; +import javax.xml.stream.Location; +import javax.xml.stream.XMLResolver; +import javax.xml.stream.XMLReporter; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import javax.xml.stream.events.Attribute; +import javax.xml.stream.events.Characters; +import javax.xml.stream.events.Comment; +import javax.xml.stream.events.DTD; +import javax.xml.stream.events.EndDocument; +import javax.xml.stream.events.EndElement; +import javax.xml.stream.events.EndEntity; +import javax.xml.stream.events.EntityDeclaration; +import javax.xml.stream.events.EntityReference; +import javax.xml.stream.events.Namespace; +import javax.xml.stream.events.NotationDeclaration; +import javax.xml.stream.events.ProcessingInstruction; +import javax.xml.stream.events.StartDocument; +import javax.xml.stream.events.StartElement; +import javax.xml.stream.events.StartEntity; +import javax.xml.stream.events.XMLEvent; + +import org.xml.sax.Attributes; +import org.xml.sax.ContentHandler; +import org.xml.sax.DTDHandler; +import org.xml.sax.EntityResolver; +import org.xml.sax.ErrorHandler; +import org.xml.sax.InputSource; +import org.xml.sax.Locator; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; +import org.xml.sax.XMLReader; +import org.xml.sax.ext.Attributes2; +import org.xml.sax.ext.DeclHandler; +import org.xml.sax.ext.LexicalHandler; +import org.xml.sax.ext.Locator2; +import org.xml.sax.helpers.NamespaceSupport; + +/** + * An XML parser. + * + * This implementation uses SAX to create a series of events in memory, + * and then iterates over this series. This has the advantage of being simple + * and unifying the existing XML parsing code. However, it is quite + * memory-inefficient and obviously won't cope with streams of arbitrary + * length. + * + * A future task could be to write a real, progressive/incremental + * implementation of this class. In that case we should consider making that + * the default XML parser implementation and using a SAX wrapper to it to + * provide the GNU SAX implementation. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +public class XMLStreamReaderImpl + implements XMLStreamReader, NamespaceContext +{ + + private LinkedList events; + private XMLEvent currentEvent; + private int eventType; + private NamespaceSupport namespaces; + + protected String publicId; + protected String systemId; + + protected XMLResolver resolver; + protected XMLReporter reporter; + protected boolean validating; + protected boolean namespaceAware; + protected boolean coalescing; + protected boolean replacingEntityReferences; + protected boolean externalEntities; + protected boolean supportDTD; + + protected XMLStreamReaderImpl(InputStream in, + String publicId, + String systemId, + XMLResolver resolver, + XMLReporter reporter, + boolean validating, + boolean namespaceAware, + boolean coalescing, + boolean replacingEntityReferences, + boolean externalEntities, + boolean supportDTD) + throws XMLStreamException + { + //this.in = in; + this.publicId = publicId; + this.systemId = systemId; + this.resolver = resolver; + this.reporter = reporter; + this.validating = validating; + this.namespaceAware = namespaceAware; + this.coalescing = coalescing; + this.replacingEntityReferences = replacingEntityReferences; + this.externalEntities = externalEntities; + this.supportDTD = supportDTD; + namespaces = new NamespaceSupport(); + events = new LinkedList(); + + // Configure the SAX parser and perform the parse + try + { + SAXParserFactory f = SAXParserFactory.newInstance(); + f.setNamespaceAware(namespaceAware); + f.setValidating(validating); + SAXParser p = f.newSAXParser(); + XMLReader r = p.getXMLReader(); + CallbackHandler ch = this.new CallbackHandler(r); + r.setFeature("http://xml.org/sax/features/external-general-entities", + externalEntities); + r.setFeature("http://xml.org/sax/features/namespaces", + namespaceAware); + r.setContentHandler(ch); + r.setDTDHandler(ch); + r.setEntityResolver(ch); + r.setErrorHandler(ch); + r.setProperty("http://xml.org/sax/properties/lexical-handler", + ch); + InputSource source = new InputSource(in); + source.setSystemId(systemId); + r.parse(source); + } + catch (SAXException e) + { + events.add(e); + } + catch (IOException e) + { + events.add(e); + } + catch (ParserConfigurationException e) + { + XMLStreamException e2 = new XMLStreamException(e); + e2.initCause(e); + throw e2; + } + } + + protected XMLStreamReaderImpl(Reader reader, + String publicId, + String systemId, + XMLResolver resolver, + XMLReporter reporter, + boolean validating, + boolean namespaceAware, + boolean coalescing, + boolean replacingEntityReferences, + boolean externalEntities, + boolean supportDTD) + throws XMLStreamException + { + //this.reader = reader; + this.publicId = publicId; + this.systemId = systemId; + this.resolver = resolver; + this.reporter = reporter; + this.validating = validating; + this.namespaceAware = namespaceAware; + this.coalescing = coalescing; + this.replacingEntityReferences = replacingEntityReferences; + this.externalEntities = externalEntities; + this.supportDTD = supportDTD; + namespaces = new NamespaceSupport(); + events = new LinkedList(); + + // Configure the SAX parser and perform the parse + try + { + SAXParserFactory f = SAXParserFactory.newInstance(); + f.setNamespaceAware(namespaceAware); + f.setValidating(validating); + SAXParser p = f.newSAXParser(); + XMLReader r = p.getXMLReader(); + CallbackHandler ch = this.new CallbackHandler(r); + r.setFeature("http://xml.org/sax/features/external-general-entities", + externalEntities); + r.setFeature("http://xml.org/sax/features/namespaces", + namespaceAware); + r.setContentHandler(ch); + r.setDTDHandler(ch); + r.setEntityResolver(ch); + r.setErrorHandler(ch); + r.setProperty("http://xml.org/sax/properties/lexical-handler", + ch); + InputSource source = new InputSource(reader); + source.setSystemId(systemId); + r.parse(source); + } + catch (SAXException e) + { + events.add(e); + } + catch (IOException e) + { + events.add(e); + } + catch (ParserConfigurationException e) + { + XMLStreamException e2 = new XMLStreamException(e); + e2.initCause(e); + throw e2; + } + } + + public Object getProperty(String name) + throws IllegalArgumentException + { + throw new IllegalArgumentException(name); + } + + public int next() + throws XMLStreamException + { + if (events.isEmpty()) + throw new XMLStreamException("EOF"); + Object event = events.removeFirst(); + if (event instanceof Exception) + { + Exception e = (Exception) event; + XMLStreamException e2 = new XMLStreamException(e); + e2.initCause(e); + throw e2; + } + currentEvent = (XMLEvent) event; + eventType = currentEvent.getEventType(); + return eventType; + } + + public void require(int type, String namespaceURI, String localName) + throws XMLStreamException + { + // TODO + throw new UnsupportedOperationException(); + } + + public String getElementText() + throws XMLStreamException + { + // TODO + throw new UnsupportedOperationException(); + } + + public int nextTag() + throws XMLStreamException + { + int ret; + do + { + ret = next(); + } + while (ret != XMLStreamConstants.START_ELEMENT && + ret != XMLStreamConstants.END_ELEMENT); + return ret; + } + + public boolean hasNext() + throws XMLStreamException + { + return !events.isEmpty(); + } + + public void close() + throws XMLStreamException + { + } + + public String getNamespaceURI(String prefix) + { + return namespaces.getURI(prefix); + } + + public String getPrefix(String namespaceURI) + { + return namespaces.getPrefix(namespaceURI); + } + + public Iterator getPrefixes(String namespaceURI) + { + LinkedList acc = new LinkedList(); + for (Enumeration e = namespaces.getPrefixes(namespaceURI); + e.hasMoreElements(); ) + acc.add(e.nextElement()); + return acc.iterator(); + } + + public boolean isStartElement() + { + return eventType == START_ELEMENT; + } + + public boolean isEndElement() + { + return eventType == END_ELEMENT; + } + + public boolean isCharacters() + { + return eventType == CHARACTERS || eventType == CDATA; + } + + public boolean isWhiteSpace() + { + return eventType == SPACE; + } + + public String getAttributeValue(String namespaceURI, String localName) + { + StartElement se = (StartElement) currentEvent; + for (Iterator i = se.getAttributes(); i.hasNext(); ) + { + Attribute attr = (Attribute) i.next(); + QName name = attr.getName(); + if (namespaceURI != null && + !namespaceURI.equals(name.getNamespaceURI())) + continue; + if (!localName.equals(name.getLocalPart())) + continue; + return attr.getValue(); + } + return null; + } + + public int getAttributeCount() + { + StartElement se = (StartElement) currentEvent; + int count = 0; + for (Iterator i = se.getAttributes(); i.hasNext(); ) + { + i.next(); + count++; + } + return count; + } + + public QName getAttributeQName(int index) + { + StartElement se = (StartElement) currentEvent; + int count = 0; + for (Iterator i = se.getAttributes(); i.hasNext(); ) + { + Attribute attr = (Attribute) i.next(); + if (index == count) + return attr.getName(); + count++; + } + return null; + } + + public String getAttributeNamespace(int index) + { + QName name = getAttributeQName(index); + return (name == null) ? null : name.getNamespaceURI(); + } + + public String getAttributeName(int index) + { + QName name = getAttributeQName(index); + return (name == null) ? null : name.getLocalPart(); + } + + public String getAttributePrefix(int index) + { + QName name = getAttributeQName(index); + return (name == null) ? null : name.getPrefix(); + } + + public String getAttributeType(int index) + { + StartElement se = (StartElement) currentEvent; + int count = 0; + for (Iterator i = se.getAttributes(); i.hasNext(); ) + { + Attribute attr = (Attribute) i.next(); + if (index == count) + { + QName type = attr.getDTDType(); + return (type == null) ? "CDATA" : type.toString(); + } + count++; + } + return null; + } + + public String getAttributeValue(int index) + { + StartElement se = (StartElement) currentEvent; + int count = 0; + for (Iterator i = se.getAttributes(); i.hasNext(); ) + { + Attribute attr = (Attribute) i.next(); + if (index == count) + return attr.getValue(); + count++; + } + return null; + } + + public boolean isAttributeSpecified(int index) + { + StartElement se = (StartElement) currentEvent; + int count = 0; + for (Iterator i = se.getAttributes(); i.hasNext(); ) + { + Attribute attr = (Attribute) i.next(); + if (index == count) + return attr.isSpecified(); + count++; + } + return false; + } + + public int getNamespaceCount() + { + Iterator i = null; + switch (eventType) + { + case XMLStreamConstants.START_ELEMENT: + i = ((StartElement) currentEvent).getNamespaces(); + break; + case XMLStreamConstants.END_ELEMENT: + i = ((EndElement) currentEvent).getNamespaces(); + break; + default: + throw new IllegalStateException(); + } + int count = 0; + while (i.hasNext()) + { + i.next(); + count++; + } + return count; + } + + public String getNamespacePrefix(int index) + { + Iterator i = null; + switch (eventType) + { + case XMLStreamConstants.START_ELEMENT: + i = ((StartElement) currentEvent).getNamespaces(); + break; + case XMLStreamConstants.END_ELEMENT: + i = ((EndElement) currentEvent).getNamespaces(); + break; + default: + throw new IllegalStateException(); + } + int count = 0; + while (i.hasNext()) + { + Namespace ns = (Namespace) i.next(); + if (index == count) + return ns.getPrefix(); + count++; + } + return null; + } + + public String getNamespaceURI(int index) + { + Iterator i = null; + switch (eventType) + { + case XMLStreamConstants.START_ELEMENT: + i = ((StartElement) currentEvent).getNamespaces(); + break; + case XMLStreamConstants.END_ELEMENT: + i = ((EndElement) currentEvent).getNamespaces(); + break; + default: + throw new IllegalStateException(); + } + int count = 0; + while (i.hasNext()) + { + Namespace ns = (Namespace) i.next(); + if (index == count) + return ns.getNamespaceURI(); + count++; + } + return null; + } + + public NamespaceContext getNamespaceContext() + { + return this; + } + + public int getEventType() + { + return eventType; + } + + public String getText() + { + switch (eventType) + { + case XMLStreamConstants.CHARACTERS: + case XMLStreamConstants.CDATA: + case XMLStreamConstants.SPACE: + return ((Characters) currentEvent).getData(); + case XMLStreamConstants.COMMENT: + return ((Comment) currentEvent).getText(); + case XMLStreamConstants.ENTITY_REFERENCE: + return ((EntityReference) currentEvent).getReplacementText(); + case XMLStreamConstants.DTD: + return ((DTD) currentEvent).getDocumentTypeDeclaration(); + } + return null; + } + + public char[] getTextCharacters() + { + String text = getText(); + return (text == null) ? null : text.toCharArray(); + } + + public int getTextCharacters(int sourceStart, char[] target, + int targetStart, int length) + throws XMLStreamException + { + char[] source = getTextCharacters(); + int len = Math.min(source.length, length); + System.arraycopy(source, sourceStart, target, targetStart, len); + return len; + } + + public int getTextStart() + { + return 0; + } + + public int getTextLength() + { + String text = getText(); + return (text == null) ? 0 : text.length(); + } + + public String getEncoding() + { + // XXX SAX doesn't provide this + return null; + } + + public boolean hasText() + { + return eventType == CHARACTERS || eventType == DTD || + eventType == SPACE || eventType == ENTITY_REFERENCE || + eventType == COMMENT || eventType == DTD; + } + + public Location getLocation() + { + return currentEvent.getLocation(); + } + + public QName getName() + { + switch (eventType) + { + case XMLStreamConstants.START_ELEMENT: + return ((StartElement) currentEvent).getName(); + case XMLStreamConstants.END_ELEMENT: + return ((EndElement) currentEvent).getName(); + case XMLStreamConstants.ATTRIBUTE: + return ((Attribute) currentEvent).getName(); + } + return null; + } + + public String getLocalName() + { + QName name = getName(); + return (name == null) ? null : name.getLocalPart(); + } + + public boolean hasName() + { + return getName() != null; + } + + public String getNamespaceURI() + { + QName name = getName(); + return (name == null) ? null : name.getNamespaceURI(); + } + + public String getPrefix() + { + QName name = getName(); + return (name == null) ? null : name.getPrefix(); + } + + public String getVersion() + { + StartDocument sd = (StartDocument) currentEvent; + return sd.getVersion(); + } + + public boolean isStandalone() + { + StartDocument sd = (StartDocument) currentEvent; + return sd.isStandalone(); + } + + public boolean standaloneSet() + { + StartDocument sd = (StartDocument) currentEvent; + return sd.standaloneSet(); + } + + public String getCharacterEncodingScheme() + { + StartDocument sd = (StartDocument) currentEvent; + return sd.getCharacterEncodingScheme(); + } + + public String getPITarget() + { + ProcessingInstruction pi = (ProcessingInstruction) currentEvent; + return pi.getTarget(); + } + + public String getPIData() + { + ProcessingInstruction pi = (ProcessingInstruction) currentEvent; + return pi.getData(); + } + + /** + * This class is used to construct the event series from SAX callbacks. + */ + class CallbackHandler + implements ContentHandler, DTDHandler, LexicalHandler, + DeclHandler, EntityResolver, ErrorHandler + { + + XMLReader reader; + Locator locator; + Location location; + private boolean inCDATA; + private LinkedList namespaces = new LinkedList(); + private LinkedList notations; + private LinkedList entities; + + CallbackHandler(XMLReader reader) + { + this.reader = reader; + } + + public void setDocumentLocator(Locator locator) + { + this.locator = locator; + location = new LocationImpl(-1, + locator.getColumnNumber(), + locator.getLineNumber(), + locator.getSystemId()); + } + + public void startDocument() + throws SAXException + { + String version = (locator instanceof Locator2) ? + ((Locator2) locator).getXMLVersion() : null; + String encoding = (locator instanceof Locator2) ? + ((Locator2) locator).getEncoding() : null; + boolean standalone = + reader.getFeature("http://xml.org/sax/features/is-standalone"); + boolean standaloneDeclared = standalone; + boolean encodingDeclared = (encoding != null); + events.add(new StartDocumentImpl(location, + location.getLocationURI(), + encoding, + version, + standalone, + standaloneDeclared, + encodingDeclared)); + } + + public void endDocument() + throws SAXException + { + events.add(new EndDocumentImpl(location)); + } + + public void startPrefixMapping(String prefix, String uri) + throws SAXException + { + namespaces.add(new NamespaceImpl(location, prefix, uri)); + } + + public void endPrefixMapping(String prefix) + throws SAXException + { + } + + public void startElement(String namespaceURI, String localName, + String qName, Attributes atts) + throws SAXException + { + LinkedList ns = namespaces; + namespaces = new LinkedList(); + int ci = qName.indexOf(':'); + String prefix = null; + localName = qName; + if (ci != -1) + { + prefix = qName.substring(0, ci); + localName = qName.substring(ci + 1); + } + QName name = new QName(namespaceURI, localName, prefix); + LinkedList attrs = new LinkedList(); + StartElementImpl se = new StartElementImpl(location, name, + attrs, ns, null); + events.add(se); + // Add namespaces + //for (Iterator i = ns.iterator(); i.hasNext(); ) + // events.add(i.next()); + // Add attributes + int len = atts.getLength(); + for (int i = 0; i < len; i++) + { + String attURI = atts.getURI(i); + String attQName = atts.getQName(i); + String value = atts.getValue(i); + QName type = QName.valueOf(atts.getType(i)); + boolean specified = (atts instanceof Attributes2) && + ((Attributes2) atts).isSpecified(i); + ci = attQName.indexOf(':'); + String attPrefix = null; + String attLocalName = attQName; + if (ci != -1) + { + attPrefix = attQName.substring(0, ci); + attLocalName = attQName.substring(ci + 1); + } + if ("xmlns".equals(attPrefix) || "xmlns".equals(attQName)) + continue; + QName attrName = new QName(attURI, attLocalName, attPrefix); + AttributeImpl attr = new AttributeImpl(location, attrName, + value, type, specified); + attrs.add(attr); + //events.add(attr); + } + } + + public void endElement(String namespaceURI, String localName, + String qName) + throws SAXException + { + int ci = qName.indexOf(':'); + String prefix = null; + localName = qName; + if (ci != -1) + { + prefix = qName.substring(0, ci); + localName = qName.substring(ci + 1); + } + QName name = new QName(namespaceURI, localName, prefix); + events.add(new EndElementImpl(location, name, new LinkedList())); + // TODO namespaces out of scope + } + + public void characters(char[] ch, int start, int length) + throws SAXException + { + boolean whitespace = isWhitespace(ch, start, length); + events.add(new CharactersImpl(location, new String(ch, start, length), + whitespace, inCDATA, false)); + } + + public void ignorableWhitespace(char[] ch, int start, int length) + throws SAXException + { + boolean whitespace = isWhitespace(ch, start, length); + events.add(new CharactersImpl(location, new String(ch, start, length), + whitespace, inCDATA, true)); + } + + boolean isWhitespace(char[] ch, int start, int len) + { + int end = start + len; + for (int i = start; i < end; i++) + { + char c = ch[i]; + if (c != ' ' && c != '\t' && c != '\n' && c != '\r') + return false; + } + return true; + } + + public void processingInstruction(String target, String data) + throws SAXException + { + events.add(new ProcessingInstructionImpl(location, target, data)); + } + + public void skippedEntity(String name) + throws SAXException + { + } + + public void startDTD(String name, String publicId, String systemId) + throws SAXException + { + notations = new LinkedList(); + entities = new LinkedList(); + events.add(new DTDImpl(location, null, null, notations, entities)); + } + + public void endDTD() + throws SAXException + { + } + + public void startEntity(String name) + throws SAXException + { + events.add(new StartEntityImpl(location, name)); + } + + public void endEntity(String name) + throws SAXException + { + events.add(new EndEntityImpl(location, name)); + } + + public void startCDATA() + throws SAXException + { + inCDATA = true; + } + + public void endCDATA() + throws SAXException + { + inCDATA = false; + } + + public void comment(char[] ch, int start, int length) + throws SAXException + { + events.add(new CommentImpl(location, new String(ch, start, length))); + } + + public void notationDecl(String name, String publicId, String systemId) + throws SAXException + { + Object n = new NotationDeclarationImpl(location, name, publicId, + systemId); + notations.add(n); + //events.add(n); + } + + public void unparsedEntityDecl(String name, String publicId, + String systemId, String notationName) + throws SAXException + { + Object e = new EntityDeclarationImpl(location, publicId, systemId, + name, notationName, + null, null); + entities.add(e); + //events.add(e); + } + + public void elementDecl(String name, String model) + throws SAXException + { + } + + public void attributeDecl(String eName, String aName, String type, + String valueDefault, String value) + throws SAXException + { + } + + public void internalEntityDecl(String name, String value) + throws SAXException + { + Object e = new EntityDeclarationImpl(location, null, null, + name, null, value, null); + entities.add(e); + //events.add(e); + } + + public void externalEntityDecl(String name, String publicId, + String systemId) + throws SAXException + { + Object e = new EntityDeclarationImpl(location, publicId, systemId, + name, null, null, null); + entities.add(e); + //events.add(e); + } + + public void warning(SAXParseException e) + throws SAXException + { + if (reporter != null) + { + try + { + reporter.report(e.getMessage(), "warning", e, location); + } + catch (XMLStreamException e2) + { + SAXException e3 = new SAXException(e2.getMessage()); + e3.initCause(e2); + throw e3; + } + } + } + + public void error(SAXParseException e) + throws SAXException + { + if (reporter != null) + { + try + { + reporter.report(e.getMessage(), "error", e, location); + } + catch (XMLStreamException e2) + { + SAXException e3 = new SAXException(e2.getMessage()); + e3.initCause(e2); + throw e3; + } + } + } + + public void fatalError(SAXParseException e) + throws SAXException + { + if (reporter != null) + { + try + { + reporter.report(e.getMessage(), "fatal-error", e, location); + } + catch (XMLStreamException e2) + { + SAXException e3 = new SAXException(e2.getMessage()); + e3.initCause(e2); + throw e3; + } + } + } + + public InputSource resolveEntity(String publicId, String systemId) + throws SAXException, IOException + { + if (resolver != null) + { + try + { + InputStream in = resolver.resolve(systemId); + if (in != null) + { + InputSource ret = new InputSource(in); + ret.setPublicId(publicId); + ret.setSystemId(systemId); + return ret; + } + } + catch (XMLStreamException e) + { + SAXException e2 = new SAXException(e.getMessage()); + e2.initCause(e); + throw e2; + } + } + return null; + } + + } + +} + diff --git a/libjava/classpath/gnu/xml/stream/XMLStreamWriterImpl.java b/libjava/classpath/gnu/xml/stream/XMLStreamWriterImpl.java new file mode 100644 index 00000000000..9ac0abe2712 --- /dev/null +++ b/libjava/classpath/gnu/xml/stream/XMLStreamWriterImpl.java @@ -0,0 +1,699 @@ +/* XMLStreamWriterImpl.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.stream; + +import java.io.IOException; +import java.io.Writer; +import java.util.LinkedList; + +import javax.xml.XMLConstants; +import javax.xml.namespace.NamespaceContext; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamWriter; + +import org.xml.sax.helpers.NamespaceSupport; + +/** + * Simple XML stream writer. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +public class XMLStreamWriterImpl + implements XMLStreamWriter +{ + + protected final Writer writer; + protected final String encoding; + protected final boolean prefixDefaulting; + protected NamespaceContext namespaceContext; + + private LinkedList elements; + private boolean inStartElement; + private boolean emptyElement; + private NamespaceSupport namespaces; + + protected XMLStreamWriterImpl(Writer writer, String encoding, + boolean prefixDefaulting) + { + this.writer = writer; + this.encoding = encoding; + this.prefixDefaulting = prefixDefaulting; + elements = new LinkedList(); + namespaces = new NamespaceSupport(); + } + + private void endStartElement() + throws IOException + { + if (!inStartElement) + return; + if (emptyElement) + { + writer.write('/'); + elements.removeLast(); + namespaces.popContext(); + emptyElement = false; + } + writer.write('>'); + inStartElement = false; + } + + public void writeStartElement(String localName) + throws XMLStreamException + { + try + { + endStartElement(); + namespaces.pushContext(); + + writer.write('<'); + writer.write(localName); + + elements.addLast(new String[] { null, localName }); + inStartElement = true; + } + catch (IOException e) + { + XMLStreamException e2 = new XMLStreamException(e); + e2.initCause(e); + throw e2; + } + } + + public void writeStartElement(String namespaceURI, String localName) + throws XMLStreamException + { + try + { + endStartElement(); + namespaces.pushContext(); + + String prefix = getPrefix(namespaceURI); + boolean isDeclared = (prefix != null); + if (!isDeclared) + { + if (prefixDefaulting) + prefix = XMLConstants.DEFAULT_NS_PREFIX; + else + throw new XMLStreamException("namespace " + namespaceURI + + " has not been declared"); + } + writer.write('<'); + if (!"".equals(prefix)) + { + writer.write(prefix); + writer.write(':'); + } + writer.write(localName); + if (prefixDefaulting && !isDeclared) + { + writeNamespace(prefix, namespaceURI); + } + + elements.addLast(new String[] { prefix, localName }); + inStartElement = true; + } + catch (IOException e) + { + XMLStreamException e2 = new XMLStreamException(e); + e2.initCause(e); + throw e2; + } + } + + public void writeStartElement(String prefix, String localName, + String namespaceURI) + throws XMLStreamException + { + try + { + endStartElement(); + namespaces.pushContext(); + + String currentPrefix = getPrefix(namespaceURI); + boolean isCurrent = prefix.equals(currentPrefix); + writer.write('<'); + if (!"".equals(prefix)) + { + writer.write(prefix); + writer.write(':'); + } + writer.write(localName); + if (prefixDefaulting && !isCurrent) + { + writeNamespace(prefix, namespaceURI); + } + + elements.addLast(new String[] { prefix, localName }); + inStartElement = true; + } + catch (IOException e) + { + XMLStreamException e2 = new XMLStreamException(e); + e2.initCause(e); + throw e2; + } + } + + public void writeEmptyElement(String namespaceURI, String localName) + throws XMLStreamException + { + writeStartElement(namespaceURI, localName); + emptyElement = true; + } + + public void writeEmptyElement(String prefix, String localName, + String namespaceURI) + throws XMLStreamException + { + writeStartElement(prefix, localName, namespaceURI); + emptyElement = true; + } + + public void writeEmptyElement(String localName) + throws XMLStreamException + { + writeStartElement(localName); + emptyElement = true; + } + + public void writeEndElement() + throws XMLStreamException + { + try + { + endStartElement(); + String[] element = (String[]) elements.removeLast(); + namespaces.popContext(); + + writer.write('<'); + writer.write('/'); + if (element[0] != null && !"".equals(element[0])) + { + writer.write(element[0]); + writer.write(':'); + } + writer.write(element[1]); + writer.write('>'); + } + catch (IOException e) + { + XMLStreamException e2 = new XMLStreamException(e); + e2.initCause(e); + throw e2; + } + } + + public void writeEndDocument() + throws XMLStreamException + { + while (!elements.isEmpty()) + writeEndElement(); + } + + public void close() + throws XMLStreamException + { + flush(); + } + + public void flush() + throws XMLStreamException + { + try + { + writer.flush(); + } + catch (IOException e) + { + XMLStreamException e2 = new XMLStreamException(e); + e2.initCause(e); + throw e2; + } + } + + public void writeAttribute(String localName, String value) + throws XMLStreamException + { + if (!inStartElement) + throw new IllegalStateException(); + try + { + writer.write(' '); + writer.write(localName); + writer.write('='); + writer.write('"'); + writeEncoded(value, true); + writer.write('"'); + } + catch (IOException e) + { + XMLStreamException e2 = new XMLStreamException(e); + e2.initCause(e); + throw e2; + } + } + + public void writeAttribute(String prefix, String namespaceURI, + String localName, String value) + throws XMLStreamException + { + if (!inStartElement) + throw new IllegalStateException(); + try + { + String currentPrefix = getPrefix(namespaceURI); + if (currentPrefix == null) + { + if (prefixDefaulting) + writeNamespace(prefix, namespaceURI); + else + throw new XMLStreamException("namespace " + namespaceURI + + " is not bound"); + } + else if (!currentPrefix.equals(prefix)) + throw new XMLStreamException("namespace " + namespaceURI + + " is bound to prefix " + + currentPrefix); + writer.write(' '); + if (!"".equals(prefix)) + { + writer.write(prefix); + writer.write(':'); + } + writer.write(localName); + writer.write('='); + writer.write('"'); + writeEncoded(value, true); + writer.write('"'); + } + catch (IOException e) + { + XMLStreamException e2 = new XMLStreamException(e); + e2.initCause(e); + throw e2; + } + } + + public void writeAttribute(String namespaceURI, String localName, + String value) + throws XMLStreamException + { + if (!inStartElement) + throw new IllegalStateException(); + try + { + String prefix = getPrefix(namespaceURI); + if (prefix == null) + { + if (prefixDefaulting) + { + prefix = XMLConstants.DEFAULT_NS_PREFIX; + writeNamespace(prefix, namespaceURI); + } + else + throw new XMLStreamException("namespace " + namespaceURI + + " is not bound"); + } + writer.write(' '); + if (!"".equals(prefix)) + { + writer.write(prefix); + writer.write(':'); + } + writer.write(localName); + writer.write('='); + writer.write('"'); + writeEncoded(value, true); + writer.write('"'); + } + catch (IOException e) + { + XMLStreamException e2 = new XMLStreamException(e); + e2.initCause(e); + throw e2; + } + } + + public void writeNamespace(String prefix, String namespaceURI) + throws XMLStreamException + { + if (!inStartElement) + throw new IllegalStateException(); + try + { + if (prefix == null) + prefix = XMLConstants.DEFAULT_NS_PREFIX; + + setPrefix(prefix, namespaceURI); + + writer.write(' '); + writer.write("xmlns"); + if (!XMLConstants.DEFAULT_NS_PREFIX.equals(prefix)) + { + writer.write(':'); + writer.write(prefix); + } + writer.write('='); + writer.write('"'); + writer.write(namespaceURI); + writer.write('"'); + } + catch (IOException e) + { + XMLStreamException e2 = new XMLStreamException(e); + e2.initCause(e); + throw e2; + } + } + + public void writeDefaultNamespace(String namespaceURI) + throws XMLStreamException + { + writeNamespace(XMLConstants.DEFAULT_NS_PREFIX, namespaceURI); + } + + public void writeComment(String data) + throws XMLStreamException + { + try + { + endStartElement(); + + if (data != null && data.indexOf("--") != -1) + throw new IllegalArgumentException(data); + + writer.write("<!--"); + if (data != null) + writer.write(data); + writer.write("-->"); + } + catch (IOException e) + { + XMLStreamException e2 = new XMLStreamException(e); + e2.initCause(e); + throw e2; + } + } + + public void writeProcessingInstruction(String target) + throws XMLStreamException + { + writeProcessingInstruction(target, null); + } + + public void writeProcessingInstruction(String target, String data) + throws XMLStreamException + { + try + { + endStartElement(); + + writer.write('<'); + writer.write('?'); + writer.write(target); + if (data != null) + { + writer.write(' '); + writer.write(data); + } + writer.write('?'); + writer.write('>'); + } + catch (IOException e) + { + XMLStreamException e2 = new XMLStreamException(e); + e2.initCause(e); + throw e2; + } + } + + public void writeCData(String data) + throws XMLStreamException + { + try + { + endStartElement(); + + if (data.indexOf("]]") != -1) + throw new IllegalArgumentException(data); + + writer.write("<![CDATA["); + writer.write(data); + writer.write("]]>"); + } + catch (IOException e) + { + XMLStreamException e2 = new XMLStreamException(e); + e2.initCause(e); + throw e2; + } + } + + public void writeDTD(String dtd) + throws XMLStreamException + { + try + { + writer.write("<!DOCTYPE "); + writer.write(dtd); + writer.write('>'); + } + catch (IOException e) + { + XMLStreamException e2 = new XMLStreamException(e); + e2.initCause(e); + throw e2; + } + } + + public void writeEntityRef(String name) + throws XMLStreamException + { + try + { + endStartElement(); + + writer.write('&'); + writer.write(name); + writer.write(';'); + } + catch (IOException e) + { + XMLStreamException e2 = new XMLStreamException(e); + e2.initCause(e); + throw e2; + } + } + + public void writeStartDocument() + throws XMLStreamException + { + writeStartDocument(null, null); + } + + public void writeStartDocument(String version) + throws XMLStreamException + { + writeStartDocument(null, version); + } + + public void writeStartDocument(String encoding, String version) + throws XMLStreamException + { + if (version == null) + version = "1.0"; + encoding = this.encoding; // YES: the parameter must be ignored + if (encoding == null) + encoding = "UTF-8"; + if (!"1.0".equals(version) && !"1.1".equals(version)) + throw new IllegalArgumentException(version); + try + { + writer.write("<?xml version=\""); + writer.write(version); + writer.write("\" encoding=\""); + writer.write(encoding); + writer.write("\"?>"); + writer.write(System.getProperty("line.separator")); + } + catch (IOException e) + { + XMLStreamException e2 = new XMLStreamException(e); + e2.initCause(e); + throw e2; + } + } + + public void writeCharacters(String text) + throws XMLStreamException + { + try + { + endStartElement(); + + if (text != null) + writeEncoded(text, false); + } + catch (IOException e) + { + XMLStreamException e2 = new XMLStreamException(e); + e2.initCause(e); + throw e2; + } + } + + public void writeCharacters(char[] text, int start, int len) + throws XMLStreamException + { + try + { + endStartElement(); + + int end = start + len; + len = 0; + for (int i = start; i < end; i++) + { + char c = text[i]; + if (c == '<' || c == '>' || c == '&') + { + writer.write(text, start, len); + if (c == '<') + writer.write("<"); + else if (c == '>') + writer.write(">"); + else + writer.write("&"); + start = i + 1; + len = 0; + } + else + len++; + } + if (len > 0) + writer.write(text, start, len); + } + catch (IOException e) + { + XMLStreamException e2 = new XMLStreamException(e); + e2.initCause(e); + throw e2; + } + } + + public String getPrefix(String uri) + throws XMLStreamException + { + String prefix = namespaces.getPrefix(uri); + if (prefix == null && namespaceContext != null) + prefix = namespaceContext.getPrefix(uri); + return prefix; + } + + public void setPrefix(String prefix, String uri) + throws XMLStreamException + { + if (!namespaces.declarePrefix(prefix, uri)) + throw new XMLStreamException("illegal prefix " + prefix); + } + + public void setDefaultNamespace(String uri) + throws XMLStreamException + { + if (!namespaces.declarePrefix(XMLConstants.DEFAULT_NS_PREFIX, uri)) + throw new XMLStreamException("illegal default namespace prefix"); + } + + public void setNamespaceContext(NamespaceContext context) + throws XMLStreamException + { + namespaceContext = context; + } + + public NamespaceContext getNamespaceContext() + { + return namespaceContext; + } + + public Object getProperty(String name) + throws IllegalArgumentException + { + throw new IllegalArgumentException(name); + } + + private void writeEncoded(String text, boolean inAttr) + throws IOException + { + char[] chars = text.toCharArray(); + int start = 0; + int end = chars.length; + int len = 0; + for (int i = start; i < end; i++) + { + char c = chars[i]; + if (c == '<' || c == '>' || c == '&') + { + writer.write(chars, start, len); + if (c == '<') + writer.write("<"); + else if (c == '>') + writer.write(">"); + else + writer.write("&"); + start = i + 1; + len = 0; + } + else if (inAttr && (c == '"' || c == '\'')) + { + writer.write(chars, start, len); + if (c == '"') + writer.write("""); + else + writer.write("'"); + start = i + 1; + len = 0; + } + else + len++; + } + if (len > 0) + writer.write(chars, start, len); + } + +} + |