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.