diff options
Diffstat (limited to 'libjava/classpath/gnu')
104 files changed, 4667 insertions, 3171 deletions
diff --git a/libjava/classpath/gnu/CORBA/CDR/Vio.java b/libjava/classpath/gnu/CORBA/CDR/Vio.java index 8f17bd2f5a9..0a37132b26f 100644 --- a/libjava/classpath/gnu/CORBA/CDR/Vio.java +++ b/libjava/classpath/gnu/CORBA/CDR/Vio.java @@ -46,6 +46,7 @@ import org.omg.CORBA.DataOutputStream; import org.omg.CORBA.MARSHAL; import org.omg.CORBA.NO_IMPLEMENT; import org.omg.CORBA.StringSeqHelper; +import org.omg.CORBA.portable.BoxedValueHelper; import org.omg.CORBA.portable.InputStream; import org.omg.CORBA.portable.OutputStream; import org.omg.CORBA.portable.Streamable; @@ -55,6 +56,8 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.Serializable; +import java.lang.reflect.Method; + /** * A specialised class for reading and writing the value types. * @@ -222,7 +225,7 @@ public abstract class Vio throw new MARSHAL("Unable to instantiate the value type"); else { - read_instance(input, ox, value_tag); + read_instance(input, ox, value_tag, null); return (Serializable) ox; } } @@ -285,7 +288,7 @@ public abstract class Vio } } - read_instance(input, ox, value_tag); + read_instance(input, ox, value_tag, null); return (Serializable) ox; } catch (Exception ex) @@ -301,17 +304,22 @@ public abstract class Vio * an instance. * * @param input a stream to read from. - * @param value_instance an instance of the value. + * + * @param value_instance an pre-created instance of the value. If the + * helper is not null, this parameter is ignored an should be null. + * + * @param helper a helper to create an instance and read the object- + * specific part of the record. If the value_instance is used instead, + * this parameter should be null. * * @return the loaded value. * * @throws MARSHAL if the reading has failed due any reason. */ - public static Serializable read(InputStream input, Serializable value_instance) + public static Object read(InputStream input, Object value_instance, + Object helper + ) { - // Explicitly prevent the stream from closing as we may need - // to read the subsequent bytes as well. Stream may be auto-closed - // in its finalizer. try { int value_tag = input.read_long(); @@ -345,8 +353,9 @@ public abstract class Vio } } - read_instance(input, value_instance, value_tag); - return (Serializable) value_instance; + value_instance = + read_instance(input, value_instance, value_tag, helper); + return value_instance; } catch (Exception ex) { @@ -355,18 +364,43 @@ public abstract class Vio } /** + * Read using provided boxed value helper. This method expects + * the full value type header, followed by contents, that are + * delegated to the provided helper. It handles null. + * + * @param input the stream to read from. + * @param helper the helper that reads the type-specific part of + * the content. + * + * @return the value, created by the helper, or null if the + * header indicates that null was previously written. + */ + public static Serializable read(InputStream input, Object helper) + { + return (Serializable) read(input, null, helper); + } + + /** * Fill in the instance fields by the data from the input stream. * The method assumes that the value header, if any, is already * behind. The information from the stream is stored into the * passed ox parameter. * * @param input an input stream to read from. - * @param value a value type object, must be either Streamable or - * CustomMarshal. + * + * @param value a pre-instantiated value type object, must be either + * Streamable or CustomMarshal. If the helper is used, this parameter + * is ignored and should be null. + * + * @param value_tag the tag that must be read previously. + * @param helper the helper for read object specific part; may be + * null to read in using other methods. + * + * @return the value that was read. */ - public static void read_instance(InputStream input, Object value, - int value_tag - ) + private static Object read_instance(InputStream input, Object value, + int value_tag, Object helper + ) { try { @@ -377,7 +411,7 @@ public abstract class Vio // Read all chunks. int chunk_size = input.read_long(); - if (chunk_size <= 0) + if (chunk_size < 0) throw new MARSHAL("Invalid first chunk size " + chunk_size); byte[] r = new byte[ chunk_size ]; @@ -412,12 +446,29 @@ public abstract class Vio // More than one chunk was present. // Add the last chunk. bout.write(r, 0, n); - input = new cdrBufInput(bout.toByteArray()); + input = new noHeaderInput(bout.toByteArray()); } else { // Only one chunk was present. - input = new cdrBufInput(r); + input = new noHeaderInput(r); + } + } + else + { + if (input instanceof cdrBufInput) + { + // Highly probable case. + input = + new noHeaderInput(((cdrBufInput) input).buffer.getBuffer()); + } + else + { + cdrBufOutput bout = new cdrBufOutput(); + int c; + while ((c = input.read()) >= 0) + bout.write((byte) c); + input = new noHeaderInput(bout.buffer.toByteArray()); } } } @@ -447,12 +498,17 @@ public abstract class Vio { ((Streamable) value)._read(input); } + else if (helper instanceof BoxedValueHelper) + value = ((BoxedValueHelper) helper).read_value(input); + else if (helper instanceof ValueFactory) + value = + ((ValueFactory) helper).read_value((org.omg.CORBA_2_3.portable.InputStream) input); else // Stating the interfaces that the USER should use. throw new MARSHAL("The " + value.getClass().getName() + - " must implement either StreamableValue or CustomValue." - ); + " must implement either StreamableValue or CustomValue." + ); // The negative end of state marker is expected from OMG standard. // If the chunking is used, this marker is already extracted. @@ -462,6 +518,8 @@ public abstract class Vio if (eor >= 0) throw new MARSHAL("End of state marker has an invalid value " + eor); } + + return value; } /** @@ -504,8 +562,8 @@ public abstract class Vio * @throws MARSHAL if the writing failed due any reason. */ public static void write(OutputStream output, Serializable value, - Class substitute - ) + Class substitute + ) { // Write null if this is a null value. if (value == null) @@ -527,7 +585,35 @@ public abstract class Vio if (value == null) output.write_long(vt_NULL); else - write_instance(output, value, id); + write_instance(output, value, id, null); + } + + /** + * Write standard value type header, followed by contents, produced + * by the boxed value helper. + * + * @param output the stream to write to. + * @param value the value to write, can be null. + * @param helper the helper that writes the value content if it is + * not null. + */ + public static void write(OutputStream output, Serializable value, + Object helper + ) + { + if (value == null) + output.write_long(vt_NULL); + else + { + String id; + + if (helper instanceof BoxedValueHelper) + id = ((BoxedValueHelper) helper).get_id(); + else + id = ""; + + write_instance(output, value, id, helper); + } } /** @@ -537,10 +623,12 @@ public abstract class Vio * @param output an output stream to write into. * @param value a value to write. * @param id a value repository id. + * @param helper a helper, writing object - specifica part. Can be null + * if the value should be written unsing other methods. */ private static void write_instance(OutputStream output, Serializable value, - String id - ) + String id, Object helper + ) { // This implementation always writes a single repository id. // It never writes multiple repository ids and currently does not use @@ -563,6 +651,11 @@ public abstract class Vio output.write_long(value_tag); output.write_string(id); + if (helper instanceof BoxedValueHelper) + { + ((BoxedValueHelper) helper).write_value(outObj, value); + } + else // User defince write method is present. if (value instanceof CustomMarshal) { @@ -580,11 +673,36 @@ public abstract class Vio ((Streamable) value)._write(outObj); } else + { + // Try to find helper via class loader. + boolean ok = false; + try + { + Class helperClass = Class.forName(ObjectCreator.toHelperName(id)); + + // It will be the helper for the encapsulated boxed value, not the + // for the global boxed value type itself. + Method write = + helperClass.getMethod("write", + new Class[] + { + org.omg.CORBA.portable.OutputStream.class, value.getClass() + } + ); + write.invoke(null, new Object[] { outObj, value }); + ok = true; + } + catch (Exception ex) + { + ok = false; + } - // Stating the interfaces that the USER should use. - throw new MARSHAL("The " + value.getClass().getName() + - " must implement either StreamableValue or CustomValue." - ); + // Stating the interfaces that the USER should use. + if (!ok) + throw new MARSHAL("The " + value.getClass().getName() + + " must implement either StreamableValue" + " or CustomValue." + ); + } if (USE_CHUNKING) { @@ -611,8 +729,7 @@ public abstract class Vio * * @throws NO_IMPLEMENT, always. */ - private static void incorrect_plug_in(Throwable ex) - throws NO_IMPLEMENT + static void incorrect_plug_in(Throwable ex) throws NO_IMPLEMENT { NO_IMPLEMENT no = new NO_IMPLEMENT("Incorrect CORBA plug-in"); no.initCause(ex); @@ -629,10 +746,11 @@ public abstract class Vio private static final void checkTag(int value_tag) { if ((value_tag < 0x7fffff00 || value_tag > 0x7fffffff) && - value_tag != vt_NULL && value_tag != vt_INDIRECTION - ) + value_tag != vt_NULL && + value_tag != vt_INDIRECTION + ) throw new MARSHAL("Invalid value record, unsupported header tag: " + - value_tag - ); + value_tag + ); } }
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/CDR/cdrInput.java b/libjava/classpath/gnu/CORBA/CDR/cdrInput.java index 859f93ae5f0..69f9c8c5837 100644 --- a/libjava/classpath/gnu/CORBA/CDR/cdrInput.java +++ b/libjava/classpath/gnu/CORBA/CDR/cdrInput.java @@ -1180,7 +1180,8 @@ public abstract class cdrInput } // Discard the null terminator and, if needed, the endian marker. - return new String(s, p, n - nt - p); + String r = new String(s, p, n - nt - p); + return r; } catch (EOFException ex) { diff --git a/libjava/classpath/gnu/CORBA/CDR/cdrOutput.java b/libjava/classpath/gnu/CORBA/CDR/cdrOutput.java index 86ca3b1cb3d..85f341c912d 100644 --- a/libjava/classpath/gnu/CORBA/CDR/cdrOutput.java +++ b/libjava/classpath/gnu/CORBA/CDR/cdrOutput.java @@ -41,6 +41,7 @@ package gnu.CORBA.CDR; import gnu.CORBA.BigDecimalHelper; import gnu.CORBA.GIOP.CharSets_OSF; import gnu.CORBA.GIOP.cxCodeSet; +import gnu.CORBA.Poa.gnuServantObject; import gnu.CORBA.IOR; import gnu.CORBA.Simple_delegate; import gnu.CORBA.TypeCodeHelper; @@ -99,7 +100,7 @@ public abstract class cdrOutput /** * The GIOP version. */ - protected Version giop = new Version(1, 0); + protected Version giop = new Version(1, 2); /** * The code set information. @@ -327,6 +328,15 @@ public abstract class cdrOutput IOR.write_null(this); return; } + else if (x instanceof gnuServantObject) + { + // The ORB may be different if several ORBs coexist + // in the same machine. + gnuServantObject g = (gnuServantObject) x; + IOR ior = g.orb.getLocalIor(x); + ior._write_no_endian(this); + return; + } else if (x instanceof ObjectImpl) { Delegate d = ((ObjectImpl) x)._get_delegate(); diff --git a/libjava/classpath/gnu/CORBA/Connected_objects.java b/libjava/classpath/gnu/CORBA/Connected_objects.java index 30d15e75c3a..b7eefb133a2 100644 --- a/libjava/classpath/gnu/CORBA/Connected_objects.java +++ b/libjava/classpath/gnu/CORBA/Connected_objects.java @@ -60,11 +60,14 @@ public class Connected_objects /** * Create an initialised instance. */ - cObject(org.omg.CORBA.Object _object, int _port, byte[] _key) + cObject(org.omg.CORBA.Object _object, int _port, byte[] _key, + java.lang.Object an_identity + ) { object = _object; port = _port; key = _key; + identity = an_identity; } /** @@ -82,6 +85,12 @@ public class Connected_objects */ public final byte[] key; + /** + * The shared serving identity (usually POA) or null if no such + * applicable. + */ + public final java.lang.Object identity; + public boolean equals(java.lang.Object other) { if (other instanceof cObject) @@ -118,17 +127,23 @@ public class Connected_objects */ public cObject getKey(org.omg.CORBA.Object stored_object) { - Map.Entry item; - Iterator iter = objects.entrySet().iterator(); - cObject ref; - - while (iter.hasNext()) + synchronized (objects) { - item = (Map.Entry) iter.next(); - ref = (cObject) item.getValue(); - if (stored_object.equals(ref.object)) - return ref; + Map.Entry item; + Iterator iter = objects.entrySet().iterator(); + cObject ref; + + while (iter.hasNext()) + { + item = (Map.Entry) iter.next(); + ref = (cObject) item.getValue(); + if (stored_object.equals(ref.object) || + stored_object._is_equivalent(ref.object) + ) + return ref; + } } + return null; } @@ -144,7 +159,7 @@ public class Connected_objects */ public cObject add(org.omg.CORBA.Object object, int port) { - return add(generateObjectKey(object), object, port); + return add(generateObjectKey(object), object, port, null); } /** @@ -155,10 +170,15 @@ public class Connected_objects * @param port the port, on that the ORB will be listening on the * remote invocations. */ - public cObject add(byte[] key, org.omg.CORBA.Object object, int port) + public cObject add(byte[] key, org.omg.CORBA.Object object, int port, + java.lang.Object identity + ) { - cObject rec = new cObject(object, port, key); - objects.put(key, rec); + cObject rec = new cObject(object, port, key, identity); + synchronized (objects) + { + objects.put(key, rec); + } return rec; } @@ -171,12 +191,14 @@ public class Connected_objects */ public cObject get(byte[] key) { - return (cObject) objects.get(key); + synchronized (objects) + { + return (cObject) objects.get(key); + } } /** * Get the map entry set. - * @return */ public Set entrySet() { @@ -190,9 +212,12 @@ public class Connected_objects */ public void remove(org.omg.CORBA.Object object) { - cObject ref = getKey(object); - if (ref != null) - objects.remove(ref.key); + synchronized (objects) + { + cObject ref = getKey(object); + if (ref != null) + objects.remove(ref.key); + } } /** diff --git a/libjava/classpath/gnu/CORBA/DynAn/NameValuePairHolder.java b/libjava/classpath/gnu/CORBA/DynAn/NameValuePairHolder.java index 7afc81cd4ea..2558f5335aa 100644 --- a/libjava/classpath/gnu/CORBA/DynAn/NameValuePairHolder.java +++ b/libjava/classpath/gnu/CORBA/DynAn/NameValuePairHolder.java @@ -46,9 +46,8 @@ import org.omg.CORBA.portable.OutputStream; import org.omg.CORBA.portable.Streamable; /** - * The name-value pair holder. The {@link NameValuePair} has no standard - * holder defined, but it is needed to store the {@link NameValuePair} into - * {@link Any}. + * The name-value pair holder. The {@link NameValuePair} has no standard holder + * defined, but it is needed to store the {@link NameValuePair} into {@link Any}. * * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) */ @@ -92,4 +91,4 @@ public class NameValuePairHolder { NameValuePairHelper.write(output, value); } -} +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/ExceptionCreator.java b/libjava/classpath/gnu/CORBA/ExceptionCreator.java index 536053cef90..8b75205056b 100644 --- a/libjava/classpath/gnu/CORBA/ExceptionCreator.java +++ b/libjava/classpath/gnu/CORBA/ExceptionCreator.java @@ -145,14 +145,11 @@ public class ExceptionCreator { try { - String holder = toHelperName(idl); - - System.out.println("Helper " + holder); - - Class holderClass = Class.forName(holder); + String helper = toHelperName(idl); + Class helperClass = Class.forName(helper); Method read = - holderClass.getMethod("read", + helperClass.getMethod("read", new Class[] { org.omg.CORBA.portable.InputStream.class diff --git a/libjava/classpath/gnu/CORBA/Functional_ORB.java b/libjava/classpath/gnu/CORBA/Functional_ORB.java index 7395f3172e4..1565b2cf14a 100644 --- a/libjava/classpath/gnu/CORBA/Functional_ORB.java +++ b/libjava/classpath/gnu/CORBA/Functional_ORB.java @@ -1,4 +1,4 @@ -/* FunctionalORB.java -- +/* Functional_ORB.java -- Copyright (C) 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -40,24 +40,28 @@ package gnu.CORBA; import gnu.CORBA.CDR.cdrBufInput; import gnu.CORBA.CDR.cdrBufOutput; +import gnu.CORBA.GIOP.CloseMessage; import gnu.CORBA.GIOP.ErrorMessage; import gnu.CORBA.GIOP.MessageHeader; import gnu.CORBA.GIOP.ReplyHeader; import gnu.CORBA.GIOP.RequestHeader; -import gnu.CORBA.GIOP.CloseMessage; +import gnu.CORBA.NamingService.NameParser; import gnu.CORBA.NamingService.NamingServiceTransient; +import gnu.CORBA.Poa.gnuForwardRequest; -import org.omg.CORBA.BAD_INV_ORDER; import org.omg.CORBA.BAD_OPERATION; import org.omg.CORBA.BAD_PARAM; import org.omg.CORBA.CompletionStatus; +import org.omg.CORBA.DATA_CONVERSION; import org.omg.CORBA.MARSHAL; import org.omg.CORBA.NO_RESOURCES; import org.omg.CORBA.OBJECT_NOT_EXIST; +import org.omg.CORBA.Object; import org.omg.CORBA.ORBPackage.InvalidName; import org.omg.CORBA.Request; import org.omg.CORBA.SystemException; import org.omg.CORBA.UNKNOWN; +import org.omg.CORBA.WrongTransaction; import org.omg.CORBA.portable.Delegate; import org.omg.CORBA.portable.InvokeHandler; import org.omg.CORBA.portable.ObjectImpl; @@ -78,6 +82,7 @@ import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Enumeration; +import java.util.Hashtable; import java.util.Iterator; import java.util.LinkedList; import java.util.Map; @@ -87,26 +92,25 @@ import java.util.TreeMap; /** * The ORB implementation, capable to handle remote invocations on the - * registered object. + * registered object. This class implements all features, required till the jdk + * 1.3 inclusive, but does not support the POA that appears since 1.4. The POA + * is supported by {@link gnu.CORBA.Poa.ORB_1_4}. * * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) */ -public class Functional_ORB - extends Restricted_ORB +public class Functional_ORB extends Restricted_ORB { /** - * A server, responsible for listening on requests on some - * local port. The ORB may listen on multiple ports and process - * the requests in separate threads. Normally the server takes - * one port per object being served. + * A server, responsible for listening on requests on some local port. The ORB + * may listen on multiple ports and process the requests in separate threads. + * Normally the server takes one port per object being served. */ - class portServer - extends Thread + class portServer extends Thread { /** * The number of the currently running parallel threads. */ - private int running_threads; + int running_threads; /** * The port on that this portServer is listening for requests. @@ -119,8 +123,7 @@ public class Functional_ORB ServerSocket service; /** - * True if the serving node must shutdown due - * call of the close_now(). + * True if the serving node must shutdown due call of the close_now(). */ boolean terminated; @@ -133,9 +136,8 @@ public class Functional_ORB } /** - * Enter the serving loop (get request/process it). - * All portServer normally terminate thy threads when - * the Functional_ORB.running is set to false. + * Enter the serving loop (get request/process it). All portServer normally + * terminate thy threads when the Functional_ORB.running is set to false. */ public void run() { @@ -155,7 +157,7 @@ public class Functional_ORB { try { - serve(this, service); + tick(); } catch (SocketException ex) { @@ -180,6 +182,16 @@ public class Functional_ORB } /** + * Perform a single serving step. + * + * @throws java.lang.Exception + */ + void tick() throws Exception + { + serve(this, service); + } + + /** * Forcibly close the server socket and mark this port as free. */ public void close_now() @@ -206,14 +218,41 @@ public class Functional_ORB } /** - * The default value where the first instance of this ORB will start - * looking for a free port. + * A server, responsible for listening on requests on some local port and + * serving multiple requests (probably to the different objects) on the same + * thread. + */ + class sharedPortServer extends portServer + { + /** + * Create a new portServer, serving on specific port. + */ + sharedPortServer(int _port) + { + super(_port); + } + + /** + * Perform a single serving step. + * + * @throws java.lang.Exception + */ + void tick() throws Exception + { + Socket request = service.accept(); + serveStep(request, false); + } + } + + /** + * The default value where the first instance of this ORB will start looking + * for a free port. */ public static int DEFAULT_INITIAL_PORT = 1126; /** - * The property of port, on that this ORB is listening for requests from clients. - * This class supports one port per ORB only. + * The property of port, on that this ORB is listening for requests from + * clients. This class supports one port per ORB only. */ public static final String LISTEN_ON = "gnu.classpath.CORBA.ListenOn"; @@ -223,12 +262,14 @@ public class Functional_ORB public static final String REFERENCE = "org.omg.CORBA.ORBInitRef"; /** - * The property, defining the port on that the default name service is running. + * The property, defining the port on that the default name service is + * running. */ public static final String NS_PORT = "org.omg.CORBA.ORBInitialPort"; /** - * The property, defining the host on that the default name service is running. + * The property, defining the host on that the default name service is + * running. */ public static final String NS_HOST = "org.omg.CORBA.ORBInitialHost"; @@ -238,24 +279,25 @@ public class Functional_ORB public static final String NAME_SERVICE = "NameService"; /** - * The if the client has once opened a socket, it should start sending - * the message header in a given time. Otherwise the server will close the - * socket. This prevents server hang when the client opens the socket, - * but does not send any message, usually due crash on the client side. + * The if the client has once opened a socket, it should start sending the + * message header in a given time. Otherwise the server will close the socket. + * This prevents server hang when the client opens the socket, but does not + * send any message, usually due crash on the client side. */ public static String START_READING_MESSAGE = "gnu.classpath.CORBA.TOUT_START_READING_MESSAGE"; /** - * If the client has started to send the request message, the socket time - * out changes to the specified value. + * If the client has started to send the request message, the socket time out + * changes to the specified value. */ - public static String WHILE_READING = "gnu.classpath.CORBA.TOUT_WHILE_READING"; + public static String WHILE_READING = + "gnu.classpath.CORBA.TOUT_WHILE_READING"; /** - * If the message body is received, the time out changes to the - * specifice value. This must be longer, as includes time, required to - * process the received task. We make it 40 minutes. + * If the message body is received, the time out changes to the specifice + * value. This must be longer, as includes time, required to process the + * received task. We make it 40 minutes. */ public static String AFTER_RECEIVING = "gnu.classpath.CORBA.TOUT_AFTER_RECEIVING"; @@ -266,60 +308,59 @@ public class Functional_ORB public final String LOCAL_HOST; /** - * The if the client has once opened a socket, it should start sending - * the message header in a given time. Otherwise the server will close the - * socket. This prevents server hang when the client opens the socket, - * but does not send any message, usually due crash on the client side. + * The if the client has once opened a socket, it should start sending the + * message header in a given time. Otherwise the server will close the socket. + * This prevents server hang when the client opens the socket, but does not + * send any message, usually due crash on the client side. */ private int TOUT_START_READING_MESSAGE = 20 * 1000; // (Here and below, we use * to make the meaning of the constant clearler). /** - * If the client has started to send the request message, the socket time - * out changes to the specified value. + * If the client has started to send the request message, the socket time out + * changes to the specified value. */ private int TOUT_WHILE_READING = 2 * 60 * 1000; /** - * If the message body is received, the time out changes to the - * specifice value. This must be longer, as includes time, required to - * process the received task. We make it 40 minutes. + * If the message body is received, the time out changes to the specifice + * value. This must be longer, as includes time, required to process the + * received task. We make it 40 minutes. */ private int TOUT_AFTER_RECEIVING = 40 * 60 * 1000; /** - * Some clients tend to submit multiple requests over the - * same socket. The server waits for the next request on - * the same socket for the duration, specified - * below. In additions, the request of this implementation also - * waits for the same duration before closing the socket. - * The default time is seven seconds. + * Some clients tend to submit multiple requests over the same socket. The + * server waits for the next request on the same socket for the duration, + * specified below. In additions, the request of this implementation also + * waits for the same duration before closing the socket. The default time is + * seven seconds. */ public static int TANDEM_REQUESTS = 7000; /** * The map of the already conncted objects. */ - protected final Connected_objects connected_objects = new Connected_objects(); + protected final Connected_objects connected_objects = + new Connected_objects(); /** - * The maximal CORBA version, supported by this ORB. The default value - * 0 means that the ORB will not check the request version while trying - * to respond. + * The maximal CORBA version, supported by this ORB. The default value 0 means + * that the ORB will not check the request version while trying to respond. */ protected Version max_version; /** - * Setting this value to false causes the ORB to shutdown after the - * latest serving operation is complete. + * Setting this value to false causes the ORB to shutdown after the latest + * serving operation is complete. */ protected boolean running; /** * The map of the initial references. */ - private Map initial_references = new TreeMap(); + protected Map initial_references = new TreeMap(); /** * The currently active portServers. @@ -332,12 +373,12 @@ public class Functional_ORB private String ns_host; /** - * Probably free port, under that the ORB will try listening for - * remote requests first. When the new object is connected, this - * port is used first, then it is incremented by 1, etc. If the given - * port is not available, up to 20 subsequent values are tried and then - * the parameterless server socket contructor is called. The constant is - * shared between multiple instances of this ORB. + * Probably free port, under that the ORB will try listening for remote + * requests first. When the new object is connected, this port is used first, + * then it is incremented by 1, etc. If the given port is not available, up to + * 20 subsequent values are tried and then the parameterless server socket + * contructor is called. The constant is shared between multiple instances of + * this ORB. */ private static int Port = DEFAULT_INITIAL_PORT; @@ -345,6 +386,11 @@ public class Functional_ORB * The port, on that the name service is expected to be running. */ private int ns_port = 900; + + /** + * The name parser. + */ + NameParser nameParser = new NameParser(); /** * The instance, stored in this field, handles the asynchronous dynamic @@ -358,10 +404,14 @@ public class Functional_ORB protected LinkedList freed_ports = new LinkedList(); /** - * The maximal allowed number of the currently running parallel - * threads per object. For security reasons, this is made private and - * unchangeable. After exceeding this limit, the NO_RESOURCES - * is thrown back to the client. + * Maps a single-threaded POAs to they sharedPortServants. + */ + protected Hashtable identities = new Hashtable(); + + /** + * The maximal allowed number of the currently running parallel threads per + * object. For security reasons, this is made private and unchangeable. After + * exceeding this limit, the NO_RESOURCES is thrown back to the client. */ private int MAX_RUNNING_THREADS = 256; @@ -385,20 +435,19 @@ public class Functional_ORB } /** - * If the max version is assigned, the orb replies with the error - * message if the request version is above the supported 1.2 version. - * This behavior is recommended by OMG, but not all implementations - * respond that error message by re-sending the request, encoded in the older - * version. - */ + * If the max version is assigned, the orb replies with the error message if + * the request version is above the supported 1.2 version. This behavior is + * recommended by OMG, but not all implementations respond that error message + * by re-sending the request, encoded in the older version. + */ public void setMaxVersion(Version max_supported) { max_version = max_supported; } /** - * Get the maximal supported GIOP version or null if the version is - * not checked. + * Get the maximal supported GIOP version or null if the version is not + * checked. */ public Version getMaxVersion() { @@ -406,17 +455,15 @@ public class Functional_ORB } /** - * Get the currently free port, starting from the initially set port - * and going up max 20 steps, then trying to bind into any free - * address. + * Get the currently free port, starting from the initially set port and going + * up max 20 steps, then trying to bind into any free address. * * @return the currently available free port. * - * @throws NO_RESOURCES if the server socked cannot be opened on the - * local host. + * @throws NO_RESOURCES if the server socked cannot be opened on the local + * host. */ - public int getFreePort() - throws BAD_OPERATION + public int getFreePort() throws BAD_OPERATION { ServerSocket s; int a_port; @@ -473,12 +520,11 @@ public class Functional_ORB } /** - * Set the port, on that the server is listening for the client requests. - * If only one object is connected to the orb, the server will be - * try listening on this port first. It the port is busy, or if more - * objects are connected, the subsequent object will receive a larger - * port values, skipping unavailable ports, if required. The change - * applies globally. + * Set the port, on that the server is listening for the client requests. If + * only one object is connected to the orb, the server will be try listening + * on this port first. It the port is busy, or if more objects are connected, + * the subsequent object will receive a larger port values, skipping + * unavailable ports, if required. The change applies globally. * * @param a_Port a port, on that the server is listening for requests. */ @@ -488,14 +534,13 @@ public class Functional_ORB } /** - * Connect the given CORBA object to this ORB. After the object is - * connected, it starts receiving remote invocations via this ORB. + * Connect the given CORBA object to this ORB. After the object is connected, + * it starts receiving remote invocations via this ORB. * - * The ORB tries to connect the object to the port, that has been - * previously set by {@link setPort(int)}. On failure, it tries - * 20 subsequent larger values and then calls the parameterless - * server socked constructor to get any free local port. - * If this fails, the {@link NO_RESOURCES} is thrown. + * The ORB tries to connect the object to the port, that has been previously + * set by {@link setPort(int)}. On failure, it tries 20 subsequent larger + * values and then calls the parameterless server socked constructor to get + * any free local port. If this fails, the {@link NO_RESOURCES} is thrown. * * @param object the object, must implement the {@link InvokeHandler}) * interface. @@ -515,19 +560,18 @@ public class Functional_ORB } /** - * Connect the given CORBA object to this ORB, explicitly specifying - * the object key. + * Connect the given CORBA object to this ORB, explicitly specifying the + * object key. * - * The ORB tries to connect the object to the port, that has been - * previously set by {@link setPort(int)}. On failure, it tries - * 20 subsequent larger values and then calls the parameterless - * server socked constructor to get any free local port. - * If this fails, the {@link NO_RESOURCES} is thrown. + * The ORB tries to connect the object to the port, that has been previously + * set by {@link setPort(int)}. On failure, it tries 20 subsequent larger + * values and then calls the parameterless server socked constructor to get + * any free local port. If this fails, the {@link NO_RESOURCES} is thrown. * * @param object the object, must implement the {@link InvokeHandler}) * interface. - * @param key the object key, usually used to identify the object from - * remote side. + * @param key the object key, usually used to identify the object from remote + * side. * * @throws BAD_PARAM if the object does not implement the * {@link InvokeHandler}). @@ -536,7 +580,8 @@ public class Functional_ORB { int a_port = getFreePort(); - Connected_objects.cObject ref = connected_objects.add(key, object, a_port); + Connected_objects.cObject ref = + connected_objects.add(key, object, a_port, null); IOR ior = createIOR(ref); prepareObject(object, ior); if (running) @@ -544,11 +589,56 @@ public class Functional_ORB } /** + * Connect the given CORBA object to this ORB, explicitly specifying the + * object key and the identity of the thread (and port), where the object must + * be served. The identity is normally the POA. + * + * The new port server will be started only if there is no one already running + * for the same identity. Otherwise, the task of the existing port server will + * be widened, including duty to serve the given object. All objects, + * connected to a single identity by this method, will process they requests + * subsequently in the same thread. The method is used when the expected + * number of the objects is too large to have a single port and thread per + * object. This method is used by POAs, having a single thread policy. + * + * @param object the object, must implement the {@link InvokeHandler}) + * interface. + * @param key the object key, usually used to identify the object from remote + * side. + * @param port the port, where the object must be connected. + * + * @throws BAD_PARAM if the object does not implement the + * {@link InvokeHandler}). + */ + public void connect_1_thread(org.omg.CORBA.Object object, byte[] key, + java.lang.Object identity + ) + { + sharedPortServer shared = (sharedPortServer) identities.get(identity); + if (shared == null) + { + int a_port = getFreePort(); + shared = new sharedPortServer(a_port); + identities.put(identity, shared); + if (running) + { + portServers.add(shared); + shared.start(); + } + } + + Connected_objects.cObject ref = + connected_objects.add(key, object, shared.s_port, identity); + IOR ior = createIOR(ref); + prepareObject(object, ior); + } + + /** * Start the service on the given port of this IOR. * * @param ior the ior (only Internet.port is used). */ - private void startService(IOR ior) + public void startService(IOR ior) { portServer p = new portServer(ior.Internet.port); portServers.add(p); @@ -560,23 +650,22 @@ public class Functional_ORB */ public void destroy() { - super.destroy(); - portServer p; for (int i = 0; i < portServers.size(); i++) { p = (portServer) portServers.get(i); p.close_now(); } + super.destroy(); } /** - * Disconnect the given CORBA object from this ORB. The object will be - * no longer receiving the remote invocations. In response to the - * remote invocation on this object, the ORB will send the - * exception {@link OBJECT_NOT_EXIST}. The object, however, is not - * destroyed and can receive the local invocations. - + * Disconnect the given CORBA object from this ORB. The object will be no + * longer receiving the remote invocations. In response to the remote + * invocation on this object, the ORB will send the exception + * {@link OBJECT_NOT_EXIST}. The object, however, is not destroyed and can + * receive the local invocations. + * * @param object the object to disconnect. */ public void disconnect(org.omg.CORBA.Object object) @@ -599,8 +688,6 @@ public class Functional_ORB // object implementation. if (rmKey == null) rmKey = connected_objects.getKey(object); - - // Disconnect the object on any success. if (rmKey != null) { // Find and stop the corresponding portServer. @@ -609,7 +696,7 @@ public class Functional_ORB for (int i = 0; i < portServers.size(); i++) { p = (portServer) portServers.get(i); - if (p.s_port == rmKey.port) + if (p.s_port == rmKey.port && !(p instanceof sharedPortServer)) { p.close_now(); freed_ports.addFirst(new Integer(rmKey.port)); @@ -621,12 +708,47 @@ public class Functional_ORB } /** + * Notifies ORB that the shared service indentity (usually POA) is destroyed. + * The matching shared port server is terminated and the identity table entry + * is deleted. If this identity is not known for this ORB, the method returns + * without action. + * + * @param identity the identity that has been destroyed. + */ + public void identityDestroyed(java.lang.Object identity) + { + if (identity == null) + return; + + sharedPortServer ise = (sharedPortServer) identities.get(identity); + if (ise != null) + { + synchronized (connected_objects) + { + ise.close_now(); + identities.remove(identity); + + Connected_objects.cObject obj; + Map.Entry m; + Iterator iter = connected_objects.entrySet().iterator(); + while (iter.hasNext()) + { + m = (Map.Entry) iter.next(); + obj = (Connected_objects.cObject) m.getValue(); + if (obj.identity == identity) + iter.remove(); + } + } + } + } + + /** * Find the local object, connected to this ORB. * * @param ior the ior of the potentially local object. * - * @return the local object, represented by the given IOR, - * or null if this is not a local connected object. + * @return the local object, represented by the given IOR, or null if this is + * not a local connected object. */ public org.omg.CORBA.Object find_local_object(IOR ior) { @@ -655,26 +777,26 @@ public class Functional_ORB Iterator iter = initial_references.keySet().iterator(); while (iter.hasNext()) - refs [ p++ ] = (String) iter.next(); - + { + refs [ p++ ] = (String) iter.next(); + } return refs; } /** - * Get the IOR reference string for the given object. - * The string embeds information about the object - * repository Id, its access key and the server internet - * address and port. With this information, the object - * can be found by another ORB, possibly located on remote - * computer. + * Get the IOR reference string for the given object. The string embeds + * information about the object repository Id, its access key and the server + * internet address and port. With this information, the object can be found + * by another ORB, possibly located on remote computer. * * @param the CORBA object * @return the object IOR representation. * - * @throws BAD_PARAM if the object has not been previously - * connected to this ORB. - * @throws BAD_OPERATION in the unlikely case if the local host - * address cannot be resolved. + * @throws BAD_PARAM if the object has not been previously connected to this + * ORB. + * + * @throws BAD_OPERATION in the unlikely case if the local host address cannot + * be resolved. * * @see string_to_object(String) */ @@ -693,8 +815,8 @@ public class Functional_ORB if (rec == null) throw new BAD_PARAM("The object " + forObject + - " has not been previously connected to this ORB" - ); + " has not been previously connected to this ORB" + ); IOR ior = createIOR(rec); @@ -702,17 +824,28 @@ public class Functional_ORB } /** - * Find and return the easily accessible CORBA object, addressed - * by name. + * Get the local IOR for the given object, null if the object is not local. + */ + public IOR getLocalIor(org.omg.CORBA.Object forObject) + { + Connected_objects.cObject rec = connected_objects.getKey(forObject); + if (rec == null) + return null; + else + return createIOR(rec); + } + + /** + * Find and return the easily accessible CORBA object, addressed by name. * * @param name the object name. * @return the object * - * @throws org.omg.CORBA.ORBPackage.InvalidName if the given name - * is not associated with the known object. + * @throws org.omg.CORBA.ORBPackage.InvalidName if the given name is not + * associated with the known object. */ public org.omg.CORBA.Object resolve_initial_references(String name) - throws InvalidName + throws InvalidName { org.omg.CORBA.Object object = null; try @@ -738,9 +871,8 @@ public class Functional_ORB } /** - * Start the ORBs main working cycle - * (receive invocation - invoke on the local object - send response - - * wait for another invocation). + * Start the ORBs main working cycle (receive invocation - invoke on the local + * object - send response - wait for another invocation). * * The method only returns after calling {@link #shutdown(boolean)}. */ @@ -758,27 +890,37 @@ public class Functional_ORB m = (Map.Entry) iter.next(); obj = (Connected_objects.cObject) m.getValue(); - portServer subserver = new portServer(obj.port); - portServers.add(subserver); + portServer subserver; - // Reuse the current thread for the last portServer. - if (!iter.hasNext()) + if (obj.identity == null) { - // Discard the iterator, eliminating lock checks. - iter = null; - subserver.run(); - return; + subserver = new portServer(obj.port); + portServers.add(subserver); } else - subserver.start(); + subserver = (portServer) identities.get(obj.identity); + + if (!subserver.isAlive()) + { + // Reuse the current thread for the last portServer. + if (!iter.hasNext()) + { + // Discard the iterator, eliminating lock checks. + iter = null; + subserver.run(); + return; + } + else + subserver.start(); + } } } /** * Shutdown the ORB server. * - * @param wait_for_completion if true, the current thread is - * suspended until the shutdown process is complete. + * @param wait_for_completion if true, the current thread is suspended until + * the shutdown process is complete. */ public void shutdown(boolean wait_for_completion) { @@ -796,19 +938,26 @@ public class Functional_ORB } /** - * Find and return the CORBA object, addressed by the given - * IOR string representation. The object can (an usually is) - * located on a remote computer, possibly running a different - * (not necessary java) CORBA implementation. - * + * Find and return the CORBA object, addressed by the given IOR string + * representation. The object can (an usually is) located on a remote + * computer, possibly running a different (not necessary java) CORBA + * implementation. + * * @param ior the object IOR representation string. - * + * * @return the found CORBA object. * @see object_to_string(org.omg.CORBA.Object) */ public org.omg.CORBA.Object string_to_object(String an_ior) { - IOR ior = IOR.parse(an_ior); + return nameParser.corbaloc(an_ior, this); + } + + /** + * Convert ior reference to CORBA object. + */ + public org.omg.CORBA.Object ior_to_object(IOR ior) + { org.omg.CORBA.Object object = find_local_object(ior); if (object == null) { @@ -816,9 +965,7 @@ public class Functional_ORB try { if (impl._get_delegate() == null) - { - impl._set_delegate(new IOR_Delegate(this, ior)); - } + impl._set_delegate(new IOR_Delegate(this, ior)); } catch (BAD_OPERATION ex) { @@ -828,21 +975,19 @@ public class Functional_ORB } object = impl; - connected_objects.add(ior.key, impl, ior.Internet.port); + connected_objects.add(ior.key, impl, ior.Internet.port, null); } return object; } /** - * Get the default naming service for the case when there no - * NameService entries. + * Get the default naming service for the case when there no NameService + * entries. */ protected org.omg.CORBA.Object getDefaultNameService() { if (initial_references.containsKey(NAME_SERVICE)) - { - return (org.omg.CORBA.Object) initial_references.get(NAME_SERVICE); - } + return (org.omg.CORBA.Object) initial_references.get(NAME_SERVICE); IOR ior = new IOR(); ior.Id = NamingContextExtHelper.id(); @@ -857,8 +1002,8 @@ public class Functional_ORB } /** - * Find and return the object, that must be previously connected - * to this ORB. Return null if no such object is available. + * Find and return the object, that must be previously connected to this ORB. + * Return null if no such object is available. * * @param key the object key. * @@ -877,8 +1022,7 @@ public class Functional_ORB * @param app the current applet. * * @param props application specific properties, passed as the second - * parameter in {@link #init(Applet, Properties)}. - * Can be <code>null</code>. + * parameter in {@link #init(Applet, Properties)}. Can be <code>null</code>. */ protected void set_parameters(Applet app, Properties props) { @@ -891,27 +1035,23 @@ public class Functional_ORB { if (para [ i ] [ 0 ].equals(LISTEN_ON)) Port = Integer.parseInt(para [ i ] [ 1 ]); - if (para [ i ] [ 0 ].equals(REFERENCE)) { - StringTokenizer st = new StringTokenizer(para [ i ] [ 1 ], "="); + StringTokenizer st = + new StringTokenizer(para [ i ] [ 1 ], "="); initial_references.put(st.nextToken(), - string_to_object(st.nextToken()) - ); + string_to_object(st.nextToken()) + ); } if (para [ i ] [ 0 ].equals(NS_HOST)) ns_host = para [ i ] [ 1 ]; - if (para [ i ] [ 0 ].equals(START_READING_MESSAGE)) TOUT_START_READING_MESSAGE = Integer.parseInt(para [ i ] [ 1 ]); - if (para [ i ] [ 0 ].equals(WHILE_READING)) TOUT_WHILE_READING = Integer.parseInt(para [ i ] [ 1 ]); - if (para [ i ] [ 0 ].equals(AFTER_RECEIVING)) TOUT_AFTER_RECEIVING = Integer.parseInt(para [ i ] [ 1 ]); - try { if (para [ i ] [ 0 ].equals(NS_PORT)) @@ -921,9 +1061,9 @@ public class Functional_ORB { BAD_PARAM bad = new BAD_PARAM("Invalid " + NS_PORT + - "property, unable to parse '" + - props.getProperty(NS_PORT) + "'" - ); + "property, unable to parse '" + + props.getProperty(NS_PORT) + "'" + ); bad.initCause(ex); throw bad; } @@ -935,52 +1075,54 @@ public class Functional_ORB * Set the ORB parameters. This method is normally called from * {@link #init(String[], Properties)}. * - * @param para the parameters, that were passed as the parameters - * to the <code>main(String[] args)</code> method of the current standalone + * @param para the parameters, that were passed as the parameters to the + * <code>main(String[] args)</code> method of the current standalone * application. * - * @param props application specific properties that were passed - * as a second parameter in {@link init(String[], Properties)}). - * Can be <code>null</code>. + * @param props application specific properties that were passed as a second + * parameter in {@link init(String[], Properties)}). Can be <code>null</code>. */ protected void set_parameters(String[] para, Properties props) { if (para.length > 1) - for (int i = 0; i < para.length - 1; i++) - { - if (para [ i ].endsWith("ListenOn")) - Port = Integer.parseInt(para [ i + 1 ]); - - if (para [ i ].endsWith("ORBInitRef")) - { - StringTokenizer st = new StringTokenizer(para [ i + 1 ], "="); - initial_references.put(st.nextToken(), - string_to_object(st.nextToken()) - ); - } - - if (para [ i ].endsWith("ORBInitialHost")) - ns_host = para [ i + 1 ]; + { + for (int i = 0; i < para.length - 1; i++) + { + if (para [ i ].endsWith("ListenOn")) + Port = Integer.parseInt(para [ i + 1 ]); + if (para [ i ].endsWith("ORBInitRef")) + { + StringTokenizer st = new StringTokenizer(para [ i + 1 ], "="); + initial_references.put(st.nextToken(), + string_to_object(st.nextToken()) + ); + } - try - { - if (para [ i ].endsWith("ORBInitialPort")) - ns_port = Integer.parseInt(para [ i + 1 ]); - } - catch (NumberFormatException ex) - { - throw new BAD_PARAM("Invalid " + para [ i ] + - "parameter, unable to parse '" + - props.getProperty(para [ i + 1 ]) + "'" - ); - } - } + if (para [ i ].endsWith("ORBInitialHost")) + ns_host = para [ i + 1 ]; + try + { + if (para [ i ].endsWith("ORBInitialPort")) + ns_port = Integer.parseInt(para [ i + 1 ]); + } + catch (NumberFormatException ex) + { + throw new BAD_PARAM("Invalid " + para [ i ] + + "parameter, unable to parse '" + + props.getProperty(para [ i + 1 ]) + "'" + ); + } + } + } useProperties(props); } - private IOR createIOR(Connected_objects.cObject ref) - throws BAD_OPERATION + /** + * Create IOR for the given object references. + */ + protected IOR createIOR(Connected_objects.cObject ref) + throws BAD_OPERATION { IOR ior = new IOR(); ior.key = ref.key; @@ -994,7 +1136,6 @@ public class Functional_ORB } if (ior.Id == null) ior.Id = ref.object.getClass().getName(); - try { ior.Internet.host = InetAddress.getLocalHost().getHostAddress(); @@ -1016,12 +1157,13 @@ public class Functional_ORB * {@link InvokeHandler}). */ private void prepareObject(org.omg.CORBA.Object object, IOR ior) - throws BAD_PARAM + throws BAD_PARAM { - if (!(object instanceof InvokeHandler)) - throw new BAD_PARAM(object.getClass().getName() + - " does not implement InvokeHandler. " - ); + /* + * if (!(object instanceof InvokeHandler)) throw new + * BAD_PARAM(object.getClass().getName() + " does not implement + * InvokeHandler. " ); + */ // If no delegate is set, set the default delegate. if (object instanceof ObjectImpl) @@ -1030,9 +1172,7 @@ public class Functional_ORB try { if (impl._get_delegate() == null) - { - impl._set_delegate(new Simple_delegate(this, ior)); - } + impl._set_delegate(new Simple_delegate(this, ior)); } catch (BAD_OPERATION ex) { @@ -1048,20 +1188,17 @@ public class Functional_ORB * @param net_out the stream to write response into * @param msh_request the request message header * @param rh_request the request header - * @param handler the invocation handler that has been used to - * invoke the operation - * @param sysEx the system exception, thrown during the invocation, - * null if none. + * @param handler the invocation handler that has been used to invoke the + * operation + * @param sysEx the system exception, thrown during the invocation, null if + * none. * * @throws IOException */ private void respond_to_client(OutputStream net_out, - MessageHeader msh_request, - RequestHeader rh_request, - bufferedResponseHandler handler, - SystemException sysEx - ) - throws IOException + MessageHeader msh_request, RequestHeader rh_request, + bufferedResponseHandler handler, SystemException sysEx + ) throws IOException { // Set the reply header properties. ReplyHeader reply = handler.reply_header; @@ -1072,17 +1209,23 @@ public class Functional_ORB reply.reply_status = ReplyHeader.USER_EXCEPTION; else reply.reply_status = ReplyHeader.NO_EXCEPTION; - reply.request_id = rh_request.request_id; - cdrBufOutput out = new cdrBufOutput(50 + handler.getBuffer().buffer.size()); + cdrBufOutput out = + new cdrBufOutput(50 + handler.getBuffer().buffer.size()); out.setOrb(this); out.setOffset(msh_request.getHeaderSize()); reply.write(out); - // Write the reply data from the handler. + if (msh_request.version.since_inclusive(1, 2)) + { + out.align(8); + + // Write the reply data from the handler. The handler data already + // include the necessary heading zeroes for alignment. + } handler.getBuffer().buffer.writeTo(out); MessageHeader msh_reply = new MessageHeader(); @@ -1098,19 +1241,53 @@ public class Functional_ORB } /** + * Forward request to another target, as indicated by the passed exception. + */ + private void forward_request(OutputStream net_out, + MessageHeader msh_request, RequestHeader rh_request, gnuForwardRequest info + ) throws IOException + { + MessageHeader msh_forward = new MessageHeader(); + msh_forward.version = msh_request.version; + + ReplyHeader rh_forward = msh_forward.create_reply_header(); + msh_forward.message_type = MessageHeader.REPLY; + rh_forward.reply_status = info.forwarding_code; + rh_forward.request_id = rh_request.request_id; + + // The forwarding code is either LOCATION_FORWARD or LOCATION_FORWARD_PERM. + cdrBufOutput out = new cdrBufOutput(); + out.setOrb(this); + out.setOffset(msh_forward.getHeaderSize()); + + rh_forward.write(out); + + if (msh_forward.version.since_inclusive(1, 2)) + out.align(8); + out.write_Object(info.forward_reference); + + msh_forward.message_size = out.buffer.size(); + + // Write the forwarding instruction. + msh_forward.write(net_out); + out.buffer.writeTo(net_out); + net_out.flush(); + } + + /** * Contains a single servicing task. * - * Normally, each task matches a single remote invocation. - * However under frequent tandem submissions the same - * task may span over several invocations. + * Normally, each task matches a single remote invocation. However under + * frequent tandem submissions the same task may span over several + * invocations. * * @param serverSocket the ORB server socket. * * @throws MARSHAL * @throws IOException */ - private void serve(final portServer p, ServerSocket serverSocket) - throws MARSHAL, IOException + void serve(final portServer p, ServerSocket serverSocket) + throws MARSHAL, IOException { final Socket service; service = serverSocket.accept(); @@ -1148,15 +1325,15 @@ public class Functional_ORB /** * A single servicing step, when the client socket is alrady open. * - * Normally, each task matches a single remote invocation. - * However under frequent tandem submissions the same - * task may span over several invocations. + * Normally, each task matches a single remote invocation. However under + * frequent tandem submissions the same task may span over several + * invocations. * * @param service the opened client socket. - * @param no_resources if true, the "NO RESOURCES" exception - * is thrown to the client. + * @param no_resources if true, the "NO RESOURCES" exception is thrown to the + * client. */ - private void serveStep(Socket service, boolean no_resources) + void serveStep(Socket service, boolean no_resources) { try { @@ -1179,15 +1356,17 @@ public class Functional_ORB } if (max_version != null) - if (!msh_request.version.until_inclusive(max_version.major, - max_version.minor - ) - ) - { - OutputStream out = service.getOutputStream(); - new ErrorMessage(max_version).write(out); - return; - } + { + if (!msh_request.version.until_inclusive(max_version.major, + max_version.minor + ) + ) + { + OutputStream out = service.getOutputStream(); + new ErrorMessage(max_version).write(out); + return; + } + } byte[] r = new byte[ msh_request.message_size ]; @@ -1221,9 +1400,12 @@ public class Functional_ORB // in 1.2 and higher, align the current position at // 8 octet boundary. if (msh_request.version.since_inclusive(1, 2)) - cin.align(8); + { + cin.align(8); + + // find the target object. + } - // find the target object. InvokeHandler target = (InvokeHandler) find_connected_object(rh_request.object_key); @@ -1234,7 +1416,9 @@ public class Functional_ORB // TODO log errors about not existing objects and methods. bufferedResponseHandler handler = - new bufferedResponseHandler(this, msh_request, rh_reply); + new bufferedResponseHandler(this, msh_request, rh_reply, + rh_request + ); SystemException sysEx = null; @@ -1246,6 +1430,18 @@ public class Functional_ORB throw new OBJECT_NOT_EXIST(); target._invoke(rh_request.operation, cin, handler); } + catch (gnuForwardRequest forwarded) + { + OutputStream sou = service.getOutputStream(); + forward_request(sou, msh_request, rh_request, forwarded); + if (service != null && !service.isClosed()) + { + // Wait for the subsequent invocations on the + // same socket for the TANDEM_REQUEST duration. + service.setSoTimeout(TANDEM_REQUESTS); + continue Serving; + } + } catch (SystemException ex) { sysEx = ex; @@ -1256,8 +1452,11 @@ public class Functional_ORB } catch (Exception except) { + except.printStackTrace(); sysEx = - new UNKNOWN("Unknown", 2, CompletionStatus.COMPLETED_MAYBE); + new UNKNOWN("Unknown", 2, + CompletionStatus.COMPLETED_MAYBE + ); org.omg.CORBA.portable.OutputStream ech = handler.createExceptionReply(); @@ -1270,28 +1469,26 @@ public class Functional_ORB { OutputStream sou = service.getOutputStream(); respond_to_client(sou, msh_request, rh_request, handler, - sysEx - ); + sysEx + ); } } else if (msh_request.message_type == MessageHeader.CLOSE_CONNECTION || - msh_request.message_type == MessageHeader.MESSAGE_ERROR - ) + msh_request.message_type == MessageHeader.MESSAGE_ERROR + ) { CloseMessage.close(service.getOutputStream()); service.close(); return; } - else - ; + ; // TODO log error: "Not a request message." if (service != null && !service.isClosed()) - { - // Wait for the subsequent invocations on the - // same socket for the TANDEM_REQUEST duration. - service.setSoTimeout(TANDEM_REQUESTS); - } + + // Wait for the subsequent invocations on the + // same socket for the TANDEM_REQUEST duration. + service.setSoTimeout(TANDEM_REQUESTS); else return; } @@ -1315,23 +1512,18 @@ public class Functional_ORB { if (props.containsKey(LISTEN_ON)) Port = Integer.parseInt(props.getProperty(LISTEN_ON)); - if (props.containsKey(NS_HOST)) ns_host = props.getProperty(NS_HOST); - try { if (props.containsKey(NS_PORT)) ns_port = Integer.parseInt(props.getProperty(NS_PORT)); - if (props.containsKey(START_READING_MESSAGE)) TOUT_START_READING_MESSAGE = Integer.parseInt(props.getProperty(START_READING_MESSAGE)); - if (props.containsKey(WHILE_READING)) TOUT_WHILE_READING = Integer.parseInt(props.getProperty(WHILE_READING)); - if (props.containsKey(AFTER_RECEIVING)) TOUT_AFTER_RECEIVING = Integer.parseInt(props.getProperty(AFTER_RECEIVING)); @@ -1339,9 +1531,9 @@ public class Functional_ORB catch (NumberFormatException ex) { throw new BAD_PARAM("Invalid " + NS_PORT + - "property, unable to parse '" + - props.getProperty(NS_PORT) + "'" - ); + "property, unable to parse '" + props.getProperty(NS_PORT) + + "'" + ); } Enumeration en = props.elements(); @@ -1350,33 +1542,31 @@ public class Functional_ORB String item = (String) en.nextElement(); if (item.equals(REFERENCE)) initial_references.put(item, - string_to_object(props.getProperty(item)) - ); + string_to_object(props.getProperty(item)) + ); } } } /** - * Get the next instance with a response being received. If all currently - * sent responses not yet processed, this method pauses till at least one of - * them is complete. If there are no requests currently sent, the method - * pauses till some request is submitted and the response is received. - * This strategy is identical to the one accepted by Suns 1.4 ORB - * implementation. + * Get the next instance with a response being received. If all currently sent + * responses not yet processed, this method pauses till at least one of them + * is complete. If there are no requests currently sent, the method pauses + * till some request is submitted and the response is received. This strategy + * is identical to the one accepted by Suns 1.4 ORB implementation. * - * The returned response is removed from the list of the currently - * submitted responses and is never returned again. + * The returned response is removed from the list of the currently submitted + * responses and is never returned again. * * @return the previously sent request that now contains the received * response. * * @throws WrongTransaction If the method was called from the transaction - * scope different than the one, used to send the request. The exception - * can be raised only if the request is implicitly associated with some - * particular transaction. + * scope different than the one, used to send the request. The exception can + * be raised only if the request is implicitly associated with some particular + * transaction. */ - public Request get_next_response() - throws org.omg.CORBA.WrongTransaction + public Request get_next_response() throws org.omg.CORBA.WrongTransaction { return asynchron.get_next_response(); } @@ -1385,8 +1575,8 @@ public class Functional_ORB * Find if any of the requests that have been previously sent with * {@link #send_multiple_requests_deferred}, have a response yet. * - * @return true if there is at least one response to the previously - * sent request, false otherwise. + * @return true if there is at least one response to the previously sent + * request, false otherwise. */ public boolean poll_next_response() { @@ -1394,12 +1584,12 @@ public class Functional_ORB } /** - * Send multiple prepared requests expecting to get a reply. All requests - * are send in parallel, each in its own separate thread. When the - * reply arrives, it is stored in the agreed fields of the corresponing - * request data structure. If this method is called repeatedly, - * the new requests are added to the set of the currently sent requests, - * but the old set is not discarded. + * Send multiple prepared requests expecting to get a reply. All requests are + * send in parallel, each in its own separate thread. When the reply arrives, + * it is stored in the agreed fields of the corresponing request data + * structure. If this method is called repeatedly, the new requests are added + * to the set of the currently sent requests, but the old set is not + * discarded. * * @param requests the prepared array of requests. * @@ -1414,8 +1604,8 @@ public class Functional_ORB /** * Send multiple prepared requests one way, do not caring about the answer. - * The messages, containing requests, will be marked, indicating that - * the sender is not expecting to get a reply. + * The messages, containing requests, will be marked, indicating that the + * sender is not expecting to get a reply. * * @param requests the prepared array of requests. * @@ -1429,8 +1619,7 @@ public class Functional_ORB /** * Set the flag, forcing all server threads to terminate. */ - protected void finalize() - throws java.lang.Throwable + protected void finalize() throws java.lang.Throwable { running = false; super.finalize(); diff --git a/libjava/classpath/gnu/CORBA/GIOP/ReplyHeader.java b/libjava/classpath/gnu/CORBA/GIOP/ReplyHeader.java index 1e0e154f80d..f0f409394e6 100644 --- a/libjava/classpath/gnu/CORBA/GIOP/ReplyHeader.java +++ b/libjava/classpath/gnu/CORBA/GIOP/ReplyHeader.java @@ -41,13 +41,13 @@ package gnu.CORBA.GIOP; import gnu.CORBA.CDR.cdrInput; import gnu.CORBA.CDR.cdrOutput; - /** * The header of the standard reply. * * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) */ public abstract class ReplyHeader + extends contextSupportingHeader { /** * Reply status, if no exception occured. @@ -65,9 +65,8 @@ public abstract class ReplyHeader public static final int SYSTEM_EXCEPTION = 2; /** - * Reply status, if the client ORB must re - send - * the request to another destination. The body - * contains IOR. + * Reply status, if the client ORB must re - send the request to another + * destination. The body contains IOR. */ public static final int LOCATION_FORWARD = 3; @@ -84,16 +83,6 @@ public abstract class ReplyHeader public static final int NEEDS_ADDRESSING_MODE = 5; /** - * Empty array, indicating that no service context is available. - */ - protected static final ServiceContext[] NO_CONTEXT = new ServiceContext[ 0 ]; - - /** - * The ORB service data. - */ - public ServiceContext[] service_context = NO_CONTEXT; - - /** * The status of this reply, holds one of the reply status constants. */ public int reply_status; @@ -110,19 +99,19 @@ public abstract class ReplyHeader { switch (reply_status) { - case NO_EXCEPTION : + case NO_EXCEPTION: return "ok"; - case USER_EXCEPTION : + case USER_EXCEPTION: return "user exception"; - case SYSTEM_EXCEPTION : + case SYSTEM_EXCEPTION: return "system exception"; - case LOCATION_FORWARD : + case LOCATION_FORWARD: return "moved"; - default : + default: return null; } } diff --git a/libjava/classpath/gnu/CORBA/GIOP/RequestHeader.java b/libjava/classpath/gnu/CORBA/GIOP/RequestHeader.java index f2de4e2715b..17cccb8834a 100644 --- a/libjava/classpath/gnu/CORBA/GIOP/RequestHeader.java +++ b/libjava/classpath/gnu/CORBA/GIOP/RequestHeader.java @@ -41,7 +41,6 @@ package gnu.CORBA.GIOP; import gnu.CORBA.CDR.cdrInput; import gnu.CORBA.CDR.cdrOutput; - import org.omg.CORBA.portable.IDLEntity; /** @@ -50,13 +49,13 @@ import org.omg.CORBA.portable.IDLEntity; * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) */ public abstract class RequestHeader + extends contextSupportingHeader implements IDLEntity { /** - * The currently free request id. This field is incremented - * each time the new request header is constructed. To facilitate - * error detection, the first free id is equal to 0x01234567 - * (19088743). + * The currently free request id. This field is incremented each time the new + * request header is constructed. To facilitate error detection, the first + * free id is equal to 0x01234567 (19088743). */ private static int freeId = 0x01234567; @@ -71,23 +70,17 @@ public abstract class RequestHeader public byte[] object_key; /** - * A value identifying the requesting principal. - * Initialised into a single zero byte. + * A value identifying the requesting principal. Initialised into a single + * zero byte. * * @deprecated by CORBA 2.2. */ public byte[] requesting_principal; /** - * Contains the ORB service data being passed. Initialised as the - * zero size array by default. - */ - public ServiceContext[] service_context = new ServiceContext[ 0 ]; - - /** - * This is used to associate the reply message with the - * previous request message. Initialised each time by the - * different value, increasing form 1 to Integer.MAX_VALUE. + * This is used to associate the reply message with the previous request + * message. Initialised each time by the different value, increasing form 1 to + * Integer.MAX_VALUE. */ public int request_id = getNextId(); @@ -97,10 +90,9 @@ public abstract class RequestHeader protected boolean response_expected = true; /** - * Get next free request id. The value of the free request - * id starts from 0x02345678, it is incremented each time this - * function is called and is reset to 1 after reaching - * Integer.MAX_VALUE. + * Get next free request id. The value of the free request id starts from + * 0x02345678, it is incremented each time this function is called and is + * reset to 1 after reaching Integer.MAX_VALUE. * * @return the next free request id. */ @@ -126,15 +118,15 @@ public abstract class RequestHeader public abstract boolean isResponseExpected(); /** - * Converts an byte array into hexadecimal string values. - * Used in various toString() methods. + * Converts an byte array into hexadecimal string values. Used in various + * toString() methods. */ public String bytes(byte[] array) { StringBuffer b = new StringBuffer(); for (int i = 0; i < array.length; i++) { - b.append(Integer.toHexString(array [ i ] & 0xFF)); + b.append(Integer.toHexString(array[i] & 0xFF)); b.append(" "); } return b.toString(); @@ -158,4 +150,5 @@ public abstract class RequestHeader * @param out a stream to write into. */ public abstract void write(cdrOutput out); + } diff --git a/libjava/classpath/gnu/CORBA/GIOP/ServiceContext.java b/libjava/classpath/gnu/CORBA/GIOP/ServiceContext.java index 7e44bdcea77..29a8ea8ac77 100644 --- a/libjava/classpath/gnu/CORBA/GIOP/ServiceContext.java +++ b/libjava/classpath/gnu/CORBA/GIOP/ServiceContext.java @@ -41,7 +41,9 @@ package gnu.CORBA.GIOP; import gnu.CORBA.CDR.cdrInput; import gnu.CORBA.CDR.cdrOutput; - +import org.omg.CORBA.BAD_INV_ORDER; +import org.omg.CORBA.BAD_PARAM; +import org.omg.CORBA.CompletionStatus; import org.omg.CORBA.portable.IDLEntity; /** @@ -53,16 +55,40 @@ public class ServiceContext implements IDLEntity { /** - * The context data. + * Use serialVersionUID for interoperability. */ - public byte[] context_data; + private static final long serialVersionUID = 1; /** - * The context id. + * The context id (for instance, 0x1 for code sets context). At the moment of + * writing, the OMG defines 16 standard values and provides rules to register + * the vendor specific context ids. The range 0-4095 is reserved for the + * future standard OMG contexts. */ public int context_id; /** + * The context_data. + */ + public byte[] context_data; + + /** + * Crete unitialised instance. + */ + public ServiceContext() + { + } + + /** + * Create from omg context. + */ + public ServiceContext(org.omg.IOP.ServiceContext from) + { + context_id = from.context_id; + context_data = from.context_data; + } + + /** * Read the context values from the stream. * * @param istream a stream to read from. @@ -73,13 +99,13 @@ public class ServiceContext switch (id) { - case cxCodeSet.ID : + case cxCodeSet.ID: cxCodeSet codeset = new cxCodeSet(); codeset.readContext(istream); return codeset; - default : + default: ServiceContext ctx = new ServiceContext(); ctx.context_id = id; @@ -94,9 +120,9 @@ public class ServiceContext public static ServiceContext[] readSequence(cdrInput istream) { int size = istream.read_long(); - ServiceContext[] value = new gnu.CORBA.GIOP.ServiceContext[ size ]; + ServiceContext[] value = new gnu.CORBA.GIOP.ServiceContext[size]; for (int i = 0; i < value.length; i++) - value [ i ] = read(istream); + value[i] = read(istream); return value; } @@ -118,7 +144,99 @@ public class ServiceContext { ostream.write_long(value.length); for (int i = 0; i < value.length; i++) - value [ i ].write(ostream); + value[i].write(ostream); + } + + /** + * Add context to the given array of contexts. + */ + public static void add(org.omg.IOP.ServiceContext[] cx, + org.omg.IOP.ServiceContext service_context, boolean replace) + { + int exists = -1; + + for (int i = 0; i < cx.length; i++) + if (cx[i].context_id == service_context.context_id) + exists = i; + + if (exists < 0) + { + // Add context. + org.omg.IOP.ServiceContext[] n = new org.omg.IOP.ServiceContext[cx.length + 1]; + for (int i = 0; i < cx.length; i++) + n[i] = cx[i]; + n[cx.length] = service_context; + } + else + { + // Replace context. + if (!replace) + throw new BAD_INV_ORDER("Repetetive setting of the context " + + service_context.context_id, 15, + CompletionStatus.COMPLETED_NO); + else + cx[exists] = service_context; + } + } + + /** + * Add context to the given array of contexts. + */ + public static ServiceContext[] add(ServiceContext[] cx, + org.omg.IOP.ServiceContext service_context, boolean replace) + { + int exists = -1; + + for (int i = 0; i < cx.length; i++) + if (cx[i].context_id == service_context.context_id) + exists = i; + + if (exists < 0) + { + // Add context. + ServiceContext[] n = new ServiceContext[cx.length + 1]; + for (int i = 0; i < cx.length; i++) + n[i] = cx[i]; + n[cx.length] = new ServiceContext(service_context); + return n; + } + else + { + // Replace context. + if (!replace) + throw new BAD_INV_ORDER("Repetetive setting of the context " + + service_context.context_id, 15, + CompletionStatus.COMPLETED_NO); + else + cx[exists] = new ServiceContext(service_context); + return cx; + } + } + + + /** + * Find context with the given name in the context array. + */ + public static org.omg.IOP.ServiceContext findContext(int ctx_name, + org.omg.IOP.ServiceContext[] cx) + { + for (int i = 0; i < cx.length; i++) + if (cx[i].context_id == ctx_name) + return cx[i]; + throw new BAD_PARAM("No context with id " + ctx_name); + } + + /** + * Find context with the given name in the context array, + * converting into org.omg.IOP.ServiceContext. + */ + public static org.omg.IOP.ServiceContext findContext(int ctx_name, + ServiceContext[] cx) + { + for (int i = 0; i < cx.length; i++) + if (cx[i].context_id == ctx_name) + return new org.omg.IOP.ServiceContext(ctx_name, cx[i].context_data); + throw new BAD_PARAM("No context with id " + ctx_name); } /** @@ -126,6 +244,6 @@ public class ServiceContext */ public String toString() { - return "ctx "+context_id+", size "+context_data.length; + return "ctx " + context_id + ", size " + context_data.length; } } diff --git a/libjava/classpath/gnu/CORBA/GIOP/v1_0/RequestHeader.java b/libjava/classpath/gnu/CORBA/GIOP/v1_0/RequestHeader.java index ffa45c37bc0..7ede4e5b926 100644 --- a/libjava/classpath/gnu/CORBA/GIOP/v1_0/RequestHeader.java +++ b/libjava/classpath/gnu/CORBA/GIOP/v1_0/RequestHeader.java @@ -40,11 +40,11 @@ package gnu.CORBA.GIOP.v1_0; import gnu.CORBA.CDR.cdrInput; import gnu.CORBA.CDR.cdrOutput; - -import org.omg.CORBA.portable.IDLEntity; import gnu.CORBA.GIOP.ServiceContext; import gnu.CORBA.GIOP.cxCodeSet; +import org.omg.CORBA.portable.IDLEntity; + /** * The GIOP 1.0 request message. * diff --git a/libjava/classpath/gnu/CORBA/IOR.java b/libjava/classpath/gnu/CORBA/IOR.java index cedbce46175..02e94aa6426 100644 --- a/libjava/classpath/gnu/CORBA/IOR.java +++ b/libjava/classpath/gnu/CORBA/IOR.java @@ -47,22 +47,29 @@ import gnu.CORBA.GIOP.cxCodeSet; import org.omg.CORBA.BAD_PARAM; import org.omg.CORBA.CompletionStatus; +import org.omg.CORBA.MARSHAL; import org.omg.CORBA.ULongSeqHelper; +import org.omg.IOP.TAG_INTERNET_IOP; +import org.omg.IOP.TAG_MULTIPLE_COMPONENTS; +import org.omg.IOP.TaggedComponent; +import org.omg.IOP.TaggedComponentHelper; +import org.omg.IOP.TaggedProfile; +import org.omg.IOP.TaggedProfileHelper; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.util.ArrayList; /** - * The implementaton of the Interoperable Object Reference (IOR). - * IOR can be compared with the Internet address for a web page, - * it provides means to locate the CORBA service on the web. - * IOR contains the host address, port number, the object identifier - * (key) inside the server, the communication protocol version, - * supported charsets and so on. + * The implementaton of the Interoperable Object Reference (IOR). IOR can be + * compared with the Internet address for a web page, it provides means to + * locate the CORBA service on the web. IOR contains the host address, port + * number, the object identifier (key) inside the server, the communication + * protocol version, supported charsets and so on. * - * Ths class provides method for encoding and - * decoding the IOR information from/to the stringified references, - * usually returned by {@link org.omg.CORBA.ORB#String object_to_string()}. + * Ths class provides method for encoding and decoding the IOR information + * from/to the stringified references, usually returned by + * {@link org.omg.CORBA.ORB#String object_to_string()}. * * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) * @@ -72,10 +79,22 @@ import java.io.IOException; public class IOR { /** - * The code sets profile. + * The code sets tagged component, normally part of the Internet profile. This + * compone consists of the two componenets itself. */ public static class CodeSets_profile { + public CodeSets_profile() + { + int[] supported = CharSets_OSF.getSupportedCharSets(); + + narrow.native_set = CharSets_OSF.NATIVE_CHARACTER; + narrow.conversion = supported; + + wide.native_set = CharSets_OSF.NATIVE_WIDE_CHARACTER; + wide.conversion = supported; + } + /** * The code set component. */ @@ -112,7 +131,7 @@ public class IOR b.append(" conversion "); for (int i = 0; i < conversion.length; i++) { - b.append(name(conversion [ i ])); + b.append(name(conversion[i])); b.append(' '); } } @@ -131,8 +150,8 @@ public class IOR private String name(int set) { - return "0x" + Integer.toHexString(set) + " (" + - CharSets_OSF.getName(set) + ") "; + return "0x" + Integer.toHexString(set) + " (" + + CharSets_OSF.getName(set) + ") "; } } @@ -201,7 +220,7 @@ public class IOR /** * The internet profile. */ - public static class Internet_profile + public class Internet_profile { /** * The agreed tag for the Internet profile. @@ -224,6 +243,18 @@ public class IOR public int port; /** + * The code sets component in the internet profile of this IOR. This is not + * a separate profile. + */ + public CodeSets_profile CodeSets = new CodeSets_profile(); + + /** + * Reserved for all components of this profile, this array holds the + * components other than code set components. + */ + ArrayList components = new ArrayList(); + + /** * Return the human readable representation. */ public String toString() @@ -235,22 +266,63 @@ public class IOR b.append(" (v"); b.append(version); b.append(")"); + if (components.size() > 0) + b.append(" " + components.size() + " extra components."); return b.toString(); } + + /** + * Write the internet profile (except the heading tag. + */ + public void write(cdrOutput out) + { + try + { + // Need to write the Internet profile into the separate + // stream as we must know the size in advance. + cdrOutput b = out.createEncapsulation(); + + version.write(b); + b.write_string(host); + + b.write_ushort((short) (port & 0xFFFF)); + + // Write the object key. + b.write_long(key.length); + b.write(key); + + // Number of the tagged components. + b.write_long(1 + components.size()); + + b.write_long(CodeSets_profile.TAG_CODE_SETS); + CodeSets.write(b); + + TaggedComponent t; + + for (int i = 0; i < components.size(); i++) + { + t = (TaggedComponent) components.get(i); + TaggedComponentHelper.write(b, t); + } + + b.close(); + } + catch (Exception e) + { + MARSHAL m = new MARSHAL("Unable to write Internet profile."); + m.initCause(e); + throw m; + } + } } /** - * The standard minor code, indicating that the string to object - * converstio has failed due non specific reasons. + * The standard minor code, indicating that the string to object converstio + * has failed due non specific reasons. */ public static final int FAILED = 10; /** - * The code sets profile of this IOR. - */ - public CodeSets_profile CodeSets = new CodeSets_profile(); - - /** * The internet profile of this IOR. */ public Internet_profile Internet = new Internet_profile(); @@ -261,45 +333,35 @@ public class IOR public String Id; /** - * The additional tagged components, encapsulated in - * the byte arrays. They are only supported by the - * later versions, than currently implemented. + * The object key. */ - public byte[][] extra; + public byte[] key; /** - * The object key. + * All tagged profiles of this IOR, except the separately defined Internet + * profile. */ - public byte[] key; + ArrayList profiles = new ArrayList(); /** - * True if the profile was encoded using the Big Endian or - * the encoding is not known. + * True if the profile was encoded using the Big Endian or the encoding is not + * known. * * false if it was encoded using the Little Endian. */ public boolean Big_Endian = true; /** - * Create an empty instance, initialising the code sets to default - * values. + * Create an empty instance, initialising the code sets to default values. */ public IOR() { - int[] supported = CharSets_OSF.getSupportedCharSets(); - - CodeSets.narrow.native_set = CharSets_OSF.NATIVE_CHARACTER; - CodeSets.narrow.conversion = supported; - - CodeSets.wide.native_set = CharSets_OSF.NATIVE_WIDE_CHARACTER; - CodeSets.wide.conversion = supported; } /** * Parse the provided stringifed reference. * - * @param stringified_reference, in the form of - * IOR:nnnnnn..... + * @param stringified_reference, in the form of IOR:nnnnnn..... * * @return the parsed IOR * @@ -308,14 +370,13 @@ public class IOR * TODO corballoc and other alternative formats. */ public static IOR parse(String stringified_reference) - throws BAD_PARAM + throws BAD_PARAM { try { if (!stringified_reference.startsWith("IOR:")) throw new BAD_PARAM("The string refernce must start with IOR:", - FAILED, CompletionStatus.COMPLETED_NO - ); + FAILED, CompletionStatus.COMPLETED_NO); IOR r = new IOR(); @@ -340,8 +401,7 @@ public class IOR { ex.printStackTrace(); throw new BAD_PARAM(ex + " while parsing " + stringified_reference, - FAILED, CompletionStatus.COMPLETED_NO - ); + FAILED, CompletionStatus.COMPLETED_NO); } } @@ -352,7 +412,7 @@ public class IOR * @throws IOException if the stream throws it. */ public void _read(cdrInput c) - throws IOException, BAD_PARAM + throws IOException, BAD_PARAM { int endian; @@ -366,23 +426,21 @@ public class IOR } /** - * Read the IOR from the provided input stream, not reading - * the endian data at the beginning of the stream. The IOR is - * thansferred in this form in + * Read the IOR from the provided input stream, not reading the endian data at + * the beginning of the stream. The IOR is thansferred in this form in * {@link write_Object(org.omg.CORBA.Object)}. * * If the stream contains a null value, the Id and Internet fields become - * equal to null. Otherwise Id contains some string (possibly - * empty). + * equal to null. Otherwise Id contains some string (possibly empty). * - * Id is checked for null in cdrInput that then returns - * null instead of object. + * Id is checked for null in cdrInput that then returns null instead of + * object. * * @param c a stream to read from. * @throws IOException if the stream throws it. */ public void _read_no_endian(cdrInput c) - throws IOException, BAD_PARAM + throws IOException, BAD_PARAM { Id = c.read_string(); @@ -407,9 +465,7 @@ public class IOR Internet.host = profile.read_string(); Internet.port = profile.gnu_read_ushort(); - int lk = profile.read_long(); - key = new byte[ lk ]; - profile.read(key); + key = profile.read_sequence(); // Read tagged components. int n_components = 0; @@ -425,7 +481,16 @@ public class IOR if (ctag == CodeSets_profile.TAG_CODE_SETS) { - CodeSets.read(profile); + Internet.CodeSets.read(profile); + } + else + { + // Construct a generic component for codesets + // profile. + TaggedComponent pc = new TaggedComponent(); + pc.tag = ctag; + pc.component_data = profile.read_sequence(); + Internet.components.add(pc); } } } @@ -434,12 +499,21 @@ public class IOR ex.printStackTrace(); } } + else + { + // Construct a generic profile. + TaggedProfile p = new TaggedProfile(); + p.tag = tag; + p.profile_data = profile.buffer.getBuffer(); + + profiles.add(p); + } } } /** - * Write this IOR record to the provided CDR stream. - * This procedure writes the zero (Big Endian) marker first. + * Write this IOR record to the provided CDR stream. This procedure writes the + * zero (Big Endian) marker first. */ public void _write(cdrOutput out) { @@ -451,8 +525,8 @@ public class IOR /** * Write a null value to the CDR output stream. * - * The null value is written as defined in OMG specification - * (zero length string, followed by an empty set of profiles). + * The null value is written as defined in OMG specification (zero length + * string, followed by an empty set of profiles). */ public static void write_null(cdrOutput out) { @@ -464,47 +538,27 @@ public class IOR } /** - * Write this IOR record to the provided CDR stream. The procedure - * writed data in Big Endian, but does NOT add any endian marker - * to the beginning. + * Write this IOR record to the provided CDR stream. The procedure writed data + * in Big Endian, but does NOT add any endian marker to the beginning. */ public void _write_no_endian(cdrOutput out) { - try - { - // Write repository id. - out.write_string(Id); - - // Always one profile. - out.write_long(1); - - // It is the Internet profile. - out.write_long(Internet_profile.TAG_INTERNET_IOP); + // Write repository id. + out.write_string(Id); - // Need to write the Internet profile into the separate - // stream as we must know the size in advance. - cdrOutput b = out.createEncapsulation(); + out.write_long(1 + profiles.size()); - Internet.version.write(b); - b.write_string(Internet.host); + // Write the Internet profile. + out.write_long(Internet_profile.TAG_INTERNET_IOP); + Internet.write(out); - b.write_ushort((short) (Internet.port & 0xFFFF)); + // Write other profiles. + TaggedProfile tp; - // Write the object key. - b.write_long(key.length); - b.write(key); - - // One tagged component. - b.write_long(1); - - b.write_long(CodeSets_profile.TAG_CODE_SETS); - CodeSets.write(b); - - b.close(); - } - catch (IOException ex) + for (int i = 0; i < profiles.size(); i++) { - Unexpected.error(ex); + tp = (TaggedProfile) profiles.get(i); + TaggedProfileHelper.write(out, tp); } } @@ -525,11 +579,11 @@ public class IOR for (int i = 0; i < key.length; i++) { - b.append(Integer.toHexString(key [ i ] & 0xFF)); + b.append(Integer.toHexString(key[i] & 0xFF)); } b.append(" "); - b.append(CodeSets); + b.append(Internet.CodeSets); return b.toString(); } @@ -552,7 +606,7 @@ public class IOR for (int i = 0; i < binary.length; i++) { - s = Integer.toHexString(binary [ i ] & 0xFF); + s = Integer.toHexString(binary[i] & 0xFF); if (s.length() == 1) b.append('0'); b.append(s); @@ -560,4 +614,105 @@ public class IOR return b.toString(); } + + /** + * Adds a service-specific component to the IOR profile. The specified + * component will be included in all profiles, present in the IOR. + * + * @param tagged_component a tagged component being added. + */ + public void add_ior_component(TaggedComponent tagged_component) + { + // Add to the Internet profile. + Internet.components.add(tagged_component); + + // Add to others. + for (int i = 0; i < profiles.size(); i++) + { + TaggedProfile profile = (TaggedProfile) profiles.get(i); + addComponentTo(profile, tagged_component); + } + } + + /** + * Adds a service-specific component to the IOR profile. + * + * @param tagged_component a tagged component being added. + * + * @param profile_id the IOR profile to that the component must be added. The + * 0 value ({@link org.omg.IOP.TAG_INTERNET_IOP#value}) adds to the Internet + * profile where host and port are stored by default. + */ + public void add_ior_component_to_profile(TaggedComponent tagged_component, + int profile_id) + { + if (profile_id == TAG_INTERNET_IOP.value) + // Add to the Internet profile + Internet.components.add(tagged_component); + else + { + // Add to others. + for (int i = 0; i < profiles.size(); i++) + { + TaggedProfile profile = (TaggedProfile) profiles.get(i); + if (profile.tag == profile_id) + addComponentTo(profile, tagged_component); + } + } + } + + /** + * Add given component to the given profile that is NOT an Internet profile. + * + * @param profile the profile, where the component should be added. + * @param component the component to add. + */ + private static void addComponentTo(TaggedProfile profile, + TaggedComponent component) + { + if (profile.tag == TAG_MULTIPLE_COMPONENTS.value) + { + TaggedComponent[] present; + if (profile.profile_data.length > 0) + { + cdrBufInput in = new cdrBufInput(profile.profile_data); + + present = new TaggedComponent[in.read_long()]; + + for (int i = 0; i < present.length; i++) + { + present[i] = TaggedComponentHelper.read(in); + } + } + else + present = new TaggedComponent[0]; + + cdrBufOutput out = new cdrBufOutput(profile.profile_data.length + + component.component_data.length + + 8); + + // Write new amount of components. + out.write_long(present.length + 1); + + // Write other components. + for (int i = 0; i < present.length; i++) + TaggedComponentHelper.write(out, present[i]); + + // Write the passed component. + TaggedComponentHelper.write(out, component); + + try + { + out.close(); + } + catch (IOException e) + { + throw new Unexpected(e); + } + profile.profile_data = out.buffer.toByteArray(); + } + else + // The future supported tagged profiles should be added here. + throw new BAD_PARAM("Unsupported profile type " + profile.tag); + } }
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/IOR_Delegate.java b/libjava/classpath/gnu/CORBA/IOR_Delegate.java index b06f6300d95..3b64eb585c4 100644 --- a/libjava/classpath/gnu/CORBA/IOR_Delegate.java +++ b/libjava/classpath/gnu/CORBA/IOR_Delegate.java @@ -40,7 +40,9 @@ package gnu.CORBA; import gnu.CORBA.CDR.cdrBufInput; import gnu.CORBA.GIOP.ReplyHeader; +import gnu.CORBA.Poa.activeObjectMap; +import org.omg.CORBA.CompletionStatus; import org.omg.CORBA.Context; import org.omg.CORBA.ContextList; import org.omg.CORBA.ExceptionList; @@ -53,6 +55,7 @@ import org.omg.CORBA.portable.ApplicationException; import org.omg.CORBA.portable.InputStream; import org.omg.CORBA.portable.OutputStream; import org.omg.CORBA.portable.RemarshalException; +import org.omg.PortableInterceptor.ForwardRequest; import java.io.IOException; @@ -67,10 +70,20 @@ import java.net.Socket; * * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) */ -public class IOR_Delegate - extends Simple_delegate +public class IOR_Delegate extends Simple_delegate { /** + * True if the current IOR does not map into the local servant. If false, the + * IOR is either local or should be checked. + */ + boolean remote_ior; + + /** + * If not null, this field contains data about the local servant. + */ + activeObjectMap.Obj local_ior; + + /** * Contructs an instance of object using the given IOR. */ public IOR_Delegate(ORB an_orb, IOR an_ior) @@ -92,11 +105,10 @@ public class IOR_Delegate * @return the created request. */ public Request create_request(org.omg.CORBA.Object target, Context context, - String operation, NVList parameters, - NamedValue returns - ) + String operation, NVList parameters, NamedValue returns + ) { - gnuRequest request = new gnuRequest(); + gnuRequest request = getRequestInstance(target); request.setIor(getIor()); request.set_target(target); @@ -122,12 +134,11 @@ public class IOR_Delegate * @return the created request. */ public Request create_request(org.omg.CORBA.Object target, Context context, - String operation, NVList parameters, - NamedValue returns, ExceptionList exceptions, - ContextList ctx_list - ) + String operation, NVList parameters, NamedValue returns, + ExceptionList exceptions, ContextList ctx_list + ) { - gnuRequest request = new gnuRequest(); + gnuRequest request = getRequestInstance(target); request.setIor(ior); request.set_target(target); @@ -144,100 +155,219 @@ public class IOR_Delegate } /** - * Invoke operation on the given object, writing parameters to the given - * output stream. + * Get the instance of request. + */ + protected gnuRequest getRequestInstance(org.omg.CORBA.Object target) + { + return new gnuRequest(); + } + + /** + * Invoke operation on the given object, als handling temproray and permanent + * redirections. The ReplyHeader.LOCATION_FORWARD will cause to resend the + * request to the new direction. The ReplyHeader.LOCATION_FORWARD_PERM will + * cause additionally to remember the new location by this delegate, so + * subsequent calls will be immediately delivered to the new target. * * @param target the target object. * @param output the output stream, previously returned by * {@link #request(org.omg.CORBA.Object, String, boolean)}. * - * @return the input stream, to read the response from or null for a - * one-way request. + * @return the input stream, to read the response from or null for a one-way + * request. * * @throws SystemException if the SystemException has been thrown on the - * remote side (the exact type and the minor code matches the data of - * the remote exception that has been thrown). + * remote side (the exact type and the minor code matches the data of the + * remote exception that has been thrown). * * @throws org.omg.CORBA.portable.ApplicationException as specified. * @throws org.omg.CORBA.portable.RemarshalException as specified. */ public InputStream invoke(org.omg.CORBA.Object target, OutputStream output) - throws ApplicationException, RemarshalException + throws ApplicationException, RemarshalException { streamRequest request = (streamRequest) output; - if (request.response_expected) + Forwardings: + while (true) { - binaryReply response = request.request.submit(); - - // Read reply header. - ReplyHeader rh = response.header.create_reply_header(); - cdrBufInput input = response.getStream(); - input.setOrb(orb); - rh.read(input); - - boolean moved_permanently = false; - - switch (rh.reply_status) + try { - case ReplyHeader.NO_EXCEPTION : - if (response.header.version.since_inclusive(1, 2)) - input.align(8); - return input; - - case ReplyHeader.SYSTEM_EXCEPTION : - if (response.header.version.since_inclusive(1, 2)) - input.align(8); - throw ObjectCreator.readSystemException(input); - - case ReplyHeader.USER_EXCEPTION : - if (response.header.version.since_inclusive(1, 2)) - input.align(8); - input.mark(2000); - - String uxId = input.read_string(); - input.reset(); - - throw new ApplicationException(uxId, input); - - case ReplyHeader.LOCATION_FORWARD_PERM : - moved_permanently = true; - - case ReplyHeader.LOCATION_FORWARD : - if (response.header.version.since_inclusive(1, 2)) - input.align(8); - - IOR forwarded = new IOR(); - try - { - forwarded._read_no_endian(input); - } - catch (IOException ex) - { - MARSHAL t = new MARSHAL("Cant read forwarding info"); - t.initCause(ex); - throw t; - } - - request.request.setIor(forwarded); - - // If the object has moved permanently, its IOR is replaced. - if (moved_permanently) - setIor(forwarded); - - return invoke(target, request); - - default : - throw new MARSHAL("Unknow reply status: " + rh.reply_status); + if (request.response_expected) + { + binaryReply response = request.request.submit(); + + // Read reply header. + ReplyHeader rh = response.header.create_reply_header(); + cdrBufInput input = response.getStream(); + input.setOrb(orb); + rh.read(input); + request.request.m_rph = rh; + + boolean moved_permanently = false; + + switch (rh.reply_status) + { + case ReplyHeader.NO_EXCEPTION : + if (request.request.m_interceptor != null) + request.request.m_interceptor. + receive_reply(request.request.m_info); + if (response.header.version.since_inclusive(1, 2)) + input.align(8); + return input; + + case ReplyHeader.SYSTEM_EXCEPTION : + if (response.header.version.since_inclusive(1, 2)) + input.align(8); + showException(request, input); + + throw ObjectCreator.readSystemException(input); + + case ReplyHeader.USER_EXCEPTION : + if (response.header.version.since_inclusive(1, 2)) + input.align(8); + showException(request, input); + + throw new ApplicationException(request. + request.m_exception_id, input + ); + + case ReplyHeader.LOCATION_FORWARD_PERM : + moved_permanently = true; + + case ReplyHeader.LOCATION_FORWARD : + if (response.header.version.since_inclusive(1, 2)) + input.align(8); + + IOR forwarded = new IOR(); + try + { + forwarded._read_no_endian(input); + } + catch (IOException ex) + { + MARSHAL t = + new MARSHAL("Cant read forwarding info", 5102, + CompletionStatus.COMPLETED_NO + ); + t.initCause(ex); + throw t; + } + + gnuRequest prev = request.request; + gnuRequest r = getRequestInstance(target); + + r.m_interceptor = prev.m_interceptor; + r.m_slots = prev.m_slots; + + r.m_args = prev.m_args; + r.m_context = prev.m_context; + r.m_context_list = prev.m_context_list; + r.m_environment = prev.m_environment; + r.m_exceptions = prev.m_exceptions; + r.m_operation = prev.m_operation; + r.m_parameter_buffer = prev.m_parameter_buffer; + r.m_parameter_buffer.request = r; + r.m_result = prev.m_result; + r.m_target = prev.m_target; + r.oneWay = prev.oneWay; + r.m_forward_ior = forwarded; + + if (r.m_interceptor != null) + r.m_interceptor.receive_other(r.m_info); + + r.setIor(forwarded); + + IOR_contructed_object it = + new IOR_contructed_object(orb, forwarded); + + r.m_target = it; + + request.request = r; + + IOR prev_ior = getIor(); + + setIor(forwarded); + + try + { + return invoke(it, request); + } + finally + { + if (!moved_permanently) + setIor(prev_ior); + } + + default : + throw new MARSHAL("Unknow reply status: " + + rh.reply_status, 8000 + rh.reply_status, + CompletionStatus.COMPLETED_NO + ); + } + } + else + { + request.request.send_oneway(); + return null; + } + } + catch (ForwardRequest forwarded) + { + ForwardRequest fw = forwarded; + Forwarding2: + while (true) + { + try + { + gnuRequest prev = request.request; + gnuRequest r = getRequestInstance(target); + + r.m_interceptor = prev.m_interceptor; + r.m_args = prev.m_args; + r.m_context = prev.m_context; + r.m_context_list = prev.m_context_list; + r.m_environment = prev.m_environment; + r.m_exceptions = prev.m_exceptions; + r.m_operation = prev.m_operation; + r.m_parameter_buffer = prev.m_parameter_buffer; + r.m_parameter_buffer.request = r; + r.m_result = prev.m_result; + r.m_target = prev.m_target; + r.oneWay = prev.oneWay; + + r.m_forwarding_target = fw.forward; + + if (r.m_interceptor != null) + r.m_interceptor.receive_other(r.m_info); + + r.m_target = fw.forward; + request.request = r; + break Forwarding2; + } + catch (ForwardRequest e) + { + forwarded = e; + } + } } - } - else - { - request.request.send_oneway(); - return null; } } /** + * Show exception to interceptor. + */ + void showException(streamRequest request, cdrBufInput input) + throws ForwardRequest + { + input.mark(2048); + request.request.m_exception_id = input.read_string(); + input.reset(); + + if (request.request.m_interceptor != null) + request.request.m_interceptor.receive_exception(request.request.m_info); + } + + /** * Create a request to invoke the method of this CORBA object. * * @param target the CORBA object, to that this operation must be applied. @@ -247,7 +377,7 @@ public class IOR_Delegate */ public Request request(org.omg.CORBA.Object target, String operation) { - gnuRequest request = new gnuRequest(); + gnuRequest request = getRequestInstance(target); request.setIor(ior); request.set_target(target); @@ -269,27 +399,28 @@ public class IOR_Delegate * @return the stream where the method arguments should be written. */ public OutputStream request(org.omg.CORBA.Object target, String operation, - boolean response_expected - ) + boolean response_expected + ) { - gnuRequest request = new gnuRequest(); + gnuRequest request = getRequestInstance(target); request.setIor(ior); request.set_target(target); request.setOperation(operation); - request.getParameterStream().response_expected = response_expected; + streamRequest out = request.getParameterStream(); + out.response_expected = response_expected; request.setORB(orb); - return request.getParameterStream(); + return out; } /** - * If there is an opened cache socket to access this object, close - * that socket. + * If there is an opened cache socket to access this object, close that + * socket. * - * @param target The target is not used, this delegate requires a - * single instance per object. + * @param target The target is not used, this delegate requires a single + * instance per object. */ public void release(org.omg.CORBA.Object target) { @@ -308,4 +439,28 @@ public class IOR_Delegate // do nothing, then. } } + + /** + * Reset the remote_ior flag, forcing to check if the object is local on the + * next getRequestInstance call. + */ + public void setIor(IOR an_ior) + { + super.setIor(an_ior); + remote_ior = false; + local_ior = null; + } + + /** + * Checks if the ior is local so far it is easy. + */ + public boolean is_local(org.omg.CORBA.Object self) + { + if (remote_ior) + return false; + else if (local_ior != null) + return true; + else + return super.is_local(self); + } }
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/NamingService/NamingServiceTransient.java b/libjava/classpath/gnu/CORBA/NamingService/NamingServiceTransient.java index fda46adbb00..e46bed7f7a1 100644 --- a/libjava/classpath/gnu/CORBA/NamingService/NamingServiceTransient.java +++ b/libjava/classpath/gnu/CORBA/NamingService/NamingServiceTransient.java @@ -39,6 +39,7 @@ exception statement from your version. */ package gnu.CORBA.NamingService; import gnu.CORBA.Functional_ORB; +import gnu.CORBA.IOR; import org.omg.CosNaming.NamingContextExt; @@ -47,15 +48,14 @@ import java.io.PrintStream; import java.io.UnsupportedEncodingException; /** - * The server for the gnu classpath naming service. This is an executable - * class that must be started to launch the GNU Classpath CORBA - * transient naming service. - * + * The server for the gnu classpath naming service. This is an executable class + * that must be started to launch the GNU Classpath CORBA transient naming + * service. + * * GNU Classpath currently works with this naming service and is also - * interoperable with the Sun Microsystems naming services from - * releases 1.3 and 1.4, both transient <i>tnameserv</i> and persistent - * <i>orbd</i>. - * + * interoperable with the Sun Microsystems naming services from releases 1.3 and + * 1.4, both transient <i>tnameserv</i> and persistent <i>orbd</i>. + * * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) */ public class NamingServiceTransient @@ -67,9 +67,9 @@ public class NamingServiceTransient public static final int PORT = 900; /** - * Get the object key for the naming service. The default - * key is the string "NameService" in ASCII. - * + * Get the object key for the naming service. The default key is the string + * "NameService" in ASCII. + * * @return the byte array. */ public static byte[] getDefaultKey() @@ -85,15 +85,14 @@ public class NamingServiceTransient } /** - * Start the naming service on the current host at the given port. - * The parameter -org.omg.CORBA.ORBInitialPort NNN or - * -ORBInitialPort NNN, if present, specifies the port, on that - * the service must be started. If this key is not specified, - * the service starts at the port 900. - * - * The parameter -ior FILE_NAME, if present, forces to store the ior string - * of this naming service to the specified file. - * + * Start the naming service on the current host at the given port. The + * parameter -org.omg.CORBA.ORBInitialPort NNN or -ORBInitialPort NNN, if + * present, specifies the port, on that the service must be started. If this + * key is not specified, the service starts at the port 900. + * + * The parameter -ior FILE_NAME, if present, forces to store the ior string of + * this naming service to the specified file. + * * @param args the parameter string. */ public static void main(String[] args) @@ -108,21 +107,24 @@ public class NamingServiceTransient if (args.length > 1) for (int i = 0; i < args.length - 1; i++) { - if (args [ i ].endsWith("ORBInitialPort")) - port = Integer.parseInt(args [ i + 1 ]); + if (args[i].endsWith("ORBInitialPort")) + port = Integer.parseInt(args[i + 1]); - if (args [ i ].equals("-ior")) - iorf = args [ i + 1 ]; + if (args[i].equals("-ior")) + iorf = args[i + 1]; } Functional_ORB.setPort(port); // Create the servant and register it with the ORB NamingContextExt namer = new Ext(new TransientContext()); - orb.connect(namer, getDefaultKey()); + + // Case with the key "NameService". + orb.connect(namer, "NameService".getBytes()); // Storing the IOR reference. String ior = orb.object_to_string(namer); + IOR iorr = IOR.parse(ior); if (iorf != null) { FileOutputStream f = new FileOutputStream(iorf); @@ -131,22 +133,23 @@ public class NamingServiceTransient p.close(); } - System.out.println("GNU Classpath, transient naming service. " + - "Copyright (C) 2005 Free Software Foundation\n" + - "This tool comes with ABSOLUTELY NO WARRANTY. " + - "This is free software, and you are\nwelcome to " + - "redistribute it under conditions, defined in " + - "GNU Classpath license.\n\n" + ior - ); + System.out.println("GNU Classpath transient naming service " + + "started at " + iorr.Internet.host + ":" + iorr.Internet.port + + " key 'NameService'.\n\n" + + "Copyright (C) 2005 Free Software Foundation\n" + + "This tool comes with ABSOLUTELY NO WARRANTY. " + + "This is free software, and you are\nwelcome to " + + "redistribute it under conditions, defined in " + + "GNU Classpath license.\n\n" + ior); new Thread() + { + public void run() { - public void run() - { - // Wait for invocations from clients. - orb.run(); - } - }.start(); + // Wait for invocations from clients. + orb.run(); + } + }.start(); } catch (Exception e) { @@ -154,7 +157,8 @@ public class NamingServiceTransient e.printStackTrace(System.out); } - // Restore the default value for allocating ports for the subsequent objects. + // Restore the default value for allocating ports for the subsequent + // objects. Functional_ORB.setPort(Functional_ORB.DEFAULT_INITIAL_PORT); } } diff --git a/libjava/classpath/gnu/CORBA/ObjectCreator.java b/libjava/classpath/gnu/CORBA/ObjectCreator.java index b99c46ba63f..81c1d06e775 100644 --- a/libjava/classpath/gnu/CORBA/ObjectCreator.java +++ b/libjava/classpath/gnu/CORBA/ObjectCreator.java @@ -1,4 +1,4 @@ -/* ExceptionCreator.java -- +/* ObjectCreator.java -- Copyright (C) 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,10 +38,15 @@ exception statement from your version. */ package gnu.CORBA; +import gnu.CORBA.CDR.cdrBufOutput; + +import org.omg.CORBA.Any; import org.omg.CORBA.CompletionStatus; import org.omg.CORBA.CompletionStatusHelper; import org.omg.CORBA.MARSHAL; +import org.omg.CORBA.StructMember; import org.omg.CORBA.SystemException; +import org.omg.CORBA.TCKind; import org.omg.CORBA.UNKNOWN; import org.omg.CORBA.UserException; import org.omg.CORBA.portable.InputStream; @@ -51,9 +56,8 @@ import java.lang.reflect.Constructor; import java.lang.reflect.Method; /** - * Creates java objects from the agreed IDL names for the simple - * case when the CORBA object is directly mapped into the locally - * defined java class. + * Creates java objects from the agreed IDL names for the simple case when the + * CORBA object is directly mapped into the locally defined java class. * * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) */ @@ -70,20 +74,17 @@ public class ObjectCreator public static final String JAVA_PREFIX = "org.omg."; /** - * The prefix for classes that are placed instide the - * gnu.CORBA namespace. + * The prefix for classes that are placed instide the gnu.CORBA namespace. */ public static final String CLASSPATH_PREFIX = "gnu.CORBA."; /** - * Try to instantiate an object with the given IDL name. - * The object must be mapped to the local java class. - * The omg.org domain must be mapped into the object in either - * org/omg or gnu/CORBA namespace. + * Try to instantiate an object with the given IDL name. The object must be + * mapped to the local java class. The omg.org domain must be mapped into the + * object in either org/omg or gnu/CORBA namespace. * * @param IDL name - * @return instantiated object instance or null if no such - * available. + * @return instantiated object instance or null if no such available. */ public static java.lang.Object createObject(String idl, String suffix) { @@ -109,16 +110,15 @@ public class ObjectCreator /** * Create the system exception with the given idl name. * - * @param idl the exception IDL name, must match the syntax - * "IDL:<class/name>:1.0". + * @param idl the exception IDL name, must match the syntax "IDL:<class/name>:1.0". * @param minor the exception minor code. * @param completed the exception completion status. * * @return the created exception. */ public static SystemException createSystemException(String idl, int minor, - CompletionStatus completed - ) + CompletionStatus completed + ) { try { @@ -127,20 +127,18 @@ public class ObjectCreator Constructor constructor = exClass.getConstructor(new Class[] - { - String.class, int.class, - CompletionStatus.class - } - ); + { + String.class, int.class, CompletionStatus.class + } + ); Object exception = constructor.newInstance(new Object[] - { - " Remote exception " + idl + ", minor " + - minor + ", " + completed + ".", - new Integer(minor), completed - } - ); + { + " Remote exception " + idl + ", minor " + minor + ", " + + completed + ".", new Integer(minor), completed + } + ); return (SystemException) exception; } @@ -153,9 +151,10 @@ public class ObjectCreator /** * Read the system exception from the given stream. + * * @param input the CDR stream to read from. - * @return the exception that has been stored in the stream - * (IDL name, minor code and completion status). + * @return the exception that has been stored in the stream (IDL name, minor + * code and completion status). */ public static SystemException readSystemException(InputStream input) { @@ -170,8 +169,8 @@ public class ObjectCreator } /** - * Reads the user exception, having the given Id, from the - * input stream. The id is expected to be in the form like + * Reads the user exception, having the given Id, from the input stream. The + * id is expected to be in the form like * 'IDL:test/org/omg/CORBA/ORB/communication/ourUserException:1.0' * * @param idl the exception idl name. @@ -189,11 +188,8 @@ public class ObjectCreator Method read = helperClass.getMethod("read", - new Class[] - { - org.omg.CORBA.portable.InputStream.class - } - ); + new Class[] { org.omg.CORBA.portable.InputStream.class } + ); return (UserException) read.invoke(null, new Object[] { input }); } @@ -236,8 +232,8 @@ public class ObjectCreator * @param ex an exception to write. */ public static void writeSystemException(OutputStream output, - SystemException ex - ) + SystemException ex + ) { String exIDL = toIDL(ex.getClass().getName()); output.write_string(exIDL); @@ -266,14 +262,14 @@ public class ObjectCreator } /** - * Converts the given IDL name to class name and tries to load the - * matching class. The OMG prefix (omg.org) is replaced by - * the java prefix org.omg. No other prefixes are added. + * Converts the given IDL name to class name and tries to load the matching + * class. The OMG prefix (omg.org) is replaced by the java prefix org.omg. No + * other prefixes are added. * * @param IDL the idl name. * - * TODO Cache the returned classes, avoiding these string manipulations - * each time the conversion is required. + * TODO Cache the returned classes, avoiding these string manipulations each + * time the conversion is required. * * @return the matching class or null if no such is available. */ @@ -301,10 +297,10 @@ public class ObjectCreator } /** - * Converts the given IDL name to class name, tries to load the - * matching class and create an object instance with parameterless - * constructor. The OMG prefix (omg.org) is replaced by - * the java prefix org.omg. No other prefixes are added. + * Converts the given IDL name to class name, tries to load the matching class + * and create an object instance with parameterless constructor. The OMG + * prefix (omg.org) is replaced by the java prefix org.omg. No other prefixes + * are added. * * @param IDL the idl name. * @@ -341,8 +337,111 @@ public class ObjectCreator cn = OMG_PREFIX + cn.substring(JAVA_PREFIX.length()).replace('.', '/'); else if (cn.startsWith(CLASSPATH_PREFIX)) cn = - OMG_PREFIX + cn.substring(CLASSPATH_PREFIX.length()).replace('.', '/'); + OMG_PREFIX + + cn.substring(CLASSPATH_PREFIX.length()).replace('.', '/'); return "IDL:" + cn + ":1.0"; } + + /** + * Insert the passed parameter into the given Any, assuming that the helper + * class is available. The helper class must have the "Helper" suffix and be + * in the same package as the class of the object being inserted. + * + * @param into the target to insert. + * + * @param object the object to insert. It can be any object as far as the + * corresponding helper is provided. + * + * @return true on success, false otherwise. + */ + public static boolean insertWithHelper(Any into, Object object) + { + try + { + String helperClassName = object.getClass().getName() + "Helper"; + Class helperClass = Class.forName(helperClassName); + + Method insert = + helperClass.getMethod("insert", + new Class[] { Any.class, object.getClass() } + ); + + insert.invoke(null, new Object[] { into, object }); + + return true; + } + catch (Exception exc) + { + // Failed due some reason. + return false; + } + } + + /** + * Insert the system exception into the given Any. + */ + public static boolean insertSysException(Any into, SystemException exception) + { + try + { + cdrBufOutput output = new cdrBufOutput(); + + String m_exception_id = toIDL(exception.getClass().getName()); + output.write_string(m_exception_id); + output.write_ulong(exception.minor); + CompletionStatusHelper.write(output, exception.completed); + + String name = getDefaultName(m_exception_id); + + universalHolder h = new universalHolder(output); + + into.insert_Streamable(h); + + recordTypeCode r = new recordTypeCode(TCKind.tk_except); + r.setId(m_exception_id); + r.setName(name); + into.type(r); + + return true; + } + catch (Exception ex) + { + ex.printStackTrace(); + return false; + } + } + + /** + * Get the type name from the IDL string. + */ + public static String getDefaultName(String idl) + { + int f1 = idl.lastIndexOf("/"); + int p1 = (f1 < 0) ? 0 : f1; + int p2 = idl.indexOf(":", p1); + if (p2 < 0) + p2 = idl.length(); + + String name = idl.substring(f1 + 1, p2); + return name; + } + + /** + * Insert this exception into the given Any. On failure, insert the UNKNOWN + * exception. + */ + public static void insertException(Any into, Throwable exception) + { + boolean ok = false; + if (exception instanceof SystemException) + ok = insertSysException(into, (SystemException) exception); + else if (exception instanceof UserException) + ok = insertWithHelper(into, exception); + + if (!ok) + ok = insertSysException(into, new UNKNOWN()); + if (!ok) + throw new InternalError("Exception wrapping broken"); + } }
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/Restricted_ORB.java b/libjava/classpath/gnu/CORBA/Restricted_ORB.java index 801154e2064..247cd205ccb 100644 --- a/libjava/classpath/gnu/CORBA/Restricted_ORB.java +++ b/libjava/classpath/gnu/CORBA/Restricted_ORB.java @@ -58,6 +58,9 @@ import org.omg.CORBA.TypeCodePackage.BadKind; import org.omg.CORBA.UnionMember; import org.omg.CORBA.portable.OutputStream; import org.omg.CORBA.portable.ValueFactory; +import org.omg.PortableInterceptor.ClientRequestInterceptorOperations; +import org.omg.PortableInterceptor.IORInterceptorOperations; +import org.omg.PortableInterceptor.ServerRequestInterceptorOperations; import java.applet.Applet; @@ -66,22 +69,20 @@ import java.util.Properties; /** * This class implements so-called Singleton ORB, a highly restricted version - * that cannot communicate over network. This ORB is provided - * for the potentially malicious applets with heavy security restrictions. - * It, however, supports some basic features that might be needed even - * when the network access is not granted. + * that cannot communicate over network. This ORB is provided for the + * potentially malicious applets with heavy security restrictions. It, however, + * supports some basic features that might be needed even when the network + * access is not granted. * - * This ORB can only create typecodes, - * {@link Any}, {@link ContextList}, {@link NVList} and - * {@link org.omg.CORBA.portable.OutputStream} that writes to an - * internal buffer. + * This ORB can only create typecodes, {@link Any}, {@link ContextList}, + * {@link NVList} and {@link org.omg.CORBA.portable.OutputStream} that writes to + * an internal buffer. * * All other methods throw the {@link NO_IMPLEMENT} exception. * * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) */ -public class Restricted_ORB - extends org.omg.CORBA_2_3.ORB +public class Restricted_ORB extends org.omg.CORBA_2_3.ORB { /** * The singleton instance of this ORB. @@ -89,13 +90,41 @@ public class Restricted_ORB public static final ORB Singleton = new Restricted_ORB(); /** + * The cumulated listener for all IOR interceptors. Interceptors are used by + * {@link gnu.CORBA.Poa.ORB_1_4}. + */ + public IORInterceptorOperations iIor; + + /** + * The cumulated listener for all server request interceptors. Interceptors + * are used by {@link gnu.CORBA.Poa.ORB_1_4}. + */ + public ServerRequestInterceptorOperations iServer; + + /** + * The cumulated listener for all client request interceptros. Interceptors + * are used by {@link gnu.CORBA.Poa.ORB_1_4}. + */ + public ClientRequestInterceptorOperations iClient; + + /** + * The required size of the interceptor slot array. + */ + public int icSlotSize = 0; + + /** * The value factories. */ protected Hashtable factories = new Hashtable(); /** - * Create a new instance of the RestrictedORB. This is used - * in derived classes only. + * The policy factories. + */ + protected Hashtable policyFactories = new Hashtable(); + + /** + * Create a new instance of the RestrictedORB. This is used in derived classes + * only. */ protected Restricted_ORB() { @@ -159,8 +188,8 @@ public class Restricted_ORB /** {@inheritDoc} */ public TypeCode create_exception_tc(String id, String name, - StructMember[] members - ) + StructMember[] members + ) { recordTypeCode r = new recordTypeCode(TCKind.tk_except); r.setId(id); @@ -224,8 +253,8 @@ public class Restricted_ORB /** {@inheritDoc} */ public TypeCode create_struct_tc(String id, String name, - StructMember[] members - ) + StructMember[] members + ) { recordTypeCode r = new recordTypeCode(TCKind.tk_struct); r.setId(id); @@ -240,13 +269,15 @@ public class Restricted_ORB } /** {@inheritDoc} */ - public TypeCode create_union_tc(String id, String name, TypeCode type, - UnionMember[] members - ) + public TypeCode create_union_tc(String id, String name, + TypeCode discriminator_type, UnionMember[] members + ) { recordTypeCode r = new recordTypeCode(TCKind.tk_union); r.setId(id); r.setName(name); + r.setDiscriminator_type(discriminator_type); + r.setDefaultIndex(0); for (int i = 0; i < members.length; i++) { @@ -274,8 +305,8 @@ public class Restricted_ORB catch (BadKind ex) { throw new BAD_PARAM("This is not a primitive type code: " + - tcKind.value() - ); + tcKind.value() + ); } } @@ -304,13 +335,13 @@ public class Restricted_ORB /** * This method is not allowed for a RestrictedORB. * - * @throws InvalidName never in this class, but it is thrown - * in the derived classes. + * @throws InvalidName never in this class, but it is thrown in the derived + * classes. * * @throws NO_IMPLEMENT, always. */ public org.omg.CORBA.Object resolve_initial_references(String name) - throws InvalidName + throws InvalidName { no(); throw new InternalError(); @@ -366,8 +397,8 @@ public class Restricted_ORB } /** - * Throws an exception, stating that the given method is not supported - * by the Restricted ORB. + * Throws an exception, stating that the given method is not supported by the + * Restricted ORB. */ private final void no() { @@ -381,8 +412,7 @@ public class Restricted_ORB * * @throws NO_IMPLEMENT, always. */ - public Request get_next_response() - throws org.omg.CORBA.WrongTransaction + public Request get_next_response() throws org.omg.CORBA.WrongTransaction { no(); throw new InternalError(); @@ -423,8 +453,8 @@ public class Restricted_ORB * Register the value factory under the given repository id. */ public ValueFactory register_value_factory(String repository_id, - ValueFactory factory - ) + ValueFactory factory + ) { factories.put(repository_id, factory); return factory; @@ -440,9 +470,9 @@ public class Restricted_ORB /** * Look for the value factory for the value, having the given repository id. - * The implementation checks for the registered value factories first. - * If none found, it tries to load and instantiate the class, mathing the - * given naming convention. If this faild, null is returned. + * The implementation checks for the registered value factories first. If none + * found, it tries to load and instantiate the class, mathing the given naming + * convention. If this faild, null is returned. * * @param repository_id a repository id. * @@ -452,12 +482,43 @@ public class Restricted_ORB { ValueFactory f = (ValueFactory) factories.get(repository_id); if (f != null) - return f; + { + return f; + } - f = (ValueFactory) ObjectCreator.createObject(repository_id, "DefaultFactory"); + f = (ValueFactory) ObjectCreator.createObject(repository_id, + "DefaultFactory" + ); if (f != null) - factories.put(repository_id, f); - + { + factories.put(repository_id, f); + } return f; } + + /** + * Destroy the interceptors, if they are present. + */ + public void destroy() + { + if (iIor != null) + { + iIor.destroy(); + iIor = null; + } + + if (iServer != null) + { + iServer.destroy(); + iServer = null; + } + + if (iClient != null) + { + iClient.destroy(); + iClient = null; + } + + super.destroy(); + } }
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/ServiceRequestAdapter.java b/libjava/classpath/gnu/CORBA/ServiceRequestAdapter.java index 0b698818215..7f40fc84d2d 100644 --- a/libjava/classpath/gnu/CORBA/ServiceRequestAdapter.java +++ b/libjava/classpath/gnu/CORBA/ServiceRequestAdapter.java @@ -53,10 +53,11 @@ import org.omg.CORBA.portable.ResponseHandler; import org.omg.CORBA.portable.Streamable; /** - * This class exists to handle obsolete invocation style using - * ServerRequest. - * - * @deprecated The method {@link ObjectImpl#_invoke} is much faster. + * This class supports invocation using ServerRequest. When possible, + * it is better to use the {@link ObjectImpl#_invoke} rather than + * working via ServerRequest. However since 1.4 the ServerRequest is + * involved into POA machinery making this type of call is sometimes + * inavoidable. * * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) */ @@ -86,13 +87,13 @@ public class ServiceRequestAdapter } /** - * The old style invocation using the currently deprecated server - * request class. + * Make an invocation. * * @param request a server request, containg the invocation information. * @param target the invocation target - * @param result the result holder with the set suitable streamable to read - * the result or null for void. + * @param result the result holder with the set suitable streamable. + * Using this parameter only increase the performance. It can be + * null if the return type is void or unknown. */ public static void invoke(ServerRequest request, InvokeHandler target, Streamable result @@ -133,12 +134,20 @@ public class ServiceRequestAdapter else { if (result != null) - { - result._read(in); - gnuAny r = new gnuAny(); - r.insert_Streamable(result); - request.set_result(r); - }; + { + // Use the holder for the return value, if provided. + result._read(in); + + gnuAny r = new gnuAny(); + r.insert_Streamable(result); + request.set_result(r); + } + else + { + // Use the universal holder otherwise. + gnuAny r = new gnuAny(); + r.insert_Streamable(new streamReadyHolder(in)); + } // Unpack the arguments for (int i = 0; i < args.count(); i++) diff --git a/libjava/classpath/gnu/CORBA/Simple_delegate.java b/libjava/classpath/gnu/CORBA/Simple_delegate.java index d0b2ad29e0b..5eabc7da8a0 100644 --- a/libjava/classpath/gnu/CORBA/Simple_delegate.java +++ b/libjava/classpath/gnu/CORBA/Simple_delegate.java @@ -195,13 +195,40 @@ public class Simple_delegate } /** - * Only returns true if the objects are equal ('=='). + * Returns true if the objects are the same of have + * the same delegate set. All objects in this implementation + * have a separate delegate. */ public boolean is_equivalent(org.omg.CORBA.Object target, org.omg.CORBA.Object other ) { - return target == other; + if (target == other) + return true; + if ((target instanceof ObjectImpl) && other instanceof ObjectImpl) + { + try + { + org.omg.CORBA.portable.Delegate a = + ((ObjectImpl) target)._get_delegate(); + org.omg.CORBA.portable.Delegate b = + ((ObjectImpl) other)._get_delegate(); + if (a == b) + { + return true; + } + if (a != null && b != null) + { + return a.equals(b); + } + } + catch (Exception ex) + { + // Unable to get one of the delegates. + return false; + } + } + return false; } /** @@ -246,4 +273,4 @@ public class Simple_delegate { throw new InternalError(); } -} +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/SocketRepository.java b/libjava/classpath/gnu/CORBA/SocketRepository.java index 70bceadf5f7..a6b99200a48 100644 --- a/libjava/classpath/gnu/CORBA/SocketRepository.java +++ b/libjava/classpath/gnu/CORBA/SocketRepository.java @@ -39,6 +39,7 @@ exception statement from your version. */ package gnu.CORBA; import java.net.Socket; +import java.net.SocketException; import java.util.HashMap; @@ -70,16 +71,18 @@ public class SocketRepository /** * Get a socket. - * + * * @param key a socket key. - * - * @return an opened socket for reuse, null if no such - * available or it is closed. + * + * @return an opened socket for reuse, null if no such available or it is + * closed. */ public static Socket get_socket(Object key) { Socket s = (Socket) sockets.get(key); - if (s != null && s.isClosed()) + if (s == null) + return null; + else if (s.isClosed()) { sockets.remove(key); return null; @@ -87,6 +90,15 @@ public class SocketRepository else { sockets.remove(key); + try + { + // Set one minute time out that will be changed later. + s.setSoTimeout(60*1000); + } + catch (SocketException e) + { + s = null; + } return s; } } diff --git a/libjava/classpath/gnu/CORBA/bufferedResponseHandler.java b/libjava/classpath/gnu/CORBA/bufferedResponseHandler.java index e7f00baebe2..0fe945ca1f0 100644 --- a/libjava/classpath/gnu/CORBA/bufferedResponseHandler.java +++ b/libjava/classpath/gnu/CORBA/bufferedResponseHandler.java @@ -41,6 +41,7 @@ package gnu.CORBA; import gnu.CORBA.CDR.cdrBufOutput; import gnu.CORBA.GIOP.MessageHeader; import gnu.CORBA.GIOP.ReplyHeader; +import gnu.CORBA.GIOP.RequestHeader; import gnu.CORBA.GIOP.cxCodeSet; import org.omg.CORBA.ORB; @@ -48,31 +49,33 @@ import org.omg.CORBA.portable.OutputStream; import org.omg.CORBA.portable.ResponseHandler; /** - * Provides the CDR output streams for writing the response to the given - * buffer. + * Provides the CDR output streams for writing the response to the given buffer. * * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) */ -class bufferedResponseHandler +public class bufferedResponseHandler implements ResponseHandler { /** - * The message header. - * This field is used to compute the size and alignments. + * The message header. This field is used to compute the size and alignments. * It is, however, never directly written to the buffer stream. */ - final MessageHeader message_header; + public final MessageHeader message_header; /** * The associated orb. */ - final ORB orb; + public final ORB orb; /** - * The reply header. This field is used to compute the size and alignments. - * It is, however, never directly written to the buffer stream. + * The reply header. + */ + public final ReplyHeader reply_header; + + /** + * The request header. */ - final ReplyHeader reply_header; + public final RequestHeader request_header; /** * True if the stream was obtained by invoking {@link #createExceptionReply()}, @@ -86,28 +89,27 @@ class bufferedResponseHandler private cdrBufOutput buffer; /** - * Create a new buffered response handler that uses the given message - * headers. The headers are used to compute sizes and check the versions. - * They are not written into a stream inside this class. + * Create a new buffered response handler that uses the given message headers. + * The headers are used to compute sizes and check the versions. They are not + * written into a stream inside this class. * * @param m_header a message header. * @param r_header a reply header. */ bufferedResponseHandler(ORB an_orb, MessageHeader m_header, - ReplyHeader r_header - ) + ReplyHeader r_header, RequestHeader rq_header) { message_header = m_header; reply_header = r_header; + request_header = rq_header; orb = an_orb; prepareStream(); } /** - * 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. + * 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. */ @@ -121,8 +123,8 @@ class bufferedResponseHandler /** * 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. + * 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. */ @@ -135,27 +137,26 @@ class bufferedResponseHandler } /** - * 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. + * 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 + * 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() + public cdrBufOutput getBuffer() { return buffer; } /** - * True if the stream was obtained by invoking - * {@link #createExceptionReply()}, false otherwise - * (usually no-exception reply). + * True if the stream was obtained by invoking {@link #createExceptionReply()}, + * false otherwise (usually no-exception reply). */ - boolean isExceptionReply() + public boolean isExceptionReply() { return exceptionReply; } @@ -167,21 +168,22 @@ class bufferedResponseHandler { buffer = new cdrBufOutput(); buffer.setOrb(orb); - buffer.setOffset(message_header.getHeaderSize()); - - // Get the position after the reply header would be written. - reply_header.write(buffer); + buffer.setVersion(message_header.version); + buffer.setCodeSet(cxCodeSet.find(reply_header.service_context)); - int new_offset = message_header.getHeaderSize() + buffer.buffer.size(); + // Since 1.2, the data section is always aligned on the 8 byte boundary. + // In older versions, it is necessary to set the offset correctly. + if (message_header.version.until_inclusive(1, 1)) + { + buffer.setOffset(message_header.getHeaderSize()); - buffer.buffer.reset(); - buffer.setOffset(new_offset); + // Get the position after the reply header would be written. + reply_header.write(buffer); - if (message_header.version.since_inclusive(1, 2)) - buffer.align(8); + int new_offset = message_header.getHeaderSize() + buffer.buffer.size(); - buffer.setVersion(message_header.version); - - buffer.setCodeSet(cxCodeSet.find(reply_header.service_context)); + buffer.buffer.reset(); + buffer.setOffset(new_offset); + } } } diff --git a/libjava/classpath/gnu/CORBA/fixedTypeCode.java b/libjava/classpath/gnu/CORBA/fixedTypeCode.java index ec88c22be34..eb610417b29 100644 --- a/libjava/classpath/gnu/CORBA/fixedTypeCode.java +++ b/libjava/classpath/gnu/CORBA/fixedTypeCode.java @@ -109,16 +109,12 @@ public class fixedTypeCode return number.unscaledValue().abs().toString().length(); } - public boolean equals(Object other) + /** + * Compare with other type code for equality. + */ + public boolean equal(TypeCode other) { - if (other == this) - { - return true; - } - if (!(other instanceof TypeCode)) - { - return false; - } + if (other == this) return true; try { TypeCode that = (TypeCode) other; diff --git a/libjava/classpath/gnu/CORBA/gnuAny.java b/libjava/classpath/gnu/CORBA/gnuAny.java index a48c50d61ba..7e5ef335149 100644 --- a/libjava/classpath/gnu/CORBA/gnuAny.java +++ b/libjava/classpath/gnu/CORBA/gnuAny.java @@ -38,6 +38,7 @@ exception statement from your version. */ package gnu.CORBA; +import gnu.CORBA.CDR.Vio; import gnu.CORBA.CDR.cdrBufInput; import gnu.CORBA.CDR.cdrBufOutput; @@ -63,6 +64,7 @@ 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.BoxedValueHelper; import org.omg.CORBA.portable.Streamable; import java.io.IOException; @@ -499,20 +501,33 @@ public class gnuAny } /** {@inheritDoc} */ - public void insert_Value(Serializable x, TypeCode typecode) + public void insert_Value(Serializable x, TypeCode c_typecode) { - type(typecode); - insert_Value(x); + if (typecode != null && typecode.kind() == TCKind.tk_value_box) + { + has = new gnuValueHolder(x, typecode); + } + else + { + type(typecode); + insert_Value(x); + } } /** {@inheritDoc} */ public void insert_Value(Serializable x) { - resetTypes(); - if (has instanceof ValueBaseHolder) - ((ValueBaseHolder) has).value = x; + if (typecode != null && typecode.kind() == TCKind.tk_value_box) + { + has = new gnuValueHolder(x, typecode); + } else - has = new ValueBaseHolder(x); + { + if (has instanceof ValueBaseHolder) + ((ValueBaseHolder) has).value = x; + else + has = new ValueBaseHolder(x); + } } /** @@ -748,15 +763,38 @@ public class gnuAny } } type(a_type); - has._read(input); - } - catch (BadKind ex) - { - throw new MARSHAL("Bad kind: " + ex.getMessage()); + + if (!(has instanceof universalHolder) && + (kind == TCKind._tk_value_box)) + { + // The streamable only contains operations for + // reading the value, not the value header. + Field vField = has.getClass().getField("value"); + + BoxedValueHelper helper; + + try + { + Class helperClass = + Class.forName(ObjectCreator.toHelperName(a_type.id())); + helper = (BoxedValueHelper) helperClass.newInstance(); + } + catch (Exception ex) + { + helper = null; + } + + Object content = Vio.read(input, helper); + vField.set(has, content); + } + else + has._read(input); } - catch (IOException ex) + catch (Exception ex) { - throw new MARSHAL("IO exception: " + ex.getMessage()); + MARSHAL m = new MARSHAL(); + m.initCause(ex); + throw m; } } @@ -790,6 +828,12 @@ public class gnuAny { if (has != null) has._write(output); + else + // These kinds support null. + if (xKind == TCKind._tk_null || xKind == TCKind._tk_objref || + xKind == TCKind._tk_value || xKind == TCKind._tk_value_box + ) + output.write_long(0); } /** @@ -806,16 +850,26 @@ public class gnuAny if (xKind >= 0) { if (xKind != kind) - throw new BAD_OPERATION("Extracting " + typeNamer.nameIt(kind) + - " when stored " + typeNamer.nameIt(xKind) - ); + if (!( + xKind == TCKind._tk_alias && + has._type().kind().value() == kind + ) + ) + throw new BAD_OPERATION("Extracting " + typeNamer.nameIt(kind) + + " when stored " + typeNamer.nameIt(xKind) + ); } else { if (type().kind().value() != kind) - throw new BAD_OPERATION("Extracting " + typeNamer.nameIt(kind) + - " stored " + typeNamer.nameIt(type()) - ); + if (!( + type().kind().value() == TCKind._tk_alias && + has._type().kind().value() == kind + ) + ) + throw new BAD_OPERATION("Extracting " + typeNamer.nameIt(kind) + + " stored " + typeNamer.nameIt(type()) + ); } } diff --git a/libjava/classpath/gnu/CORBA/gnuCodecFactory.java b/libjava/classpath/gnu/CORBA/gnuCodecFactory.java index 8b71baf149c..067de498c79 100644 --- a/libjava/classpath/gnu/CORBA/gnuCodecFactory.java +++ b/libjava/classpath/gnu/CORBA/gnuCodecFactory.java @@ -38,12 +38,12 @@ exception statement from your version. */ package gnu.CORBA; -import org.omg.CORBA.*; import org.omg.CORBA.LocalObject; -import org.omg.IOP.*; +import org.omg.CORBA.ORB; import org.omg.IOP.Codec; import org.omg.IOP.CodecFactory; import org.omg.IOP.CodecFactoryPackage.UnknownEncoding; +import org.omg.IOP.ENCODING_CDR_ENCAPS; import org.omg.IOP.Encoding; /** @@ -52,9 +52,7 @@ import org.omg.IOP.Encoding; * * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) */ -public class gnuCodecFactory - extends LocalObject - implements CodecFactory +public class gnuCodecFactory extends LocalObject implements CodecFactory { /** * The associated ORB. @@ -78,18 +76,15 @@ public class gnuCodecFactory * * @throws UnknownEncoding if the encoding is not a ENCODING_CDR_ENCAPS. */ - public Codec create_codec(Encoding for_encoding) - throws UnknownEncoding + public Codec create_codec(Encoding for_encoding) throws UnknownEncoding { if (for_encoding.format != ENCODING_CDR_ENCAPS.value) throw new UnknownEncoding("Only ENCODING_CDR_ENCAPS is " + - "supported by this factory." - ); + "supported by this factory." + ); return new cdrEncapsCodec(orb, - new Version(for_encoding.major_version, - for_encoding.minor_version - ) - ); + new Version(for_encoding.major_version, for_encoding.minor_version) + ); } }
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/gnuRequest.java b/libjava/classpath/gnu/CORBA/gnuRequest.java index a47410e0bc5..7d756eddba3 100644 --- a/libjava/classpath/gnu/CORBA/gnuRequest.java +++ b/libjava/classpath/gnu/CORBA/gnuRequest.java @@ -40,32 +40,47 @@ package gnu.CORBA; import gnu.CORBA.CDR.cdrBufInput; import gnu.CORBA.CDR.cdrBufOutput; -import gnu.CORBA.GIOP.CloseMessage; import gnu.CORBA.GIOP.MessageHeader; import gnu.CORBA.GIOP.ReplyHeader; import gnu.CORBA.GIOP.RequestHeader; import gnu.CORBA.GIOP.cxCodeSet; +import gnu.CORBA.Interceptor.gnuClientRequestInfo; +import gnu.CORBA.Poa.ORB_1_4; 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_INV_ORDER; +import org.omg.CORBA.BAD_PARAM; import org.omg.CORBA.Bounds; +import org.omg.CORBA.CompletionStatus; import org.omg.CORBA.Context; import org.omg.CORBA.ContextList; import org.omg.CORBA.Environment; import org.omg.CORBA.ExceptionList; +import org.omg.CORBA.INV_POLICY; import org.omg.CORBA.MARSHAL; +import org.omg.CORBA.NO_IMPLEMENT; import org.omg.CORBA.NO_RESOURCES; import org.omg.CORBA.NVList; import org.omg.CORBA.NamedValue; import org.omg.CORBA.ORB; +import org.omg.CORBA.Policy; import org.omg.CORBA.Request; import org.omg.CORBA.SystemException; import org.omg.CORBA.TypeCode; import org.omg.CORBA.UnknownUserException; -import org.omg.CORBA.UserException; +import org.omg.CORBA.portable.ObjectImpl; +import org.omg.IOP.ServiceContext; +import org.omg.IOP.TAG_CODE_SETS; +import org.omg.IOP.TAG_INTERNET_IOP; +import org.omg.IOP.TaggedComponent; +import org.omg.IOP.TaggedProfile; +import org.omg.PortableInterceptor.ClientRequestInfo; +import org.omg.PortableInterceptor.ClientRequestInterceptorOperations; +import org.omg.PortableInterceptor.ForwardRequest; +import org.omg.PortableInterceptor.InvalidSlot; import java.io.IOException; import java.io.InputStream; @@ -74,14 +89,14 @@ import java.io.OutputStream; import java.net.BindException; import java.net.Socket; +import java.util.ArrayList; + /** * The implementation of the CORBA request. * * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) */ -public class gnuRequest - extends Request - implements Cloneable +public class gnuRequest extends Request implements Cloneable { /** * The maximal supported GIOP version. @@ -89,25 +104,34 @@ public class gnuRequest public static Version MAX_SUPPORTED = new Version(1, 2); /** - * The initial pause that the Request makes when - * the required port is not available. + * The initial pause that the Request makes when the required port is not + * available. */ public static int PAUSE_INITIAL = 50; /** - * The number of repretetive attempts to get a required - * port, if it is not immediately available. + * The number of repretetive attempts to get a required port, if it is not + * immediately available. */ public static int PAUSE_STEPS = 12; /** - * The maximal pausing interval between two repetetive attempts. - * The interval doubles after each unsuccessful attempt, but - * will not exceed this value. + * The maximal pausing interval between two repetetive attempts. The interval + * doubles after each unsuccessful attempt, but will not exceed this value. */ public static int PAUSE_MAX = 1000; /** + * The interceptor, listening the major request submission points. + */ + ClientRequestInterceptorOperations m_interceptor; + + /** + * The request info, used by interceptor. + */ + ClientRequestInfo m_info = new gnuClientRequestInfo(this); + + /** * The empty byte array. */ private static final binaryReply EMPTY = @@ -124,14 +148,13 @@ public class gnuRequest protected ContextList m_context_list; /** - * The request environment for holding the exception - * the has possibly been thrown by the method being invoked. + * The request environment for holding the exception the has possibly been + * thrown by the method being invoked. */ protected Environment m_environment = new gnuEnvironment(); /** - * The list of all exceptions that can be thrown by the - * method being invoked. + * The list of all exceptions that can be thrown by the method being invoked. */ protected ExceptionList m_exceptions = new gnuExceptionList(); @@ -141,6 +164,16 @@ public class gnuRequest protected NamedValue m_result = new gnuNamedValue(); /** + * The exception id, received from the server, null if none. + */ + protected String m_exception_id; + + /** + * The thrown system exception. + */ + protected SystemException m_sys_ex; + + /** * The invocation target. */ protected org.omg.CORBA.Object m_target; @@ -151,20 +184,32 @@ public class gnuRequest protected String m_operation; /** - * The flag, indicating that the request has been sent - * and the result is already received. + * This field temporary remembers the value of the forwarded ior reference. If + * it is not null, the request was forwarded and the effective target is not + * the same as the default target. + */ + public IOR m_forward_ior; + + /** + * Is set when object, and not IOR is directly available. + */ + public org.omg.CORBA.Object m_forwarding_target; + + /** + * The flag, indicating that the request has been sent and the result is + * already received. */ protected boolean complete; /** - * The flag, indicating that the response to this request must be - * ignored (used with {@link #send_oneway()}). + * The flag, indicating that the response to this request must be ignored + * (used with {@link #send_oneway()}). */ protected boolean oneWay; /** - * The flag, indicating that the request has been sent - * and no result is yet received. + * The flag, indicating that the request has been sent and no result is yet + * received. */ protected boolean running; @@ -174,12 +219,27 @@ public class gnuRequest protected gnuNVList m_args = new gnuNVList(); /** - * The request arguments in the case when they are directly written into - * the parameter buffer. + * The request arguments in the case when they are directly written into the + * parameter buffer. */ protected streamRequest m_parameter_buffer; /** + * The array of slots. + */ + protected Any[] m_slots; + + /** + * The request header currently in use. + */ + protected RequestHeader m_rqh; + + /** + * The reply header currently in use. + */ + protected ReplyHeader m_rph; + + /** * The IOR of the target. */ private IOR ior; @@ -192,17 +252,16 @@ public class gnuRequest /** * The encoding, used to send the message. * - * The default encoding is inherited from the set IOR - * (that string reference can be encoded in either Big or - * Little endian). If the IOR encoding is not known - * (for example, by obtaining the reference from the naming - * service), the Big Endian is used. + * The default encoding is inherited from the set IOR (that string reference + * can be encoded in either Big or Little endian). If the IOR encoding is not + * known (for example, by obtaining the reference from the naming service), + * the Big Endian is used. */ private boolean Big_endian = true; /** - * Set the IOR data, sufficient to find the invocation target. - * This also sets default endian encoding for invocations. + * Set the IOR data, sufficient to find the invocation target. This also sets + * default endian encoding for invocations. * * @see IOR.parse(String) */ @@ -213,6 +272,11 @@ public class gnuRequest } /** + * Used when redirecting request to another target. + */ + gnuRequest redirected; + + /** * Get the IOR data, sufficient to find the invocation target. * * @return the IOR data. @@ -228,18 +292,26 @@ public class gnuRequest public void setORB(ORB an_orb) { orb = an_orb; + + // Take the interceptor from the ORB. + if (orb instanceof Restricted_ORB) + m_interceptor = ((Restricted_ORB) orb).iClient; + + if (m_interceptor != null && orb instanceof ORB_1_4) + { + m_slots = ((ORB_1_4) orb).ic_current.clone_slots(); + } } /** - * Set the encoding that will be used to send the message. - * The default encoding is inherited from the set IOR - * (that string reference can be encoded in either Big or - * Little endian). If the IOR encoding is not known - * (for example, by obtaining the reference from the naming - * service), the Big Endian is used. + * Set the encoding that will be used to send the message. The default + * encoding is inherited from the set IOR (that string reference can be + * encoded in either Big or Little endian). If the IOR encoding is not known + * (for example, by obtaining the reference from the naming service), the Big + * Endian is used. * - * @param use_big_endian true to use the Big Endian, false - * to use the Little Endian encoding. + * @param use_big_endian true to use the Big Endian, false to use the Little + * Endian encoding. */ public void setBigEndian(boolean use_big_endian) { @@ -257,17 +329,32 @@ public class gnuRequest } /** - * Get the parameter stream, where the invocation arguments should - * be written if they are written into the stream directly. + * 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.setVersion(ior.Internet.version); - m_parameter_buffer.setCodeSet(cxCodeSet.negotiate(ior.CodeSets)); + m_parameter_buffer.setCodeSet(cxCodeSet.negotiate(ior.Internet.CodeSets)); m_parameter_buffer.setOrb(orb); m_parameter_buffer.setBigEndian(Big_endian); + + // For the old iiop versions, it is important to set the size + // correctly. + if (ior.Internet.version.until_inclusive(1, 1)) + { + cdrBufOutput measure = new cdrBufOutput(); + measure.setOffset(12); + if (m_rqh == null) + m_rqh = new gnu.CORBA.GIOP.v1_0.RequestHeader(); + m_rqh.operation = m_operation; + m_rqh.object_key = ior.key; + m_rqh.write(measure); + m_parameter_buffer.setOffset(12 + measure.buffer.size()); + } + return m_parameter_buffer; } @@ -380,33 +467,29 @@ public class gnuRequest } /** {@inheritDoc} */ - public void get_response() - throws org.omg.CORBA.WrongTransaction + public void get_response() throws org.omg.CORBA.WrongTransaction { /** - * The response is ready after it is received. - * FIXME implement context checks and any other functionality, - * if required. + * The response is ready after it is received. FIXME implement context + * checks and any other functionality, if required. */ } /** - * Submit the request, suspending the current thread until the - * answer is received. + * Submit the request, suspending the current thread until the answer is + * received. * - * This implementation requires to set the IOR property - * ({@link #setIOR(IOR)} before calling this method. + * This implementation requires to set the IOR property ({@link #setIOR(IOR)} + * before calling this method. * - * @throws BAD_INV_ORDER, minor code 0, if the IOR has not been - * previously set. + * @throws BAD_INV_ORDER, minor code 0, if the IOR has not been previously + * set. * - * @throws SystemException if this exception has been thrown on - * remote side. The exact exception type and the minor code are - * the same as they have been for the exception, thrown on remoted - * side. + * @throws SystemException if this exception has been thrown on remote side. + * The exact exception type and the minor code are the same as they have been + * for the exception, thrown on remoted side. */ - public synchronized void invoke() - throws BAD_INV_ORDER + public synchronized void invoke() throws BAD_INV_ORDER { waitWhileBusy(); complete = false; @@ -417,7 +500,32 @@ public class gnuRequest try { - p_invoke(); + Forwardings: + while (true) + { + try + { + p_invoke(); + break Forwardings; + } + catch (ForwardRequest e) + { + try + { + ObjectImpl impl = (ObjectImpl) e.forward; + Simple_delegate delegate = + (Simple_delegate) impl._get_delegate(); + ior = delegate.getIor(); + } + catch (Exception ex) + { + BAD_PARAM bad = + new BAD_PARAM("Unsupported forwarding target"); + bad.initCause(ex); + throw bad; + } + } + } } finally { @@ -452,7 +560,8 @@ public class gnuRequest return m_result; } - /** {@inheritDoc} + /** + * {@inheritDoc} * */ public Any return_value() @@ -474,9 +583,8 @@ public class gnuRequest } /** - * Send a request and forget about it, not waiting for a response. - * This can be done also for methods that normally are expected - * to return some values. + * Send a request and forget about it, not waiting for a response. This can be + * done also for methods that normally are expected to return some values. * * TODO It is generally recommended to reuse the threads. Reuse? */ @@ -495,9 +603,8 @@ public class gnuRequest } /** - * Set the argument list. - * This field is initialised as empty non null instance by default, - * so the method is only used in cases when the direct replacement + * Set the argument list. This field is initialised as empty non null instance + * by default, so the method is only used in cases when the direct replacement * is desired. * * @param a_args the argument list. @@ -525,8 +632,8 @@ public class gnuRequest } /** - * Set the context list that is later returned by the - * method {@link #contexts()}. + * Set the context list that is later returned by the method + * {@link #contexts()}. * * @param a_context_list a new context list. */ @@ -536,10 +643,9 @@ public class gnuRequest } /** - * Set the exception container. - * This field is initialised as empty non null instance by default, - * so the method is only used in cases when the direct replacement - * is desired. + * Set the exception container. This field is initialised as empty non null + * instance by default, so the method is only used in cases when the direct + * replacement is desired. * * @param a_environment the new exception container. */ @@ -549,10 +655,9 @@ public class gnuRequest } /** - * Set the list of exceptions. - * This field is initialised as empty non null instance by default, - * so the method is only used in cases when the direct replacement - * is desired. + * Set the list of exceptions. This field is initialised as empty non null + * instance by default, so the method is only used in cases when the direct + * replacement is desired. * * @param a_exceptions a list of exceptions. */ @@ -572,10 +677,9 @@ public class gnuRequest } /** - * Set the named value, returned as result. - * This field is initialised as empty non null instance by default, - * so the method is only used in cases when the direct replacement - * is desired. + * Set the named value, returned as result. This field is initialised as empty + * non null instance by default, so the method is only used in cases when the + * direct replacement is desired. * * @param a_result the result keeper. */ @@ -585,8 +689,8 @@ public class gnuRequest } /** - * Set the type of the named value, returned as a result. - * Instantiates a new instance of the result value. + * Set the type of the named value, returned as a result. Instantiates a new + * instance of the result value. */ public void set_return_type(TypeCode returns) { @@ -608,17 +712,16 @@ public class gnuRequest } /** - * Do the actual invocation. - * This implementation requires to set the IOR property - * ({@link #setIOR(IOR)} before calling this method. + * Do the actual invocation. This implementation requires to set the IOR + * property ({@link #setIOR(IOR)} before calling this method. * - * @throws BAD_INV_ORDER, minor code 0, if the IOR has not been - * previously set or if the direct argument addition is mixed with - * the direct argument writing into the output stream. + * @throws BAD_INV_ORDER, minor code 0, if the IOR has not been previously set + * or if the direct argument addition is mixed with the direct argument + * writing into the output stream. * * @return the server response in binary form. */ - public synchronized binaryReply submit() + public synchronized binaryReply submit() throws ForwardRequest { gnu.CORBA.GIOP.MessageHeader header = new gnu.CORBA.GIOP.MessageHeader(); @@ -629,32 +732,36 @@ public class gnuRequest header.version = useVersion(ior.Internet.version); RequestHeader rh = header.create_request_header(); - - rh.object_key = ior.key; rh.operation = m_operation; + rh.object_key = ior.key; + + // Update interceptor. + m_rqh = rh; + + if (m_interceptor != null) + m_interceptor.send_request(m_info); // Prepare the submission. cdrBufOutput request_part = new cdrBufOutput(); request_part.setOffset(header.getHeaderSize()); request_part.setVersion(header.version); - request_part.setCodeSet(cxCodeSet.negotiate(ior.CodeSets)); + request_part.setCodeSet(cxCodeSet.negotiate(ior.Internet.CodeSets)); request_part.setOrb(orb); request_part.setBigEndian(header.isBigEndian()); // This also sets the stream encoding to the encoding, specified // in the header. rh.write(request_part); - + 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." - ); + "write them into stream, but not both " + "at once." + ); } if (m_parameter_buffer != null) @@ -710,8 +817,8 @@ public class gnuRequest if (socket == null) throw new NO_RESOURCES(ior.Internet.host + ":" + ior.Internet.port + - " in use" - ); + " in use" + ); socket.setKeepAlive(true); OutputStream socketOutput = socket.getOutputStream(); @@ -745,8 +852,9 @@ public class gnuRequest { MARSHAL m = new MARSHAL("Unable to open a socket at " + ior.Internet.host + ":" + - ior.Internet.port - ); + ior.Internet.port, 10000 + ior.Internet.port, + CompletionStatus.COMPLETED_NO + ); m.initCause(io_ex); throw m; } @@ -776,9 +884,9 @@ public class gnuRequest } /** - * Get the used version. Normally, it is better to respond using the - * same version as it is specified in IOR, but not above the maximal - * supported version. + * Get the used version. Normally, it is better to respond using the same + * version as it is specified in IOR, but not above the maximal supported + * version. */ public Version useVersion(Version desired) { @@ -790,12 +898,11 @@ public class gnuRequest /** * Wait while the response to request, submitted using - * {@link #send_deferred()} or {@link #invoke()} (from other thread) - * is returned. + * {@link #send_deferred()} or {@link #invoke()} (from other thread) is + * returned. * - * FIXME It is possible to rewrite this using - * Object.wait() and Object.notify(), but be sure to prepare the test - * as well. + * FIXME It is possible to rewrite this using Object.wait() and + * Object.notify(), but be sure to prepare the test as well. */ public synchronized void waitWhileBusy() { @@ -819,26 +926,25 @@ public class gnuRequest } /** - * Do actual invocation. This method recursively calls itself if - * the redirection is detected. + * Do actual invocation. This method recursively calls itself if the + * redirection is detected. */ - private void p_invoke() - throws SystemException + private void p_invoke() throws SystemException, ForwardRequest { binaryReply response = submit(); - ReplyHeader rh = response.header.create_reply_header(); + if (m_rph == null) + m_rph = response.header.create_reply_header(); + cdrBufInput input = response.getStream(); input.setOrb(orb); - rh.read(input); + m_rph.read(input); // The stream must be aligned sinve v1.2, but only once. boolean align = response.header.version.since_inclusive(1, 2); - boolean moved_permanently = false; - - switch (rh.reply_status) + switch (m_rph.reply_status) { case ReplyHeader.NO_EXCEPTION : @@ -881,6 +987,9 @@ public class gnuRequest } } + if (m_interceptor != null) + m_interceptor.receive_reply(m_info); + break; case ReplyHeader.SYSTEM_EXCEPTION : @@ -889,12 +998,15 @@ public class gnuRequest input.align(8); align = false; } + readExceptionId(input); - SystemException exception = ObjectCreator.readSystemException(input); + m_sys_ex = ObjectCreator.readSystemException(input); + m_environment.exception(m_sys_ex); - m_environment.exception(exception); + if (m_interceptor != null) + m_interceptor.receive_exception(m_info); - throw exception; + throw m_sys_ex; case ReplyHeader.USER_EXCEPTION : if (align) @@ -902,15 +1014,20 @@ public class gnuRequest input.align(8); align = false; } + readExceptionId(input); // Prepare an Any that will hold the exception. gnuAny exc = new gnuAny(); + exc.setOrb(orb); exc.insert_Streamable(new streamReadyHolder(input)); UnknownUserException unuex = new UnknownUserException(exc); m_environment.exception(unuex); + if (m_interceptor != null) + m_interceptor.receive_exception(m_info); + break; case ReplyHeader.LOCATION_FORWARD_PERM : @@ -925,21 +1042,40 @@ public class gnuRequest } catch (IOException ex) { - throw new MARSHAL(ex + " while reading the forwarding info"); + new MARSHAL("Cant read forwarding info", 5103, + CompletionStatus.COMPLETED_NO + ); } setIor(forwarded); + m_forward_ior = forwarded; + + if (m_interceptor != null) + m_interceptor.receive_other(m_info); + // Repeat with the forwarded information. p_invoke(); return; default : - throw new MARSHAL("Unknow reply status: " + rh.reply_status); + throw new MARSHAL("Unknow reply status", 8100 + m_rph.reply_status, + CompletionStatus.COMPLETED_NO + ); } } /** + * Read exception id without changing the stream pointer position. + */ + void readExceptionId(cdrBufInput input) + { + input.mark(2048); + m_exception_id = input.read_string(); + input.reset(); + } + + /** * Write the operation parameters. * * @param header the message header @@ -947,10 +1083,9 @@ public class gnuRequest * * @throws MARSHAL if the attempt to write the parameters has failde. */ - private void write_parameter_buffer(MessageHeader header, - cdrBufOutput request_part - ) - throws MARSHAL + protected void write_parameter_buffer(MessageHeader header, + cdrBufOutput request_part + ) throws MARSHAL { try { @@ -974,8 +1109,9 @@ public class gnuRequest * * @throws MARSHAL if the attempt to write the parameters has failde. */ - private void write_parameters(MessageHeader header, cdrBufOutput request_part) - throws MARSHAL + protected void write_parameters(MessageHeader header, + cdrBufOutput request_part + ) throws MARSHAL { // Align after 1.2, but only once. boolean align = header.version.since_inclusive(1, 2); @@ -988,7 +1124,7 @@ public class gnuRequest { para = m_args.item(i); - //This bit is set both for ARG_IN and ARG_INOUT + // This bit is set both for ARG_IN and ARG_INOUT if ((para.flags() & ARG_IN.value) != 0) { if (align) @@ -1002,7 +1138,277 @@ public class gnuRequest } catch (Bounds ex) { - throw new MARSHAL("Unable to write method arguments to CDR output."); + InternalError ierr = new InternalError(); + ierr.initCause(ex); + throw ierr; } } + + /* **************Implementation of the request info operations. ***** */ + + /** + * Add context to request. + */ + public void add_request_service_context(ServiceContext service_context, + boolean replace + ) + { + m_rqh.addContext(service_context, replace); + } + + /** + * Get the Internet profile as an effective profile. + */ + public TaggedProfile effective_profile() + { + cdrBufOutput buf = new cdrBufOutput(512); + buf.setOrb(orb); + ior.Internet.write(buf); + + TaggedProfile p = new TaggedProfile(); + p.tag = TAG_INTERNET_IOP.value; + p.profile_data = buf.buffer.toByteArray(); + return p; + } + + /** + * Return either target or forwarded targed. + */ + public org.omg.CORBA.Object effective_target() + { + return new IOR_contructed_object(orb, ior); + } + + /** + * Get effective component with the give id from the Internet profile. + */ + public TaggedComponent get_effective_component(int id) + throws BAD_PARAM + { + if (id == TAG_CODE_SETS.value) + { + // Codesets are encoded separately. + cdrBufOutput buf = new cdrBufOutput(512); + buf.setOrb(orb); + ior.Internet.CodeSets.write(buf); + + TaggedComponent t = new TaggedComponent(); + t.tag = TAG_CODE_SETS.value; + t.component_data = buf.buffer.toByteArray(); + return t; + } + else + { + for (int i = 0; i < ior.Internet.components.size(); i++) + { + TaggedComponent c = + (TaggedComponent) ior.Internet.components.get(i); + if (c.tag == id) + return c; + } + } + throw new BAD_PARAM("No component " + id + " in the Internet profile", 28, + CompletionStatus.COMPLETED_MAYBE + ); + } + + /** + * Get all components with the given id from the internet profile. + */ + public TaggedComponent[] get_effective_components(int id) + throws BAD_PARAM + { + if (id == TAG_CODE_SETS.value) + return new TaggedComponent[] { get_effective_component(TAG_CODE_SETS.value) }; + else + { + ArrayList components = new ArrayList(ior.Internet.components.size()); + for (int i = 0; i < ior.Internet.components.size(); i++) + { + TaggedComponent c = + (TaggedComponent) ior.Internet.components.get(i); + if (c.tag == id) + components.add(c); + } + if (components.size() == 0) + throw new BAD_PARAM("No component " + id + + " in the Internet profile", 28, CompletionStatus.COMPLETED_MAYBE + ); + else + { + TaggedComponent[] t = new TaggedComponent[ components.size() ]; + for (int i = 0; i < t.length; i++) + t [ i ] = (TaggedComponent) components.get(i); + return t; + } + } + } + + /** + * This should be not implemented up till jdk 1.5 inclusive. + */ + public Policy get_request_policy(int type) throws INV_POLICY + { + throw new NO_IMPLEMENT(); + } + + /** @inheritDoc */ + public String received_exception_id() + { + return m_exception_id; + } + + /** @inheritDoc */ + public Any received_exception() + { + if (m_exception_id == null) + return null; + + if (m_sys_ex != null) + { + Any a = orb.create_any(); + ObjectCreator.insertSysException(a, m_sys_ex); + return a; + } + + Exception mex = m_environment.exception(); + + UnknownUserException ex = (UnknownUserException) mex; + if (ex == null) + return null; + else + return ex.except; + } + + /** + * Return the forwarded reference, null if none. + */ + public org.omg.CORBA.Object forward_reference() + { + if (m_forwarding_target != null) + return m_forwarding_target; + + if (m_forward_ior != null) + return new IOR_contructed_object(orb, m_forward_ior); + else + return null; + } + + /** + * Get the slot from the slot array inside this request. + */ + public Any get_slot(int id) throws InvalidSlot + { + try + { + return m_slots [ id ]; + } + catch (Exception e) + { + throw new InvalidSlot("slot id " + id + ":" + e); + } + } + + /** + * Get the reply status. + */ + public short reply_status() + { + if (m_rph == null) + throw new BAD_INV_ORDER("Request not yet sent", 14, + CompletionStatus.COMPLETED_NO + ); + return (short) m_rph.reply_status; + } + + /** + * Get the request id. + */ + public int request_id() + { + return m_rqh.request_id; + } + + /** + * Return true if the response is expected. + */ + public boolean response_expected() + { + return !oneWay; + } + + /** + * 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 org.omg.Messaging.SYNC_WITH_TRANSPORT.value; + } + + /** @inheritDoc */ + public ServiceContext get_request_service_context(int ctx_name) + throws BAD_PARAM + { + return gnu.CORBA.GIOP.ServiceContext.findContext(ctx_name, + m_rqh.service_context + ); + } + + /** @inheritDoc */ + public ServiceContext get_reply_service_context(int ctx_name) + throws BAD_PARAM + { + if (m_rph == null) + throw new BAD_INV_ORDER("Reply context not yet available"); + return gnu.CORBA.GIOP.ServiceContext.findContext(ctx_name, + m_rph.service_context + ); + } + + /** @inheritDoc */ + public String[] operation_context() + { + return ice_contexts(); + } + + /** + * Get contexts as required by interceptor. + */ + public String[] ice_contexts() + { + if (m_context_list == null) + return new String[ 0 ]; + else + { + try + { + String[] cn = new String[ m_context_list.count() ]; + for (int i = 0; i < cn.length; i++) + cn [ i ] = m_context_list.item(i); + return cn; + } + catch (Bounds e) + { + throw new Unexpected(e); + } + } + } + + /** + * Check if the call is done via DII. + */ + public void checkDii() + { + if (m_parameter_buffer != null) + throw new NO_RESOURCES("The invocation method provides " + + "no access to this resource. DII call required.", 1, + CompletionStatus.COMPLETED_MAYBE + ); + } }
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/holderFactory.java b/libjava/classpath/gnu/CORBA/holderFactory.java index 177797a9c0c..159d22332dc 100644 --- a/libjava/classpath/gnu/CORBA/holderFactory.java +++ b/libjava/classpath/gnu/CORBA/holderFactory.java @@ -68,74 +68,76 @@ import org.omg.CORBA.UShortSeqHolder; import org.omg.CORBA.WCharSeqHolder; import org.omg.CORBA.WStringSeqHolder; import org.omg.CORBA.portable.Streamable; +import org.omg.CORBA.ObjectHolder; /** - * Creates the suitable holder for storing the value of the given - * type. + * Creates the suitable holder for storing the value of the given final_type. * * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) */ public class holderFactory { /** - * The array, sufficiently large to use any {@link TCKind}._tk* constant - * as an index. + * The array, sufficiently large to use any {@link TCKind}._tk* constant as + * an index. */ private static final Class[] holders; + private static final Class[] seqHolders; static - { - holders = new Class[ 32 ]; - holders [ TCKind._tk_Principal ] = PrincipalHolder.class; - holders [ TCKind._tk_TypeCode ] = TypeCodeHolder.class; - holders [ TCKind._tk_any ] = AnyHolder.class; - holders [ TCKind._tk_boolean ] = BooleanHolder.class; - holders [ TCKind._tk_char ] = CharHolder.class; - holders [ TCKind._tk_double ] = DoubleHolder.class; - holders [ TCKind._tk_float ] = FloatHolder.class; - holders [ TCKind._tk_fixed ] = FixedHolder.class; - holders [ TCKind._tk_long ] = IntHolder.class; - holders [ TCKind._tk_longdouble ] = DoubleHolder.class; - holders [ TCKind._tk_longlong ] = LongHolder.class; - holders [ TCKind._tk_octet ] = OctetHolder.class; - holders [ TCKind._tk_short ] = ShortHolder.class; - holders [ TCKind._tk_string ] = StringHolder.class; - holders [ TCKind._tk_ulong ] = IntHolder.class; - holders [ TCKind._tk_ulonglong ] = LongHolder.class; - holders [ TCKind._tk_ushort ] = ShortHolder.class; - holders [ TCKind._tk_wchar ] = WCharHolder.class; - holders [ TCKind._tk_wstring ] = WStringHolder.class; - - seqHolders = new Class[ 32 ]; - - seqHolders [ TCKind._tk_ulonglong ] = ULongLongSeqHolder.class; - seqHolders [ TCKind._tk_short ] = ShortSeqHolder.class; - seqHolders [ TCKind._tk_octet ] = OctetSeqHolder.class; - seqHolders [ TCKind._tk_any ] = AnySeqHolder.class; - seqHolders [ TCKind._tk_long ] = LongSeqHolder.class; - seqHolders [ TCKind._tk_longlong ] = LongLongSeqHolder.class; - seqHolders [ TCKind._tk_float ] = FloatSeqHolder.class; - seqHolders [ TCKind._tk_double ] = DoubleSeqHolder.class; - seqHolders [ TCKind._tk_char ] = CharSeqHolder.class; - seqHolders [ TCKind._tk_boolean ] = BooleanSeqHolder.class; - seqHolders [ TCKind._tk_wchar ] = WCharSeqHolder.class; - seqHolders [ TCKind._tk_ushort ] = UShortSeqHolder.class; - seqHolders [ TCKind._tk_ulong ] = ULongSeqHolder.class; - seqHolders [ TCKind._tk_string ] = StringSeqHolder.class; - seqHolders [ TCKind._tk_wstring ] = WStringSeqHolder.class; - } + { + holders = new Class[32]; + holders[TCKind._tk_Principal] = PrincipalHolder.class; + holders[TCKind._tk_TypeCode] = TypeCodeHolder.class; + holders[TCKind._tk_any] = AnyHolder.class; + holders[TCKind._tk_boolean] = BooleanHolder.class; + holders[TCKind._tk_char] = CharHolder.class; + holders[TCKind._tk_double] = DoubleHolder.class; + holders[TCKind._tk_float] = FloatHolder.class; + holders[TCKind._tk_fixed] = FixedHolder.class; + holders[TCKind._tk_long] = IntHolder.class; + holders[TCKind._tk_longdouble] = DoubleHolder.class; + holders[TCKind._tk_longlong] = LongHolder.class; + holders[TCKind._tk_octet] = OctetHolder.class; + holders[TCKind._tk_short] = ShortHolder.class; + holders[TCKind._tk_string] = StringHolder.class; + holders[TCKind._tk_ulong] = IntHolder.class; + holders[TCKind._tk_ulonglong] = LongHolder.class; + holders[TCKind._tk_ushort] = ShortHolder.class; + holders[TCKind._tk_wchar] = WCharHolder.class; + holders[TCKind._tk_wstring] = WStringHolder.class; + holders[TCKind._tk_objref] = ObjectHolder.class; + + seqHolders = new Class[32]; + + seqHolders[TCKind._tk_ulonglong] = ULongLongSeqHolder.class; + seqHolders[TCKind._tk_short] = ShortSeqHolder.class; + seqHolders[TCKind._tk_octet] = OctetSeqHolder.class; + seqHolders[TCKind._tk_any] = AnySeqHolder.class; + seqHolders[TCKind._tk_long] = LongSeqHolder.class; + seqHolders[TCKind._tk_longlong] = LongLongSeqHolder.class; + seqHolders[TCKind._tk_float] = FloatSeqHolder.class; + seqHolders[TCKind._tk_double] = DoubleSeqHolder.class; + seqHolders[TCKind._tk_char] = CharSeqHolder.class; + seqHolders[TCKind._tk_boolean] = BooleanSeqHolder.class; + seqHolders[TCKind._tk_wchar] = WCharSeqHolder.class; + seqHolders[TCKind._tk_ushort] = UShortSeqHolder.class; + seqHolders[TCKind._tk_ulong] = ULongSeqHolder.class; + seqHolders[TCKind._tk_string] = StringSeqHolder.class; + seqHolders[TCKind._tk_wstring] = WStringSeqHolder.class; + } /** - * Create a holder for storing the value of the given built-in type. - * This function returns the defined holders for the built-in primitive - * types and they sequences. + * Create a holder for storing the value of the given built-in final_type. This + * function returns the defined holders for the built-in primitive types and + * they sequences. * * @param t the typecode * - * @return an instance of the corresponding built-in holder of null - * if no such is defined for this type. The holder is created with a - * parameterless constructor. + * @return an instance of the corresponding built-in holder of null if no such + * is defined for this final_type. The holder is created with a parameterless + * constructor. */ public static Streamable createHolder(TypeCode t) { @@ -145,24 +147,23 @@ public class holderFactory int componentKind; Streamable holder = null; - Streamable component; - if (kind < holders.length && holders [ kind ] != null) - holder = (Streamable) holders [ kind ].newInstance(); + if (kind < holders.length && holders[kind] != null) + holder = (Streamable) holders[kind].newInstance(); if (holder != null) return holder; switch (kind) { - case TCKind._tk_sequence : - componentKind = t.content_type().kind().value(); - if (componentKind < seqHolders.length) - return (Streamable) seqHolders [ componentKind ].newInstance(); - break; - - default : - break; + case TCKind._tk_sequence: + componentKind = t.content_type().kind().value(); + if (componentKind < seqHolders.length) + return (Streamable) seqHolders[componentKind].newInstance(); + break; + + default: + break; } } catch (Exception ex) diff --git a/libjava/classpath/gnu/CORBA/primitiveArrayTypeCode.java b/libjava/classpath/gnu/CORBA/primitiveArrayTypeCode.java index 7e2beebc949..fc020bed788 100644 --- a/libjava/classpath/gnu/CORBA/primitiveArrayTypeCode.java +++ b/libjava/classpath/gnu/CORBA/primitiveArrayTypeCode.java @@ -1,39 +1,39 @@ /* primitiveArrayTypeCode.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. */ + 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; @@ -61,10 +61,10 @@ public class primitiveArrayTypeCode private int length; /** - * Create a primitive array type code, defining the sequence - * {@link TCKind.tk_sequence)} with + * Create a primitive array type code, defining the sequence + * {@link TCKind.tk_sequence)} with * the given member type. - * + * * @param array_of the sequence member type. */ public primitiveArrayTypeCode(TCKind array_of) @@ -76,7 +76,7 @@ public class primitiveArrayTypeCode /** * Create a primitive array type code, defining the array, sequence * or other type with the given member type. - * + * * @param this_type the type of this type (normally either * sequence of array). * @param array_of the sequence member type. diff --git a/libjava/classpath/gnu/CORBA/primitiveTypeCode.java b/libjava/classpath/gnu/CORBA/primitiveTypeCode.java index 1fa5cd09fe0..4bf97d0230b 100644 --- a/libjava/classpath/gnu/CORBA/primitiveTypeCode.java +++ b/libjava/classpath/gnu/CORBA/primitiveTypeCode.java @@ -1,40 +1,41 @@ /* primitiveTypeCode.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. */ - + 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; diff --git a/libjava/classpath/gnu/CORBA/typeNamer.java b/libjava/classpath/gnu/CORBA/typeNamer.java index 8b701015e23..f790dc95970 100644 --- a/libjava/classpath/gnu/CORBA/typeNamer.java +++ b/libjava/classpath/gnu/CORBA/typeNamer.java @@ -83,7 +83,7 @@ public class typeNamer new primitiveTypeCode(TCKind.tk_any), new primitiveTypeCode(TCKind.tk_TypeCode), new primitiveTypeCode(TCKind.tk_Principal), - new primitiveTypeCode(TCKind.tk_objref), + new recordTypeCode(TCKind.tk_objref), new primitiveTypeCode(TCKind.tk_struct), new primitiveTypeCode(TCKind.tk_union), new primitiveTypeCode(TCKind.tk_enum), @@ -104,6 +104,15 @@ public class typeNamer new primitiveTypeCode(TCKind.tk_abstract_interface) }; + static + { + // The Id of the "abstract object" is defined as empty string. + recordTypeCode object = + (recordTypeCode) primitveCodes [ TCKind._tk_objref ]; + object.setId(""); + object.setName("Object"); + } + /** * Get the primitive type code. * @@ -168,4 +177,4 @@ public class typeNamer return "type of kind '" + type.kind().value() + "'"; } } -} +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/universalHolder.java b/libjava/classpath/gnu/CORBA/universalHolder.java index 6d8b7747290..c20dac442dd 100644 --- a/libjava/classpath/gnu/CORBA/universalHolder.java +++ b/libjava/classpath/gnu/CORBA/universalHolder.java @@ -60,7 +60,7 @@ import java.io.IOException; * * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) */ -class universalHolder +public class universalHolder implements Streamable { /** @@ -71,7 +71,7 @@ class universalHolder /** * Create the universal holder that uses the given buffer to store the data. */ - universalHolder(cdrBufOutput buffer) + public universalHolder(cdrBufOutput buffer) { value = buffer; } @@ -154,4 +154,21 @@ class universalHolder { return value.create_input_stream(); } -} + + /** + * Clone. + */ + public universalHolder Clone() + { + try + { + cdrBufOutput nb = new cdrBufOutput(value.buffer.size()); + value.buffer.writeTo(nb); + return new universalHolder(nb); + } + catch (IOException ex) + { + throw new Unexpected(ex); + } + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/classpath/Configuration.java.in b/libjava/classpath/gnu/classpath/Configuration.java.in index 9da4a820c83..569ccf541ff 100644 --- a/libjava/classpath/gnu/classpath/Configuration.java.in +++ b/libjava/classpath/gnu/classpath/Configuration.java.in @@ -80,33 +80,6 @@ public interface Configuration boolean INIT_LOAD_LIBRARY = @INIT_LOAD_LIBRARY@; /** - * Set to true if the VM provides a native method to implement - * Proxy.getProxyClass completely, including argument verification. - * If this is true, HAVE_NATIVE_GET_PROXY_DATA and - * HAVE_NATIVE_GENERATE_PROXY_CLASS should be false. - * @see java.lang.reflect.Proxy - */ - boolean HAVE_NATIVE_GET_PROXY_CLASS = false; - - /** - * Set to true if the VM provides a native method to implement - * the first part of Proxy.getProxyClass: generation of the array - * of methods to convert, and verification of the arguments. - * If this is true, HAVE_NATIVE_GET_PROXY_CLASS should be false. - * @see java.lang.reflect.Proxy - */ - boolean HAVE_NATIVE_GET_PROXY_DATA = false; - - /** - * Set to true if the VM provides a native method to implement - * the second part of Proxy.getProxyClass: conversion of an array of - * methods into an actual proxy class. - * If this is true, HAVE_NATIVE_GET_PROXY_CLASS should be false. - * @see java.lang.reflect.Proxy - */ - boolean HAVE_NATIVE_GENERATE_PROXY_CLASS = false; - - /** * Name of default AWT peer library. */ String default_awt_peer_toolkit = "@default_toolkit@"; diff --git a/libjava/classpath/gnu/classpath/RawData.java b/libjava/classpath/gnu/classpath/RawData.java deleted file mode 100644 index 3ce97482c02..00000000000 --- a/libjava/classpath/gnu/classpath/RawData.java +++ /dev/null @@ -1,47 +0,0 @@ -/* RawData.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 RawData -{ -} diff --git a/libjava/classpath/gnu/classpath/RawData32.java b/libjava/classpath/gnu/classpath/RawData32.java deleted file mode 100644 index c77163152f2..00000000000 --- a/libjava/classpath/gnu/classpath/RawData32.java +++ /dev/null @@ -1,52 +0,0 @@ -/* RawData32.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 RawData32 extends RawData -{ - final int data; - - public RawData32(int data) - { - this.data = data; - } -} diff --git a/libjava/classpath/gnu/classpath/RawData64.java b/libjava/classpath/gnu/classpath/RawData64.java deleted file mode 100644 index e3b6a93e28e..00000000000 --- a/libjava/classpath/gnu/classpath/RawData64.java +++ /dev/null @@ -1,52 +0,0 @@ -/* RawData64.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 RawData64 extends RawData -{ - final long data; - - public RawData64(long data) - { - this.data = data; - } -} diff --git a/libjava/classpath/gnu/classpath/debug/Component.java b/libjava/classpath/gnu/classpath/debug/Component.java index 3dfc8927bb7..242419ce4ae 100644 --- a/libjava/classpath/gnu/classpath/debug/Component.java +++ b/libjava/classpath/gnu/classpath/debug/Component.java @@ -110,6 +110,12 @@ public final class Component extends Level */ public static final Component X509 = new Component ("X.509", 6); + /** + * Trace access control policies, including the parsing of + * java.policy files. + */ + public static final Component POLICY = new Component ("POLICY", 7); + private final int startIndex; private final int endIndex; diff --git a/libjava/classpath/gnu/classpath/jdwp/exception/InvalidThreadGroupException.java b/libjava/classpath/gnu/classpath/jdwp/exception/InvalidThreadGroupException.java index 04762189210..8b05e0446d2 100644 --- a/libjava/classpath/gnu/classpath/jdwp/exception/InvalidThreadGroupException.java +++ b/libjava/classpath/gnu/classpath/jdwp/exception/InvalidThreadGroupException.java @@ -53,11 +53,11 @@ public class InvalidThreadGroupException public InvalidThreadGroupException (long id) { super (JdwpConstants.Error.INVALID_THREAD_GROUP, - "invalid thread id (" + id + ")"); + "invalid thread group id (" + id + ")"); } public InvalidThreadGroupException (Throwable t) { - super (JdwpConstants.Error.INVALID_THREAD, t); + super (JdwpConstants.Error.INVALID_THREAD_GROUP, t); } } diff --git a/libjava/classpath/gnu/classpath/jdwp/exception/JdwpInternalErrorException.java b/libjava/classpath/gnu/classpath/jdwp/exception/JdwpInternalErrorException.java index c022dc53742..3cf8592f47f 100644 --- a/libjava/classpath/gnu/classpath/jdwp/exception/JdwpInternalErrorException.java +++ b/libjava/classpath/gnu/classpath/jdwp/exception/JdwpInternalErrorException.java @@ -50,8 +50,13 @@ import gnu.classpath.jdwp.JdwpConstants; public class JdwpInternalErrorException extends JdwpException { - public JdwpInternalErrorException (Throwable cause) + public JdwpInternalErrorException(Throwable cause) { - super (JdwpConstants.Error.INTERNAL, cause); + super(JdwpConstants.Error.INTERNAL, cause); + } + + public JdwpInternalErrorException(String msg) + { + super(JdwpConstants.Error.INTERNAL, msg); } } diff --git a/libjava/classpath/gnu/classpath/jdwp/id/ClassLoaderId.java b/libjava/classpath/gnu/classpath/jdwp/id/ClassLoaderId.java index 133872566fd..37c4c365577 100644 --- a/libjava/classpath/gnu/classpath/jdwp/id/ClassLoaderId.java +++ b/libjava/classpath/gnu/classpath/jdwp/id/ClassLoaderId.java @@ -40,6 +40,7 @@ exception statement from your version. */ package gnu.classpath.jdwp.id; import gnu.classpath.jdwp.JdwpConstants; +import gnu.classpath.jdwp.exception.InvalidClassLoaderException; /** * A class which represents a JDWP thread id @@ -61,4 +62,21 @@ public class ClassLoaderId { super (JdwpConstants.Tag.CLASS_LOADER); } + + /** + * Gets the ClassLoader represented by this ID + * + * @throws InvalidClassLoaderException if ClassLoader is garbage collected, + * or otherwise invalid + */ + public ClassLoader getClassLoader () + throws InvalidClassLoaderException + { + ClassLoader cl = (ClassLoader) _reference.get (); + + if (cl == null) + throw new InvalidClassLoaderException (getId ()); + + return cl; + } } diff --git a/libjava/classpath/gnu/classpath/jdwp/id/ClassObjectId.java b/libjava/classpath/gnu/classpath/jdwp/id/ClassObjectId.java index e5559ce10f3..3e164221281 100644 --- a/libjava/classpath/gnu/classpath/jdwp/id/ClassObjectId.java +++ b/libjava/classpath/gnu/classpath/jdwp/id/ClassObjectId.java @@ -40,6 +40,7 @@ exception statement from your version. */ package gnu.classpath.jdwp.id; import gnu.classpath.jdwp.JdwpConstants; +import gnu.classpath.jdwp.exception.InvalidClassException; /** * A class which represents a JDWP class object id @@ -61,4 +62,21 @@ public class ClassObjectId { super (JdwpConstants.Tag.CLASS_OBJECT); } + + /** + * Gets the Class object represented by this ID + * + * @throws InvalidClassException if Class is garbage collected, + * or otherwise invalid + */ + public Class getClassObject () + throws InvalidClassException + { + Class cl = (Class) _reference.get (); + + if (cl == null) + throw new InvalidClassException (getId ()); + + return cl; + } } diff --git a/libjava/classpath/gnu/classpath/jdwp/id/JdwpId.java b/libjava/classpath/gnu/classpath/jdwp/id/JdwpId.java index 37f82e208c5..7f610e353a1 100644 --- a/libjava/classpath/gnu/classpath/jdwp/id/JdwpId.java +++ b/libjava/classpath/gnu/classpath/jdwp/id/JdwpId.java @@ -41,6 +41,7 @@ package gnu.classpath.jdwp.id; import java.io.DataOutputStream; import java.io.IOException; +import java.lang.ref.SoftReference; /** * A baseclass for all object types reported to the debugger @@ -62,6 +63,11 @@ public abstract class JdwpId private byte _tag; /** + * The object/class represented by this Id + */ + protected SoftReference _reference; + + /** * Constructs an empty <code>JdwpId</code> */ public JdwpId (byte tag) @@ -72,7 +78,7 @@ public abstract class JdwpId /** * Sets the id for this object reference */ - void setId (long id) + public void setId (long id) { _id = id; } @@ -86,15 +92,33 @@ public abstract class JdwpId } /** + * Gets the object/class reference for this ID + * + * @returns a refernce to the object or class + */ + public SoftReference getReference () + { + return _reference; + } + + /** + * Sets the object/class reference for this ID + * + * @param ref a refernce to the object or class + */ + public void setReference (SoftReference ref) + { + _reference = ref; + } + + /** * Compares two object ids for equality. Two object ids * are equal if they point to the same type and contain to - * the same id number. (NOTE: This is a much stricter check - * than is necessary: all <code>JdwpId</code>s have unique - * ids.) + * the same id number. */ public boolean equals (JdwpId id) { - return ((id.getClass () == getClass ()) && (id.getId () == getId ())); + return (id.getId () == getId ()); } /** diff --git a/libjava/classpath/gnu/classpath/jdwp/id/JdwpIdFactory.java b/libjava/classpath/gnu/classpath/jdwp/id/JdwpIdFactory.java deleted file mode 100644 index 06ec3c7681f..00000000000 --- a/libjava/classpath/gnu/classpath/jdwp/id/JdwpIdFactory.java +++ /dev/null @@ -1,165 +0,0 @@ -/* JdwpIdFactory.java -- factory for generating type and object IDs - 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.id; - -import java.util.HashMap; - -/** - * This factory generates ids for objects and types that may - * be sent to a debugger. - * - * @author Keith Seitz (keiths@redhat.com) - */ -public class JdwpIdFactory -{ - // ID of last object / referencetype - private static Object _idLock = new Object (); - private static Object _ridLock = new Object (); - private static long _lastId = 0; - private static long _lastRid = 0; - - // A list of all ID types - private static HashMap _idList = new HashMap (); - - // Initialize the id list with known types - static - { - // ObjectId and ArrayId are special cases. See newId. - _idList.put (ClassLoaderId.typeClass, ClassLoaderId.class); - _idList.put (ClassObjectId.typeClass, ClassObjectId.class); - //_idList.put (FieldId.typeClass, FieldId.class); - //_idList.put (FrameId.typeClass, FrameId.class); - //_idList.put (MethodId.typeClass, MethodId.class); - _idList.put (StringId.typeClass, StringId.class); - _idList.put (ThreadId.typeClass, ThreadId.class); - _idList.put (ThreadGroupId.typeClass, ThreadGroupId.class); - } - - /** - * Returns a new id for the given object - * - * @param object the object for which an id is desired - * @returns a suitable object id - */ - public static JdwpId newId (Object object) - { - JdwpId id = null; - - // Special case: arrays - if (object.getClass ().isArray ()) - id = new ArrayId (); - else - { - // Loop through all classes until we hit baseclass - Class myClass; - for (myClass = object.getClass (); myClass != null; - myClass = myClass.getSuperclass ()) - { - Class clz = (Class) _idList.get (myClass); - if (clz != null) - { - try - { - id = (JdwpId) clz.newInstance (); - synchronized (_idLock) - { - id.setId (++_lastId); - } - return id; - } - catch (InstantiationException ie) - { - // This really should not happen - throw new RuntimeException ("cannot create new ID", ie); - } - catch (IllegalAccessException iae) - { - // This really should not happen - throw new RuntimeException ("illegal access of ID", iae); - } - } - } - - /* getSuperclass returned null and no matching ID type found. - So it must derive from Object. */ - id = new ObjectId (); - } - - synchronized (_idLock) - { - id.setId (++_lastId); - } - - return id; - } - - /** - * Returns a new reference type id for the given class - * - * @param clazz the <code>Class</code> for which an id is desired - * @returns a suitable reference type id or <code>null</code> - */ - public static ReferenceTypeId newReferenceTypeId (Class clazz) - { - ReferenceTypeId id = null; - try - { - if (clazz.isArray ()) - id = new ArrayReferenceTypeId (); - else if (clazz.isInterface ()) - id = new InterfaceReferenceTypeId (); - else - id = new ClassReferenceTypeId (); - synchronized (_ridLock) - { - id.setId (++_lastRid); - } - return id; - } - catch (InstantiationException ie) - { - return null; - } - catch (IllegalAccessException iae) - { - return null; - } - } -} diff --git a/libjava/classpath/gnu/classpath/jdwp/id/ObjectId.java b/libjava/classpath/gnu/classpath/jdwp/id/ObjectId.java index e34a3b59ebf..3e2abd4f630 100644 --- a/libjava/classpath/gnu/classpath/jdwp/id/ObjectId.java +++ b/libjava/classpath/gnu/classpath/jdwp/id/ObjectId.java @@ -40,12 +40,15 @@ exception statement from your version. */ package gnu.classpath.jdwp.id; import gnu.classpath.jdwp.JdwpConstants; +import gnu.classpath.jdwp.exception.InvalidObjectException; import java.io.DataOutputStream; import java.io.IOException; /** - * A class which represents a JDWP object id for an object + * This is a base class for all ObjectID-like entities in JDWP, + * inculding Objects, ClassObject, ClassLoader, Thread, ThreadGroup, + * etc. * * @author Keith Seitz <keiths@redhat.com> */ @@ -57,6 +60,9 @@ public class ObjectId */ public static final Class typeClass = Object.class; + // Handle to disable garbage collection + private Object _handle; + /** * Constructs a new <code>ObjectId</code> */ @@ -85,6 +91,23 @@ public class ObjectId } /** + * Returns the object referred to by this ID + * + * @returns the object + * @throws InvalidObjectException if the object was garbage collected + * or is invalid + */ + public Object getObject () + throws InvalidObjectException + { + Object obj = _reference.get (); + if (obj == null) + throw new InvalidObjectException (_id); + + return obj; + } + + /** * Writes the id to the stream * * @param outStream the stream to which to write @@ -96,4 +119,21 @@ public class ObjectId // All we need to do is write out our id as an 8-byte integer outStream.writeLong (_id); } + + /** + * Disable garbage collection on object + */ + public void disableCollection () + throws InvalidObjectException + { + _handle = getObject (); + } + + /** + * Enable garbage collection on object + */ + public void enableCollection () + { + _handle = null; + } } diff --git a/libjava/classpath/gnu/classpath/jdwp/id/ReferenceTypeId.java b/libjava/classpath/gnu/classpath/jdwp/id/ReferenceTypeId.java index cdb78040a41..e7a5d2c3d83 100644 --- a/libjava/classpath/gnu/classpath/jdwp/id/ReferenceTypeId.java +++ b/libjava/classpath/gnu/classpath/jdwp/id/ReferenceTypeId.java @@ -39,6 +39,8 @@ exception statement from your version. */ package gnu.classpath.jdwp.id; +import gnu.classpath.jdwp.exception.InvalidClassException; + import java.io.DataOutputStream; import java.io.IOException; @@ -68,6 +70,22 @@ public class ReferenceTypeId } /** + * Gets the class associated with this ID + * + * @returns the class + * @throws InvalidClassException if the class is not valid + */ + public Class getType () + throws InvalidClassException + { + Class clazz = (Class) _reference.get (); + if (clazz == null) + throw new InvalidClassException (_id); + + return clazz; + } + + /** * Outputs the reference type ID to the given output stream * * @param outStream the stream to which to write the data diff --git a/libjava/classpath/gnu/classpath/jdwp/id/StringId.java b/libjava/classpath/gnu/classpath/jdwp/id/StringId.java index ea1a83a56a2..1ba8f6d4d01 100644 --- a/libjava/classpath/gnu/classpath/jdwp/id/StringId.java +++ b/libjava/classpath/gnu/classpath/jdwp/id/StringId.java @@ -40,6 +40,7 @@ exception statement from your version. */ package gnu.classpath.jdwp.id; import gnu.classpath.jdwp.JdwpConstants; +import gnu.classpath.jdwp.exception.InvalidStringException; /** * A class which represents a JDWP string id @@ -61,4 +62,21 @@ public class StringId { super (JdwpConstants.Tag.STRING); } + + /** + * Gets the String represented by this ID + * + * @throws InvalidStringException if String is garbage collected, + * or otherwise invalid + */ + public String getString () + throws InvalidStringException + { + String string = (String) _reference.get (); + + if (string == null) + throw new InvalidStringException (getId ()); + + return string; + } } diff --git a/libjava/classpath/gnu/classpath/jdwp/id/ThreadGroupId.java b/libjava/classpath/gnu/classpath/jdwp/id/ThreadGroupId.java index aef7d5b5421..f4d9d803d1e 100644 --- a/libjava/classpath/gnu/classpath/jdwp/id/ThreadGroupId.java +++ b/libjava/classpath/gnu/classpath/jdwp/id/ThreadGroupId.java @@ -40,6 +40,7 @@ exception statement from your version. */ package gnu.classpath.jdwp.id; import gnu.classpath.jdwp.JdwpConstants; +import gnu.classpath.jdwp.exception.InvalidThreadGroupException; /** * A class which represents a JDWP thread group id @@ -61,4 +62,21 @@ public class ThreadGroupId { super (JdwpConstants.Tag.THREAD_GROUP); } + + /** + * Gets the thread group represented by this ID + * + * @throws InvalidThreadGroupException if the group is invalid + * or garbage collected + */ + public ThreadGroup getThreadGroup () + throws InvalidThreadGroupException + { + ThreadGroup group = (ThreadGroup) _reference.get (); + + if (group == null) + throw new InvalidThreadGroupException (getId ()); + + return group; + } } diff --git a/libjava/classpath/gnu/classpath/jdwp/id/ThreadId.java b/libjava/classpath/gnu/classpath/jdwp/id/ThreadId.java index 733bf55102b..207d6b0a1f1 100644 --- a/libjava/classpath/gnu/classpath/jdwp/id/ThreadId.java +++ b/libjava/classpath/gnu/classpath/jdwp/id/ThreadId.java @@ -40,6 +40,7 @@ exception statement from your version. */ package gnu.classpath.jdwp.id; import gnu.classpath.jdwp.JdwpConstants; +import gnu.classpath.jdwp.exception.InvalidThreadException; /** * A class which represents a JDWP thread id @@ -61,4 +62,24 @@ public class ThreadId { super (JdwpConstants.Tag.THREAD); } + + /** + * Gets the Thread represented by this ID + * + * @throws InvalidThreadException if thread is garbage collected, + * exited, or otherwise invalid + */ + public Thread getThread () + throws InvalidThreadException + { + Thread thread = (Thread) _reference.get (); + + /* Spec says if thread is null, not valid, or exited, + throw invalid thread */ + // FIXME: not valid? exited? Is this check valid? + if (thread == null || !thread.isAlive ()) + throw new InvalidThreadException (getId ()); + + return thread; + } } diff --git a/libjava/classpath/gnu/classpath/jdwp/processor/CommandSet.java b/libjava/classpath/gnu/classpath/jdwp/processor/CommandSet.java index 17b956ceadc..d3a27532b39 100644 --- a/libjava/classpath/gnu/classpath/jdwp/processor/CommandSet.java +++ b/libjava/classpath/gnu/classpath/jdwp/processor/CommandSet.java @@ -15,8 +15,8 @@ General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -02111-1307 USA. +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. Linking this library statically or dynamically with other modules is making a combined work based on this library. Thus, the terms and @@ -40,6 +40,7 @@ exception statement from your version. */ package gnu.classpath.jdwp.processor; import gnu.classpath.jdwp.exception.JdwpException; +import gnu.classpath.jdwp.VMIdManager; import java.io.DataOutputStream; import java.nio.ByteBuffer; @@ -50,9 +51,14 @@ import java.nio.ByteBuffer; * * @author Aaron Luchko <aluchko@redhat.com> */ -public interface CommandSet +public abstract class CommandSet { /** + * The VM's ID manager + */ + protected final VMIdManager idMan = VMIdManager.getDefault (); + + /** * Runs the given command with the data in distr and writes the data for the * reply packet to ostr. * @@ -62,7 +68,7 @@ public interface CommandSet * @return true if the JDWP layer should shut down in response to this packet * @throws JdwpException command wasn't carried out successfully */ - public boolean runCommand(ByteBuffer bb, DataOutputStream os, - byte command) + public abstract boolean runCommand(ByteBuffer bb, DataOutputStream os, + byte command) throws JdwpException; } diff --git a/libjava/classpath/gnu/classpath/jdwp/processor/FieldCommandSet.java b/libjava/classpath/gnu/classpath/jdwp/processor/FieldCommandSet.java index f14635b9188..090770038ad 100644 --- a/libjava/classpath/gnu/classpath/jdwp/processor/FieldCommandSet.java +++ b/libjava/classpath/gnu/classpath/jdwp/processor/FieldCommandSet.java @@ -49,7 +49,8 @@ import java.nio.ByteBuffer; * * @author Aaron Luchko <aluchko@redhat.com> */ -public class FieldCommandSet implements CommandSet +public class FieldCommandSet + extends CommandSet { /** * There are no commands for this CommandSet at this time so we just throw a diff --git a/libjava/classpath/gnu/classpath/jdwp/processor/InterfaceTypeCommandSet.java b/libjava/classpath/gnu/classpath/jdwp/processor/InterfaceTypeCommandSet.java index a32da38b324..5b29182ecb6 100644 --- a/libjava/classpath/gnu/classpath/jdwp/processor/InterfaceTypeCommandSet.java +++ b/libjava/classpath/gnu/classpath/jdwp/processor/InterfaceTypeCommandSet.java @@ -50,7 +50,8 @@ import java.nio.ByteBuffer; * * @author Aaron Luchko <aluchko@redhat.com> */ -public class InterfaceTypeCommandSet implements CommandSet +public class InterfaceTypeCommandSet + extends CommandSet { /** * There are no commands for this CommandSet at this time so we just throw a diff --git a/libjava/classpath/gnu/classpath/jdwp/processor/ObjectReferenceCommandSet.java b/libjava/classpath/gnu/classpath/jdwp/processor/ObjectReferenceCommandSet.java index 38bb0cdbf96..23a64c341e6 100644 --- a/libjava/classpath/gnu/classpath/jdwp/processor/ObjectReferenceCommandSet.java +++ b/libjava/classpath/gnu/classpath/jdwp/processor/ObjectReferenceCommandSet.java @@ -1,4 +1,4 @@ -/* ObjectReferenceCommandSet.java -- lass to implement the ObjectReference +/* ObjectReferenceCommandSet.java -- class to implement the ObjectReference Command Set Copyright (C) 2005 Free Software Foundation @@ -36,20 +36,19 @@ this exception to your version of the library, but 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.IVirtualMachine; -import gnu.classpath.jdwp.Jdwp; 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.IdManager; import gnu.classpath.jdwp.id.ObjectId; import gnu.classpath.jdwp.id.ReferenceTypeId; import gnu.classpath.jdwp.util.Value; -import gnu.classpath.jdwp.util.MethodInvoker; +import gnu.classpath.jdwp.util.MethodResult; import java.io.DataOutputStream; import java.io.IOException; @@ -62,14 +61,9 @@ import java.nio.ByteBuffer; * * @author Aaron Luchko <aluchko@redhat.com> */ -public class ObjectReferenceCommandSet implements CommandSet +public class ObjectReferenceCommandSet + extends CommandSet { - // Our hook into the jvm - private final IVirtualMachine vm = Jdwp.getIVirtualMachine(); - - // Manages all the different ids that are assigned by jdwp - private final IdManager idMan = Jdwp.getIdManager(); - public boolean runCommand(ByteBuffer bb, DataOutputStream os, byte command) throws JdwpException { @@ -103,7 +97,7 @@ public class ObjectReferenceCommandSet implements CommandSet break; default: throw new NotImplementedException("Command " + command + - " not found in String Reference Command Set."); + " not found in ObjectReference Command Set."); } } catch (IOException ex) @@ -118,7 +112,7 @@ public class ObjectReferenceCommandSet implements CommandSet private void executeReferenceType(ByteBuffer bb, DataOutputStream os) throws JdwpException, IOException { - ObjectId oid = idMan.readId(bb); + ObjectId oid = idMan.readObjectId(bb); Object obj = oid.getObject(); Class clazz = obj.getClass(); ReferenceTypeId refId = idMan.getReferenceTypeId(clazz); @@ -128,7 +122,7 @@ public class ObjectReferenceCommandSet implements CommandSet private void executeGetValues(ByteBuffer bb, DataOutputStream os) throws JdwpException, IOException { - ObjectId oid = idMan.readId(bb); + ObjectId oid = idMan.readObjectId(bb); Object obj = oid.getObject(); int numFields = bb.getInt(); @@ -137,25 +131,41 @@ public class ObjectReferenceCommandSet implements CommandSet for (int i = 0; i < numFields; i++) { - Field field = (Field) idMan.readId(bb).getObject(); - Value.writeValueFromField(os, field, obj); + Field field = (Field) idMan.readObjectId(bb).getObject(); + try + { + field.setAccessible(true); // Might be a private field + Object value = field.get(obj); + Value.writeTaggedValue(os, value); + } + catch (IllegalArgumentException ex) + { + // I suppose this would best qualify as an invalid field then + throw new InvalidFieldException(ex); + } + catch (IllegalAccessException ex) + { + // Since we set it as accessible this really shouldn't happen + throw new JdwpInternalErrorException(ex); + } } } private void executeSetValues(ByteBuffer bb, DataOutputStream os) throws JdwpException, IOException { - ObjectId oid = idMan.readId(bb); + ObjectId oid = idMan.readObjectId(bb); Object obj = oid.getObject(); int numFields = bb.getInt(); for (int i = 0; i < numFields; i++) { - Field field = (Field) idMan.readId(bb).getObject(); - Object value = Value.getObj(bb, field); + Field field = (Field) idMan.readObjectId(bb).getObject(); + Object value = Value.getUntaggedObj(bb, field.getType()); try { + field.setAccessible(true); // Might be a private field field.set(obj, value); } catch (IllegalArgumentException ex) @@ -165,7 +175,7 @@ public class ObjectReferenceCommandSet implements CommandSet } catch (IllegalAccessException ex) { - // We should be able to access any field + // Since we set it as accessible this really shouldn't happen throw new JdwpInternalErrorException(ex); } } @@ -184,16 +194,16 @@ public class ObjectReferenceCommandSet implements CommandSet private void executeInvokeMethod(ByteBuffer bb, DataOutputStream os) throws JdwpException, IOException { - ObjectId oid = idMan.readId(bb); + ObjectId oid = idMan.readObjectId(bb); Object obj = oid.getObject(); - ObjectId tid = idMan.readId(bb); + ObjectId tid = idMan.readObjectId(bb); Thread thread = (Thread) tid.getObject(); ReferenceTypeId rid = idMan.readReferenceTypeId(bb); Class clazz = rid.getType(); - ObjectId mid = idMan.readId(bb); + ObjectId mid = idMan.readObjectId(bb); Method method = (Method) mid.getObject(); int args = bb.getInt(); @@ -205,45 +215,49 @@ public class ObjectReferenceCommandSet implements CommandSet } int invokeOptions = bb.getInt(); - - if ((invokeOptions & JdwpConstants.InvokeOptions.INVOKE_SINGLE_THREADED) != 0) - { // We must suspend all other running threads first - vm.suspendAllThreads(); + boolean suspend = ((invokeOptions + & JdwpConstants.InvokeOptions.INVOKE_SINGLE_THREADED) + != 0); + if (suspend) + { + // We must suspend all other running threads first + VMVirtualMachine.suspendAllThreads (); } - boolean nonVirtual; - if ((invokeOptions & JdwpConstants.InvokeOptions.INVOKE_NONVIRTUAL) != 0) - nonVirtual = true; - else - nonVirtual = false; - MethodInvoker vmi = new MethodInvoker(vm); - - vmi.executeMethod(obj, thread, clazz, method, values, nonVirtual); - Object value = vmi.getReturnedValue(); - ObjectId exceptionId = vmi.getExceptionId(); - - Value.writeValue(os, value); - exceptionId.writeTagged(os); + + boolean nonVirtual = ((invokeOptions + & JdwpConstants.InvokeOptions.INVOKE_NONVIRTUAL) + != 0); + + MethodResult mr = VMVirtualMachine.executeMethod(obj, thread, + clazz, method, + values, nonVirtual); + Object value = mr.getReturnedValue(); + Exception exception = mr.getThrownException(); + + ObjectId eId = idMan.getObjectId(exception); + Value.writeTaggedValue(os, value); + eId.writeTagged(os); } private void executeDisableCollection(ByteBuffer bb, DataOutputStream os) throws JdwpException, IOException { - ObjectId oid = idMan.readId(bb); + ObjectId oid = idMan.readObjectId(bb); oid.disableCollection(); } private void executeEnableCollection(ByteBuffer bb, DataOutputStream os) throws JdwpException, IOException { - ObjectId oid = idMan.readId(bb); + ObjectId oid = idMan.readObjectId(bb); oid.enableCollection(); } private void executeIsCollected(ByteBuffer bb, DataOutputStream os) throws JdwpException, IOException { - ObjectId oid = idMan.readId(bb); - boolean collected = oid.isCollected(); + ObjectId oid = idMan.readObjectId(bb); + boolean collected = (oid.getReference().get () == null); os.writeBoolean(collected); } } diff --git a/libjava/classpath/gnu/classpath/jdwp/processor/PacketProcessor.java b/libjava/classpath/gnu/classpath/jdwp/processor/PacketProcessor.java index 914494c249f..9e281f217f2 100644 --- a/libjava/classpath/gnu/classpath/jdwp/processor/PacketProcessor.java +++ b/libjava/classpath/gnu/classpath/jdwp/processor/PacketProcessor.java @@ -52,6 +52,7 @@ import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.nio.ByteBuffer; +import java.security.PrivilegedAction; /** * This class is responsible for processing packets from the @@ -62,7 +63,7 @@ import java.nio.ByteBuffer; * @author Keith Seitz (keiths@redhat.com) */ public class PacketProcessor - extends Thread + implements PrivilegedAction { // The connection to the debugger private JdwpConnection _connection; @@ -134,7 +135,7 @@ public class PacketProcessor * Main run routine for this thread. Will loop getting packets * from the connection and processing them. */ - public void run () + public Object run () { try { @@ -149,6 +150,7 @@ public class PacketProcessor } // Time to shutdown, tell Jdwp to shutdown Jdwp.getDefault().shutdown(); + return null; } /** @@ -157,7 +159,6 @@ public class PacketProcessor public void shutdown () { _shutdown = true; - interrupt (); } // Helper function which actually does all the work of waiting diff --git a/libjava/classpath/gnu/classpath/jdwp/processor/ReferenceTypeCommandSet.java b/libjava/classpath/gnu/classpath/jdwp/processor/ReferenceTypeCommandSet.java index 34def9f2d07..b9944f7d9a0 100644 --- a/libjava/classpath/gnu/classpath/jdwp/processor/ReferenceTypeCommandSet.java +++ b/libjava/classpath/gnu/classpath/jdwp/processor/ReferenceTypeCommandSet.java @@ -1,4 +1,4 @@ -/* ReferenceTypeCommandSet.java -- lass to implement the ReferenceType +/* ReferenceTypeCommandSet.java -- class to implement the ReferenceType Command Set Copyright (C) 2005 Free Software Foundation @@ -36,16 +36,15 @@ this exception to your version of the library, but 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.IVirtualMachine; -import gnu.classpath.jdwp.Jdwp; 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.IdManager; import gnu.classpath.jdwp.id.ObjectId; import gnu.classpath.jdwp.id.ReferenceTypeId; import gnu.classpath.jdwp.util.JdwpString; @@ -63,14 +62,9 @@ import java.nio.ByteBuffer; * * @author Aaron Luchko <aluchko@redhat.com> */ -public class ReferenceTypeCommandSet implements CommandSet +public class ReferenceTypeCommandSet + extends CommandSet { - // Our hook into the jvm - private final IVirtualMachine vm = Jdwp.getIVirtualMachine(); - - // Manages all the different ids that are assigned by jdwp - private final IdManager idMan = Jdwp.getIdManager(); - public boolean runCommand(ByteBuffer bb, DataOutputStream os, byte command) throws JdwpException { @@ -125,7 +119,7 @@ public class ReferenceTypeCommandSet implements CommandSet break; default: throw new NotImplementedException("Command " + command + - " not found in String Reference Command Set."); + " not found in ReferenceType Command Set."); } } catch (IOException ex) @@ -152,7 +146,7 @@ public class ReferenceTypeCommandSet implements CommandSet Class clazz = refId.getType(); ClassLoader loader = clazz.getClassLoader(); - ObjectId oid = idMan.getId(loader); + ObjectId oid = idMan.getObjectId(loader); oid.write(os); } @@ -176,7 +170,7 @@ public class ReferenceTypeCommandSet implements CommandSet for (int i = 0; i < fields.length; i++) { Field field = fields[i]; - idMan.getId(field).write(os); + idMan.getObjectId(field).write(os); JdwpString.writeString(os, field.getName()); JdwpString.writeString(os, Signature.computeFieldSignature(field)); os.writeInt(field.getModifiers()); @@ -194,7 +188,7 @@ public class ReferenceTypeCommandSet implements CommandSet for (int i = 0; i < methods.length; i++) { Method method = methods[i]; - idMan.getId(method).write(os); + idMan.getObjectId(method).write(os); JdwpString.writeString(os, method.getName()); JdwpString.writeString(os, Signature.computeMethodSignature(method)); os.writeInt(method.getModifiers()); @@ -211,14 +205,31 @@ public class ReferenceTypeCommandSet implements CommandSet os.writeInt(numFields); // Looks pointless but this is the protocol for (int i = 0; i < numFields; i++) { - ObjectId fieldId = idMan.readId(bb); + ObjectId fieldId = idMan.readObjectId(bb); Field field = (Field) (fieldId.getObject()); Class fieldClazz = field.getDeclaringClass(); // We don't actually need the clazz to get the field but we might as // well check that the debugger got it right if (fieldClazz.isAssignableFrom(clazz)) - Value.writeStaticValueFromField(os, field); + { + try + { + field.setAccessible(true); // Might be a private field + Object value = field.get(null); + Value.writeTaggedValue(os, value); + } + catch (IllegalArgumentException ex) + { + // I suppose this would best qualify as an invalid field then + throw new InvalidFieldException(ex); + } + catch (IllegalAccessException ex) + { + // Since we set it as accessible this really shouldn't happen + throw new JdwpInternalErrorException(ex); + } + } else throw new InvalidFieldException(fieldId.getId()); } @@ -231,7 +242,7 @@ public class ReferenceTypeCommandSet implements CommandSet Class clazz = refId.getType(); // We'll need to go into the jvm for this unless there's an easier way - String sourceFileName = vm.getSourceFile(clazz); + String sourceFileName = VMVirtualMachine.getSourceFile(clazz); JdwpString.writeString(os, sourceFileName); // clazz.getProtectionDomain().getCodeSource().getLocation(); } @@ -258,7 +269,7 @@ public class ReferenceTypeCommandSet implements CommandSet Class clazz = refId.getType(); // I don't think there's any other way to get this - int status = vm.getStatus(clazz); + int status = VMVirtualMachine.getClassStatus(clazz); os.writeInt(status); } @@ -282,7 +293,7 @@ public class ReferenceTypeCommandSet implements CommandSet { ReferenceTypeId refId = idMan.readReferenceTypeId(bb); Class clazz = refId.getType(); - ObjectId clazzObjectId = idMan.getId(clazz); + ObjectId clazzObjectId = idMan.getObjectId(clazz); clazzObjectId.write(os); } diff --git a/libjava/classpath/gnu/classpath/jdwp/processor/StringReferenceCommandSet.java b/libjava/classpath/gnu/classpath/jdwp/processor/StringReferenceCommandSet.java index 1f1b04cb0cc..8f5bc685cda 100644 --- a/libjava/classpath/gnu/classpath/jdwp/processor/StringReferenceCommandSet.java +++ b/libjava/classpath/gnu/classpath/jdwp/processor/StringReferenceCommandSet.java @@ -16,8 +16,8 @@ General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -02111-1307 USA. +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. Linking this library statically or dynamically with other modules is making a combined work based on this library. Thus, the terms and @@ -40,7 +40,6 @@ exception statement from your version. */ package gnu.classpath.jdwp.processor; -import gnu.classpath.jdwp.Jdwp; import gnu.classpath.jdwp.JdwpConstants; import gnu.classpath.jdwp.exception.JdwpException; import gnu.classpath.jdwp.exception.JdwpInternalErrorException; @@ -57,7 +56,8 @@ import java.nio.ByteBuffer; * * @author Aaron Luchko <aluchko@redhat.com> */ -public class StringReferenceCommandSet implements CommandSet +public class StringReferenceCommandSet + extends CommandSet { public boolean runCommand(ByteBuffer bb, DataOutputStream os, byte command) @@ -90,7 +90,7 @@ public class StringReferenceCommandSet implements CommandSet private void executeValue(ByteBuffer bb, DataOutputStream os) throws JdwpException, IOException { - ObjectId oid = Jdwp.getIdManager().readId(bb); + ObjectId oid = idMan.readObjectId(bb); String str = (String) oid.getObject(); JdwpString.writeString(os, str); diff --git a/libjava/classpath/gnu/classpath/jdwp/processor/VirtualMachineCommandSet.java b/libjava/classpath/gnu/classpath/jdwp/processor/VirtualMachineCommandSet.java index 32b98781727..b83406873e3 100644 --- a/libjava/classpath/gnu/classpath/jdwp/processor/VirtualMachineCommandSet.java +++ b/libjava/classpath/gnu/classpath/jdwp/processor/VirtualMachineCommandSet.java @@ -39,13 +39,11 @@ exception statement from your version. */ package gnu.classpath.jdwp.processor; -import gnu.classpath.jdwp.IVirtualMachine; -import gnu.classpath.jdwp.Jdwp; 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.IdManager; import gnu.classpath.jdwp.id.ObjectId; import gnu.classpath.jdwp.id.ReferenceTypeId; import gnu.classpath.jdwp.util.JdwpString; @@ -63,17 +61,9 @@ import java.util.Properties; * * @author Aaron Luchko <aluchko@redhat.com> */ -public class VirtualMachineCommandSet implements CommandSet +public class VirtualMachineCommandSet + extends CommandSet { - // Our hook into the jvm - private final IVirtualMachine vm = Jdwp.getIVirtualMachine(); - - // Manages all the different ids that are assigned by jdwp - private final IdManager idMan = Jdwp.getIdManager(); - - // The Jdwp object - private final Jdwp jdwp = Jdwp.getDefault(); - public boolean runCommand(ByteBuffer bb, DataOutputStream os, byte command) throws JdwpException { @@ -144,9 +134,9 @@ public class VirtualMachineCommandSet implements CommandSet case JdwpConstants.CommandSet.VirtualMachine.ALL_CLASSES_WITH_GENERIC: executeAllClassesWithGeneric(bb, os); break; - default: - break; + throw new NotImplementedException("Command " + command + + " not found in VirtualMachine Command Set."); } } catch (IOException ex) @@ -187,7 +177,7 @@ public class VirtualMachineCommandSet implements CommandSet ArrayList allMatchingClasses = new ArrayList(); // This will be an Iterator over all loaded Classes - Iterator iter = vm.getAllLoadedClasses(); + Iterator iter = VMVirtualMachine.getAllLoadedClasses(); while (iter.hasNext()) { @@ -203,7 +193,7 @@ public class VirtualMachineCommandSet implements CommandSet Class clazz = (Class) allMatchingClasses.get(i); ReferenceTypeId id = idMan.getReferenceTypeId(clazz); id.writeTagged(os); - int status = vm.getStatus(clazz); + int status = VMVirtualMachine.getClassStatus(clazz); os.writeInt(status); } } @@ -214,14 +204,14 @@ public class VirtualMachineCommandSet implements CommandSet // Disable garbage collection while we're collecting the info on loaded // classes so we some classes don't get collected between the time we get // the count and the time we get the list - vm.disableGarbageCollection(); + //VMVirtualMachine.disableGarbageCollection(); - int classCount = vm.getAllLoadedClassesCount(); + int classCount = VMVirtualMachine.getAllLoadedClassesCount(); os.writeInt(classCount); // This will be an Iterator over all loaded Classes - Iterator iter = vm.getAllLoadedClasses(); - vm.enableGarbageCollection(); + Iterator iter = VMVirtualMachine.getAllLoadedClasses(); + //VMVirtualMachine.enableGarbageCollection(); int count = 0; // Note it's possible classes were created since out classCount so make @@ -233,7 +223,7 @@ public class VirtualMachineCommandSet implements CommandSet id.writeTagged(os); String sig = Signature.computeClassSignature(clazz); JdwpString.writeString(os, sig); - int status = vm.getStatus(clazz); + int status = VMVirtualMachine.getClassStatus(clazz); os.writeInt(status); } } @@ -246,7 +236,7 @@ public class VirtualMachineCommandSet implements CommandSet int numThreads = root.activeCount(); Thread allThreads[] = new Thread[numThreads]; - root.enumerate(allThreads, true); + root.enumerate(allThreads); // We need to loop through for the true count since some threads may have // been destroyed since we got @@ -270,18 +260,18 @@ public class VirtualMachineCommandSet implements CommandSet if (thread == null) break; // No threads after this point if (!thread.getThreadGroup().equals(jdwpGroup)) - idMan.getId(thread).write(os); + idMan.getObjectId(thread).write(os); } } private void executeTopLevelThreadGroups(ByteBuffer bb, DataOutputStream os) throws JdwpException, IOException { - ThreadGroup jdwpGroup = jdwp.getJdwpThreadGroup(); + ThreadGroup jdwpGroup = Thread.currentThread().getThreadGroup (); ThreadGroup root = getRootThreadGroup(jdwpGroup); os.writeInt(1); // Just one top level group allowed? - idMan.getId(root); + idMan.getObjectId(root); } private void executeDispose(ByteBuffer bb, DataOutputStream os) @@ -291,11 +281,11 @@ public class VirtualMachineCommandSet implements CommandSet // suspended multiple times, we likely need a way to keep track of how many // times a thread has been suspended or else a stronger resume method for // this purpose - // vm.resumeAllThreadsExcept(jdwp.getJdwpThreadGroup()); + // VMVirtualMachine.resumeAllThreads (); // Simply shutting down the jdwp layer will take care of the rest of the // shutdown other than disabling debugging in the VM - // vm.disableDebugging(); + // VMVirtualMachine.disableDebugging(); // Don't implement this until we're sure how to remove all the debugging // effects from the VM. @@ -318,27 +308,27 @@ public class VirtualMachineCommandSet implements CommandSet private void executeSuspend(ByteBuffer bb, DataOutputStream os) throws JdwpException { - vm.suspendAllThreadsExcept(jdwp.getJdwpThreadGroup()); + VMVirtualMachine.suspendAllThreads (); } private void executeResume(ByteBuffer bb, DataOutputStream os) throws JdwpException { - vm.resumeAllThreadsExcept(jdwp.getJdwpThreadGroup()); + VMVirtualMachine.resumeAllThreads (); } private void executeExit(ByteBuffer bb, DataOutputStream os) throws JdwpException, IOException { int exitCode = bb.getInt(); - jdwp.setExit(exitCode); + System.exit (exitCode); } private void executeCreateString(ByteBuffer bb, DataOutputStream os) throws JdwpException, IOException { String string = JdwpString.readString(bb); - ObjectId stringId = Jdwp.getIdManager().getId(string); + ObjectId stringId = idMan.getObjectId(string); // Since this string isn't referenced anywhere we'll disable garbage // collection on it so it's still around when the debugger gets back to it. @@ -386,7 +376,7 @@ public class VirtualMachineCommandSet implements CommandSet { // Instead of going through the list of objects they give us it's probably // better just to find the garbage collected objects ourselves - idMan.update(); + //idMan.update(); } private void executeHoldEvents(ByteBuffer bb, DataOutputStream os) diff --git a/libjava/classpath/gnu/classpath/jdwp/transport/ITransport.java b/libjava/classpath/gnu/classpath/jdwp/transport/ITransport.java index 371cf8f06af..60f1bb00df9 100644 --- a/libjava/classpath/gnu/classpath/jdwp/transport/ITransport.java +++ b/libjava/classpath/gnu/classpath/jdwp/transport/ITransport.java @@ -49,7 +49,7 @@ import java.util.HashMap; * A class representing a transport layer. This class serves as a generic * interface for all transport types used in the JDWP back-end. * - * @author Keith Seitz <keiths@redhat.com> + * @author Keith Seitz (keiths@redhat.com) */ public interface ITransport { @@ -71,6 +71,11 @@ public interface ITransport throws TransportException; /** + * Shutdown the transport + */ + public void shutdown (); + + /** * Get the input stream for the transport */ public InputStream getInputStream () diff --git a/libjava/classpath/gnu/classpath/jdwp/transport/JdwpConnection.java b/libjava/classpath/gnu/classpath/jdwp/transport/JdwpConnection.java index 18250d3209b..f008bbd00ca 100644 --- a/libjava/classpath/gnu/classpath/jdwp/transport/JdwpConnection.java +++ b/libjava/classpath/gnu/classpath/jdwp/transport/JdwpConnection.java @@ -96,8 +96,9 @@ public class JdwpConnection * * @param transport the transport to use for communications */ - public JdwpConnection (ITransport transport) + public JdwpConnection (ThreadGroup group, ITransport transport) { + super (group, "JDWP connection thread"); _transport = transport; _commandQueue = new ArrayList (); _shutdown = false; @@ -177,7 +178,7 @@ public class JdwpConnection 2. Transport was shutdown In either case, we make sure that all of the back-end gets shutdown. */ - Jdwp.getInstance().shutdown (); + Jdwp.getDefault().shutdown (); } catch (Throwable t) { diff --git a/libjava/classpath/gnu/classpath/jdwp/transport/SocketTransport.java b/libjava/classpath/gnu/classpath/jdwp/transport/SocketTransport.java index 0ad7357e183..49d9e1f3bf6 100644 --- a/libjava/classpath/gnu/classpath/jdwp/transport/SocketTransport.java +++ b/libjava/classpath/gnu/classpath/jdwp/transport/SocketTransport.java @@ -57,7 +57,7 @@ import javax.net.SocketFactory; * configury string that looks like "name=dt_socket, * address=localhost:1234,server=y". * - * @author Keith Seitz <keiths@redhat.com> + * @author Keith Seitz (keiths@redhat.com) */ class SocketTransport implements ITransport @@ -146,6 +146,22 @@ class SocketTransport } /** + * Shutdown the socket. This could cause SocketExceptions + * for anyone blocked on socket i/o + */ + public void shutdown () + { + try + { + _socket.close (); + } + catch (Throwable t) + { + // We don't really care about errors at this point + } + } + + /** * Returns an <code>InputStream</code> for the transport * * @throws IOException if an I/O error occurs creating the stream diff --git a/libjava/classpath/gnu/java/awt/AWTUtilities.java b/libjava/classpath/gnu/java/awt/AWTUtilities.java index a02d1c462b0..af1fc13ca50 100644 --- a/libjava/classpath/gnu/java/awt/AWTUtilities.java +++ b/libjava/classpath/gnu/java/awt/AWTUtilities.java @@ -37,17 +37,28 @@ exception statement from your version. */ package gnu.java.awt; +import java.applet.Applet; import java.awt.Component; import java.awt.Container; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Insets; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Toolkit; +import java.awt.Window; +import java.awt.event.MouseEvent; import java.util.AbstractSequentialList; import java.util.List; import java.util.ListIterator; import java.util.NoSuchElementException; import java.util.WeakHashMap; +import java.lang.reflect.InvocationTargetException; /** - * This class provides utility methods that are commonly used in AWT - * (and Swing). + * This class mirrors the javax.swing.SwingUtilities class. It + * provides commonly needed functionalities for AWT classes without + * the need to reference classes in the javax.swing package. */ public class AWTUtilities { @@ -318,4 +329,366 @@ public class AWTUtilities return visibleChildren; } + + /** + * Calculates the portion of the base rectangle which is inside the + * insets. + * + * @param base The rectangle to apply the insets to + * @param insets The insets to apply to the base rectangle + * @param ret A rectangle to use for storing the return value, or + * <code>null</code> + * + * @return The calculated area inside the base rectangle and its insets, + * either stored in ret or a new Rectangle if ret is <code>null</code> + * + * @see #calculateInnerArea + */ + public static Rectangle calculateInsetArea(Rectangle base, Insets insets, + Rectangle ret) + { + if (ret == null) + ret = new Rectangle(); + ret.setBounds(base.x + insets.left, base.y + insets.top, + base.width - (insets.left + insets.right), + base.height - (insets.top + insets.bottom)); + return ret; + } + + /** + * Calculates the bounds of a component in the component's own coordinate + * space. The result has the same height and width as the component's + * bounds, but its location is set to (0,0). + * + * @param aComponent The component to measure + * + * @return The component's bounds in its local coordinate space + */ + public static Rectangle getLocalBounds(Component aComponent) + { + Rectangle bounds = aComponent.getBounds(); + return new Rectangle(0, 0, bounds.width, bounds.height); + } + + /** + * Returns the font metrics object for a given font. The metrics can be + * used to calculate crude bounding boxes and positioning information, + * for laying out components with textual elements. + * + * @param font The font to get metrics for + * + * @return The font's metrics + * + * @see java.awt.font.GlyphMetrics + */ + public static FontMetrics getFontMetrics(Font font) + { + return Toolkit.getDefaultToolkit().getFontMetrics(font); + } + + /** + * Returns the least ancestor of <code>comp</code> which has the + * specified name. + * + * @param name The name to search for + * @param comp The component to search the ancestors of + * + * @return The nearest ancestor of <code>comp</code> with the given + * name, or <code>null</code> if no such ancestor exists + * + * @see java.awt.Component#getName + * @see #getAncestorOfClass + */ + public static Container getAncestorNamed(String name, Component comp) + { + while (comp != null && (comp.getName() != name)) + comp = comp.getParent(); + return (Container) comp; + } + + /** + * Returns the least ancestor of <code>comp</code> which is an instance + * of the specified class. + * + * @param c The class to search for + * @param comp The component to search the ancestors of + * + * @return The nearest ancestor of <code>comp</code> which is an instance + * of the given class, or <code>null</code> if no such ancestor exists + * + * @see #getAncestorOfClass + * @see #windowForComponent + * @see + * + */ + public static Container getAncestorOfClass(Class c, Component comp) + { + while (comp != null && (! c.isInstance(comp))) + comp = comp.getParent(); + return (Container) comp; + } + + /** + * Equivalent to calling <code>getAncestorOfClass(Window, comp)</code>. + * + * @param comp The component to search for an ancestor window + * + * @return An ancestral window, or <code>null</code> if none exists + */ + public static Window windowForComponent(Component comp) + { + return (Window) getAncestorOfClass(Window.class, comp); + } + + /** + * Returns the "root" of the component tree containint <code>comp</code> + * The root is defined as either the <em>least</em> ancestor of + * <code>comp</code> which is a {@link Window}, or the <em>greatest</em> + * ancestor of <code>comp</code> which is a {@link Applet} if no {@link + * Window} ancestors are found. + * + * @param comp The component to search for a root + * + * @return The root of the component's tree, or <code>null</code> + */ + public static Component getRoot(Component comp) + { + Applet app = null; + Window win = null; + + while (comp != null) + { + if (win == null && comp instanceof Window) + win = (Window) comp; + else if (comp instanceof Applet) + app = (Applet) comp; + comp = comp.getParent(); + } + + if (win != null) + return win; + else + return app; + } + + /** + * Return true if a descends from b, in other words if b is an + * ancestor of a. + * + * @param a The child to search the ancestry of + * @param b The potential ancestor to search for + * + * @return true if a is a descendent of b, false otherwise + */ + public static boolean isDescendingFrom(Component a, Component b) + { + while (true) + { + if (a == null || b == null) + return false; + if (a == b) + return true; + a = a.getParent(); + } + } + + /** + * Returns the deepest descendent of parent which is both visible and + * contains the point <code>(x,y)</code>. Returns parent when either + * parent is not a container, or has no children which contain + * <code>(x,y)</code>. Returns <code>null</code> when either + * <code>(x,y)</code> is outside the bounds of parent, or parent is + * <code>null</code>. + * + * @param parent The component to search the descendents of + * @param x Horizontal coordinate to search for + * @param y Vertical coordinate to search for + * + * @return A component containing <code>(x,y)</code>, or + * <code>null</code> + * + * @see java.awt.Container#findComponentAt + */ + public static Component getDeepestComponentAt(Component parent, int x, int y) + { + if (parent == null || (! parent.contains(x, y))) + return null; + + if (! (parent instanceof Container)) + return parent; + + Container c = (Container) parent; + return c.findComponentAt(x, y); + } + + /** + * Converts a point from a component's local coordinate space to "screen" + * coordinates (such as the coordinate space mouse events are delivered + * in). This operation is equivalent to translating the point by the + * location of the component (which is the origin of its coordinate + * space). + * + * @param p The point to convert + * @param c The component which the point is expressed in terms of + * + * @see convertPointFromScreen + */ + public static void convertPointToScreen(Point p, Component c) + { + Point c0 = c.getLocationOnScreen(); + p.translate(c0.x, c0.y); + } + + /** + * Converts a point from "screen" coordinates (such as the coordinate + * space mouse events are delivered in) to a component's local coordinate + * space. This operation is equivalent to translating the point by the + * negation of the component's location (which is the origin of its + * coordinate space). + * + * @param p The point to convert + * @param c The component which the point should be expressed in terms of + */ + public static void convertPointFromScreen(Point p, Component c) + { + Point c0 = c.getLocationOnScreen(); + p.translate(-c0.x, -c0.y); + } + + /** + * Converts a point <code>(x,y)</code> from the coordinate space of one + * component to another. This is equivalent to converting the point from + * <code>source</code> space to screen space, then back from screen space + * to <code>destination</code> space. If exactly one of the two + * Components is <code>null</code>, it is taken to refer to the root + * ancestor of the other component. If both are <code>null</code>, no + * transformation is done. + * + * @param source The component which the point is expressed in terms of + * @param x Horizontal coordinate of point to transform + * @param y Vertical coordinate of point to transform + * @param destination The component which the return value will be + * expressed in terms of + * + * @return The point <code>(x,y)</code> converted from the coordinate + * space of the + * source component to the coordinate space of the destination component + * + * @see #convertPointToScreen + * @see #convertPointFromScreen + * @see #convertRectangle + * @see #getRoot + */ + public static Point convertPoint(Component source, int x, int y, + Component destination) + { + Point pt = new Point(x, y); + + if (source == null && destination == null) + return pt; + + if (source == null) + source = getRoot(destination); + + if (destination == null) + destination = getRoot(source); + + convertPointToScreen(pt, source); + convertPointFromScreen(pt, destination); + + return pt; + } + + + /** + * Converts a rectangle from the coordinate space of one component to + * another. This is equivalent to converting the rectangle from + * <code>source</code> space to screen space, then back from screen space + * to <code>destination</code> space. If exactly one of the two + * Components is <code>null</code>, it is taken to refer to the root + * ancestor of the other component. If both are <code>null</code>, no + * transformation is done. + * + * @param source The component which the rectangle is expressed in terms of + * @param rect The rectangle to convert + * @param destination The component which the return value will be + * expressed in terms of + * + * @return A new rectangle, equal in size to the input rectangle, but + * with its position converted from the coordinate space of the source + * component to the coordinate space of the destination component + * + * @see #convertPointToScreen + * @see #convertPointFromScreen + * @see #convertPoint + * @see #getRoot + */ + public static Rectangle convertRectangle(Component source, Rectangle rect, + Component destination) + { + Point pt = convertPoint(source, rect.x, rect.y, destination); + return new Rectangle(pt.x, pt.y, rect.width, rect.height); + } + + /** + * Convert a mouse event which refrers to one component to another. This + * includes changing the mouse event's coordinate space, as well as the + * source property of the event. If <code>source</code> is + * <code>null</code>, it is taken to refer to <code>destination</code>'s + * root component. If <code>destination</code> is <code>null</code>, the + * new event will remain expressed in <code>source</code>'s coordinate + * system. + * + * @param source The component the mouse event currently refers to + * @param sourceEvent The mouse event to convert + * @param destination The component the new mouse event should refer to + * + * @return A new mouse event expressed in terms of the destination + * component's coordinate space, and with the destination component as + * its source + * + * @see #convertPoint + */ + public static MouseEvent convertMouseEvent(Component source, + MouseEvent sourceEvent, + Component destination) + { + Point newpt = convertPoint(source, sourceEvent.getX(), sourceEvent.getY(), + destination); + + return new MouseEvent(destination, sourceEvent.getID(), + sourceEvent.getWhen(), sourceEvent.getModifiers(), + newpt.x, newpt.y, sourceEvent.getClickCount(), + sourceEvent.isPopupTrigger(), + sourceEvent.getButton()); + } + + + /** + * Calls {@link java.awt.EventQueue.invokeLater} with the + * specified {@link Runnable}. + */ + public static void invokeLater(Runnable doRun) + { + java.awt.EventQueue.invokeLater(doRun); + } + + /** + * Calls {@link java.awt.EventQueue.invokeAndWait} with the + * specified {@link Runnable}. + */ + public static void invokeAndWait(Runnable doRun) + throws InterruptedException, + InvocationTargetException + { + java.awt.EventQueue.invokeAndWait(doRun); + } + + /** + * Calls {@link java.awt.EventQueue.isEventDispatchThread}. + */ + public static boolean isEventDispatchThread() + { + return java.awt.EventQueue.isDispatchThread(); + } } diff --git a/libjava/classpath/gnu/java/awt/ClasspathToolkit.java b/libjava/classpath/gnu/java/awt/ClasspathToolkit.java index 5fb444f9866..1ec5664dc3e 100644 --- a/libjava/classpath/gnu/java/awt/ClasspathToolkit.java +++ b/libjava/classpath/gnu/java/awt/ClasspathToolkit.java @@ -1,5 +1,5 @@ /* ClasspathToolkit.java -- Abstract superclass for Classpath toolkits. - Copyright (C) 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -42,11 +42,12 @@ import gnu.java.awt.EmbeddedWindow; import gnu.java.awt.peer.ClasspathFontPeer; import gnu.java.awt.peer.EmbeddedWindowPeer; import gnu.java.awt.peer.ClasspathTextLayoutPeer; +import gnu.java.security.action.SetAccessibleAction; import java.awt.AWTException; +import java.awt.Component; import java.awt.Dimension; import java.awt.DisplayMode; -import java.awt.EventQueue; import java.awt.Font; import java.awt.FontMetrics; import java.awt.GraphicsDevice; @@ -59,11 +60,14 @@ import java.awt.image.ImageProducer; import java.awt.peer.RobotPeer; import java.io.File; import java.io.InputStream; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; import java.net.MalformedURLException; import java.net.URL; import java.text.AttributedString; import java.util.HashMap; import java.util.Map; +import java.security.AccessController; import javax.imageio.spi.IIORegistry; @@ -92,14 +96,6 @@ public abstract class ClasspathToolkit extends Toolkit { /** - * A map from URLs to previously loaded images, used by {@link - * #getImage(java.net.URL)}. For images that were loaded via a path - * to an image file, the map contains a key with a file URL. - */ - private HashMap imageCache; - - - /** * Returns a shared instance of the local, platform-specific * graphics environment. * @@ -109,59 +105,6 @@ public abstract class ClasspathToolkit */ public abstract GraphicsEnvironment getLocalGraphicsEnvironment(); - - /** - * Determines the current size of the default, primary screen. - * - * @throws HeadlessException if the local graphics environment is - * headless, which means that no screen is attached and no user - * interaction is allowed. - */ - public Dimension getScreenSize() - { - DisplayMode mode; - - // getDefaultScreenDevice throws HeadlessException if the - // local graphics environment is headless. - mode = GraphicsEnvironment.getLocalGraphicsEnvironment() - .getDefaultScreenDevice().getDisplayMode(); - - return new Dimension(mode.getWidth(), mode.getHeight()); - } - - - /** - * Determines the current color model of the default, primary - * screen. - * - * @see GraphicsEnvironment#getDefaultScreenDevice() - * @see java.awt.GraphicsDevice#getDefaultConfiguration() - * @see java.awt.GraphicsConfiguration#getColorModel() - * - * @throws HeadlessException if the local graphics environment is - * headless, which means that no screen is attached and no user - * interaction is allowed. - */ - public ColorModel getColorModel() - { - // getDefaultScreenDevice throws HeadlessException if the - // local graphics environment is headless. - return GraphicsEnvironment.getLocalGraphicsEnvironment() - .getDefaultScreenDevice().getDefaultConfiguration() - .getColorModel(); - } - - /** - * Retrieves the metrics for rendering a font on the screen. - * - * @param font the font whose metrics are requested. - */ - public FontMetrics getFontMetrics(Font font) - { - return ((ClasspathFontPeer) font.getPeer ()).getFontMetrics (font); - } - - /** * Acquires an appropriate {@link ClasspathFontPeer}, for use in * classpath's implementation of {@link java.awt.Font}. @@ -185,15 +128,42 @@ public abstract class ClasspathToolkit * Creates a {@link Font}, in a platform-specific manner. * * The default implementation simply constructs a {@link Font}, but some - * toolkits may wish to override this, to return {@link Font} subclasses which - * implement {@link java.awt.font.OpenType} or + * toolkits may wish to override this, to return {@link Font} subclasses + * which implement {@link java.awt.font.OpenType} or * {@link java.awt.font.MultipleMaster}. */ public Font getFont (String name, Map attrs) { - return new Font (name, attrs); - } + Font f = null; + // Circumvent the package-privateness of the + // java.awt.Font.Font(String,Map) constructor. + try + { + Constructor fontConstructor = Font.class.getDeclaredConstructor + (new Class[] { String.class, Map.class }); + AccessController.doPrivileged + (new SetAccessibleAction(fontConstructor)); + f = (Font) fontConstructor.newInstance(new Object[] { name, attrs }); + } + catch (IllegalAccessException e) + { + throw new AssertionError(e); + } + catch (NoSuchMethodException e) + { + throw new AssertionError(e); + } + catch (InstantiationException e) + { + throw new AssertionError(e); + } + catch (InvocationTargetException e) + { + throw new AssertionError(e); + } + return f; + } /** * Creates a font, reading the glyph definitions from a stream. @@ -223,137 +193,6 @@ public abstract class ClasspathToolkit */ public abstract Font createFont(int format, InputStream stream); - - /** - * Returns an image from the specified file, which must be in a - * recognized format. The set of recognized image formats may vary - * from toolkit to toolkit. - * - * <p>This method maintains a cache for images. If an image has been - * loaded from the same path before, the cached copy will be - * returned. The implementation may hold cached copies for an - * indefinite time, which can consume substantial resources with - * large images. Users are therefore advised to use {@link - * #createImage(java.lang.String)} instead. - * - * <p>The default implementation creates a file URL for the - * specified path and invokes {@link #getImage(URL)}. - * - * @param path A path to the image file. - * - * @return IllegalArgumentException if <code>path</code> does not - * designate a valid path. - */ - public Image getImage(String path) - { - try - { - return getImage(new File(path).toURL()); - } - catch (MalformedURLException muex) - { - throw (IllegalArgumentException) new IllegalArgumentException(path) - .initCause(muex); - } - } - - - /** - * Loads an image from the specified URL. The image data must be in - * a recognized format. The set of recognized image formats may vary - * from toolkit to toolkit. - * - * <p>This method maintains a cache for images. If an image has been - * loaded from the same URL before, the cached copy will be - * returned. The implementation may hold cached copies for an - * indefinite time, which can consume substantial resources with - * large images. Users are therefore advised to use {@link - * #createImage(java.net.URL)} instead. - * - * @param url the URL from where the image is read. - */ - public Image getImage(URL url) - { - Image result; - - synchronized (this) - { - // Many applications never call getImage. Therefore, we lazily - // create the image cache when it is actually needed. - if (imageCache == null) - imageCache = new HashMap(); - else - { - result = (Image) imageCache.get(url); - if (result != null) - return result; - } - - // The createImage(URL) method, which is specified by - // java.awt.Toolkit, is not implemented by this abstract class - // because it is platform-dependent. Once Classpath has support - // for the javax.imageio package, it might be worth considering - // that toolkits provide native stream readers. Then, the class - // ClasspathToolkit could provide a general implementation that - // delegates the image format parsing to javax.imageio. - result = createImage(url); - - // It is not clear whether it would be a good idea to use weak - // references here. The advantage would be reduced memory - // consumption, since loaded images would not be kept - // forever. But on VMs that frequently perform garbage - // collection (which includes VMs with a parallel or incremental - // collector), the image might frequently need to be re-loaded, - // possibly over a slow network connection. - imageCache.put(url, result); - - return result; - } - } - - - /** - * Returns an image from the specified file, which must be in a - * recognized format. The set of recognized image formats may vary - * from toolkit to toolkit. - * - * <p>A new image is created every time this method gets called, - * even if the same path has been passed before. - * - * <p>The default implementation creates a file URL for the - * specified path and invokes {@link #createImage(URL)}. - * - * @param path A path to the file to be read in. - */ - public Image createImage(String path) - { - try - { - // The abstract method createImage(URL) is defined by - // java.awt.Toolkit, but intentionally not implemented by - // ClasspathToolkit because it is platform specific. - return createImage(new File(path).toURL()); - } - catch (MalformedURLException muex) - { - throw (IllegalArgumentException) new IllegalArgumentException(path) - .initCause(muex); - } - } - - /** - * Creates an ImageProducer from the specified URL. The image is assumed - * to be in a recognised format. If the toolkit does not implement the - * image format or the image format is not recognised, null is returned. - * This default implementation is overriden by the Toolkit implementations. - * - * @param url URL to read image data from. - */ - public ImageProducer createImageProducer(URL url) - { - return null; - } - public abstract RobotPeer createRobot (GraphicsDevice screen) throws AWTException; @@ -365,15 +204,10 @@ public abstract class ClasspathToolkit */ public abstract EmbeddedWindowPeer createEmbeddedWindow (EmbeddedWindow w); - /** + /** * Used to register ImageIO SPIs provided by the toolkit. */ - - public void registerImageIOSpis(IIORegistry reg) - { - } - - public abstract boolean nativeQueueEmpty(); - public abstract void wakeNativeQueue(); - public abstract void iterateNativeQueue(EventQueue locked, boolean block); + public void registerImageIOSpis(IIORegistry reg) + { + } } diff --git a/libjava/classpath/gnu/java/awt/EmbeddedWindow.java b/libjava/classpath/gnu/java/awt/EmbeddedWindow.java index a85ce7454c1..08b2140f443 100644 --- a/libjava/classpath/gnu/java/awt/EmbeddedWindow.java +++ b/libjava/classpath/gnu/java/awt/EmbeddedWindow.java @@ -98,11 +98,13 @@ public class EmbeddedWindow extends Frame } catch (IllegalAccessException e) { - // This should never happen. + throw new RuntimeException + ("couldn't set java.awt.Component.peer field"); } catch (NoSuchFieldException e) { - // This should never happen. + throw new RuntimeException + ("couldn't set java.awt.Component.peer field"); } super.addNotify(); diff --git a/libjava/classpath/gnu/java/awt/peer/GLightweightPeer.java b/libjava/classpath/gnu/java/awt/peer/GLightweightPeer.java index 3bcaebcea62..5252e80f1e0 100644 --- a/libjava/classpath/gnu/java/awt/peer/GLightweightPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/GLightweightPeer.java @@ -52,6 +52,7 @@ import java.awt.GraphicsConfiguration; import java.awt.Image; import java.awt.Insets; import java.awt.Point; +import java.awt.Rectangle; import java.awt.Toolkit; import java.awt.event.PaintEvent; import java.awt.image.ColorModel; @@ -295,4 +296,44 @@ public class GLightweightPeer public void flip(BufferCapabilities.FlipContents contents) { } public void destroyBuffers() { } + + public boolean isRestackSupported() + { + return false; + } + + public void cancelPendingPaint(int x, int y, int width, int height) + { + + } + + public void restack() + { + + } + + public Rectangle getBounds() + { + return null; + } + + public void reparent(ContainerPeer parent) + { + + } + + public void setBounds(int x, int y, int z, int width, int height) + { + + } + + public boolean isReparentSupported() + { + return false; + } + + public void layout() + { + + } } diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphics.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphics.java index a125be7b95e..160602b03bf 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphics.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphics.java @@ -38,6 +38,8 @@ exception statement from your version. */ package gnu.java.awt.peer.gtk; +import gnu.classpath.Configuration; + import java.awt.Color; import java.awt.Dimension; import java.awt.Font; @@ -52,7 +54,17 @@ import java.text.AttributedCharacterIterator; public class GdkGraphics extends Graphics { - private final int native_state = GtkGenericPeer.getUniqueInteger(); + static + { + if (Configuration.INIT_LOAD_LIBRARY) + { + System.loadLibrary("gtkpeer"); + } + initStaticState (); + } + + static native void initStaticState(); + private final int native_state = GtkGenericPeer.getUniqueInteger (); Color color, xorColor; GtkComponentPeer component; @@ -66,6 +78,7 @@ public class GdkGraphics extends Graphics static final int GDK_COPY = 0, GDK_XOR = 2; native void initState (GtkComponentPeer component); + native void initStateUnlocked (GtkComponentPeer component); native void initState (int width, int height); native void initFromImage (GtkImage image); native void copyState (GdkGraphics g); @@ -119,6 +132,15 @@ public class GdkGraphics extends Graphics clip = new Rectangle (0, 0, d.width, d.height); } + // called back by native side: realize_cb + void initComponentGraphicsUnlocked () + { + initStateUnlocked (component); + color = component.awtComponent.getForeground (); + Dimension d = component.awtComponent.getSize (); + clip = new Rectangle (0, 0, d.width, d.height); + } + native void connectSignals (GtkComponentPeer component); public native void clearRect(int x, int y, int width, int height); @@ -327,7 +349,13 @@ public class GdkGraphics extends Graphics public void setClip (Shape clip) { - if (clip != null) + if (clip == null) + { + // Reset clipping. + Dimension d = component.awtComponent.getSize(); + setClip(new Rectangle (0, 0, d.width, d.height)); + } + else setClip(clip.getBounds()); } diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphics2D.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphics2D.java index b8203179d29..6d9aabf77d5 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphics2D.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphics2D.java @@ -45,6 +45,7 @@ import java.awt.AlphaComposite; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Composite; +import java.awt.Dimension; import java.awt.Font; import java.awt.FontMetrics; import java.awt.GradientPaint; @@ -106,8 +107,7 @@ public class GdkGraphics2D extends Graphics2D if (Configuration.INIT_LOAD_LIBRARY) System.loadLibrary("gtkpeer"); - if (GtkToolkit.useGraphics2D()) - initStaticState(); + initStaticState(); } static native void initStaticState(); @@ -132,12 +132,14 @@ public class GdkGraphics2D extends Graphics2D Composite comp; private Stack stateStack; + private native void initStateUnlocked(GtkComponentPeer component); private native void initState(GtkComponentPeer component); private native void initState(int width, int height); private native void initState(int[] pixes, int width, int height); private native void copyState(GdkGraphics2D g); public native void dispose(); private native void cairoSurfaceSetFilter(int filter); + private native void cairoSurfaceSetFilterUnlocked(int filter); native void connectSignals(GtkComponentPeer component); public void finalize() @@ -236,6 +238,21 @@ public class GdkGraphics2D extends Graphics2D stateStack = new Stack(); } + void initComponentGraphics2DUnlocked() + { + initStateUnlocked(component); + + setColorUnlocked(component.awtComponent.getForeground()); + setBackgroundUnlocked(component.awtComponent.getBackground()); + setPaintUnlocked(getColorUnlocked()); + setTransformUnlocked(new AffineTransform()); + setStrokeUnlocked(new BasicStroke()); + setRenderingHintsUnlocked(getDefaultHints()); + setFontUnlocked(new Font("SansSerif", Font.PLAIN, 12)); + + stateStack = new Stack(); + } + GdkGraphics2D(BufferedImage bimage) { this.bimage = bimage; @@ -280,25 +297,37 @@ public class GdkGraphics2D extends Graphics2D // drawing utility methods private native void drawPixels(int[] pixels, int w, int h, int stride, double[] i2u); + private native void setTexturePixelsUnlocked(int[] pixels, int w, int h, int stride); private native void setTexturePixels(int[] pixels, int w, int h, int stride); private native void setGradient(double x1, double y1, double x2, double y2, int r1, int g1, int b1, int a1, int r2, int g2, int b2, int a2, boolean cyclic); + private native void setGradientUnlocked(double x1, double y1, double x2, double y2, + int r1, int g1, int b1, int a1, int r2, + int g2, int b2, int a2, boolean cyclic); // simple passthroughs to cairo private native void cairoSave(); private native void cairoRestore(); private native void cairoSetMatrix(double[] m); + private native void cairoSetMatrixUnlocked(double[] m); private native void cairoSetOperator(int cairoOperator); private native void cairoSetRGBAColor(double red, double green, double blue, double alpha); + private native void cairoSetRGBAColorUnlocked(double red, double green, + double blue, double alpha); private native void cairoSetFillRule(int cairoFillRule); private native void cairoSetLineWidth(double width); + private native void cairoSetLineWidthUnlocked(double width); private native void cairoSetLineCap(int cairoLineCap); + private native void cairoSetLineCapUnlocked(int cairoLineCap); private native void cairoSetLineJoin(int cairoLineJoin); + private native void cairoSetLineJoinUnlocked(int cairoLineJoin); private native void cairoSetDash(double[] dashes, int ndash, double offset); + private native void cairoSetDashUnlocked(double[] dashes, int ndash, double offset); private native void cairoSetMiterLimit(double limit); + private native void cairoSetMiterLimitUnlocked(double limit); private native void cairoNewPath(); private native void cairoMoveTo(double x, double y); private native void cairoLineTo(double x, double y); @@ -689,6 +718,49 @@ public class GdkGraphics2D extends Graphics2D throw new java.lang.UnsupportedOperationException(); } + public void setPaintUnlocked(Paint p) + { + if (paint == null) + return; + + paint = p; + if (paint instanceof Color) + { + setColorUnlocked((Color) paint); + } + else if (paint instanceof TexturePaint) + { + TexturePaint tp = (TexturePaint) paint; + BufferedImage img = tp.getImage(); + + // map the image to the anchor rectangle + int width = (int) tp.getAnchorRect().getWidth(); + int height = (int) tp.getAnchorRect().getHeight(); + + double scaleX = width / (double) img.getWidth(); + double scaleY = width / (double) img.getHeight(); + + AffineTransform at = new AffineTransform(scaleX, 0, 0, scaleY, 0, 0); + AffineTransformOp op = new AffineTransformOp(at, getRenderingHints()); + BufferedImage texture = op.filter(img, null); + int[] pixels = texture.getRGB(0, 0, width, height, null, 0, width); + setTexturePixelsUnlocked(pixels, width, height, width); + } + else if (paint instanceof GradientPaint) + { + GradientPaint gp = (GradientPaint) paint; + Point2D p1 = gp.getPoint1(); + Point2D p2 = gp.getPoint2(); + Color c1 = gp.getColor1(); + Color c2 = gp.getColor2(); + setGradientUnlocked(p1.getX(), p1.getY(), p2.getX(), p2.getY(), c1.getRed(), + c1.getGreen(), c1.getBlue(), c1.getAlpha(), c2.getRed(), + c2.getGreen(), c2.getBlue(), c2.getAlpha(), gp.isCyclic()); + } + else + throw new java.lang.UnsupportedOperationException(); + } + public void setTransform(AffineTransform tx) { transform = tx; @@ -700,6 +772,17 @@ public class GdkGraphics2D extends Graphics2D } } + public void setTransformUnlocked(AffineTransform tx) + { + transform = tx; + if (transform != null) + { + double[] m = new double[6]; + transform.getMatrix(m); + cairoSetMatrixUnlocked(m); + } + } + public void transform(AffineTransform tx) { if (transform == null) @@ -784,6 +867,32 @@ public class GdkGraphics2D extends Graphics2D cairoSetDash(double_dashes, double_dashes.length, (double) bs.getDashPhase()); } + else + cairoSetDash(new double[0], 0, 0.0); + } + } + + public void setStrokeUnlocked(Stroke st) + { + stroke = st; + if (stroke instanceof BasicStroke) + { + BasicStroke bs = (BasicStroke) stroke; + cairoSetLineCapUnlocked(bs.getEndCap()); + cairoSetLineWidthUnlocked(bs.getLineWidth()); + cairoSetLineJoinUnlocked(bs.getLineJoin()); + cairoSetMiterLimitUnlocked(bs.getMiterLimit()); + float[] dashes = bs.getDashArray(); + if (dashes != null) + { + double[] double_dashes = new double[dashes.length]; + for (int i = 0; i < dashes.length; i++) + double_dashes[i] = dashes[i]; + cairoSetDashUnlocked(double_dashes, double_dashes.length, + (double) bs.getDashPhase()); + } + else + cairoSetDashUnlocked(new double[0], 0, 0.0); } } @@ -812,11 +921,27 @@ public class GdkGraphics2D extends Graphics2D fg.getBlue() / 255.0, fg.getAlpha() / 255.0); } + public void setColorUnlocked(Color c) + { + if (c == null) + c = Color.BLACK; + + fg = c; + paint = c; + cairoSetRGBAColorUnlocked(fg.getRed() / 255.0, fg.getGreen() / 255.0, + fg.getBlue() / 255.0, fg.getAlpha() / 255.0); + } + public Color getColor() { return fg; } + public Color getColorUnlocked() + { + return getColor(); + } + public void clipRect(int x, int y, int width, int height) { clip(new Rectangle(x, y, width, height)); @@ -864,7 +989,13 @@ public class GdkGraphics2D extends Graphics2D public void setClip(Shape s) { clip = s; - if (s != null) + if (clip == null) + { + // Reset clipping. + Dimension d = component.awtComponent.getSize(); + setClip(0, 0, d.width, d.height); + } + else { cairoNewPath(); if (s instanceof Rectangle2D) @@ -929,6 +1060,11 @@ public class GdkGraphics2D extends Graphics2D bg = c; } + public void setBackgroundUnlocked(Color c) + { + setBackground(c); + } + public Color getBackground() { return bg; @@ -1180,6 +1316,36 @@ public class GdkGraphics2D extends Graphics2D || hints.containsValue(RenderingHints.VALUE_STROKE_DEFAULT); } + public void setRenderingHintsUnlocked(Map hints) + { + this.hints = new RenderingHints(getDefaultHints()); + this.hints.add(new RenderingHints(hints)); + + if (hints.containsKey(RenderingHints.KEY_INTERPOLATION)) + { + if (hints.containsValue(RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR)) + cairoSurfaceSetFilterUnlocked(0); + + else if (hints.containsValue(RenderingHints.VALUE_INTERPOLATION_BILINEAR)) + cairoSurfaceSetFilterUnlocked(1); + } + + if (hints.containsKey(RenderingHints.KEY_ALPHA_INTERPOLATION)) + { + if (hints.containsValue(RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED)) + cairoSurfaceSetFilterUnlocked(2); + + else if (hints.containsValue(RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY)) + cairoSurfaceSetFilterUnlocked(3); + + else if (hints.containsValue(RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT)) + cairoSurfaceSetFilterUnlocked(4); + } + + shiftDrawCalls = hints.containsValue(RenderingHints.VALUE_STROKE_NORMALIZE) + || hints.containsValue(RenderingHints.VALUE_STROKE_DEFAULT); + } + public void addRenderingHints(Map hints) { this.hints.add(new RenderingHints(hints)); @@ -1344,6 +1510,9 @@ public class GdkGraphics2D extends Graphics2D public void drawString(String str, float x, float y) { + if (str == null || str.length() == 0) + return; + drawGlyphVector(getFont().createGlyphVector(null, str), x, y); updateBufferedImage (); } @@ -1443,6 +1612,11 @@ public class GdkGraphics2D extends Graphics2D .getFont(f.getName(), f.getAttributes()); } + public void setFontUnlocked(Font f) + { + setFont (f); + } + public String toString() { return (getClass().getName() diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphicsConfiguration.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphicsConfiguration.java index bfad87acac0..6cf7310a550 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphicsConfiguration.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphicsConfiguration.java @@ -42,6 +42,7 @@ import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; import java.awt.ImageCapabilities; import java.awt.Rectangle; +import java.awt.Toolkit; import java.awt.geom.AffineTransform; @@ -56,16 +57,11 @@ public class GdkGraphicsConfiguration ColorModel cm; Rectangle bounds; - public GtkToolkit getToolkit() - { - return gdkScreenGraphicsDevice.getToolkit(); - } - public GdkGraphicsConfiguration(GdkScreenGraphicsDevice dev) { this.gdkScreenGraphicsDevice = dev; cm = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB).getColorModel(); - bounds = getToolkit().getBounds(); + bounds = ((GtkToolkit) Toolkit.getDefaultToolkit()).getBounds(); } public GraphicsDevice getDevice() @@ -135,4 +131,10 @@ public class GdkGraphicsConfiguration return new ImageCapabilities(false); } + public VolatileImage createCompatibleVolatileImage(int width, int height, int transparency) + { + // FIXME: implement + return null; + } + } diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java index 4f9d1c27af6..4b0b5d30893 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java @@ -43,22 +43,14 @@ import java.awt.Graphics2D; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.awt.HeadlessException; +import java.awt.Toolkit; import java.awt.image.BufferedImage; import java.util.Locale; public class GdkGraphicsEnvironment extends GraphicsEnvironment { - GtkToolkit gtkToolkit; - - public GtkToolkit getToolkit() - { - return gtkToolkit; - } - - public GdkGraphicsEnvironment (GtkToolkit tk) + public GdkGraphicsEnvironment () { - super(); - gtkToolkit = tk; } public GraphicsDevice[] getScreenDevices () diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java index 57d5a36da3a..85cb1e47a9e 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java @@ -122,7 +122,7 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder super (imagedata, imageoffset, imagelength); } - // called back by native side + // called back by native side: area_prepared_cb void areaPrepared (int width, int height) { @@ -138,7 +138,7 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder } } - // called back by native side + // called back by native side: area_updated_cb void areaUpdated (int x, int y, int width, int height, int pixels[], int scansize) { @@ -306,7 +306,7 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder static String findFormatName(Object ext, boolean needWritable) { if (ext == null) - throw new IllegalArgumentException("extension is null"); + return null; if (!(ext instanceof String)) throw new IllegalArgumentException("extension is not a string"); diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkScreenGraphicsDevice.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkScreenGraphicsDevice.java index 2bf9d23db94..b5d1237a45d 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GdkScreenGraphicsDevice.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkScreenGraphicsDevice.java @@ -42,16 +42,12 @@ import java.awt.Dimension; import java.awt.DisplayMode; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; +import java.awt.Toolkit; public class GdkScreenGraphicsDevice extends GraphicsDevice { GdkGraphicsEnvironment env; - public GtkToolkit getToolkit() - { - return env.getToolkit(); - } - public GdkScreenGraphicsDevice (GdkGraphicsEnvironment e) { super (); @@ -94,7 +90,7 @@ public class GdkScreenGraphicsDevice extends GraphicsDevice public DisplayMode getDisplayMode() { // determine display mode - Dimension dim = getToolkit().getScreenSize(); + Dimension dim = Toolkit.getDefaultToolkit().getScreenSize(); DisplayMode mode = new DisplayMode(dim.width, dim.height, 0, DisplayMode.REFRESH_RATE_UNKNOWN); return mode; diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkButtonPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkButtonPeer.java index ab5df9f463f..054ead6d601 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkButtonPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkButtonPeer.java @@ -42,10 +42,14 @@ import java.awt.AWTEvent; import java.awt.Button; import java.awt.Component; import java.awt.Point; +import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.awt.peer.ButtonPeer; +// A composite widget. GtkButtons have transparent backgrounds. An +// AWT Button is opaque. To compensate, a GtkButtonPeer is a +// GtkButton packed in a GtkEventBox. public class GtkButtonPeer extends GtkComponentPeer implements ButtonPeer { @@ -61,6 +65,11 @@ public class GtkButtonPeer extends GtkComponentPeer native void gtkWidgetRequestFocus (); native void setNativeBounds (int x, int y, int width, int height); + // Because this is a composite widget, we need to retrieve the + // GtkButton's preferred dimensions, not the enclosing + // GtkEventBox's. + native void gtkWidgetGetPreferredDimensions (int[] dim); + public GtkButtonPeer (Button b) { super (b); @@ -76,32 +85,11 @@ public class GtkButtonPeer extends GtkComponentPeer gtkSetLabel(label); } - public void handleEvent (AWTEvent e) + void postActionEvent (int mods) { - if (e.getID () == MouseEvent.MOUSE_RELEASED && isEnabled ()) - { - MouseEvent me = (MouseEvent) e; - Point p = me.getPoint(); - p.translate(((Component) me.getSource()).getX(), - ((Component) me.getSource()).getY()); - if (!me.isConsumed () - && (me.getModifiersEx () & MouseEvent.BUTTON1_DOWN_MASK) != 0 - && awtComponent.getBounds().contains(p)) - postActionEvent (((Button) awtComponent).getActionCommand (), - me.getModifiersEx ()); - } - - if (e.getID () == KeyEvent.KEY_PRESSED) - { - KeyEvent ke = (KeyEvent) e; - if (!ke.isConsumed () && ke.getKeyCode () == KeyEvent.VK_SPACE) - { - postActionEvent (((Button) awtComponent).getActionCommand (), - ke.getModifiersEx ()); - gtkActivate (); - } - } - - super.handleEvent (e); + q().postEvent (new ActionEvent (awtWidget, + ActionEvent.ACTION_PERFORMED, + ((Button) awtComponent).getActionCommand (), + mods)); } } diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkCheckboxPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkCheckboxPeer.java index 851757245aa..3e05cf8ab07 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkCheckboxPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkCheckboxPeer.java @@ -49,6 +49,7 @@ public class GtkCheckboxPeer extends GtkComponentPeer public GtkCheckboxGroupPeer old_group; // The current state of the GTK checkbox. private boolean currentState; + private boolean changing = false; public native void create (GtkCheckboxGroupPeer group); public native void nativeSetCheckboxGroup (GtkCheckboxGroupPeer group); @@ -76,6 +77,15 @@ public class GtkCheckboxPeer extends GtkComponentPeer public void setState (boolean state) { + // prevent item_toggled_cb -> postItemEvent -> + // awtComponent.setState -> this.setState -> + // gtkToggleButtonSetActive self-deadlock on the GDK lock. + if (changing && Thread.currentThread() == GtkToolkit.mainThread) + { + changing = false; + return; + } + if (currentState != state) gtkToggleButtonSetActive (state); } @@ -100,6 +110,7 @@ public class GtkCheckboxPeer extends GtkComponentPeer // Override the superclass postItemEvent so that the peer doesn't // need information that we have. + // called back by native side: item_toggled_cb public void postItemEvent (Object item, int stateChange) { Checkbox currentCheckBox = ((Checkbox)awtComponent); @@ -113,6 +124,7 @@ public class GtkCheckboxPeer extends GtkComponentPeer { super.postItemEvent (awtComponent, stateChange); currentState = !currentCheckBox.getState(); + changing = true; currentCheckBox.setState(currentState); } } diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkChoicePeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkChoicePeer.java index 5028ea779c7..c140744397a 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkChoicePeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkChoicePeer.java @@ -74,8 +74,17 @@ public class GtkChoicePeer extends GtkComponentPeer native void connectSignals (); - public native void select (int position); - + native void selectNative (int position); + native void selectNativeUnlocked (int position); + + public void select (int position) + { + if (Thread.currentThread() == GtkToolkit.mainThread) + selectNativeUnlocked (position); + else + selectNative (position); + } + public void add (String item, int index) { int before = nativeGetSelected(); diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkClipboard.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkClipboard.java index c719cddb575..a502e1fd6ef 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkClipboard.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkClipboard.java @@ -38,133 +38,357 @@ exception statement from your version. */ package gnu.java.awt.peer.gtk; -import java.awt.datatransfer.Clipboard; -import java.awt.datatransfer.ClipboardOwner; -import java.awt.datatransfer.DataFlavor; -import java.awt.datatransfer.StringSelection; -import java.awt.datatransfer.Transferable; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; +import java.awt.Image; +import java.awt.datatransfer.*; + +import java.io.*; + +import java.util.List; +import java.util.Iterator; public class GtkClipboard extends Clipboard { - /* the number of milliseconds that we'll wait around for the - owner of the GDK_SELECTION_PRIMARY selection to convert - the requested data */ - static final int SELECTION_RECEIVED_TIMEOUT = 5000; - /* We currently only support transferring of text between applications */ - static String selection; - static Object selectionLock = new Object (); + // Given to the native side so it can signal special targets that + // can be converted to one of the special predefined DataFlavors. + static final String stringMimeType; + static final String imageMimeType; + static final String filesMimeType; + + // Indicates whether the results of the clipboard selection can be + // cached by GtkSelection. True if + // gdk_display_supports_selection_notification. + static final boolean canCache; + + static + { + stringMimeType = DataFlavor.stringFlavor.getMimeType(); + imageMimeType = DataFlavor.imageFlavor.getMimeType(); + filesMimeType = DataFlavor.javaFileListFlavor.getMimeType(); + + canCache = initNativeState(stringMimeType, imageMimeType, filesMimeType); + } - static boolean hasSelection = false; + /** + * The one and only gtk+ clipboard instance. + */ + private static GtkClipboard instance = new GtkClipboard(); - protected GtkClipboard() + /** + * Creates the clipboard and sets the initial contents to the + * current gtk+ selection. + */ + private GtkClipboard() { super("System Clipboard"); - initNativeState(); + setContents(new GtkSelection(), null); + } + + /** + * Returns the one and only GtkClipboard instance. + */ + + static GtkClipboard getInstance() + { + return instance; } - public Transferable getContents(Object requestor) + /** + * Sets the GtkSelection facade as new contents of the clipboard. + * Called from gtk+ when another application grabs the clipboard and + * we loose ownership. + */ + private static void setSystemContents() { - synchronized (this) + GtkClipboardNotifier.announce(); + } + + /** + * Sets the new contents and advertises the available flavors to the + * gtk+ clipboard. + */ + public synchronized void setContents(Transferable contents, + ClipboardOwner owner) + { + super.setContents(contents, owner); + + if (contents == null) { - if (hasSelection) - return contents; + advertiseContent(null, false, false, false); + return; } - /* Java doesn't own the selection, so we need to ask X11 */ - // XXX: Does this hold with Swing too ? - synchronized (selectionLock) + // We don't need to do anything for a GtkSelection facade. + if (contents instanceof GtkSelection) + return; + + boolean text = false; + boolean images = false; + boolean files = false; + + if (contents instanceof StringSelection + || contents.isDataFlavorSupported(DataFlavor.stringFlavor) + || contents.isDataFlavorSupported(DataFlavor.plainTextFlavor) + || contents.isDataFlavorSupported(DataFlavor + .getTextPlainUnicodeFlavor())) + text = true; + + DataFlavor[] flavors = contents.getTransferDataFlavors(); + String[] mimeTargets = new String[flavors.length]; + for (int i = 0; i < flavors.length; i++) { - requestStringConversion(); - - try - { - selectionLock.wait(SELECTION_RECEIVED_TIMEOUT); - } - catch (InterruptedException e) + DataFlavor flavor = flavors[i]; + String mimeType = flavor.getMimeType(); + mimeTargets[i] = mimeType; + + if (! text) + if ("text".equals(flavor.getPrimaryType()) + || flavor.isRepresentationClassReader()) + text = true; + + // XXX - We only support automatic image conversion for + // GtkImages at the moment. So explicitly check that we have + // one. + if (! images && flavors[i].equals(DataFlavor.imageFlavor)) { - return null; + try + { + Object o = contents.getTransferData(DataFlavor.imageFlavor); + if (o instanceof GtkImage) + images = true; + } + catch (UnsupportedFlavorException ufe) + { + } + catch (IOException ioe) + { + } + catch (ClassCastException cce) + { + } } - - return selection == null ? null : new StringSelection(selection); + + if (flavors[i].equals(DataFlavor.javaFileListFlavor)) + files = true; } + + advertiseContent(mimeTargets, text, images, files); } - void stringSelectionReceived(String newSelection) + /** + * Advertises new contents to the gtk+ clipboard given a string + * array of (mime-type) targets. When the boolean flags text, images + * and/or files are set then gtk+ is asked to also advertise the + * availability of any text, image or uri/file content types it + * supports. If targets is null (and all flags false) then the + * selection has explicitly been erased. + */ + private native void advertiseContent(String[] targets, + boolean text, + boolean images, + boolean files); + + /** + * Called by the gtk+ clipboard when an application has requested + * text. Return a string representing the current clipboard + * contents or null when no text can be provided. + */ + private String provideText() { - synchronized (selectionLock) + Transferable contents = this.contents; + if (contents == null || contents instanceof GtkSelection) + return null; + + // Handle StringSelection special since that is just pure text. + if (contents instanceof StringSelection) { - selection = newSelection; - selectionLock.notify(); + try + { + return (String) contents.getTransferData(DataFlavor.stringFlavor); + } + catch (UnsupportedFlavorException ufe) + { + } + catch (IOException ioe) + { + } + catch (ClassCastException cce) + { + } } - } - - /* convert Java clipboard data into a String suitable for sending - to another application */ - synchronized String stringSelectionHandler() throws IOException - { - String selection = null; + // Try to get a plain text reader for the current contents and + // turn the result into a string. try { - if (contents.isDataFlavorSupported(DataFlavor.stringFlavor)) - selection = (String)contents.getTransferData(DataFlavor.stringFlavor); - else if (contents.isDataFlavorSupported(DataFlavor.plainTextFlavor)) + DataFlavor plainText = DataFlavor.getTextPlainUnicodeFlavor(); + Reader r = plainText.getReaderForText(contents); + if (r != null) { - StringBuffer sbuf = new StringBuffer(); - InputStreamReader reader; - char readBuf[] = new char[512]; - int numChars; - - reader = new InputStreamReader - ((InputStream) - contents.getTransferData(DataFlavor.plainTextFlavor), "UNICODE"); - - while (true) + StringBuffer sb = new StringBuffer(); + char[] cs = new char[1024]; + int l = r.read(cs); + while (l != -1) { - numChars = reader.read(readBuf); - if (numChars == -1) - break; - sbuf.append(readBuf, 0, numChars); + sb.append(cs, 0, l); + l = r.read(cs); } - - selection = new String(sbuf); + return sb.toString(); } } - catch (Exception e) + catch (IllegalArgumentException iae) + { + } + catch (UnsupportedEncodingException iee) { } - - return selection; + catch (UnsupportedFlavorException ufe) + { + } + catch (IOException ioe) + { + } + + return null; } - public synchronized void setContents(Transferable contents, - ClipboardOwner owner) + /** + * Called by the gtk+ clipboard when an application has requested an + * image. Returns a GtkImage representing the current clipboard + * contents or null when no image can be provided. + */ + private GtkImage provideImage() + { + Transferable contents = this.contents; + if (contents == null || contents instanceof GtkSelection) + return null; + + try + { + return (GtkImage) contents.getTransferData(DataFlavor.imageFlavor); + } + catch (UnsupportedFlavorException ufe) + { + } + catch (IOException ioe) + { + } + catch (ClassCastException cce) + { + } + + return null; + } + + /** + * Called by the gtk+ clipboard when an application has requested a + * uri-list. Return a string array containing the URIs representing + * the current clipboard contents or null when no URIs can be + * provided. + */ + private String[] provideURIs() { - selectionGet(); + Transferable contents = this.contents; + if (contents == null || contents instanceof GtkSelection) + return null; - this.contents = contents; - this.owner = owner; + try + { + List list = (List) contents.getTransferData + (DataFlavor.javaFileListFlavor); + String[] uris = new String[list.size()]; + int u = 0; + Iterator it = list.iterator(); + while (it.hasNext()) + uris[u++] = ((File) it.next()).toURI().toString(); + return uris; + } + catch (UnsupportedFlavorException ufe) + { + } + catch (IOException ioe) + { + } + catch (ClassCastException cce) + { + } - hasSelection = true; + return null; } - synchronized void selectionClear() + /** + * Called by gtk+ clipboard when an application requests the given + * target mime-type. Returns a byte array containing the requested + * data, or null when the contents cannot be provided in the + * requested target mime-type. Only called after any explicit text, + * image or file/uri requests have been handled earlier and failed. + */ + private byte[] provideContent(String target) { - hasSelection = false; + // Sanity check. The callback could be triggered just after we + // changed the clipboard. + Transferable contents = this.contents; + if (contents == null || contents instanceof GtkSelection) + return null; + + // XXX - We are being called from a gtk+ callback. Which means we + // should return as soon as possible and not call arbitrary code + // that could deadlock or go bonkers. But we don't really know + // what DataTransfer contents object we are dealing with. Same for + // the other provideXXX() methods. + try + { + DataFlavor flavor = new DataFlavor(target); + Object o = contents.getTransferData(flavor); + + if (o instanceof byte[]) + return (byte[]) o; + + if (o instanceof InputStream) + { + InputStream is = (InputStream) o; + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + byte[] bs = new byte[1024]; + int l = is.read(bs); + while (l != -1) + { + baos.write(bs, 0, l); + l = is.read(bs); + } + return baos.toByteArray(); + } - if (owner != null) + if (o instanceof Serializable) + { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos); + oos.writeObject(o); + oos.close(); + return baos.toByteArray(); + } + } + catch (ClassNotFoundException cnfe) + { + } + catch (UnsupportedFlavorException ufe) { - owner.lostOwnership(this, contents); - owner = null; - contents = null; } + catch (IOException ioe) + { + } + catch (ClassCastException cce) + { + } + + return null; } - native void initNativeState(); - static native void requestStringConversion(); - static native void selectionGet(); + /** + * Initializes the gtk+ clipboard and caches any native side + * structures needed. Returns whether or not the contents of the + * Clipboard can be cached (gdk_display_supports_selection_notification). + */ + private static native boolean initNativeState(String stringTarget, + String imageTarget, + String filesTarget); } diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkComponentPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkComponentPeer.java index 1578a9cfc3c..60e8371277f 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkComponentPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkComponentPeer.java @@ -70,6 +70,9 @@ import java.awt.image.ImageObserver; import java.awt.image.ImageProducer; import java.awt.image.VolatileImage; import java.awt.peer.ComponentPeer; +import java.awt.peer.ContainerPeer; +import java.util.Timer; +import java.util.TimerTask; public class GtkComponentPeer extends GtkGenericPeer implements ComponentPeer @@ -83,6 +86,8 @@ public class GtkComponentPeer extends GtkGenericPeer boolean isInRepaint; + static final Timer repaintTimer = new Timer (true); + /* this isEnabled differs from Component.isEnabled, in that it knows if a parent is disabled. In that case Component.isEnabled may return true, but our isEnabled will always return false */ @@ -95,6 +100,7 @@ public class GtkComponentPeer extends GtkGenericPeer native void gtkWidgetGetPreferredDimensions (int[] dim); native void gtkWidgetGetLocationOnScreen (int[] point); native void gtkWidgetSetCursor (int type); + native void gtkWidgetSetCursorUnlocked (int type); native void gtkWidgetSetBackground (int red, int green, int blue); native void gtkWidgetSetForeground (int red, int green, int blue); native void gtkWidgetSetSensitive (boolean sensitive); @@ -372,8 +378,26 @@ public class GtkComponentPeer extends GtkGenericPeer if (x == 0 && y == 0 && width == 0 && height == 0) return; - q().postEvent (new PaintEvent (awtComponent, PaintEvent.UPDATE, - new Rectangle (x, y, width, height))); + repaintTimer.schedule(new RepaintTimerTask(x, y, width, height), tm); + } + + private class RepaintTimerTask extends TimerTask + { + private int x, y, width, height; + + RepaintTimerTask(int x, int y, int width, int height) + { + this.x = x; + this.y = y; + this.width = width; + this.height = height; + } + + public void run() + { + q().postEvent (new PaintEvent (awtComponent, PaintEvent.UPDATE, + new Rectangle (x, y, width, height))); + } } public void requestFocus () @@ -396,7 +420,11 @@ public class GtkComponentPeer extends GtkGenericPeer public void setBounds (int x, int y, int width, int height) { + int new_x = x; + int new_y = y; + Component parent = awtComponent.getParent (); + Component next_parent; // Heavyweight components that are children of one or more // lightweight containers have to be handled specially. Because @@ -414,30 +442,44 @@ public class GtkComponentPeer extends GtkGenericPeer { lightweightChild = true; + next_parent = parent.getParent (); + i = ((Container) parent).getInsets (); - x += parent.getX () + i.left; - y += parent.getY () + i.top; + if (next_parent instanceof Window) + { + new_x += i.left; + new_y += i.top; + } + else + { + new_x += parent.getX () + i.left; + new_y += parent.getY () + i.top; + } - parent = parent.getParent (); + parent = next_parent; } // We only need to convert from Java to GTK coordinates if we're // placing a heavyweight component in a Window. if (parent instanceof Window && !lightweightChild) { - Insets insets = ((Window) parent).getInsets (); GtkWindowPeer peer = (GtkWindowPeer) parent.getPeer (); + // important: we want the window peer's insets here, not the + // window's, since user sub-classes of Window can override + // getInset and we only want to correct for the frame borders, + // not for any user-defined inset values + Insets insets = peer.getInsets (); + int menuBarHeight = 0; if (peer instanceof GtkFramePeer) menuBarHeight = ((GtkFramePeer) peer).getMenuBarHeight (); - // Convert from Java coordinates to GTK coordinates. - setNativeBounds (x - insets.left, y - insets.top + menuBarHeight, - width, height); + new_x = x - insets.left; + new_y = y - insets.top + menuBarHeight; } - else - setNativeBounds (x, y, width, height); + + setNativeBounds (new_x, new_y, width, height); } void setCursor () @@ -447,7 +489,10 @@ public class GtkComponentPeer extends GtkGenericPeer public void setCursor (Cursor cursor) { - gtkWidgetSetCursor (cursor.getType ()); + if (Thread.currentThread() == GtkToolkit.mainThread) + gtkWidgetSetCursorUnlocked (cursor.getType ()); + else + gtkWidgetSetCursor (cursor.getType ()); } public void setEnabled (boolean b) @@ -480,16 +525,26 @@ public class GtkComponentPeer extends GtkGenericPeer return new Color (rgb[0], rgb[1], rgb[2]); } + public native void setVisibleNative (boolean b); + public native void setVisibleNativeUnlocked (boolean b); + public void setVisible (boolean b) { - if (b) - show (); + if (Thread.currentThread() == GtkToolkit.mainThread) + setVisibleNativeUnlocked (b); else - hide (); + setVisibleNative (b); + } + + public void hide () + { + setVisible (false); } - public native void hide (); - public native void show (); + public void show () + { + setVisible (true); + } protected void postMouseEvent(int id, long when, int mods, int x, int y, int clickCount, boolean popupTrigger) @@ -586,7 +641,8 @@ public class GtkComponentPeer extends GtkGenericPeer public void updateCursorImmediately () { - + if (awtComponent.getCursor() != null) + setCursor(awtComponent.getCursor()); } public boolean handlesWheelScrolling () @@ -648,4 +704,36 @@ public class GtkComponentPeer extends GtkGenericPeer { backBuffer.flush(); } + + public String toString () + { + return "peer of " + awtComponent.toString(); + } + public Rectangle getBounds() + { + // FIXME: implement + return null; + } + public void reparent(ContainerPeer parent) + { + // FIXME: implement + + } + public void setBounds(int x, int y, int width, int height, int z) + { + // FIXME: implement + setBounds (x, y, width, height); + + } + public boolean isReparentSupported() + { + // FIXME: implement + + return false; + } + public void layout() + { + // FIXME: implement + + } } diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkContainerPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkContainerPeer.java index c2865f70f61..b035a9814c7 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkContainerPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkContainerPeer.java @@ -52,7 +52,6 @@ public class GtkContainerPeer extends GtkComponentPeer implements ContainerPeer { Container c; - boolean isValidating; public GtkContainerPeer(Container c) { @@ -62,7 +61,6 @@ public class GtkContainerPeer extends GtkComponentPeer public void beginValidate () { - isValidating = true; } public void endValidate () @@ -90,8 +88,6 @@ public class GtkContainerPeer extends GtkComponentPeer if (!(awtComponent instanceof Window)) setParentAndBounds (); } - - isValidating = false; } public Insets getInsets() @@ -153,4 +149,21 @@ public class GtkContainerPeer extends GtkComponentPeer comp.getPeer().setBackground(c); } } + + public boolean isRestackSupported() + { + // FIXME: implement + return false; + } + + public void cancelPendingPaint(int x, int y, int width, int height) + { + // FIXME: implement + } + + public void restack() + { + //FIXME: implement + + } } diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkFileDialogPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkFileDialogPeer.java index bd1f0775a92..333407b247f 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkFileDialogPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkFileDialogPeer.java @@ -42,6 +42,7 @@ import java.awt.Dialog; import java.awt.FileDialog; import java.awt.Graphics; import java.awt.Window; +import java.awt.event.ComponentEvent; import java.awt.peer.FileDialogPeer; import java.io.File; import java.io.FilenameFilter; @@ -54,7 +55,7 @@ public class GtkFileDialogPeer extends GtkDialogPeer implements FileDialogPeer private String currentDirectory = null; private FilenameFilter filter; - native void create (GtkContainerPeer parent); + native void create (GtkContainerPeer parent, int mode); native void connectSignals (); native void nativeSetFile (String file); public native String nativeGetDirectory(); @@ -63,7 +64,8 @@ public class GtkFileDialogPeer extends GtkDialogPeer implements FileDialogPeer public void create() { - create((GtkContainerPeer) awtComponent.getParent().getPeer()); + create((GtkContainerPeer) awtComponent.getParent().getPeer(), + ((FileDialog) awtComponent).getMode()); FileDialog fd = (FileDialog) awtComponent; @@ -87,10 +89,10 @@ public class GtkFileDialogPeer extends GtkDialogPeer implements FileDialogPeer { int[] dims = new int[2]; gtkWidgetGetPreferredDimensions (dims); - ((GtkFileDialogPeer) this).setBoundsCallback ((Window) awtComponent, - awtComponent.getX (), - awtComponent.getY (), - dims[0], dims[1]); + + if (dims[0] != awtComponent.getWidth() + || dims[1] != awtComponent.getHeight()) + awtComponent.setSize(dims[0], dims[1]); } super.setComponentBounds (); } @@ -155,6 +157,7 @@ public class GtkFileDialogPeer extends GtkDialogPeer implements FileDialogPeer GtkFileFilterInfo object and send it to this method, which will in turn call the filter's accept() method and give back the return value. */ + // called back by native side: filename_filter_cb boolean filenameFilterCallback (String fullname) { String filename = fullname.substring(fullname.lastIndexOf(FS) + 1); String dirname = fullname.substring(0, fullname.lastIndexOf(FS)); @@ -167,20 +170,25 @@ public class GtkFileDialogPeer extends GtkDialogPeer implements FileDialogPeer // GtkFileDialog will repaint by itself return null; } - + + // called back by native side: handle_response_cb + // only called from the GTK thread void gtkHideFileDialog () { + // hide calls back the peer's setVisible method, so locking is a + // problem. ((Dialog) awtComponent).hide(); } + // called back by native side: handle_response_cb void gtkDisposeFileDialog () { ((Dialog) awtComponent).dispose(); } - /* Callback to set the file and directory values when the user is finished - * with the dialog. - */ + // Callback to set the file and directory values when the user is finished + // with the dialog. + // called back by native side: handle_response_cb void gtkSetFilename (String fileName) { FileDialog fd = (FileDialog) awtWidget; diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkFramePeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkFramePeer.java index b242d66adcb..6eb90ffa0bd 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkFramePeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkFramePeer.java @@ -44,6 +44,7 @@ import java.awt.Image; import java.awt.MenuBar; import java.awt.Rectangle; import java.awt.Window; +import java.awt.event.ComponentEvent; import java.awt.event.PaintEvent; import java.awt.image.ColorModel; import java.awt.peer.FramePeer; @@ -55,6 +56,7 @@ public class GtkFramePeer extends GtkWindowPeer private int menuBarHeight; private MenuBarPeer menuBar; native int getMenuBarHeight (MenuBarPeer bar); + native void setMenuBarWidthUnlocked (MenuBarPeer bar, int width); native void setMenuBarWidth (MenuBarPeer bar, int width); native void setMenuBarPeer (MenuBarPeer bar); native void removeMenuBarPeer (); @@ -117,6 +119,17 @@ public class GtkFramePeer extends GtkWindowPeer public void setBounds (int x, int y, int width, int height) { + // prevent window_configure_cb -> awtComponent.setSize -> + // peer.setBounds -> nativeSetBounds self-deadlock on GDK lock. + if (Thread.currentThread() == GtkToolkit.mainThread) + { + int menuBarWidth = width - insets.left - insets.right; + if (menuBar != null && menuBarWidth > 0) + setMenuBarWidthUnlocked (menuBar, menuBarWidth); + + return; + } + int menuBarWidth = width - insets.left - insets.right; if (menuBar != null && menuBarWidth > 0) setMenuBarWidth (menuBar, menuBarWidth); @@ -192,31 +205,25 @@ public class GtkFramePeer extends GtkWindowPeer protected void postConfigureEvent (int x, int y, int width, int height) { - int frame_x = x - insets.left; - // Since insets.top includes the MenuBar height, we need to add back - // the MenuBar height to the frame's y position. - // If no MenuBar exists in this frame, the MenuBar height will be 0. - int frame_y = y - insets.top + menuBarHeight; int frame_width = width + insets.left + insets.right; - // Ditto as above. Since insets.top already includes the MenuBar's height, - // we need to subtract the MenuBar's height from the top inset. + // Since insets.top already includes the MenuBar's height, we need + // to subtract the MenuBar's height from the top inset. int frame_height = height + insets.top + insets.bottom - menuBarHeight; - if (frame_x != awtComponent.getX() - || frame_y != awtComponent.getY() - || frame_width != awtComponent.getWidth() + + if (frame_width != awtComponent.getWidth() || frame_height != awtComponent.getHeight()) - { - if (frame_width != awtComponent.getWidth() && menuBar != null - && width > 0) - setMenuBarWidth (menuBar, width); + awtComponent.setSize(frame_width, frame_height); - setBoundsCallback ((Window) awtComponent, - frame_x, - frame_y, - frame_width, - frame_height); + int frame_x = x - insets.left; + // Likewise, since insets.top includes the MenuBar height, we need + // to add back the MenuBar height to the frame's y position. If + // no MenuBar exists in this frame, the MenuBar height will be 0. + int frame_y = y - insets.top + menuBarHeight; - awtComponent.validate(); + if (frame_x != awtComponent.getX() + || frame_y != awtComponent.getY()) + { + // awtComponent.setLocation(frame_x, frame_y); } } @@ -251,6 +258,21 @@ public class GtkFramePeer extends GtkWindowPeer { } + 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/gtk/GtkImage.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkImage.java index abb4137f4ae..82a346304ea 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkImage.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkImage.java @@ -51,7 +51,10 @@ import java.io.File; import java.io.IOException; import java.util.Hashtable; import java.util.Vector; -import gnu.classpath.RawData; +import java.io.ByteArrayOutputStream; +import java.io.BufferedInputStream; +import java.net.URL; +import gnu.classpath.Pointer; /** * GtkImage - wraps a GdkPixbuf or GdkPixmap. @@ -87,7 +90,7 @@ public class GtkImage extends Image /** * Pointer to the GdkPixbuf */ - RawData pixmap; + Pointer pixmap; /** * Observer queue. @@ -129,11 +132,16 @@ public class GtkImage extends Image private native void setPixels(int[] pixels); /** - * Loads an image using gdk-pixbuf. + * Loads an image using gdk-pixbuf from a file. */ private native boolean loadPixbuf(String name); /** + * Loads an image using gdk-pixbuf from data. + */ + private native boolean loadImageFromData(byte[] data); + + /** * Allocates a Gtk Pixbuf or pixmap */ private native void createPixmap(); @@ -187,6 +195,21 @@ public class GtkImage extends Image } /** + * Constructs a blank GtkImage. This is called when + * GtkToolkit.createImage (String) is called with an empty string + * argument (""). A blank image is loaded immediately upon + * construction and has width -1 and height -1. + */ + public GtkImage () + { + isLoaded = true; + observers = null; + offScreen = false; + props = new Hashtable(); + errorLoading = false; + } + + /** * Constructs a GtkImage by loading a given file. * * @throws IllegalArgumentException if the image could not be loaded. @@ -211,6 +234,58 @@ public class GtkImage extends Image } /** + * Constructs a GtkImage from a byte array of an image file. + * + * @throws IllegalArgumentException if the image could not be + * loaded. + */ + public GtkImage (byte[] data) + { + if (loadImageFromData (data) != true) + throw new IllegalArgumentException ("Couldn't load image."); + + isLoaded = true; + observers = null; + offScreen = false; + props = new Hashtable(); + errorLoading = false; + } + + /** + * Constructs a GtkImage from a URL. May result in an error image. + */ + public GtkImage (URL url) + { + 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 an empty GtkImage. */ public GtkImage (int width, int height) @@ -241,6 +316,25 @@ public class GtkImage extends Image } /** + * Package private constructor to create a GtkImage from a given + * PixBuf pointer. + */ + GtkImage (Pointer pixbuf) + { + pixmap = pixbuf; + createFromPixbuf(); + isLoaded = true; + observers = null; + offScreen = false; + props = new Hashtable(); + } + + /** + * Native helper function for constructor that takes a pixbuf Pointer. + */ + private native void createFromPixbuf(); + + /** * Callback from the image consumer. */ public void setImage(int width, int height, diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkImageConsumer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkImageConsumer.java index 564cc8d668c..299f01dcaa6 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkImageConsumer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkImageConsumer.java @@ -45,6 +45,7 @@ import java.awt.image.DirectColorModel; import java.awt.image.ImageConsumer; import java.awt.image.ImageObserver; import java.awt.image.ImageProducer; +import java.awt.image.MemoryImageSource; import java.util.Hashtable; import java.util.Vector; @@ -70,7 +71,10 @@ public class GtkImageConsumer implements ImageConsumer public synchronized void imageComplete (int status) { - source.removeConsumer(this); + // we need to reuse the pixel cache for memory image sources since + // a memory image's backing array can be updated "live". + if (!(source instanceof MemoryImageSource)) + source.removeConsumer(this); target.setImage(width, height, pixelCache, properties); } diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkLabelPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkLabelPeer.java index fdd5fd15f63..3d099e9ca00 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkLabelPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkLabelPeer.java @@ -41,6 +41,9 @@ package gnu.java.awt.peer.gtk; import java.awt.Label; import java.awt.peer.LabelPeer; +// A composite widget. GtkLabels have transparent backgrounds. An +// AWT Label is opaque. To compensate, a GtkLabelPeer is a GtkLabel +// packed in a GtkEventBox. public class GtkLabelPeer extends GtkComponentPeer implements LabelPeer { @@ -51,6 +54,10 @@ public class GtkLabelPeer extends GtkComponentPeer public native void setText(String text); native void setNativeBounds (int x, int y, int width, int height); + // Because this is a composite widget, we need to retrieve the + // GtkLabel's preferred dimensions, not the enclosing GtkEventBox's. + native void gtkWidgetGetPreferredDimensions (int[] dim); + void create () { Label label = (Label) awtComponent; diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuBarPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuBarPeer.java index 79eeaf9ba6a..a1a1cbd6d7c 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuBarPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuBarPeer.java @@ -77,4 +77,9 @@ public class GtkMenuBarPeer extends GtkMenuComponentPeer } public native void delMenu(int index); + + public void addMenu (Menu m) + { + // FIXME: implement + } } diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuComponentPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuComponentPeer.java index 8d9d1ca04a0..4c6335933a8 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuComponentPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuComponentPeer.java @@ -38,6 +38,7 @@ exception statement from your version. */ package gnu.java.awt.peer.gtk; +import java.awt.Font; import java.awt.peer.MenuComponentPeer; public class GtkMenuComponentPeer extends GtkGenericPeer @@ -60,4 +61,9 @@ public class GtkMenuComponentPeer extends GtkGenericPeer } public native void dispose(); + + public void setFont(Font font) + { + // FIXME: implement + } } diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuPeer.java index 80332dd6a72..fabcf1f090b 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuPeer.java @@ -100,4 +100,9 @@ public class GtkMenuPeer extends GtkMenuItemPeer } public native void delItem(int index); + + public void addSeparator() + { + // FIXME: implement + } } diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkTextAreaPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkTextAreaPeer.java index a842b8318a2..e6896c9136c 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkTextAreaPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkTextAreaPeer.java @@ -43,6 +43,7 @@ import java.awt.Font; import java.awt.FontMetrics; import java.awt.Rectangle; import java.awt.TextArea; +import java.awt.im.InputMethodRequests; import java.awt.peer.TextAreaPeer; import java.awt.peer.TextComponentPeer; @@ -209,4 +210,10 @@ public class GtkTextAreaPeer extends GtkComponentPeer { insert (str, pos); } + + public InputMethodRequests getInputMethodRequests() + { + // FIXME: implement + return null; + } } diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkTextFieldPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkTextFieldPeer.java index 73a976bba6d..4afdae82e5e 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkTextFieldPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkTextFieldPeer.java @@ -45,6 +45,7 @@ import java.awt.FontMetrics; import java.awt.Rectangle; import java.awt.TextField; import java.awt.event.KeyEvent; +import java.awt.im.InputMethodRequests; import java.awt.peer.TextFieldPeer; import java.awt.peer.TextComponentPeer; @@ -193,4 +194,9 @@ public class GtkTextFieldPeer extends GtkComponentPeer super.handleEvent (e); } + public InputMethodRequests getInputMethodRequests() + { + // FIXME: implement + return null; + } } diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkToolkit.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkToolkit.java index 69901102faf..0889d85f4bc 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkToolkit.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkToolkit.java @@ -88,9 +88,9 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit { Hashtable containers = new Hashtable(); static EventQueue q; - static Clipboard systemClipboard; static boolean useGraphics2dSet; static boolean useGraphics2d; + static Thread mainThread; public static boolean useGraphics2D() { @@ -121,11 +121,19 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit portableNativeSync = 0; // false gtkInit(portableNativeSync); + + mainThread = new Thread ("GTK main thread") + { + public void run () + { + gtkMain (); + } + }; + mainThread.start (); } public GtkToolkit () { - systemClipboard = new GtkClipboard (); } public native void beep(); @@ -244,6 +252,9 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit public Image createImage (String filename) { + if (filename.length() == 0) + return new GtkImage (); + if (useGraphics2D()) return bufferedImageOrError(GdkPixbufDecoder.createBufferedImage (filename)); else @@ -255,11 +266,7 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit if (useGraphics2D()) return bufferedImageOrError(GdkPixbufDecoder.createBufferedImage (url)); else - { - GdkPixbufDecoder d = new GdkPixbufDecoder (url); - GtkImage image = new GtkImage (d); - return image; - } + return new GtkImage (url); } public Image createImage (ImageProducer producer) @@ -279,11 +286,9 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit imagelength)); else { - GdkPixbufDecoder d = new GdkPixbufDecoder (imagedata, - imageoffset, - imagelength); - GtkImage image = new GtkImage (d); - return image; + byte[] datacopy = new byte[imagelength]; + System.arraycopy (imagedata, imageoffset, datacopy, 0, imagelength); + return new GtkImage (datacopy); } } @@ -395,7 +400,11 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit public Clipboard getSystemClipboard() { - return systemClipboard; + SecurityManager secman = System.getSecurityManager(); + if (secman != null) + secman.checkSystemClipboardAccess(); + + return GtkClipboard.getInstance(); } /** @@ -628,7 +637,7 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit public GraphicsEnvironment getLocalGraphicsEnvironment() { - return new GdkGraphicsEnvironment(this); + return new GdkGraphicsEnvironment(); } public Font createFont(int format, InputStream stream) @@ -646,8 +655,5 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit GdkPixbufDecoder.registerSpis(reg); } - public native boolean nativeQueueEmpty(); - public native void wakeNativeQueue(); - public native void iterateNativeQueue(EventQueue locked, boolean block); - + public static native void gtkMain(); } // class GtkToolkit diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkWindowPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkWindowPeer.java index 71e05a87dad..c84d51037e3 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkWindowPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkWindowPeer.java @@ -41,6 +41,7 @@ package gnu.java.awt.peer.gtk; import java.awt.Component; import java.awt.Frame; import java.awt.Window; +import java.awt.event.ComponentEvent; import java.awt.event.WindowEvent; import java.awt.peer.WindowPeer; @@ -104,6 +105,9 @@ public class GtkWindowPeer extends GtkContainerPeer { } + public native void setVisibleNative (boolean b); + public native void setVisibleNativeUnlocked (boolean b); + native void connectSignals (); public GtkWindowPeer (Window window) @@ -115,14 +119,27 @@ public class GtkWindowPeer extends GtkContainerPeer public native void toFront(); native void nativeSetBounds (int x, int y, int width, int height); + native void nativeSetBoundsUnlocked (int x, int y, int width, int height); public void setBounds (int x, int y, int width, int height) { + // prevent window_configure_cb -> awtComponent.setSize -> + // peer.setBounds -> nativeSetBounds self-deadlock on GDK lock. + if (Thread.currentThread() == GtkToolkit.mainThread) + return; + nativeSetBounds (x, y, width - insets.left - insets.right, height - insets.top - insets.bottom); } + public void setBoundsUnlocked (int x, int y, int width, int height) + { + nativeSetBoundsUnlocked (x, y, + width - insets.left - insets.right, + height - insets.top - insets.bottom); + } + public void setTitle (String title) { gtkWindowSetTitle (title); @@ -140,10 +157,6 @@ public class GtkWindowPeer extends GtkContainerPeer gtkWindowSetResizable (resizable); } - native void setBoundsCallback (Window window, - int x, int y, - int width, int height); - protected void postInsetsChangedEvent (int top, int left, int bottom, int right) { @@ -153,36 +166,36 @@ public class GtkWindowPeer extends GtkContainerPeer insets.right = right; } + // called back by native side: window_configure_cb + // only called from GTK thread protected void postConfigureEvent (int x, int y, int width, int height) { - int frame_x = x - insets.left; - int frame_y = y - insets.top; int frame_width = width + insets.left + insets.right; int frame_height = height + insets.top + insets.bottom; - if (frame_x != awtComponent.getX() - || frame_y != awtComponent.getY() - || frame_width != awtComponent.getWidth() + if (frame_width != awtComponent.getWidth() || frame_height != awtComponent.getHeight()) - { - setBoundsCallback ((Window) awtComponent, - frame_x, frame_y, frame_width, frame_height); + awtComponent.setSize(frame_width, frame_height); - awtComponent.validate(); + int frame_x = x - insets.left; + int frame_y = y - insets.top; + + if (frame_x != awtComponent.getX() + || frame_y != awtComponent.getY()) + { + // awtComponent.setLocation(frame_x, frame_y); } } - native void nativeSetVisible (boolean b); - public void setVisible (boolean b) + public void show () { // Prevent the window manager from automatically placing this // window when it is shown. - if (b) - setBounds (awtComponent.getX(), - awtComponent.getY(), - awtComponent.getWidth(), - awtComponent.getHeight()); - nativeSetVisible (b); + setBounds (awtComponent.getX(), + awtComponent.getY(), + awtComponent.getWidth(), + awtComponent.getHeight()); + setVisible (true); } void postWindowEvent (int id, Window opposite, int newState) @@ -209,4 +222,14 @@ public class GtkWindowPeer extends GtkContainerPeer else q().postEvent (new WindowEvent ((Window) awtComponent, id, opposite)); } + 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/nio/FileLockImpl.java b/libjava/classpath/gnu/java/nio/FileLockImpl.java index 245fa73402a..673ca2522df 100644 --- a/libjava/classpath/gnu/java/nio/FileLockImpl.java +++ b/libjava/classpath/gnu/java/nio/FileLockImpl.java @@ -1,5 +1,5 @@ -/* FileLockImpl.java -- - Copyright (C) 2002, 2004 Free Software Foundation, Inc. +/* FileLockImpl.java -- FileLock associated with a FileChannelImpl. + Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -44,20 +44,29 @@ import java.io.IOException; import java.nio.channels.FileLock; /** + * A FileLock associated with a FileChannelImpl. + * * @author Michael Koch * @since 1.4 */ -public class FileLockImpl extends FileLock +public final class FileLockImpl extends FileLock { - private FileChannelImpl ch; - + /** + * Whether or not this lock is valid, false when channel is closed or + * release has been explicitly called. + */ + private boolean valid; + public FileLockImpl (FileChannelImpl channel, long position, long size, boolean shared) { super (channel, position, size, shared); - ch = channel; + valid = true; } + /** + * Releases this lock. + */ protected void finalize() { try @@ -70,13 +79,26 @@ public class FileLockImpl extends FileLock } } - public boolean isValid () + /** + * Whether or not this lock is valid, false when channel is closed or + * release has been explicitly called. + */ + public boolean isValid() { - return channel().isOpen(); + if (valid) + valid = channel().isOpen(); + return valid; } - public synchronized void release () throws IOException + /** + * Releases the lock if it is still valid. Marks this lock as invalid. + */ + public void release() throws IOException { - ch.unlock(position(), size()); + if (isValid()) + { + valid = false; + ((FileChannelImpl) channel()).unlock(position(), size()); + } } } diff --git a/libjava/classpath/gnu/java/nio/channels/FileChannelImpl.java b/libjava/classpath/gnu/java/nio/channels/FileChannelImpl.java index a87a2e8c597..0ee5d3fc287 100644 --- a/libjava/classpath/gnu/java/nio/channels/FileChannelImpl.java +++ b/libjava/classpath/gnu/java/nio/channels/FileChannelImpl.java @@ -73,6 +73,10 @@ public final class FileChannelImpl extends FileChannel public static final int SYNC = 16; public static final int DSYNC = 32; + public static FileChannelImpl in; + public static FileChannelImpl out; + public static FileChannelImpl err; + private static native void init(); static @@ -83,6 +87,10 @@ public final class FileChannelImpl extends FileChannel } init(); + + in = new FileChannelImpl(0, READ); + out = new FileChannelImpl(1, WRITE); + err = new FileChannelImpl(2, WRITE); } /** @@ -97,6 +105,8 @@ public final class FileChannelImpl extends FileChannel private int mode; + final String description; + /* Open a file. MODE is a combination of the above mode flags. */ /* This is a static factory method, so that VM implementors can decide * substitute subclasses of FileChannelImpl. */ @@ -109,7 +119,8 @@ public final class FileChannelImpl extends FileChannel private FileChannelImpl(File file, int mode) throws FileNotFoundException { - final String path = file.getPath(); + String path = file.getPath(); + description = path; fd = open (path, mode); this.mode = mode; @@ -126,21 +137,26 @@ public final class FileChannelImpl extends FileChannel /* ignore it */ } - throw new FileNotFoundException(path + " is a directory"); + throw new FileNotFoundException(description + " is a directory"); } } - /* Used by init() (native code) */ + /** + * Constructor for default channels in, out and err. + * + * Used by init() (native code). + * + * @param fd the file descriptor (0, 1, 2 for stdin, stdout, stderr). + * + * @param mode READ or WRITE + */ FileChannelImpl (int fd, int mode) { this.fd = fd; this.mode = mode; + this.description = "descriptor(" + fd + ")"; } - public static FileChannelImpl in; - public static FileChannelImpl out; - public static FileChannelImpl err; - private native int open (String path, int mode) throws FileNotFoundException; public native int available () throws IOException; @@ -179,7 +195,7 @@ public final class FileChannelImpl extends FileChannel throws IOException { if (position < 0) - throw new IllegalArgumentException (); + throw new IllegalArgumentException ("position: " + position); long oldPosition = implPosition (); position (position); int result = read(dst); @@ -230,7 +246,7 @@ public final class FileChannelImpl extends FileChannel throws IOException { if (position < 0) - throw new IllegalArgumentException (); + throw new IllegalArgumentException ("position: " + position); if (!isOpen ()) throw new ClosedChannelException (); @@ -288,10 +304,11 @@ public final class FileChannelImpl extends FileChannel throw new NonWritableChannelException(); } else - throw new IllegalArgumentException (); + throw new IllegalArgumentException ("mode: " + mode); if (position < 0 || size < 0 || size > Integer.MAX_VALUE) - throw new IllegalArgumentException (); + throw new IllegalArgumentException ("position: " + position + + ", size: " + size); return mapImpl(nmode, position, (int) size); } @@ -336,7 +353,8 @@ public final class FileChannelImpl extends FileChannel { if (position < 0 || count < 0) - throw new IllegalArgumentException (); + throw new IllegalArgumentException ("position: " + position + + ", count: " + count); if (!isOpen ()) throw new ClosedChannelException (); @@ -399,7 +417,8 @@ public final class FileChannelImpl extends FileChannel { if (position < 0 || count < 0) - throw new IllegalArgumentException (); + throw new IllegalArgumentException ("position: " + position + + ", count: " + count); if (!isOpen ()) throw new ClosedChannelException (); @@ -424,24 +443,31 @@ public final class FileChannelImpl extends FileChannel return total; } - public FileLock tryLock (long position, long size, boolean shared) + // Shared sanity checks between lock and tryLock methods. + private void lockCheck(long position, long size, boolean shared) throws IOException { if (position < 0 || size < 0) - throw new IllegalArgumentException (); + throw new IllegalArgumentException ("position: " + position + + ", size: " + size); if (!isOpen ()) - throw new ClosedChannelException (); + throw new ClosedChannelException(); - if (shared && (mode & READ) == 0) - throw new NonReadableChannelException (); - - if (!shared && (mode & WRITE) == 0) - throw new NonWritableChannelException (); + if (shared && ((mode & READ) == 0)) + throw new NonReadableChannelException(); + if (!shared && ((mode & WRITE) == 0)) + throw new NonWritableChannelException(); + } + + public FileLock tryLock (long position, long size, boolean shared) + throws IOException + { + lockCheck(position, size, shared); + boolean completed = false; - try { begin(); @@ -468,15 +494,9 @@ public final class FileChannelImpl extends FileChannel public FileLock lock (long position, long size, boolean shared) throws IOException { - if (position < 0 - || size < 0) - throw new IllegalArgumentException (); - - if (!isOpen ()) - throw new ClosedChannelException (); + lockCheck(position, size, shared); boolean completed = false; - try { boolean lockable = lock(position, size, shared, true); @@ -504,7 +524,7 @@ public final class FileChannelImpl extends FileChannel throws IOException { if (newPosition < 0) - throw new IllegalArgumentException (); + throw new IllegalArgumentException ("newPostition: " + newPosition); if (!isOpen ()) throw new ClosedChannelException (); @@ -519,7 +539,7 @@ public final class FileChannelImpl extends FileChannel throws IOException { if (size < 0) - throw new IllegalArgumentException (); + throw new IllegalArgumentException ("size: " + size); if (!isOpen ()) throw new ClosedChannelException (); @@ -532,4 +552,12 @@ public final class FileChannelImpl extends FileChannel return this; } + + public String toString() + { + return (this.getClass() + + "[fd=" + fd + + ",mode=" + mode + "," + + description + "]"); + } } diff --git a/libjava/classpath/gnu/java/nio/charset/UTF_16Decoder.java b/libjava/classpath/gnu/java/nio/charset/UTF_16Decoder.java index 302c83e62bd..e3927d99466 100644 --- a/libjava/classpath/gnu/java/nio/charset/UTF_16Decoder.java +++ b/libjava/classpath/gnu/java/nio/charset/UTF_16Decoder.java @@ -1,5 +1,5 @@ /* UTF_16Decoder.java -- - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -105,8 +105,9 @@ final class UTF_16Decoder extends CharsetDecoder } // FIXME: Change so you only do a single comparison here. - char c = byteOrder == BIG_ENDIAN ? (char) ((b1 << 8) | b2) - : (char) ((b2 << 8) | b1); + char c = (byteOrder == BIG_ENDIAN + ? (char) (((b1 & 0xFF) << 8) | (b2 & 0xFF)) + : (char) (((b2 & 0xFF) << 8) | (b1 & 0xFF))); if (0xD800 <= c && c <= 0xDFFF) { @@ -119,8 +120,9 @@ final class UTF_16Decoder extends CharsetDecoder return CoderResult.UNDERFLOW; byte b3 = in.get (); byte b4 = in.get (); - char d = byteOrder == BIG_ENDIAN ? (char) ((b3 << 8) | b4) - : (char) ((b4 << 8) | b3); + char d = (byteOrder == BIG_ENDIAN + ? (char) (((b3 & 0xFF) << 8) | (b4 & 0xFF)) + : (char) (((b4 & 0xFF) << 8) | (b3 & 0xFF))); // make sure d is a low surrogate if (d < 0xDC00 || d > 0xDFFF) return CoderResult.malformedForLength (2); diff --git a/libjava/classpath/gnu/java/nio/charset/iconv/IconvDecoder.java b/libjava/classpath/gnu/java/nio/charset/iconv/IconvDecoder.java index fa265a92387..fa6f4970042 100644 --- a/libjava/classpath/gnu/java/nio/charset/iconv/IconvDecoder.java +++ b/libjava/classpath/gnu/java/nio/charset/iconv/IconvDecoder.java @@ -38,7 +38,7 @@ exception statement from your version. */ package gnu.java.nio.charset.iconv; -import gnu.classpath.RawData; +import gnu.classpath.Pointer; import java.nio.ByteBuffer; import java.nio.CharBuffer; @@ -55,7 +55,7 @@ final class IconvDecoder extends CharsetDecoder openIconv(info.iconvName()); } - private RawData data; + private Pointer data; private int inremaining; private int outremaining; diff --git a/libjava/classpath/gnu/java/nio/charset/iconv/IconvEncoder.java b/libjava/classpath/gnu/java/nio/charset/iconv/IconvEncoder.java index bb10c9b6347..d5cc8877f75 100644 --- a/libjava/classpath/gnu/java/nio/charset/iconv/IconvEncoder.java +++ b/libjava/classpath/gnu/java/nio/charset/iconv/IconvEncoder.java @@ -38,7 +38,7 @@ exception statement from your version. */ package gnu.java.nio.charset.iconv; -import gnu.classpath.RawData; +import gnu.classpath.Pointer; import java.nio.ByteBuffer; import java.nio.CharBuffer; @@ -49,7 +49,7 @@ import java.nio.charset.CoderResult; final class IconvEncoder extends CharsetEncoder { - private RawData data; + private Pointer data; private int inremaining; private int outremaining; diff --git a/libjava/classpath/gnu/java/security/OID.java b/libjava/classpath/gnu/java/security/OID.java index 8cda43eeee8..473b6ba5a29 100644 --- a/libjava/classpath/gnu/java/security/OID.java +++ b/libjava/classpath/gnu/java/security/OID.java @@ -1,5 +1,5 @@ /* OID.java -- numeric representation of an object identifier - Copyright (C) 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -48,7 +48,7 @@ import java.util.StringTokenizer; /** * This immutable class represents an object identifier, or OID. * - * <p>OIDs are represented as a series of hierarcical tokens, each of + * <p>OIDs are represented as a series of hierarchical tokens, each of * which is usually represented as a single, unsigned integer. The * hierarchy works so that later tokens are considered within the group * of earlier tokens. Thus, the OID for the Serpent block cipher, diff --git a/libjava/classpath/gnu/java/security/PolicyFile.java b/libjava/classpath/gnu/java/security/PolicyFile.java index dd3a4dec4c4..c6a3061ead2 100644 --- a/libjava/classpath/gnu/java/security/PolicyFile.java +++ b/libjava/classpath/gnu/java/security/PolicyFile.java @@ -37,6 +37,10 @@ exception statement from your version. */ package gnu.java.security; +import gnu.classpath.SystemProperties; +import gnu.classpath.debug.Component; +import gnu.classpath.debug.SystemLogger; + import java.io.File; import java.io.IOException; import java.io.InputStreamReader; @@ -66,6 +70,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.StringTokenizer; +import java.util.logging.Logger; /** * An implementation of a {@link java.security.Policy} object whose @@ -143,24 +148,16 @@ public final class PolicyFile extends Policy // Constants and fields. // ------------------------------------------------------------------------- - private static final boolean DEBUG = true; - // Package-private to avoid a trampoline. - static void debug(String msg) - { - System.err.print(">> PolicyFile: "); - System.err.println(msg); - } - - private static void debug(Throwable t) - { - System.err.println(">> PolicyFile"); - t.printStackTrace(System.err); - } + private static final Logger logger = SystemLogger.SYSTEM; - private static final String DEFAULT_POLICY = System.getProperty("java.home") - + System.getProperty("file.separator") + "lib" - + System.getProperty("file.separator") + "security" - + System.getProperty("file.separator") + "java.policy"; + private static final String DEFAULT_POLICY = + SystemProperties.getProperty("java.home") + + SystemProperties.getProperty("file.separator") + "lib" + + SystemProperties.getProperty("file.separator") + "security" + + SystemProperties.getProperty("file.separator") + "java.policy"; + private static final String DEFAULT_USER_POLICY = + SystemProperties.getProperty ("user.home") + + SystemProperties.getProperty ("file.separator") + ".java.policy"; private final Map cs2pc; @@ -185,7 +182,8 @@ public final class PolicyFile extends Policy CodeSource cs = (CodeSource) e.getKey(); if (cs.implies(codeSource)) { - if (DEBUG) debug(cs+" -> "+codeSource); + logger.log (Component.POLICY, "{0} -> {1}", new Object[] + { cs, codeSource }); PermissionCollection pc = (PermissionCollection) e.getValue(); for (Enumeration ee = pc.elements(); ee.hasMoreElements(); ) { @@ -193,50 +191,69 @@ public final class PolicyFile extends Policy } } else - if (DEBUG) debug(cs+" !-> "+codeSource); + logger.log (Component.POLICY, "{0} !-> {1}", new Object[] + { cs, codeSource }); } - if (DEBUG) debug ("returning permissions " + perms + " for " + codeSource); + logger.log (Component.POLICY, "returning permissions {0} for {1}", + new Object[] { perms, codeSource }); return perms; } public void refresh() { cs2pc.clear(); - List policyFiles = new LinkedList(); + final List policyFiles = new LinkedList(); try { - policyFiles.add(new File(DEFAULT_POLICY).toURL()); - if (DEBUG) debug ("defualt policy is " + DEFAULT_POLICY); - policyFiles.addAll((List) AccessController.doPrivileged( + policyFiles.add (new File (DEFAULT_POLICY).toURL()); + policyFiles.add (new File (DEFAULT_USER_POLICY).toURL ()); + + AccessController.doPrivileged( new PrivilegedExceptionAction() { public Object run() throws Exception { - LinkedList l = new LinkedList(); + String allow = Security.getProperty ("policy.allowSystemProperty"); + if (allow == null || Boolean.getBoolean (allow)) + { + String s = SystemProperties.getProperty ("java.security.policy"); + logger.log (Component.POLICY, "java.security.policy={0}", s); + if (s != null) + { + boolean only = s.startsWith ("="); + if (only) + s = s.substring (1); + policyFiles.clear (); + policyFiles.add (new URL (s)); + if (only) + return null; + } + } for (int i = 1; ; i++) { - String s = Security.getProperty("policy.file."+i); - if (DEBUG) debug("policy.file."+i+"="+s); + String pname = "policy.url." + i; + String s = Security.getProperty (pname); + logger.log (Component.POLICY, "{0}={1}", new Object [] + { pname, s }); if (s == null) break; - l.add(new URL(s)); + policyFiles.add (new URL (s)); } - String s = System.getProperty("java.security.policy"); - if (DEBUG) debug("java.security.policy="+s); - if (s != null) - l.add(new URL(s)); - return l; + return null; } - })); + }); } catch (PrivilegedActionException pae) { - if (DEBUG) debug(pae); + logger.log (Component.POLICY, "reading policy properties", pae); } catch (MalformedURLException mue) { - if (DEBUG) debug(mue); + logger.log (Component.POLICY, "setting default policies", mue); } + + logger.log (Component.POLICY, "building policy from URLs {0}", + policyFiles); for (Iterator it = policyFiles.iterator(); it.hasNext(); ) { try @@ -246,7 +263,7 @@ public final class PolicyFile extends Policy } catch (IOException ioe) { - if (DEBUG) debug(ioe); + logger.log (Component.POLICY, "reading policy", ioe); } } } @@ -273,7 +290,7 @@ public final class PolicyFile extends Policy */ private void parse(final URL url) throws IOException { - if (DEBUG) debug ("reading policy file from " + url); + logger.log (Component.POLICY, "reading policy file from {0}", url); final StreamTokenizer in = new StreamTokenizer(new InputStreamReader(url.openStream())); in.resetSyntax(); in.slashSlashComments(true); diff --git a/libjava/classpath/gnu/java/security/provider/DSAKeyPairGenerator.java b/libjava/classpath/gnu/java/security/provider/DSAKeyPairGenerator.java index 2c643d5c367..ddd1800a717 100644 --- a/libjava/classpath/gnu/java/security/provider/DSAKeyPairGenerator.java +++ b/libjava/classpath/gnu/java/security/provider/DSAKeyPairGenerator.java @@ -1,5 +1,5 @@ /* GnuDSAKeyPairGenerator.java --- Gnu DSA Key Pair Generator - Copyright (C) 1999 Free Software Foundation, Inc. + Copyright (C) 1999, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -45,10 +45,12 @@ import java.security.InvalidAlgorithmParameterException; import java.security.InvalidParameterException; import java.security.KeyPair; import java.security.KeyPairGeneratorSpi; +import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.interfaces.DSAParams; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.DSAParameterSpec; +import java.security.spec.InvalidParameterSpecException; import java.util.Random; public class DSAKeyPairGenerator extends KeyPairGeneratorSpi @@ -60,18 +62,15 @@ private BigInteger q = null; // the small prime private BigInteger p = null; // the big prime private BigInteger g = null; -DSAKeyPairGenerator() +public DSAKeyPairGenerator() { keysize = 1024; + getDefaults (); } public void initialize(int keysize, SecureRandom random) { - //if( ((keysize % 64) != 0) || (keysize < 512) || (keysize > 1024) ) - // throw new InvalidAlgorithmParameterException("Invalid key size"); - - this.keysize = keysize; - this.random = random; + initialize (keysize, false, random); } public void initialize(AlgorithmParameterSpec params, @@ -81,65 +80,87 @@ public void initialize(AlgorithmParameterSpec params, if( !( params instanceof DSAParameterSpec ) ) throw new InvalidAlgorithmParameterException("Must be DSAParameterSpec"); + try + { + initialize ((DSAParams) params, random); + } + catch (InvalidParameterException ipe) + { + InvalidAlgorithmParameterException iape = + new InvalidAlgorithmParameterException(); + iape.initCause (ipe); + throw iape; + } +} + +public void initialize (DSAParams params, SecureRandom random) +{ DSAParameterSpec dsaparameterspec = (DSAParameterSpec)params; + if (dsaparameterspec.getP() == null + || dsaparameterspec.getQ() == null + || dsaparameterspec.getG() == null) + { + throw new InvalidParameterException ("none of p, q, or g may be null"); + } p = dsaparameterspec.getP(); q = dsaparameterspec.getQ(); g = dsaparameterspec.getG(); this.random = random; } -public void initialize(DSAParams params, SecureRandom random) - throws InvalidParameterException -{ - if(params.getP() != null) - p = params.getP(); - else - throw new InvalidParameterException(); - - if(params.getQ() != null) - q = params.getQ(); - else - throw new InvalidParameterException(); - - if(params.getG() != null) - g = params.getG(); - else - throw new InvalidParameterException(); - - this.random = random; -} - public void initialize(int modlen, boolean genParams, SecureRandom random) throws InvalidParameterException { if( ((modlen % 64) != 0) || (modlen < 512) || (modlen > 1024) ) throw new InvalidParameterException(); - if( (genParams == false) && (modlen != 512) && (modlen != 768) && (modlen != 1024) ) - throw new InvalidParameterException(); - this.keysize = modlen; - this.random = random; - p = null; - q = null; - g = null; + this.keysize = modlen; + this.random = random; + if (this.random == null) + { + this.random = new SecureRandom (); + } + if (genParams) + { + try + { + AlgorithmParameterGenerator apgDSA = AlgorithmParameterGenerator.getInstance("DSA"); + apgDSA.init (modlen, random); + AlgorithmParameters apDSA = apgDSA.generateParameters(); + DSAParameterSpec dsaparameterspec = (DSAParameterSpec)apDSA.getParameterSpec( DSAParameterSpec.class ); + p = dsaparameterspec.getP(); + q = dsaparameterspec.getQ(); + g = dsaparameterspec.getG(); + } + catch (NoSuchAlgorithmException nsae) + { + InvalidParameterException ipe = + new InvalidParameterException ("can't generate DSA parameters"); + ipe.initCause (nsae); + throw ipe; + } + catch (InvalidParameterSpecException ipse) + { + InvalidParameterException ipe = + new InvalidParameterException ("can't generate DSA parameters"); + ipe.initCause (ipse); + throw ipe; + } + } + else if (!getDefaults ()) + { + throw new InvalidParameterException ("unsupported key size: " + modlen); + } } public KeyPair generateKeyPair() { - if( getDefaults() == false) { - try { - AlgorithmParameterGenerator apgDSA = AlgorithmParameterGenerator.getInstance("DSA"); - AlgorithmParameters apDSA = apgDSA.generateParameters(); - DSAParameterSpec dsaparameterspec = (DSAParameterSpec)apDSA.getParameterSpec( DSAParameterSpec.class ); - p = dsaparameterspec.getP(); - q = dsaparameterspec.getQ(); - g = dsaparameterspec.getG(); - } catch ( Exception e ) { - return null; - } - } + if (random == null) + { + random = new SecureRandom (); + } - BigInteger x = new BigInteger( 159, new Random() ); + BigInteger x = new BigInteger( 159, random ); BigInteger y = g.modPow( x, p ); @@ -160,10 +181,12 @@ private boolean getDefaults() p = new BigInteger("e9e642599d355f37c97ffd3567120b8e25c9cd43e927b3a9670fbec5d890141922d2c3b3ad2480093799869d1e846aab49fab0ad26d2ce6a22219d470bce7d777d4a21fbe9c270b57f607002f3cef8393694cf45ee3688c11a8c56ab127a3daf", 16); q = new BigInteger("9cdbd84c9f1ac2f38d0f80f42ab952e7338bf511", 16); g = new BigInteger("30470ad5a005fb14ce2d9dcd87e38bc7d1b1c5facbaecbe95f190aa7a31d23c4dbbcbe06174544401a5b2c020965d8c2bd2171d3668445771f74ba084d2029d83c1c158547f3a9f1a2715be23d51ae4d3e5a1f6a7064f316933a346d3f529252", 16); - } else if( keysize == 512) { + return true; + } else if( keysize == 1024) { p = new BigInteger("fd7f53811d75122952df4a9c2eece4e7f611b7523cef4400c31e3f80b6512669455d402251fb593d8d58fabfc5f5ba30f6cb9b556cd7813b801d346ff26660b76b9950a5a49f9fe8047b1022c24fbba9d7feb7c61bf83b57e7c6a8a6150f04fb83f6d3c51ec3023554135a169132f675f3ae2b61d72aeff22203199dd14801c7", 16); q = new BigInteger("9760508f15230bccb292b982a2eb840bf0581cf5", 16); g = new BigInteger("f7e1a085d69b3ddecbbcab5c36b857b97994afbbfa3aea82f9574c0b3d0782675159578ebad4594fe67107108180b449167123e84c281613b7cf09328cc8a6e13c167a8b547c8d28e0a3ae1e2bb3a675916ea37f0bfa213562f1fb627a01243bcca4f1bea8519089a883dfe15ae59f06928b665e807b552564014c3bfecf492a", 16); + return true; } return false; } diff --git a/libjava/classpath/gnu/java/security/provider/PKIXCertPathValidatorImpl.java b/libjava/classpath/gnu/java/security/provider/PKIXCertPathValidatorImpl.java index 1268b169d9b..ab8943443ec 100644 --- a/libjava/classpath/gnu/java/security/provider/PKIXCertPathValidatorImpl.java +++ b/libjava/classpath/gnu/java/security/provider/PKIXCertPathValidatorImpl.java @@ -1,5 +1,5 @@ /* PKIXCertPathValidatorImpl.java -- PKIX certificate path validator. - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -331,7 +331,7 @@ public class PKIXCertPathValidatorImpl extends CertPathValidatorSpi continue; try { - if (anchorCert == null) + if (anchorCert != null) anchorCert.checkValidity(now); p[p.length-1].verify(anchorKey); if (anchorCert != null && anchorCert.getBasicConstraints() >= 0 diff --git a/libjava/classpath/gnu/javax/swing/plaf/gtk/GtkBorders.java b/libjava/classpath/gnu/javax/swing/plaf/gtk/GtkBorders.java deleted file mode 100644 index ebba6a49b2a..00000000000 --- a/libjava/classpath/gnu/javax/swing/plaf/gtk/GtkBorders.java +++ /dev/null @@ -1,83 +0,0 @@ -/* GtkBorders.java - Copyright (c) 1999 by 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.javax.swing.plaf.gtk; -import java.awt.*; -import javax.swing.*; -import javax.swing.border.*; -import javax.swing.plaf.*; - -/** - * Optional class, can be used to define nifty borders. - * - * @author Brian Jones - * @see javax.swing.LookAndFeel - */ -public class GtkBorders -{ - public static class ButtonBorder extends AbstractBorder - implements UIResource - { - private Border raised; // use by default - private Border lowered; // use this one when pressed - - // creat the border - public ButtonBorder() - { - raised = BorderFactory.createRaisedBevelBorder(); - lowered = BorderFactory.createLoweredBevelBorder(); - } - - // define the insets (in terms of one of the others) - public Insets getBorderInsets(Component c) - { - return raised.getBorderInsets(c); - } - - public void paintBorder(Component c, Graphics g, int x, int y, - int width, int height) - { - AbstractButton b = (AbstractButton)c; - ButtonModel model = b.getModel(); - - if (model.isPressed() && model.isArmed()) - lowered.paintBorder(c, g, x, y, width, height); - else - raised.paintBorder(c, g, x, y, width, height); - } - } -} diff --git a/libjava/classpath/gnu/javax/swing/plaf/gtk/GtkCheckBoxUI.java b/libjava/classpath/gnu/javax/swing/plaf/gtk/GtkCheckBoxUI.java deleted file mode 100644 index 0395af61bfb..00000000000 --- a/libjava/classpath/gnu/javax/swing/plaf/gtk/GtkCheckBoxUI.java +++ /dev/null @@ -1,69 +0,0 @@ -/* GtkCheckBoxUI.java - Copyright (c) 1999 by 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.javax.swing.plaf.gtk; - -import java.awt.*; -import javax.swing.*; -import javax.swing.plaf.*; -import javax.swing.plaf.basic.*; - -/** - * - * @author Brian Jones - * @see javax.swing.LookAndFeel - */ -public class GtkCheckBoxUI extends GtkRadioButtonUI -{ - public GtkCheckBoxUI() - { - super(); - } - - public static ComponentUI createUI(JComponent c) - { - return new GtkCheckBoxUI(); - } - - public String getPropertyPrefix() - { - // FIXME - System.err.println(super.getPropertyPrefix()); - return super.getPropertyPrefix(); - } -} - diff --git a/libjava/classpath/gnu/javax/swing/plaf/gtk/GtkIconFactory.java b/libjava/classpath/gnu/javax/swing/plaf/gtk/GtkIconFactory.java deleted file mode 100644 index 28fd36e897c..00000000000 --- a/libjava/classpath/gnu/javax/swing/plaf/gtk/GtkIconFactory.java +++ /dev/null @@ -1,99 +0,0 @@ -/* GtkIconFactory.java - Copyright (c) 1999 by 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.javax.swing.plaf.gtk; -import java.awt.*; -import javax.swing.*; -import javax.swing.plaf.*; -import java.io.Serializable; - -/** - * - * @author Brian Jones - * @see javax.swing.LookAndFeel - */ -public class GtkIconFactory implements Serializable -{ - private static Icon radioButtonIcon; - private static Icon checkBoxIcon; - - public static Icon getRadioButtonIcon() - { - if (radioButtonIcon == null) - radioButtonIcon = new RadioButtonIcon(); - return radioButtonIcon; - } - - private static class RadioButtonIcon - implements Icon, UIResource, Serializable - { - private static final int size = 15; - - public int getIconWidth() { return size; } - public int getIconHeight() { return size; } - - public void paintIcon(Component c, Graphics g, int x, int y) - { - System.out.println("radiobuttonicon: paintIcon()"); - // get the button and model containing the state we are - // supposed to show - AbstractButton b = (AbstractButton)c; - ButtonModel model = b.getModel(); - - // If the button is being pressed (& armed), change the - // background color - // Note: could also do something different if the button is - // disabled - - if (model.isPressed() && model.isArmed()) - { - System.out.println("radiobuttonicon: pressed & armed"); - g.setColor(UIManager.getColor("RadioButton.pressed")); - g.fillOval(x,y,size-1, size-1); - } - // draw an outer circle - g.setColor(UIManager.getColor("RadioButton.foreground")); - g.drawOval(x,y,size-1, size-1); - - // fill a small circle inside if the button is selected - if (model.isSelected()) { - g.fillOval(x+4, y+4, size-8, size-8); - System.out.println("radiobuttonicon: is selected"); - } - } - } -} diff --git a/libjava/classpath/gnu/javax/swing/plaf/gtk/GtkLookAndFeel.java b/libjava/classpath/gnu/javax/swing/plaf/gtk/GtkLookAndFeel.java deleted file mode 100644 index ed99e6d216b..00000000000 --- a/libjava/classpath/gnu/javax/swing/plaf/gtk/GtkLookAndFeel.java +++ /dev/null @@ -1,241 +0,0 @@ -/* GtkLookAndFeel.java - Copyright (c) 1999 by 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.javax.swing.plaf.gtk; -import java.awt.*; -import javax.swing.*; -import javax.swing.border.*; -import javax.swing.plaf.*; -import javax.swing.plaf.basic.*; - -/** - * - * @author Brian Jones - * @see javax.swing.LookAndFeel - */ -public class GtkLookAndFeel extends BasicLookAndFeel -{ - private UIDefaults uiDefaults; - - /** - */ - public GtkLookAndFeel() - { - super(); - } - - /** - * A short string to identify this look and feel, for example in a - * drop down list to choose between several look and feels. - */ - public String getName() { return "GIMP Toolkit"; } - - /** - * A much longer description of the look and feel. - */ - public String getDescription() - { - return new String("The GIMP Toolkit Look and Feel for Java, " + - "written by Brian Jones (cbj@gnu.org), " + - "(c) 1999 by Free Software Foundation, Inc. " + - "http://www.classpath.org"); - } - - /** - * Return a unique string identifying this look and feel as different - * from and not a subclass of any other look and feel. Usually, a - * subclass will return the same <code>String</code> here as the - * original look and feel if only a few changes are being made rather - * than something completely new and different. - */ - public String getID() - { - return "Gtk"; - } - - public boolean isNativeLookAndFeel() - { - return false; - } - - public boolean isSupportedLookAndFeel() - { - return true; - } - - protected void initClassDefaults(UIDefaults table) - { - super.initClassDefaults(table); - - String gtkPkgName = "gnu.javax.swing.plaf.gtk."; - - - Object[] defaults = { - "SliderUI", gtkPkgName + "GtkSliderUI" - }; - /* - "CheckBoxUI", gtkPkgName + "GtkCheckBoxUI", - "ButtonUI", gtkPkgName + "GtkButtonUI" - "ColorChooserUI", "MetalColorChooserUI", - "MenuBarUI", "MetalMenuBarUI", - "MenuUI", "MetalMenuUI", - "MenuItemUI", "MetalMenuItemUI", - "CheckBoxMenuItemUI", "MetalCheckBoxMenuItemUI", - "RadioButtonMenuItemUI", "MetalRadioButtonMenuItemUI", - "RadioButtonUI", "MetalRadioButtonUI", - "ToggleButtonUI", "MetalToggleButtonUI", - "PopupMenuUI", "MetalPopupMenuUI", - "ProgressBarUI", "MetalProgressBarUI", - "ScrollBarUI", "MetalScrollBarUI", - "ScrollPaneUI", "MetalScrollPaneUI", - "SplitPaneUI", "MetalSplitPaneUI", - "SeparatorUI", "MetalSeparatorUI", - "ToolBarSeparatorUI", "MetalToolBarSeparatorUI", - "PopupMenuSeparatorUI", "MetalPopupMenuSeparatorUI", - "TabbedPaneUI", "MetalTabbedPaneUI", - "TextAreaUI", "MetalTextAreaUI", - "TextFieldUI", "MetalTextFieldUI", - "PasswordFieldUI", "MetalPasswordFieldUI", - "TextPaneUI", "MetalTextPaneUI", - "EditorPaneUI", "MetalEditorPaneUI", - "TreeUI", "MetalTreeUI", - "LabelUI", "MetalLabelUI", - "ListUI", "MetalListUI", - "ToolBarUI", "MetalToolBarUI", - "ToolTipUI", "MetalToolTipUI", - "ComboBoxUI", "MetalComboBoxUI", - "TableUI", "MetalTableUI", - "TableHeaderUI", "MetalTableHeaderUI", - "InternalFrameUI", "GtkInternalFrameUI", - "StandardDialogUI", "GtkStandardDialogUI", - "DesktopPaneUI", "GtkDesktopPaneUI", - "DesktopIconUI", "GtkDesktopIconUI", - "DirectoryPaneUI", "GtkDirectoryPaneUI", - "FileChooserUI", "GtkFileChooserUI", - "OptionPaneUI", "GtkOptionPaneUI" } - */ - table.putDefaults(defaults); - - } - - protected void initSystemColorDefaults(UIDefaults table) - { - String[] colors = { - "desktop", "#000000", - "activeCaption", "#163555", - "activeCaptionText", "#FFFFFF", - "activeCaptionBorder", "#000000", - "inactiveCaption", "#375676", - "inactiveCaptionText", "#999999", - "inactiveCaptionBorder", "#000000", - "window", "#FFFFFF", - "windowBorder", "#969696", - "windowText", "#000000", - "menu", "#d6d6d6", - "menuText", "#000000", - "text", "#FFFFFF", - "textText", "#000000", - "textHighlight", "#00009c", - "textHighlightText", "#FFFFFF", - "textInactiveText", "#999999", - "control", "#d6d6d6", - "controlText", "#000000", - "controlHighlight", "#eaeaea", - "controlLtHighlight", "#eaeaea", - "controlShadow", "#c3c3c3", - "controlDkShadow", "#888888", - "scrollbar", "#c3c3c3", - "info", "#d6d6d6", - "infoText", "#000000" - }; - - loadSystemColors(table, colors, false); - } - - protected void initComponentDefaults(UIDefaults table) - { - super.initComponentDefaults(table); - - // define common resources - // fonts - FontUIResource sansSerifPlain10 = - new FontUIResource("SansSerif", Font.PLAIN, 10); - FontUIResource serifPlain10 = - new FontUIResource("Serif", Font.PLAIN, 10); - // insets - // borders - // colors - ColorUIResource controlDkShadow = new ColorUIResource(table.getColor("controlDkShadow")); - ColorUIResource controlShadow = new ColorUIResource(table.getColor("controlShadow")); - ColorUIResource control = new ColorUIResource(table.getColor("control")); - ColorUIResource scrollbar = new ColorUIResource(table.getColor("scrollbar")); - ColorUIResource controlHighlight = new ColorUIResource(table.getColor("controlHighlight")); - if (scrollbar == null) - System.out.println("scrollbar is null"); - - ColorUIResource white = new ColorUIResource(Color.white); - ColorUIResource black = new ColorUIResource(Color.black); - ColorUIResource blue = new ColorUIResource(Color.blue); - - // icons - Object errorIcon = LookAndFeel.makeIcon(getClass(), "icons/error.gif"); - // any other resources like dimensions and integer values - - // define defaults - Object[] defaults = - { - "Button.font", sansSerifPlain10, - "CheckBox.font", sansSerifPlain10, - "RadioButton.pressed", black, - "Slider.focus", blue, - "Slider.foreground", control, - "Slider.highlight", controlHighlight, - "Slider.shadow", controlShadow, - "Slider.background", controlDkShadow - -// "Slider.background", "#888888", -// "Slider.focus", "#c3c3c3", -// "Slider.foreground", "#d6d6d6", -// "Slider.highlight", "#ffffff", -// "Slider.shadow", "#000000" - - - }; - - table.putDefaults(defaults); - } -} diff --git a/libjava/classpath/gnu/javax/swing/plaf/gtk/GtkRadioButtonUI.java b/libjava/classpath/gnu/javax/swing/plaf/gtk/GtkRadioButtonUI.java deleted file mode 100644 index 19d53387910..00000000000 --- a/libjava/classpath/gnu/javax/swing/plaf/gtk/GtkRadioButtonUI.java +++ /dev/null @@ -1,69 +0,0 @@ -/* GtkRadioButtonUI.java - Copyright (c) 1999 by 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.javax.swing.plaf.gtk; - -import java.awt.*; -import javax.swing.*; -import javax.swing.plaf.*; -import javax.swing.plaf.basic.*; - -/** - * - * @author Brian Jones - * @see javax.swing.LookAndFeel - */ -public class GtkRadioButtonUI extends BasicRadioButtonUI -{ - public GtkRadioButtonUI() - { - super(); - } - - public static ComponentUI createUI(JComponent c) - { - return new GtkRadioButtonUI(); - } - - public String getPropertyPrefix() - { - // FIXME - System.err.println(super.getPropertyPrefix()); - return super.getPropertyPrefix(); - } -} - diff --git a/libjava/classpath/gnu/javax/swing/plaf/gtk/GtkSliderUI.java b/libjava/classpath/gnu/javax/swing/plaf/gtk/GtkSliderUI.java deleted file mode 100644 index c576b3d4b50..00000000000 --- a/libjava/classpath/gnu/javax/swing/plaf/gtk/GtkSliderUI.java +++ /dev/null @@ -1,230 +0,0 @@ -/* GtkSliderUI.java - Copyright (c) 1999 by 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.javax.swing.plaf.gtk; -import java.awt.*; -import javax.swing.*; -import javax.swing.plaf.*; -import javax.swing.plaf.basic.*; - -/** - * Gtk-like slider - * - * @author Brian Jones - * @see javax.swing.LookAndFeel - */ -public class GtkSliderUI extends BasicSliderUI -{ - private static Color thumbFgColor; - private static Color thumbBgColor; - private static Color thumbHighlight; - private static Color thumbFocus; - - private static Color bgColor; - private static Color fgColor; - private static Color focusColor; - private static Color highlight; - private static Color shadow; - - private static final Dimension PREF_HORIZ = new Dimension(250, 15); - private static final Dimension PREF_VERT = new Dimension(15, 250); - private static final Dimension MIN_HORIZ = new Dimension(25, 15); - private static final Dimension MIN_VERT = new Dimension(15, 25); - - public GtkSliderUI() - { - super(null); - bgColor = UIManager.getColor("Slider.background"); - fgColor = UIManager.getColor("Slider.foreground"); - focusColor = UIManager.getColor("Slider.focus"); - highlight = UIManager.getColor("Slider.highlight"); - shadow = UIManager.getColor("Slider.shadow"); - - System.out.println("bgColor: " + bgColor); - System.out.println("fgColor: " + fgColor); - System.out.println("focusColor: " + focusColor); - System.out.println("highlight: " + highlight); - System.out.println("shadow: " + shadow); - } - - public static ComponentUI createUI(JComponent c) - { - return new GtkSliderUI(); - } - - // methods not overridden here, using Basic defaults - // installUI() - // uninstall() - - public Dimension getPreferredHorizontalSize() - { - /* - Dimension thumbSize = getThumbSize(); - Dimenstion labelSize = getLabelSize(); - // getTickLength() - int width = thumbSize.width + - getWidthOfWidestLabel - */ - return PREF_HORIZ; - } - - public Dimension getPreferredVerticalSize() - { - return PREF_VERT; - } - - public Dimension getMinimumHorizontalSize() - { - return MIN_HORIZ; - } - - public Dimension getMinimumVerticalSize() - { - return MIN_VERT; - } - - /** - * Returns thumb size based on slider orientation - */ - protected Dimension getThumbSize() - { - Dimension size = new Dimension(); - - if (slider.getOrientation() == JSlider.VERTICAL) { - size.width = 15; - size.height = 33; - } - else { - size.width = 33; - size.height = 15; - } - return size; - } - - /** - * Reserved width or height for ticks, as appropriate to the slider - * orientation. - */ - protected int getTickLength() - { - return 10; - } - - public void paintFocus(Graphics g) - { - super.paintFocus(g); - System.err.println("focus " + focusRect); - } - - /** - * Must account for Unicode when drawing text. - */ - public void paintLabels(Graphics g) - { - super.paintLabels(g); - System.err.println("label " + labelRect); - } - - /** - * A drawRect() generated slider has ghosting when moving left on - * a horizontal slider and the bottom is not painted when moving - * right. - */ - public void paintThumb(Graphics g) - { - int x = thumbRect.x; - int y = thumbRect.y; - int h = thumbRect.height; - int w = thumbRect.width; - -// "Slider.background", "#888888", -// "Slider.focus", "#c3c3c3", -// "Slider.foreground", "#d6d6d6", -// "Slider.highlight", "#ffffff", -// "Slider.shadow", "#000000" - - g.setColor(fgColor); - g.fillRect(x,y,w,h); - g.setColor(bgColor); - - if (slider.getOrientation() == JSlider.HORIZONTAL) { - g.drawRect(x, y, w, h); - g.setColor(highlight); - g.drawLine(x+1, y+h-1, x+w, y+h-1); - g.setColor(focusColor); - g.drawLine(x+2, y+h-2, x+w, y+h-2); - g.setColor(Color.black); - g.drawLine(x+1, y+h-2, x+1, y+h-2); - g.drawRect(x+1, y+1, w-1, 12); - } - else - g.drawRect(x, y, w, h); - - System.err.println("thumb " + thumbRect); - } - - // public void paintTicks(Graphics g) - - public void paintTrack(Graphics g) - { -// super.paintTrack(g); - int x = trackRect.x; - int y = trackRect.y; - int h = trackRect.height; - int w = trackRect.width; - - System.err.println("track " + trackRect); - - g.setColor(Color.black); - g.fillRect(x,y,w,h); - -// if (slider.getOrientation() == JSlider.HORIZONTAL) -// g.drawLine(x, y+h-1, x+w-1, y+h-1); -// else -// g.drawLine(x+w-1, y, x+w-1, y+h-1); - -// System.err.println("track " + trackRect); -// System.err.println("content " + contentRect); - } - - // the four methods below allow you to control tick painting without - // worrying about what paintTicks does, look for in other UI delegates - // protected void paintMajorTickForHorizSlider(Graphics g, Rectangle tickBounds, int x) - // protected void paintMajorTickForVertSlider(Graphics g, Rectangle tickBounds, int y) - // protected void paintMinorTickForHorizSlider(Graphics g, Rectangle tickBounds, int x) - // protected void paintMinorTickForVertSlider(Graphics g, Rectangle tickBounds, int y) -} diff --git a/libjava/classpath/gnu/javax/swing/plaf/gtk/README b/libjava/classpath/gnu/javax/swing/plaf/gtk/README deleted file mode 100644 index 2b3f001ddc2..00000000000 --- a/libjava/classpath/gnu/javax/swing/plaf/gtk/README +++ /dev/null @@ -1,37 +0,0 @@ -This is a start at a GTK look and feel for Java. -It is usable already, but it mainly just defaults back to Basic Look and -Feel for everything. - -Sliders are currently broken. I haven't figured out why yet. - -A bunch of system colors defined in GtkLookandFeel though I have a feeling -I'll be defining more ColorUIResources shortly. - -Based on Gnome File Manager colors... or my Window Manager setup - -desktop #000000 (gtk) -activeCaption #163555 (window manager) -activeCaptionText #FFFFFF (window manager) -activeCaptionBorder #000000 (unsure of this) -inactiveCaption #375676 (window manager) -inactiveCaptionText #999999 (window manager) -inactiveCaptionBorder #000000 (unsure of this) -window #FFFFFF (gtk) -windowBorder #969696 (gtk) -windowText #000000 (gtk) -menu #d6d6d6 (gtk) -menuText #000000 (gtk) -text #FFFFFF (gtk) -textText #000000 (gtk) -textHighlight #00009c (gtk) -textHighlightText #FFFFFF (gtk) -textInactiveText #999999 (unsure of this) -control #d6d6d6 (gtk) -controlText #000000 (gtk) -controlHighlight #eaeaea (gtk) -controlLtHighlight #eaeaea (unsure of this) -controlShadow #c3c3c3 (gtk) -controlDkShadow #888888 (unsure of this) -scrollbar #c3c3c3 (gtk) -info #d6d6d6 (gtk) -infoText #000000 (gtk) diff --git a/libjava/classpath/gnu/javax/swing/plaf/gtk/SliderTest.java b/libjava/classpath/gnu/javax/swing/plaf/gtk/SliderTest.java deleted file mode 100644 index a838444924d..00000000000 --- a/libjava/classpath/gnu/javax/swing/plaf/gtk/SliderTest.java +++ /dev/null @@ -1,82 +0,0 @@ -import javax.swing.*; -import javax.swing.event.*; -import java.awt.*; -import java.awt.event.*; -import gnu.javax.swing.plaf.gtk.*; - -public class SliderTest extends JFrame -{ - public SliderTest() - { - super("JSlider Test"); - Container c = getContentPane(); - c.setLayout(new BorderLayout()); - this.addWindowListener(new WindowAdapter() { - public void windowClosing(WindowEvent e) { System.exit(0); } - }); - - JSlider s = new JSlider(); - s.createStandardLabels(10); - s.setMinorTickSpacing(10); - s.setMajorTickSpacing(20); - s.setPaintTicks(true); - s.setPaintTrack(true); - s.setPaintLabels(true); - s.setRequestFocusEnabled(true); - - // turning off double buffering in repaint manager - // in order to use debug graphics - RepaintManager repaintManager = RepaintManager.currentManager(s); - repaintManager.setDoubleBufferingEnabled(false); - - s.setDebugGraphicsOptions(DebugGraphics.BUFFERED_OPTION | DebugGraphics.FLASH_OPTION); - DebugGraphics.setFlashColor(Color.red); // color of flash - DebugGraphics.setFlashTime(4); // time delay of drawing operation flashing - DebugGraphics.setFlashCount(3); // number of time to draw - - this.setSize(250, 100); - c.add(new JLabel("Default Slider"), "North"); - c.add(s, "Center"); - - try { - UIManager.setLookAndFeel("gnu.javax.swing.plaf.gtk.GtkLookAndFeel"); - SwingUtilities.updateComponentTreeUI(this); - } catch (Exception e) { - e.printStackTrace(); - System.exit(0); - } - - center(); - } - - public void actionPerformed(ActionEvent e) { - System.exit(0); - } - - public void center() - { - // Centering the frame - Toolkit t = this.getToolkit(); - Dimension framesize = this.getSize(); - Dimension screensize = t.getScreenSize(); - - // Calculate point for frame (main) - Point pframe = new Point(); - pframe.x = (screensize.width - framesize.width) / 2; - pframe.y = (screensize.height - framesize.height) / 2; - - // Set the location of each to be centered - this.setLocation(pframe); - } - - public static void main(String [] argv) - { - SliderTest t = new SliderTest(); - t.show(); - } - -} - - - - diff --git a/libjava/classpath/gnu/xml/xpath/ArithmeticExpr.java b/libjava/classpath/gnu/xml/xpath/ArithmeticExpr.java index 3cef4adf3cc..cbc1ee0648b 100644 --- a/libjava/classpath/gnu/xml/xpath/ArithmeticExpr.java +++ b/libjava/classpath/gnu/xml/xpath/ArithmeticExpr.java @@ -95,17 +95,31 @@ final class ArithmeticExpr case DIVIDE: if (rn == 0.0d || rn == -0.0d) { - return new Double(ln < 0.0d ? - Double.NEGATIVE_INFINITY : - Double.POSITIVE_INFINITY); + if (ln == 0.0d || ln == -0.0d) + { + return new Double(Double.NaN); + } + else + { + return new Double(ln < 0.0d ? + Double.NEGATIVE_INFINITY : + Double.POSITIVE_INFINITY); + } } return new Double(ln / rn); case MODULO: - if (rn == 0.0d || rn == -0.0d) + if (rn == 0.0d || rn == 0.0d) { - return new Double(ln < 0.0d ? - Double.NEGATIVE_INFINITY : - Double.POSITIVE_INFINITY); + if (ln == 0.0d || ln == -0.0d) + { + return new Double(Double.NaN); + } + else + { + return new Double(ln < 0.0d ? + Double.NEGATIVE_INFINITY : + Double.POSITIVE_INFINITY); + } } return new Double(ln % rn); default: diff --git a/libjava/classpath/gnu/xml/xpath/XPathParser.java b/libjava/classpath/gnu/xml/xpath/XPathParser.java index 624dcd8d46a..03066fbfc36 100644 --- a/libjava/classpath/gnu/xml/xpath/XPathParser.java +++ b/libjava/classpath/gnu/xml/xpath/XPathParser.java @@ -1,43 +1,43 @@ // created by jay 0.8 (c) 1998 Axel.Schreiner@informatik.uni-osnabrueck.de // line 2 "XPathParser.y" -/* - * XPathParser.java - * Copyright (C) 2004 The Free Software Foundation - * - * This file is part of GNU JAXP, a library. - * - * GNU JAXP is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GNU JAXP is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Linking this library statically or dynamically with other modules is - * making a combined work based on this library. Thus, the terms and - * conditions of the GNU General Public License cover the whole - * combination. - * - * As a special exception, the copyright holders of this library give you - * permission to link this library with independent modules to produce an - * executable, regardless of the license terms of these independent - * modules, and to copy and distribute the resulting executable under - * terms of your choice, provided that you also meet, for each linked - * independent module, the terms and conditions of the license of that - * module. An independent module is a module which is not derived from - * or based on this library. If you modify this library, you may extend - * this exception to your version of the library, but you are not - * obliged to do so. If you do not wish to do so, delete this - * exception statement from your version. - */ +/* XPathParser.y - An XPath 1.0 parser. + Copyright (C) 2004 The 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.xml.xpath; diff --git a/libjava/classpath/gnu/xml/xpath/XPathParser.y b/libjava/classpath/gnu/xml/xpath/XPathParser.y index d7dc4f1e8aa..55015138655 100644 --- a/libjava/classpath/gnu/xml/xpath/XPathParser.y +++ b/libjava/classpath/gnu/xml/xpath/XPathParser.y @@ -1,41 +1,41 @@ %{ -/* - * XPathParser.java - * Copyright (C) 2004 The Free Software Foundation - * - * This file is part of GNU JAXP, a library. - * - * GNU JAXP is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GNU JAXP is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Linking this library statically or dynamically with other modules is - * making a combined work based on this library. Thus, the terms and - * conditions of the GNU General Public License cover the whole - * combination. - * - * As a special exception, the copyright holders of this library give you - * permission to link this library with independent modules to produce an - * executable, regardless of the license terms of these independent - * modules, and to copy and distribute the resulting executable under - * terms of your choice, provided that you also meet, for each linked - * independent module, the terms and conditions of the license of that - * module. An independent module is a module which is not derived from - * or based on this library. If you modify this library, you may extend - * this exception to your version of the library, but you are not - * obliged to do so. If you do not wish to do so, delete this - * exception statement from your version. - */ +/* XPathParser.y - An XPath 1.0 parser. + Copyright (C) 2004 The 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.xml.xpath; |