jmsnell 2002/10/26 15:05:05 Added: java/src/org/apache/axis/ime/internal MessageExchangeProvider1.java NonPersistentMessageExchangeCorrelatorService.java MessageExchangeImpl.java MessageExchangeProvider2.java MessageWorker.java NonPersistentMessageChannel.java MessageExchangeProvider.java MessageWorkerGroup.java java/src/org/apache/axis/ime/internal/util/uuid UUIDGenFactory.java SimpleUUIDGen.java UUIDGen.java java/src/org/apache/axis/ime/internal/util/handler HandlerWrapper1.java HandlerWrapper2.java Log: Initial checkin of the AIME prototype implementation. This code will not be compiled unless the compileime environment variable is set to true. Revision Changes Path 1.1 xml-axis/java/src/org/apache/axis/ime/internal/MessageExchangeProvider1.java Index: MessageExchangeProvider1.java =================================================================== package org.apache.axis.ime.internal; import org.apache.axis.ime.MessageExchangeContextListener; import org.apache.axis.ime.MessageExchange; /** * Serves as a base class for MessageExchangeProviders that * need to thread pooling on send AND receive message * flows (as opposed to MessageExchangeProvider2 which only * does thread pooling on send flows). * * @author James M Snell ([EMAIL PROTECTED]) */ public abstract class MessageExchangeProvider1 extends MessageExchangeProvider { protected abstract MessageExchangeContextListener createSendMessageContextListener(); protected abstract MessageExchangeContextListener createReceiveMessageContextListener(); public void init(long THREAD_COUNT) { if (initialized) throw new IllegalStateException(); for (int n = 0; n < THREAD_COUNT; n++) { WORKERS.addWorker(SEND, createSendMessageContextListener()); WORKERS.addWorker(RECEIVE, createReceiveMessageContextListener()); } initialized = true; } } 1.1 xml-axis/java/src/org/apache/axis/ime/internal/NonPersistentMessageExchangeCorrelatorService.java Index: NonPersistentMessageExchangeCorrelatorService.java =================================================================== package org.apache.axis.ime.internal; import org.apache.axis.ime.MessageExchangeContext; import org.apache.axis.ime.MessageExchangeCorrelator; import org.apache.axis.ime.MessageExchangeCorrelatorService; import java.util.Hashtable; /** * @author James M Snell ([EMAIL PROTECTED]) */ public class NonPersistentMessageExchangeCorrelatorService implements MessageExchangeCorrelatorService { Hashtable contexts = new Hashtable(); /** * @see org.apache.axis.ime.MessageExchangeCorrelatorService#put(MessageExchangeCorrelator, MessageExchangeContext) */ public void put( MessageExchangeCorrelator correlator, MessageExchangeContext context) { synchronized(contexts) { contexts.put(correlator, context); } } /** * @see org.apache.axis.ime.MessageExchangeCorrelatorService#get(MessageExchangeCorrelator) */ public MessageExchangeContext get(MessageExchangeCorrelator correlator) { synchronized(contexts) { return (MessageExchangeContext)contexts.remove(correlator); } } } 1.1 xml-axis/java/src/org/apache/axis/ime/internal/MessageExchangeImpl.java Index: MessageExchangeImpl.java =================================================================== package org.apache.axis.ime.internal; import org.apache.axis.AxisFault; import org.apache.axis.MessageContext; import org.apache.axis.ime.MessageChannel; import org.apache.axis.ime.MessageExchange; import org.apache.axis.ime.MessageExchangeContext; import org.apache.axis.ime.MessageExchangeContextListener; import org.apache.axis.ime.MessageExchangeCorrelator; import org.apache.axis.ime.MessageExchangeLifecycle; import org.apache.axis.ime.MessageExchangeStatus; import org.apache.axis.ime.MessageExchangeReceiveListener; import org.apache.axis.ime.MessageExchangeStatusListener; import org.apache.axis.ime.MessageExchangeFaultListener; import org.apache.axis.ime.MessageExchangeConstants; import org.apache.axis.ime.internal.util.uuid.UUIDGen; import org.apache.axis.ime.internal.util.uuid.UUIDGenFactory; /** * @author James M Snell ([EMAIL PROTECTED]) */ public class MessageExchangeImpl implements MessageExchange, MessageExchangeLifecycle { public static final long WORKER_COUNT = 5; public static final long DEFAULT_TIMEOUT = 1000 * 20; private MessageExchangeProvider provider; private MessageChannel send; private MessageChannel receive; private MessageExchangeReceiveListener receiveListener; private MessageExchangeStatusListener statusListener; private MessageExchangeFaultListener faultListener; private MessageWorkerGroup workers = new MessageWorkerGroup(); private boolean listening = false; protected Holder holder; public MessageExchangeImpl( MessageExchangeProvider provider, MessageChannel sendChannel, MessageChannel receiveChannel) { this.send = sendChannel; this.receive = receiveChannel; } /** * @see org.apache.axis.ime.MessageExchange#send(MessageContext) */ public MessageExchangeCorrelator send( MessageContext context) throws AxisFault { MessageExchangeCorrelator correlator = (MessageExchangeCorrelator)context.getProperty( MessageExchangeConstants.MESSAGE_CORRELATOR_PROPERTY); if (correlator == null) { correlator = new MessageExchangeCorrelator( UUIDGenFactory.getUUIDGen(null).nextUUID()); context.setProperty( MessageExchangeConstants.MESSAGE_CORRELATOR_PROPERTY, correlator); } MessageExchangeContext meContext = MessageExchangeContext.newInstance( correlator, statusListener, receiveListener, faultListener, context); send.put(correlator, meContext); return correlator; } /** * @see org.apache.axis.ime.MessageExchange#setMessageExchangeStatusListener(MessageExchangeStatusListener) */ public void setMessageExchangeStatusListener( MessageExchangeStatusListener listener) throws AxisFault { if (listening) throw new IllegalStateException(); this.statusListener = listener; } /** * @see org.apache.axis.ime.MessageExchange#setMessageExchangeReceiveListener(MessageExchangeReceiveListener) */ public void setMessageExchangeReceiveListener( MessageExchangeReceiveListener listener) throws AxisFault { if (listening) throw new IllegalStateException(); this.receiveListener = listener; } /** * @see org.apache.axis.ime.MessageExchange#setMessageExchangeReceiveListener(MessageExchangeReceiveListener) */ public void setMessageExchangeFaultListener( MessageExchangeFaultListener listener) throws AxisFault { if (listening) throw new IllegalStateException(); this.faultListener = listener; } /** * @see org.apache.axis.ime.MessageExchange#cancel(MessageExchangeCorrelator) */ public MessageContext cancel( MessageExchangeCorrelator correlator) throws AxisFault { MessageExchangeContext context = send.cancel(correlator); if (context != null) return context.getMessageContext(); else return null; } /** * @see org.apache.axis.ime.MessageExchange#getReceiveChannel() */ public MessageChannel getReceiveChannel() { return receive; } /** * @see org.apache.axis.ime.MessageExchange#getSendChannel() */ public MessageChannel getSendChannel() { return send; } public MessageContext sendAndReceive( MessageContext context) throws AxisFault { holder = new Holder(); Listener listener = new Listener(holder); this.setMessageExchangeFaultListener(listener); this.setMessageExchangeReceiveListener(listener); try { this.send(context); holder.waitForNotify(); } catch (InterruptedException ie) { throw AxisFault.makeFault(ie); } if (holder.context != null) { return holder.context; } if (holder.exception != null) { throw AxisFault.makeFault((Exception)holder.exception); } return null; } public MessageContext sendAndReceive( MessageContext context, long timeout) throws AxisFault { holder = new Holder(); Listener listener = new Listener(holder); this.setMessageExchangeFaultListener(listener); this.setMessageExchangeReceiveListener(listener); try { this.send(context); holder.waitForNotify(timeout); } catch (InterruptedException ie) { throw AxisFault.makeFault(ie); } if (holder.context != null) { return holder.context; } if (holder.exception != null) { throw AxisFault.makeFault((Exception)holder.exception); } return null; } /** * @see org.apache.axis.ime.MessageExchange#startListening() */ public void startListening() { if (provider instanceof MessageExchangeProvider1) throw new UnsupportedOperationException(); for (int n = 0; n < WORKER_COUNT; n++) { workers.addWorker(receive, new ReceiverListener()); } listening = true; } /** * @see org.apache.axis.ime.MessageExchange#startListening() */ public void startListening(MessageExchangeCorrelator correlator) { throw new UnsupportedOperationException("Unsupported For Now"); } /** * @see org.apache.axis.ime.MessageExchange#stopListening() */ public void stopListening() { stopListening(false); } /** * @see org.apache.axis.ime.MessageExchange#stopListening(boolean) */ public void stopListening(boolean force) { if (provider instanceof MessageExchangeProvider1) throw new UnsupportedOperationException(); if (!force) workers.safeShutdown(); else workers.shutdown(); listening = false; } private class Holder { private MessageExchangeCorrelator correlator; private MessageContext context; private Throwable exception; public synchronized void set( MessageExchangeCorrelator correlator, MessageContext context) { this.correlator = correlator; this.context = context; notifyAll(); } public synchronized void set( MessageExchangeCorrelator correlator, Throwable throwable) { this.correlator = correlator; this.exception = throwable; notifyAll(); } public synchronized void waitForNotify() throws InterruptedException { wait(); return; } public synchronized void waitForNotify(long timeout) throws InterruptedException { wait(timeout); return; } } public class Listener implements MessageExchangeReceiveListener, MessageExchangeFaultListener { protected Holder holder; public Listener(Holder holder) { this.holder = holder; } /** * @see org.apache.axis.ime.MessageExchangeReceiveListener#onReceive(MessageExchangeCorrelator, MessageContext) */ public void onReceive( MessageExchangeCorrelator correlator, MessageContext context) { holder.set(correlator,context); } /** * @see org.apache.axis.ime.MessageExchangeFaultListener#onFault(MessageExchangeCorrelator, Throwable) */ public void onFault( MessageExchangeCorrelator correlator, Throwable exception) { holder.set(correlator,exception); } } private class ReceiverListener implements MessageExchangeContextListener { /** * @see org.apache.axis.ime.MessageExchangeContextListener#onMessageExchangeContext(MessageExchangeContext) */ public void onMessageExchangeContext( MessageExchangeContext context) { MessageContext msgContext = context.getMessageContext(); MessageExchangeCorrelator correlator = context.getMessageExchangeCorrelator(); try { // there should be code here to see if the message // contains a fault. if so, the fault listener should // be invoked if (msgContext != null && msgContext.getResponseMessage() != null && receiveListener != null) { receiveListener.onReceive(correlator, msgContext); } } catch (Exception exception) { if (faultListener != null) faultListener.onFault( correlator, exception); } } } /** * @see org.apache.axis.ime.MessageExchangeLifecycle#awaitShutdown() */ public void awaitShutdown() throws InterruptedException { provider.awaitShutdown(); } /** * @see org.apache.axis.ime.MessageExchangeLifecycle#awaitShutdown(long) */ public void awaitShutdown(long timeout) throws InterruptedException { provider.awaitShutdown(timeout); } /** * @see org.apache.axis.ime.MessageExchangeLifecycle#init() */ public void init() { provider.init(); } /** * @see org.apache.axis.ime.MessageExchangeLifecycle#shutdown() */ public void shutdown() { provider.shutdown(); } /** * @see org.apache.axis.ime.MessageExchangeLifecycle#shutdown(boolean) */ public void shutdown(boolean force) { provider.shutdown(force); } /** * @see org.apache.axis.ime.MessageExchange#receive() */ public MessageContext receive() throws AxisFault { throw new UnsupportedOperationException(); } /** * @see org.apache.axis.ime.MessageExchange#receive(long) */ public MessageContext receive(long timeout) throws AxisFault { throw new UnsupportedOperationException(); } } 1.1 xml-axis/java/src/org/apache/axis/ime/internal/MessageExchangeProvider2.java Index: MessageExchangeProvider2.java =================================================================== package org.apache.axis.ime.internal; import org.apache.axis.ime.MessageExchangeContextListener; import org.apache.axis.ime.MessageExchange; /** * Serves as a base class for MessageExchangeProviders that * need to thread pooling only on send message flows (as * opposed to MessageExchangeProvider1 which does thread * pooling on send AND receive flows) * * @author James M Snell ([EMAIL PROTECTED]) */ public abstract class MessageExchangeProvider2 extends MessageExchangeProvider { protected abstract MessageExchangeContextListener createSendMessageContextListener(); public void init(long THREAD_COUNT) { if (initialized) throw new IllegalStateException(); for (int n = 0; n < THREAD_COUNT; n++) { WORKERS.addWorker(SEND, createSendMessageContextListener()); } initialized = true; } } 1.1 xml-axis/java/src/org/apache/axis/ime/internal/MessageWorker.java Index: MessageWorker.java =================================================================== package org.apache.axis.ime.internal; import org.apache.axis.MessageContext; import org.apache.axis.ime.MessageChannel; import org.apache.axis.ime.MessageExchangeContext; import org.apache.axis.ime.MessageExchangeContextListener; /** * @author James M Snell ([EMAIL PROTECTED]) */ public class MessageWorker implements Runnable { protected static final long SELECT_TIMEOUT = 1000 * 30; protected MessageWorkerGroup pool; protected MessageChannel channel; protected MessageExchangeContextListener listener; private MessageWorker() {} public MessageWorker( MessageWorkerGroup pool, MessageChannel channel, MessageExchangeContextListener listener) { this.pool = pool; this.channel = channel; this.listener = listener; } public MessageExchangeContextListener getMessageExchangeContextListener() { return this.listener; } public MessageChannel getMessageChannel() { return this.channel; } /** * @see java.lang.Runnable#run() */ public void run() { try { while (!pool.isShuttingDown()) { MessageExchangeContext context = channel.select(SELECT_TIMEOUT); if (context != null) listener.onMessageExchangeContext(context); } } catch (Throwable t) { // kill the thread if any type of exception occurs. // don't worry, we'll create another one to replace it // if we're not currently in the process of shutting down. // once I get the logging function plugged in, we'll // log whatever errors do occur } finally { pool.workerDone(this); } } } 1.1 xml-axis/java/src/org/apache/axis/ime/internal/NonPersistentMessageChannel.java Index: NonPersistentMessageChannel.java =================================================================== package org.apache.axis.ime.internal; import java.util.Vector; import org.apache.axis.ime.MessageChannel; import org.apache.axis.ime.MessageExchangeContext; /** * Creates a non-persistent message channel. Queued messages * are stored in memory. If the Channel instance is destroyed, * so is the Queue. * * @author James M Snell ([EMAIL PROTECTED]) */ public class NonPersistentMessageChannel implements MessageChannel { private final KeyedQueue messages = new KeyedQueue(); private MessageWorkerGroup WORKERS; public NonPersistentMessageChannel( MessageWorkerGroup workers) { this.WORKERS = workers; } public MessageExchangeContext peek() { KeyedNode node = null; synchronized(messages) { node = messages.peek(); } if (node != null) { return (MessageExchangeContext)node.value; } else { return null; } } public void put( Object key, MessageExchangeContext context) { if (key == null || context == null) throw new IllegalArgumentException(); synchronized(messages) { messages.put(new KeyedNode(key,context)); messages.notify(); } } public MessageExchangeContext cancel(Object key) { if (key == null) throw new IllegalArgumentException(); MessageExchangeContext context = null; synchronized(messages) { KeyedNode node = messages.select(key); // will attempt to find an remove if (node != null) context = (MessageExchangeContext)node.value; node.key = null; node.value = null; } return context; } public MessageExchangeContext[] selectAll() { Vector v = new Vector(); KeyedNode node = null; synchronized(messages) { while ((node = messages.select()) != null) { v.add(node.value); node.key = null; node.value = null; } } MessageExchangeContext[] contexts = new MessageExchangeContext[v.size()]; v.copyInto(contexts); return contexts; } public MessageExchangeContext select() throws InterruptedException { for (;;) { if (WORKERS.isShuttingDown()) throw new IllegalStateException(); KeyedNode node = null; synchronized(messages) { node = messages.select(); } if (node != null) { MessageExchangeContext context = (MessageExchangeContext)node.value; node.key = null; node.value = null; return context; } else { messages.wait(); } } } public MessageExchangeContext select(long timeout) throws InterruptedException { for (;;) { if (WORKERS.isShuttingDown()) throw new IllegalStateException(); KeyedNode node = null; synchronized(messages) { node = messages.select(); } if (node != null) { MessageExchangeContext context = (MessageExchangeContext)node.value; node.key = null; node.value = null; return context; } else { messages.wait(timeout); } } } public MessageExchangeContext select(Object key) throws InterruptedException { for (;;) { if (WORKERS.isShuttingDown()) throw new IllegalStateException(); KeyedNode node = null; synchronized(messages) { node = messages.select(key); } if (node != null) { MessageExchangeContext context = (MessageExchangeContext)node.value; node.key = null; node.value = null; return context; } else { messages.wait(); } } } public MessageExchangeContext select(Object key, long timeout) throws InterruptedException { for (;;) { if (WORKERS.isShuttingDown()) throw new IllegalStateException(); KeyedNode node = null; synchronized(messages) { node = messages.select(key); } if (node != null) { MessageExchangeContext context = (MessageExchangeContext)node.value; node.key = null; node.value = null; return context; } else { messages.wait(timeout); } } } /// Support Classes /// protected static class KeyedNode { public Object key; public Object value; public KeyedNode next; public KeyedNode() {} public KeyedNode( Object key, Object value) { this.key = key; this.value = value; } public KeyedNode( Object key, Object value, KeyedNode next) { this(key,value); this.next = next; } } protected static class KeyedQueue { protected KeyedNode head; protected KeyedNode last; protected void put(KeyedNode node) { if (last == null) { last = head = node; } else { last = last.next = node; } } protected KeyedNode select() { KeyedNode node = head; if (node != null && (head = node.next) == null) { last = null; } if (node != null) node.next = null; return node; } protected KeyedNode select(Object key) { KeyedNode previous = null; for (KeyedNode node = head;node != null;node = node.next) { if (node.key.equals(key)) { if (previous != null) previous.next = node.next; node.next = null; return node; } previous = node; } return null; } protected KeyedNode peek() { KeyedNode node = head; return node; } } } 1.1 xml-axis/java/src/org/apache/axis/ime/internal/MessageExchangeProvider.java Index: MessageExchangeProvider.java =================================================================== package org.apache.axis.ime.internal; import org.apache.axis.ime.MessageExchangeFactory; import org.apache.axis.ime.MessageExchange; import org.apache.axis.ime.MessageChannel; /** * Serves as a base class for MessageExchangeProviders that * need to thread pooling on send AND receive message * flows (as opposed to MessageExchangeProvider2 which only * does thread pooling on send flows). * * @author James M Snell ([EMAIL PROTECTED]) */ public abstract class MessageExchangeProvider implements MessageExchangeFactory { public static final long DEFAULT_THREAD_COUNT = 5; protected final MessageWorkerGroup WORKERS = new MessageWorkerGroup(); protected final MessageChannel SEND = new NonPersistentMessageChannel(WORKERS); protected final MessageChannel RECEIVE = new NonPersistentMessageChannel(WORKERS); protected boolean initialized = false; public MessageExchange createMessageExchange() { return new MessageExchangeImpl(this,SEND,RECEIVE); } public void init() { init(DEFAULT_THREAD_COUNT); } public abstract void init(long THREAD_COUNT); public void shutdown() { shutdown(false); } public void shutdown(boolean force) { if (!force) { WORKERS.safeShutdown(); } else { WORKERS.shutdown(); } } public void awaitShutdown() throws InterruptedException { WORKERS.awaitShutdown(); } public void awaitShutdown(long shutdown) throws InterruptedException { WORKERS.awaitShutdown(shutdown); } } 1.1 xml-axis/java/src/org/apache/axis/ime/internal/MessageWorkerGroup.java Index: MessageWorkerGroup.java =================================================================== package org.apache.axis.ime.internal; import java.util.Map; import java.util.Hashtable; import java.util.Iterator; import org.apache.axis.ime.MessageChannel; import org.apache.axis.ime.MessageExchangeContextListener; /** * @author James M Snell ([EMAIL PROTECTED]) */ public class MessageWorkerGroup { protected Map threads = new Hashtable(); protected boolean interrupt; protected long threadcount; public boolean _shutdown; /** * Returns true if all workers have been shutdown */ public boolean isShutdown() { synchronized(this) { return _shutdown && threadcount == 0; } } /** * Returns true if all workers are in the process of shutting down */ public boolean isShuttingDown() { synchronized(this) { return _shutdown; } } /** * Returns the total number of currently active workers */ public long getWorkerCount() { synchronized(this) { return threadcount; } } /** * Adds a new worker to the pool */ public void addWorker( MessageChannel channel, MessageExchangeContextListener listener) { if (_shutdown) throw new IllegalStateException(); MessageWorker worker = new MessageWorker(this, channel, listener); Thread thread = new Thread(worker); threads.put(worker,thread); threadcount++; thread.start(); } /** * Forcefully interrupt all workers */ public void interruptAll() { synchronized(threads) { for (Iterator i = threads.values().iterator(); i.hasNext();) { Thread t = (Thread)i.next(); t.interrupt(); } } } /** * Forcefully shutdown the pool */ public void shutdown() { synchronized(this) { _shutdown = true; } interruptAll(); } /** * Forcefully shutdown the pool */ public void safeShutdown() { synchronized(this) { _shutdown = true; } } /** * Await shutdown of the worker */ public synchronized void awaitShutdown() throws InterruptedException { if (!_shutdown) throw new IllegalStateException(); while (threadcount > 0) wait(); } /** * Await shutdown of the worker */ public synchronized boolean awaitShutdown(long timeout) throws InterruptedException { if (!_shutdown) throw new IllegalStateException(); if (threadcount == 0) return true; long waittime = timeout; if (waittime <= 0) return false; long start = System.currentTimeMillis(); for (;;) { wait(waittime); if (threadcount == 0) return true; waittime = timeout - System.currentTimeMillis(); if (waittime <= 0) return false; } } /** * Used by MessageWorkers to notify the pool that it is done */ protected synchronized void workerDone( MessageWorker worker) { threads.remove(worker); if (--threadcount == 0 && _shutdown) { notifyAll(); } if (!_shutdown) { addWorker( worker.getMessageChannel(), worker.getMessageExchangeContextListener()); } } } 1.1 xml-axis/java/src/org/apache/axis/ime/internal/util/uuid/UUIDGenFactory.java Index: UUIDGenFactory.java =================================================================== /** * * UUIDGen adopted from the juddi project * (http://sourceforge.net/projects/juddi/) * */ package org.apache.axis.ime.internal.util.uuid; import java.io.*; /** * A Universally Unique Identifier (UUID) is a 128 bit number generated * according to an algorithm that is garanteed to be unique in time and space * from all other UUIDs. It consists of an IEEE 802 Internet Address and * various time stamps to ensure uniqueness. For a complete specification, * see ftp://ietf.org/internet-drafts/draft-leach-uuids-guids-01.txt [leach]. * * @author Steve Viens * @version 1.0 11/7/2000 * @since JDK1.2.2 */ public abstract class UUIDGenFactory { private static final String defaultUUIDGenClassName = "org.apache.axis.ime.internal.util.uuid.SimpleUUIDGen"; /** * getInstance * * Returns the singleton instance of UUIDGen */ public static UUIDGen getUUIDGen(String uuidgenClassName) { UUIDGen uuidgen = null; if ((uuidgenClassName == null) || (uuidgenClassName.length() == 0)) { // use the default UUIDGen implementation uuidgenClassName = defaultUUIDGenClassName; } Class uuidgenClass = null; try { // instruct the class loader to load the UUIDGen implementation uuidgenClass = java.lang.Class.forName(uuidgenClassName); } catch(ClassNotFoundException e) { throw new RuntimeException("The implementation of UUIDGen interface " + "specified cannot be found in the classpath: "+uuidgenClassName + " not found."); } try { // try to instantiate the UUIDGen subclass uuidgen = (UUIDGen)uuidgenClass.newInstance(); } catch(java.lang.Exception e) { throw new RuntimeException("Exception encountered while attempting to " + "instantiate the specified implementation of UUIDFactory: " + uuidgenClass.getName() + "; message = " + e.getMessage()); } return uuidgen; } /** * Release any aquired external resources and stop any background threads. */ public static void destroyUUIDGen(UUIDGen uuidgen) { if (uuidgen != null) uuidgen.destroy(); } /***************************************************************************/ /***************************** TEST DRIVER *********************************/ /***************************************************************************/ // test driver public static void main(String argc[]) { long startTime = 0; long endTime = 0; UUIDGen uuidgen = null; uuidgen = UUIDGenFactory.getUUIDGen(null); // uuidgen = UUIDGenFactory.getUUIDGen("org.juddi.uuidgen.SimpleUUIDGen"); startTime = System.currentTimeMillis(); for (int i = 1; i <= 50; ++i) { String u = uuidgen.nextUUID(); System.out.println( i + ": " + u ); } endTime = System.currentTimeMillis(); System.out.println("SimpleJavaUUIDGen took "+(endTime-startTime)+" milliseconds"); UUIDGenFactory.destroyUUIDGen(uuidgen); } } 1.1 xml-axis/java/src/org/apache/axis/ime/internal/util/uuid/SimpleUUIDGen.java Index: SimpleUUIDGen.java =================================================================== /** * * UUIDGen adopted from the juddi project * (http://sourceforge.net/projects/juddi/) * */ package org.apache.axis.ime.internal.util.uuid; import java.math.*; import java.util.*; import java.security.SecureRandom; /** * Used to create new universally unique identifiers or UUID's (sometimes called * GUID's). UDDI UUID's are allways formmated according to DCE UUID conventions. * * @author Maarten Coene * @author Steve Viens * @version 0.3.2 3/25/2001 * @since JDK1.2.2 */ public class SimpleUUIDGen implements UUIDGen { private static final BigInteger countStart = new BigInteger("-12219292800000"); // 15 October 1582 private static final int clock_sequence = (new Random()).nextInt(16384); /** * Creates a new UUID. The algorithm used is described by The Open Group. * See <a href="http://www.opengroup.org/onlinepubs/009629399/apdxa.htm"> * Universal Unique Identifier</a> for more details. * <p> * Due to a lack of functionality in Java, a part of the UUID is a secure * random. This results in a long processing time when this method is called * for the first time. */ public String nextUUID() { // TODO: this method has to be checked for it's correctness. I'm not sure the standard is // implemented correctly. // the count of 100-nanosecond intervals since 00:00:00.00 15 October 1582 BigInteger count; // the number of milliseconds since 1 January 1970 BigInteger current = BigInteger.valueOf(System.currentTimeMillis()); // the number of milliseconds since 15 October 1582 BigInteger countMillis = current.subtract(countStart); // the result count = countMillis.multiply(BigInteger.valueOf(10000)); String bitString = count.toString(2); if (bitString.length() < 60) { int nbExtraZeros = 60 - bitString.length(); String extraZeros = new String(); for (int i=0; i<nbExtraZeros; i++) extraZeros = extraZeros.concat("0"); bitString = extraZeros.concat(bitString); } byte[] bits = bitString.getBytes(); // the time_low field byte[] time_low = new byte[32]; for (int i=0; i<32; i++) time_low[i] = bits[bits.length - i - 1]; // the time_mid field byte[] time_mid = new byte[16]; for (int i=0; i<16; i++) time_mid[i] = bits[bits.length - 32 - i - 1]; // the time_hi_and_version field byte[] time_hi_and_version = new byte[16]; for (int i=0; i<12; i++) time_hi_and_version[i] = bits[bits.length - 48 - i - 1]; time_hi_and_version[12] = ((new String("1")).getBytes())[0]; time_hi_and_version[13] = ((new String("0")).getBytes())[0]; time_hi_and_version[14] = ((new String("0")).getBytes())[0]; time_hi_and_version[15] = ((new String("0")).getBytes())[0]; // the clock_seq_low field BigInteger clockSequence = BigInteger.valueOf(clock_sequence); String clockString = clockSequence.toString(2); if (clockString.length() < 14) { int nbExtraZeros = 14 - bitString.length(); String extraZeros = new String(); for (int i=0; i<nbExtraZeros; i++) extraZeros = extraZeros.concat("0"); clockString = extraZeros.concat(bitString); } byte[] clock_bits = clockString.getBytes(); byte[] clock_seq_low = new byte[8]; for (int i=0; i<8; i++) clock_seq_low[i] = clock_bits[clock_bits.length - i - 1]; // the clock_seq_hi_and_reserved byte[] clock_seq_hi_and_reserved = new byte[8]; for (int i=0; i<6; i++) clock_seq_hi_and_reserved[i] = clock_bits[clock_bits.length - 8 - i - 1]; clock_seq_hi_and_reserved[6] = ((new String("0")).getBytes())[0]; clock_seq_hi_and_reserved[7] = ((new String("1")).getBytes())[0]; String timeLow = Long.toHexString((new BigInteger(new String(reverseArray(time_low)), 2)).longValue()); if (timeLow.length() < 8) { int nbExtraZeros = 8 - timeLow.length(); String extraZeros = new String(); for (int i=0; i<nbExtraZeros; i++) extraZeros = extraZeros.concat("0"); timeLow = extraZeros.concat(timeLow); } String timeMid = Long.toHexString((new BigInteger(new String(reverseArray(time_mid)), 2)).longValue()); if (timeMid.length() < 4) { int nbExtraZeros = 4 - timeMid.length(); String extraZeros = new String(); for (int i=0; i<nbExtraZeros; i++) extraZeros = extraZeros.concat("0"); timeMid = extraZeros.concat(timeMid); } String timeHiAndVersion = Long.toHexString((new BigInteger(new String(reverseArray(time_hi_and_version)), 2)).longValue()); if (timeHiAndVersion.length() < 4) { int nbExtraZeros = 4 - timeHiAndVersion.length(); String extraZeros = new String(); for (int i=0; i<nbExtraZeros; i++) extraZeros = extraZeros.concat("0"); timeHiAndVersion = extraZeros.concat(timeHiAndVersion); } String clockSeqHiAndReserved = Long.toHexString((new BigInteger(new String(reverseArray(clock_seq_hi_and_reserved)), 2)).longValue()); if (clockSeqHiAndReserved.length() < 2) { int nbExtraZeros = 2 - clockSeqHiAndReserved.length(); String extraZeros = new String(); for (int i=0; i<nbExtraZeros; i++) extraZeros = extraZeros.concat("0"); clockSeqHiAndReserved = extraZeros.concat(clockSeqHiAndReserved); } String clockSeqLow = Long.toHexString((new BigInteger(new String(reverseArray(clock_seq_low)), 2)).longValue()); if (clockSeqLow.length() < 2) { int nbExtraZeros = 2 - clockSeqLow.length(); String extraZeros = new String(); for (int i=0; i<nbExtraZeros; i++) extraZeros = extraZeros.concat("0"); clockSeqLow = extraZeros.concat(clockSeqLow); } // problem: the node should be the IEEE 802 ethernet address, but can not // be retrieved in Java yet. // see bug ID 4173528 // workaround (also suggested in bug ID 4173528) // If a system wants to generate UUIDs but has no IEE 802 compliant // network card or other source of IEEE 802 addresses, then this section // describes how to generate one. // The ideal solution is to obtain a 47 bit cryptographic quality random // number, and use it as the low 47 bits of the node ID, with the most // significant bit of the first octet of the node ID set to 1. This bit // is the unicast/multicast bit, which will never be set in IEEE 802 // addresses obtained from network cards; hence, there can never be a // conflict between UUIDs generated by machines with and without network // cards. Random secureRandom = null; try { secureRandom = SecureRandom.getInstance("SHA1PRNG", "SUN"); } catch (Exception e) { secureRandom = new Random(); } long nodeValue = secureRandom.nextLong(); nodeValue = Math.abs(nodeValue); while (nodeValue > 140737488355328L) { nodeValue = secureRandom.nextLong(); nodeValue = Math.abs(nodeValue); } BigInteger nodeInt = BigInteger.valueOf(nodeValue); String nodeString = nodeInt.toString(2); if (nodeString.length() < 47) { int nbExtraZeros = 47 - nodeString.length(); String extraZeros = new String(); for (int i=0; i<nbExtraZeros; i++) extraZeros = extraZeros.concat("0"); nodeString = extraZeros.concat(nodeString); } byte[] node_bits = nodeString.getBytes(); byte[] node = new byte[48]; for (int i=0; i<47; i++) node[i] = node_bits[node_bits.length - i - 1]; node[47] = ((new String("1")).getBytes())[0]; String theNode = Long.toHexString((new BigInteger(new String(reverseArray(node)), 2)).longValue()); if (theNode.length() < 12) { int nbExtraZeros = 12 - theNode.length(); String extraZeros = new String(); for (int i=0; i<nbExtraZeros; i++) extraZeros = extraZeros.concat("0"); theNode = extraZeros.concat(theNode); } String result = timeLow + "-" + timeMid +"-" + timeHiAndVersion + "-" + clockSeqHiAndReserved + clockSeqLow + "-" + theNode; return result.toUpperCase(); } private static byte[] reverseArray(byte[] bits) { byte[] result = new byte[bits.length]; for (int i=0; i<result.length; i++) result[i] = bits[result.length - 1 - i]; return result; } // test driver public static void main(String argc[]) { UUIDGen uuidgen = new SimpleUUIDGen(); for (int i = 1; i <= 250; ++i) { String uuid = uuidgen.nextUUID(); System.out.println( i + ": " + uuid ); } } public void destroy() { } public void init() { } } 1.1 xml-axis/java/src/org/apache/axis/ime/internal/util/uuid/UUIDGen.java Index: UUIDGen.java =================================================================== /** * * UUIDGen adopted from the juddi project * (http://sourceforge.net/projects/juddi/) * */ package org.apache.axis.ime.internal.util.uuid; import java.io.*; /** * A Universally Unique Identifier (UUID) is a 128 bit number generated * according to an algorithm that is garanteed to be unique in time and space * from all other UUIDs. It consists of an IEEE 802 Internet Address and * various time stamps to ensure uniqueness. For a complete specification, * see ftp://ietf.org/internet-drafts/draft-leach-uuids-guids-01.txt [leach]. * * @author Steve Viens * @version 1.0 11/7/2000 * @since JDK1.2.2 */ public interface UUIDGen { public void init(); public void destroy(); public String nextUUID(); } 1.1 xml-axis/java/src/org/apache/axis/ime/internal/util/handler/HandlerWrapper1.java Index: HandlerWrapper1.java =================================================================== package org.apache.axis.ime.internal.util.handler; import org.apache.axis.Message; import org.apache.axis.MessageContext; import org.apache.axis.ime.MessageExchange; import org.apache.axis.ime.MessageExchangeContext; import org.apache.axis.ime.MessageExchangeContextListener; import org.apache.axis.ime.MessageExchangeFaultListener; import org.apache.axis.ime.MessageExchangeStatus; import org.apache.axis.ime.MessageExchangeStatusListener; import org.apache.axis.ime.MessageExchangeReceiveListener; import org.apache.axis.ime.MessageExchangeCorrelator; import org.apache.axis.ime.internal.NonPersistentMessageChannel; import org.apache.axis.ime.internal.MessageExchangeImpl; import org.apache.axis.ime.internal.MessageExchangeProvider1; import org.apache.axis.ime.internal.MessageWorkerGroup; import org.apache.axis.Handler; /** * Used to wrap synchronous handlers (e.g. Axis 1.0 transports) * * @author James M Snell ([EMAIL PROTECTED]) */ public class HandlerWrapper1 extends MessageExchangeProvider1 { private Handler handler; public HandlerWrapper1(Handler handler) { this.handler = handler; } /** * @see org.apache.axis.ime.internal.MessageExchangeProvider1#createReceiveMessageContextListener() */ protected MessageExchangeContextListener createReceiveMessageContextListener() { return new ReceiveListener(); } /** * @see org.apache.axis.ime.internal.MessageExchangeProvider1#createSendMessageContextListener() */ protected MessageExchangeContextListener createSendMessageContextListener() { return new SendListener(handler); } public class SendListener implements MessageExchangeContextListener { private Handler handler; public SendListener(Handler handler) { this.handler = handler; } /** * @see org.apache.axis.ime.MessageExchangeContextListener#onMessageExchangeContext(MessageExchangeContext) */ public void onMessageExchangeContext( MessageExchangeContext context) { try { MessageContext msgContext = context.getMessageContext(); MessageExchangeCorrelator correlator = context.getMessageExchangeCorrelator(); // should I do init's and cleanup's in here? handler.invoke(msgContext); RECEIVE.put(correlator, context); } catch (Exception exception) { MessageExchangeFaultListener listener = context.getMessageExchangeFaultListener(); if (listener != null) listener.onFault( context.getMessageExchangeCorrelator(), exception); } } } public class ReceiveListener implements MessageExchangeContextListener { /** * @see org.apache.axis.ime.MessageExchangeContextListener#onMessageExchangeContext(MessageExchangeContext) */ public void onMessageExchangeContext( MessageExchangeContext context) { MessageExchangeReceiveListener receiveListener = context.getMessageExchangeReceiveListener(); MessageExchangeFaultListener faultListener = context.getMessageExchangeFaultListener(); MessageContext msgContext = context.getMessageContext(); MessageExchangeCorrelator correlator = context.getMessageExchangeCorrelator(); try { // there should be code here to see if the message // contains a fault. if so, the fault listener should // be invoked if (msgContext != null && msgContext.getResponseMessage() != null && receiveListener != null) { receiveListener.onReceive(correlator, msgContext); } } catch (Exception exception) { if (faultListener != null) faultListener.onFault( correlator, exception); } } } } 1.1 xml-axis/java/src/org/apache/axis/ime/internal/util/handler/HandlerWrapper2.java Index: HandlerWrapper2.java =================================================================== package org.apache.axis.ime.internal.util.handler; import org.apache.axis.Message; import org.apache.axis.MessageContext; import org.apache.axis.ime.MessageExchange; import org.apache.axis.ime.MessageExchangeContext; import org.apache.axis.ime.MessageExchangeContextListener; import org.apache.axis.ime.MessageExchangeFaultListener; import org.apache.axis.ime.MessageExchangeStatus; import org.apache.axis.ime.MessageExchangeStatusListener; import org.apache.axis.ime.MessageExchangeReceiveListener; import org.apache.axis.ime.MessageExchangeCorrelator; import org.apache.axis.ime.internal.NonPersistentMessageChannel; import org.apache.axis.ime.internal.MessageExchangeImpl; import org.apache.axis.ime.internal.MessageExchangeProvider2; import org.apache.axis.ime.internal.MessageWorkerGroup; import org.apache.axis.Handler; /** * Used to wrap synchronous handlers (e.g. Axis 1.0 transports) * * @author James M Snell ([EMAIL PROTECTED]) */ public class HandlerWrapper2 extends MessageExchangeProvider2 { private Handler handler; public HandlerWrapper2(Handler handler) { this.handler = handler; } /** * @see org.apache.axis.ime.internal.MessageExchangeProvider1#createSendMessageContextListener() */ protected MessageExchangeContextListener createSendMessageContextListener() { return new SendListener(handler); } public class SendListener implements MessageExchangeContextListener { private Handler handler; public SendListener(Handler handler) { this.handler = handler; } /** * @see org.apache.axis.ime.MessageExchangeContextListener#onMessageExchangeContext(MessageExchangeContext) */ public void onMessageExchangeContext( MessageExchangeContext context) { try { MessageContext msgContext = context.getMessageContext(); MessageExchangeCorrelator correlator = context.getMessageExchangeCorrelator(); // should I do init's and cleanup's in here? handler.invoke(msgContext); RECEIVE.put(correlator, context); } catch (Exception exception) { MessageExchangeFaultListener listener = context.getMessageExchangeFaultListener(); if (listener != null) listener.onFault( context.getMessageExchangeCorrelator(), exception); } } } }