You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by jm...@apache.org on 2002/10/27 00:05:05 UTC
cvs commit: xml-axis/java/src/org/apache/axis/ime/internal/util/handler HandlerWrapper1.java HandlerWrapper2.java
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 (jasnell@us.ibm.com)
*/
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 (jasnell@us.ibm.com)
*/
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 (jasnell@us.ibm.com)
*/
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 (jasnell@us.ibm.com)
*/
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 (jasnell@us.ibm.com)
*/
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 (jasnell@us.ibm.com)
*/
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 (jasnell@us.ibm.com)
*/
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 (jasnell@us.ibm.com)
*/
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 (jasnell@us.ibm.com)
*/
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 (jasnell@us.ibm.com)
*/
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);
}
}
}
}
Re: cvs commit: xml-axis/java/src/org/apache/axis/ime/internal/util/handler HandlerWrapper1.java HandlerWrapper2.java
Posted by Steve Loughran <st...@iseran.com>.
----- Original Message -----
From: <jm...@apache.org>
To: <xm...@apache.org>
Sent: Saturday, October 26, 2002 14:05
Subject: cvs commit:
xml-axis/java/src/org/apache/axis/ime/internal/util/handler
HandlerWrapper1.java HandlerWrapper2.java
> java/src/org/apache/axis/ime/internal/util/uuid
> UUIDGenFactory.java SimpleUUIDGen.java
UUIDGen.java
I'd be tempted to make the uuid factory part of the utils stuff in in all
axis builds, uuids being so useful and all.