Author: schor
Date: Thu Dec 20 14:51:16 2018
New Revision: 1849402

URL: http://svn.apache.org/viewvc?rev=1849402&view=rev
Log:
[UIMA-5937] update pom version and scm, merge v2 updates, record merge

Added:
    
uima/uv3/uima-as-v3/trunk/uimaj-as-jms/src/main/java/org/apache/uima/adapter/jms/client/UimaAsClientStoppingException.java
      - copied unchanged from r1846915, 
uima/uima-as/trunk/uimaj-as-jms/src/main/java/org/apache/uima/adapter/jms/client/UimaAsClientStoppingException.java
Modified:
    uima/uv3/uima-as-v3/trunk/uimaj-as-jms/   (props changed)
    uima/uv3/uima-as-v3/trunk/uimaj-as-jms/pom.xml
    
uima/uv3/uima-as-v3/trunk/uimaj-as-jms/src/main/java/org/apache/uima/adapter/jms/client/BaseMessageSender.java
    
uima/uv3/uima-as-v3/trunk/uimaj-as-jms/src/main/java/org/apache/uima/adapter/jms/client/BaseUIMAAsynchronousEngineCommon_impl.java
    
uima/uv3/uima-as-v3/trunk/uimaj-as-jms/src/main/java/org/apache/uima/adapter/jms/client/ClientServiceDelegate.java
    
uima/uv3/uima-as-v3/trunk/uimaj-as-jms/src/main/java/org/apache/uima/adapter/jms/message/PendingMessage.java
    
uima/uv3/uima-as-v3/trunk/uimaj-as-jms/src/main/java/org/apache/uima/adapter/jms/service/Dd2spring.java
    
uima/uv3/uima-as-v3/trunk/uimaj-as-jms/src/main/resources/jms_adapter_messages.properties

Propchange: uima/uv3/uima-as-v3/trunk/uimaj-as-jms/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Dec 20 14:51:16 2018
@@ -1,2 +1,3 @@
 /uima/uima-as/branches/depend-on-parent-pom-4/uimaj-as-jms:961335-961760
 /uima/uima-as/branches/mavenAlign/uimaj-as-jms:941450-944450
+/uima/uima-as/trunk/uimaj-as-jms:1786000-1846915

Modified: uima/uv3/uima-as-v3/trunk/uimaj-as-jms/pom.xml
URL: 
http://svn.apache.org/viewvc/uima/uv3/uima-as-v3/trunk/uimaj-as-jms/pom.xml?rev=1849402&r1=1849401&r2=1849402&view=diff
==============================================================================
--- uima/uv3/uima-as-v3/trunk/uimaj-as-jms/pom.xml (original)
+++ uima/uv3/uima-as-v3/trunk/uimaj-as-jms/pom.xml Thu Dec 20 14:51:16 2018
@@ -15,7 +15,7 @@
        <parent>
                <groupId>org.apache.uima</groupId>
                <artifactId>uima-as-parent</artifactId>
-               <version>3.0.0-SNAPSHOT</version>
+               <version>3.0.1-SNAPSHOT</version>
                <relativePath>../uima-as-parent/pom.xml</relativePath>
        </parent>
 
@@ -30,13 +30,13 @@
                cutting/pasting the <scm> element, and just changing the 
following two properties -->
        <scm>
                <connection>
-      scm:svn:http://svn.apache.org/repos/asf/uima/uima-as/trunk/uimaj-as-jms
+      
scm:svn:http://svn.apache.org/repos/asf/uima/uv3/uima-as-v3/trunk/uimaj-as-jms
     </connection>
                <developerConnection>
-      scm:svn:https://svn.apache.org/repos/asf/uima/uima-as/trunk/uimaj-as-jms
+      
scm:svn:https://svn.apache.org/repos/asf/uima/uv3/uima-as-v3/trunk/uimaj-as-jms
     </developerConnection>
                <url>
-      http://svn.apache.org/viewvc/uima/uima-as/trunk/uimaj-as-jms
+      http://svn.apache.org/viewvc/uima/uv3/uima-as-v3/trunk/uimaj-as-jms
     </url>
        </scm>
 

Modified: 
uima/uv3/uima-as-v3/trunk/uimaj-as-jms/src/main/java/org/apache/uima/adapter/jms/client/BaseMessageSender.java
URL: 
http://svn.apache.org/viewvc/uima/uv3/uima-as-v3/trunk/uimaj-as-jms/src/main/java/org/apache/uima/adapter/jms/client/BaseMessageSender.java?rev=1849402&r1=1849401&r2=1849402&view=diff
==============================================================================
--- 
uima/uv3/uima-as-v3/trunk/uimaj-as-jms/src/main/java/org/apache/uima/adapter/jms/client/BaseMessageSender.java
 (original)
+++ 
uima/uv3/uima-as-v3/trunk/uimaj-as-jms/src/main/java/org/apache/uima/adapter/jms/client/BaseMessageSender.java
 Thu Dec 20 14:51:16 2018
@@ -20,6 +20,7 @@
 package org.apache.uima.adapter.jms.client;
 
 import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.LinkedBlockingQueue;
 
 import javax.jms.Connection;
@@ -85,7 +86,9 @@ public abstract class BaseMessageSender
 
   // Releases resources
   protected abstract void cleanup() throws Exception;
-
+  
+  protected abstract void dispatchMessage(PendingMessage pm, 
BaseUIMAAsynchronousEngineCommon_impl engine, boolean casProcessRequest ) 
throws Exception;
+         
   // Returns the name of the destination
   protected abstract String getDestinationEndpoint() throws Exception;
 
@@ -93,6 +96,7 @@ public abstract class BaseMessageSender
   
   private MessageProducer producer = null;
   
+  private CountDownLatch stopLatch = new CountDownLatch(1);
 
   public BaseMessageSender(BaseUIMAAsynchronousEngineCommon_impl anEngine) {
     messageQueue = anEngine.pendingMessageQueue;
@@ -110,9 +114,32 @@ public abstract class BaseMessageSender
    */
   public void doStop() {
     done = true;
+    
     // Create an empty message to deliver to the queue that is blocking
     PendingMessage emptyMessage = new PendingMessage(0);
+    
+    messageQueue.add(emptyMessage);
+    synchronized(emptyMessage) {
+       try {
+               emptyMessage.wait(200);
+       } catch( Exception ee) {
+               
+       }
+       
+    }
     messageQueue.add(emptyMessage);
+    if (UIMAFramework.getLogger(CLASS_NAME).isLoggable(
+                       Level.INFO)) {
+     UIMAFramework.getLogger(CLASS_NAME).logrb(Level.INFO,
+                               CLASS_NAME.getName(), "doStop",
+                               JmsConstants.JMS_LOG_RESOURCE_BUNDLE,
+                               "UIMAJMS_STOP_DISPATCH_THREAD_INFO");
+  }
+    try {
+        stopLatch.await();
+    } catch( InterruptedException e) {
+       
+    }
   }
 
   /**
@@ -216,6 +243,11 @@ public abstract class BaseMessageSender
    */
   public void run() {
     String destination = null;
+    if (UIMAFramework.getLogger(CLASS_NAME).isLoggable(Level.INFO)) {
+          UIMAFramework.getLogger(CLASS_NAME).logrb(Level.INFO, 
getClass().getName(),
+                  "run", JmsConstants.JMS_LOG_RESOURCE_BUNDLE,
+                  "UIMAJMS_START_DISPATCH_THREAD_INFO");
+    }
     //  by default, add time to live to each message
     boolean addTimeToLive = true;
     // Check the environment for existence of NoTTL tag. If present,
@@ -261,7 +293,13 @@ public abstract class BaseMessageSender
       } catch (InterruptedException e) {
       }
       if (done) {
-        break; // done in this loop
+         if (UIMAFramework.getLogger(CLASS_NAME).isLoggable(Level.INFO)) {
+              UIMAFramework.getLogger(CLASS_NAME).logrb(Level.INFO, 
getClass().getName(),
+                      "run", JmsConstants.JMS_LOG_RESOURCE_BUNDLE,
+                      "UIMAJMS_EXIT_DISPATCH_THREAD_INFO");
+            }
+         stopLatch.countDown();
+         break; // done in this loop
       }
       //  Check if the request should be rejected. If the connection to the 
broker is invalid and the request
       //  is not GetMeta Ping, reject the request after the connection is 
made. The reject() method created
@@ -283,7 +321,7 @@ public abstract class BaseMessageSender
       }
      
       //  get the producer initialized from a valid connection
-      producer = getMessageProducer();
+//      producer = getMessageProducer();
       //  Check if the request should be rejected. It would be the case if the 
connection was invalid and
       //  subsequently recovered. If it was invalid, we went through error 
handling and the request is stale.
       if ( !rejectRequest && engine.running) {
@@ -295,6 +333,24 @@ public abstract class BaseMessageSender
                       "UIMAJMS_client_dispatching_getmeta_ping__INFO", new 
Object[] { });
             }
            }
+          
+          // NEW CODE 07/12/2017
+          while( engine.running ) {
+                 try {
+                     //  blocks until the connection is re-established with a 
broker
+                     engine.recoverSharedConnectionIfClosed();
+                     SharedConnection sc = 
+                                 
engine.lookupConnection(engine.getBrokerURI());
+                     dispatchMessage(pm,engine,isProcessRequest(pm));
+               
+                         break;
+                 } catch( Exception exx) {
+                         
+                 }
+          }
+          
+          
+        /*  
            try {
              // Request JMS Message from the concrete implementation
              Message message = null;
@@ -306,7 +362,9 @@ public abstract class BaseMessageSender
              } else {
                message = createTextMessage();
              }
-
+             //  get the producer initialized from a valid connection
+             producer = getMessageProducer();
+            
              initializeMessage(pm, message);
              if (UIMAFramework.getLogger(CLASS_NAME).isLoggable(Level.FINE)) {
                UIMAFramework.getLogger(CLASS_NAME).logrb(
@@ -425,17 +483,21 @@ public abstract class BaseMessageSender
              }
              reject(pm,e);
            }
-
+*/
       }
     }
     try {
       cleanup();
+      if ( stopLatch.getCount() > 0) {
+         stopLatch.countDown();
+      }
+      stopLatch.countDown();
     } catch (Exception e) {
       handleException(e, destination);
     }
   }
 
-  private void initializeMessage(PendingMessage aPm, Message 
anOutgoingMessage) throws Exception {
+  protected void initializeMessage(PendingMessage aPm, Message 
anOutgoingMessage) throws Exception {
     // Populate message properties based on outgoing message type
     switch (aPm.getMessageType()) {
       case AsynchAEMessage.GetMeta:
@@ -459,6 +521,19 @@ public abstract class BaseMessageSender
       case AsynchAEMessage.CollectionProcessComplete:
         engine.setCPCMessage(anOutgoingMessage);
         break;
+        
+      case AsynchAEMessage.ReleaseCAS:
+          String casRefId = (String) aPm.get(AsynchAEMessage.CasReference);
+          String selector = 
+                                (String) 
aPm.get(AsynchAEMessage.TargetingSelector) ;
+
+          engine.setFreeCasMessage(anOutgoingMessage, casRefId, selector);
+          break;
+          
+      case AsynchAEMessage.Stop:
+          String casRefId2 = (String) aPm.get(AsynchAEMessage.CasReference);
+          engine.setStopMessage(anOutgoingMessage, casRefId2);
+         break;
     }
   }
 

Modified: 
uima/uv3/uima-as-v3/trunk/uimaj-as-jms/src/main/java/org/apache/uima/adapter/jms/client/BaseUIMAAsynchronousEngineCommon_impl.java
URL: 
http://svn.apache.org/viewvc/uima/uv3/uima-as-v3/trunk/uimaj-as-jms/src/main/java/org/apache/uima/adapter/jms/client/BaseUIMAAsynchronousEngineCommon_impl.java?rev=1849402&r1=1849401&r2=1849402&view=diff
==============================================================================
--- 
uima/uv3/uima-as-v3/trunk/uimaj-as-jms/src/main/java/org/apache/uima/adapter/jms/client/BaseUIMAAsynchronousEngineCommon_impl.java
 (original)
+++ 
uima/uv3/uima-as-v3/trunk/uimaj-as-jms/src/main/java/org/apache/uima/adapter/jms/client/BaseUIMAAsynchronousEngineCommon_impl.java
 Thu Dec 20 14:51:16 2018
@@ -31,6 +31,7 @@ import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Timer;
 import java.util.TimerTask;
+import java.util.UUID;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ExecutorService;
@@ -38,7 +39,6 @@ import java.util.concurrent.Executors;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.Semaphore;
 import java.util.concurrent.atomic.AtomicLong;
-
 import java.util.Collections;
 import java.util.Comparator;
 
@@ -246,8 +246,12 @@ public abstract class BaseUIMAAsynchrono
 
   abstract protected void setCASMessage(String casReferenceId, byte[] 
aSerializedCAS, Message msg)
           throws Exception;
+  
+  abstract protected void setFreeCasMessage(Message msg, String 
aCasReferenceId, String selector) throws Exception;
+
+  abstract protected void setStopMessage(Message msg, String aCasReferenceId) 
throws Exception;
 
-  abstract public void setCPCMessage(Message msg) throws Exception;
+  abstract protected void setCPCMessage(Message msg) throws Exception;
 
   abstract public void initialize(Map anApplicationContext) throws 
ResourceInitializationException;
 
@@ -264,6 +268,8 @@ public abstract class BaseUIMAAsynchrono
   abstract protected void initializeConsumer(String aBrokerURI, Connection 
connection) throws Exception;
 
   abstract protected SharedConnection validateConnection(String aBrokerURI) 
throws Exception;
+  
+  abstract protected void dispatchFreeCasRequest(String casReferenceId, 
Message message) throws Exception;
 
   // enables/disable timer per CAS. Defaul is to use single timer for
   // all outstanding CASes
@@ -536,13 +542,20 @@ public abstract class BaseUIMAAsynchrono
 
         // Unblock threads
         if (threadMonitorMap.size() > 0) {
-          Iterator it = threadMonitorMap.keySet().iterator();
+          Iterator<?> it = threadMonitorMap.keySet().iterator();
           while (it.hasNext()) {
             long key = ((Long) it.next()).longValue();
             ThreadMonitor threadMonitor = (ThreadMonitor) 
threadMonitorMap.get(key);
             if (threadMonitor == null || threadMonitor.getMonitor() == null) {
               continue;
             }
+            // convey that the semaphore was released from stop(). 
+            // Any thread waiting in sendAndReceive() will check for this
+            // and throw an exception back to the client. This would have 
+            // a similar effect to an Interrupt. A thread in blocked in 
+            // sendAndReceive() until a reply comes or stop() clears the
+            // threadMonitor semaphore.
+            threadMonitor.calledFromStopMethod();
             threadMonitor.getMonitor().release();
           }
         }
@@ -819,7 +832,14 @@ public abstract class BaseUIMAAsynchrono
          if ( (hasNext = collectionReader.hasNext()) == true) {
              cas = getCAS();
              collectionReader.getNext(cas);
-             sendCAS(cas);
+             String targetStringSelector = 
+                        
System.getProperty(UimaAsynchronousEngine.TargetSelectorProperty);
+             if (targetStringSelector != null && 
targetStringSelector.trim().length() > 0 ) {
+                sendCAS(cas, targetStringSelector );
+             } else {
+                sendCAS(cas);
+             }
+             
          } else {
            break;
          }
@@ -856,12 +876,17 @@ public abstract class BaseUIMAAsynchrono
    * Sends a given CAS for analysis to the UIMA EE Service.
    * 
    */
-  private String sendCAS(CAS aCAS, ClientRequest requestToCache) throws 
ResourceProcessException {
+  private String sendCAS(CAS aCAS, ClientRequest requestToCache, String 
targetServiceId) throws ResourceProcessException {
     synchronized (sendMux) {
       if ( requestToCache == null ) {
         throw new ResourceProcessException(new Exception("Invalid Process 
Request. Cache Entry is Null"));
       }
       String casReferenceId = requestToCache.getCasReferenceId();
+      // check if application wants to target a specific service instance to 
process the CAS
+      if ( targetServiceId != null) {
+         // the dispatcher will fetch the service target id before sending the 
msg
+         requestToCache.setTargetServiceId(targetServiceId);
+      }
       try {
         if (!running) {
           if (UIMAFramework.getLogger(CLASS_NAME).isLoggable(Level.INFO)) {
@@ -1016,8 +1041,14 @@ public abstract class BaseUIMAAsynchrono
     if ( !running ) {
        throw new ResourceProcessException(new UimaEEServiceException("Uima AS 
Client Has Been Stopped. Rejecting Request to Process CAS"));
     }
-         return this.sendCAS(aCAS, produceNewClientRequestObject());
+         return this.sendCAS(aCAS, produceNewClientRequestObject(), null);
   }
+  public synchronized String sendCAS(CAS aCAS, String targetServiceId) throws 
ResourceProcessException {
+           if ( !running ) {
+               throw new ResourceProcessException(new 
UimaEEServiceException("Uima AS Client Has Been Stopped. Rejecting Request to 
Process CAS"));
+           }
+                 return this.sendCAS(aCAS, 
produceNewClientRequestObject(),targetServiceId);
+         }
 
   /**
    * Handles response to CollectionProcessComplete request.
@@ -1108,7 +1139,7 @@ public abstract class BaseUIMAAsynchrono
                            "UIMAJMS_dispatch_delayed_cas__INFO",
                            new Object[] { casReferenceId, 
String.valueOf(cachedRequest.cas.hashCode())});
                  }
-                 sendCAS(cachedRequest.getCAS(), cachedRequest);
+                 sendCAS(cachedRequest.getCAS(), cachedRequest,null);
                }
          }
       } else {
@@ -1500,11 +1531,35 @@ public abstract class BaseUIMAAsynchrono
     // exists in the client's cache.
     // Fetch the input CAS Reference Id from which the CAS being processed was 
generated from
     String inputCasReferenceId = 
message.getStringProperty(AsynchAEMessage.InputCasReference);
-    // Fetch the destination for Free CAS notification
-    Destination freeCASNotificationDestination = message.getJMSReplyTo();
+    try {
+         String nodeIP = message.getStringProperty(AsynchAEMessage.ServerIP);
+             String pid = 
message.getStringProperty(AsynchAEMessage.UimaASProcessPID);
+              if ( 
message.getStringProperty(AsynchAEMessage.TargetingSelector) != null) {
+                         
serviceDelegate.setFreeCasSelector(message.getStringProperty(AsynchAEMessage.TargetingSelector));
+                         System.out.println("+++++++++++++++++ Client Received 
Service Targeting Selector:"+
+                                         
message.getStringProperty(AsynchAEMessage.TargetingSelector));
+                 }
+//           System.out.println("%%%%%%%%%%%%% CasMultiplier Sent 
IP:"+nodeIP+" PID:"+pid);
+       // Free a given CAS in the remote CM
+        dispatchFreeCasRequest(casReferenceId, message);
+
+    } catch (Exception e) {
+       e.printStackTrace();
+          if (UIMAFramework.getLogger(CLASS_NAME).isLoggable(Level.WARNING)) {
+            UIMAFramework.getLogger(CLASS_NAME).logrb(Level.WARNING, 
CLASS_NAME.getName(),
+                    "handleProcessReplyFromCasMultiplier", 
JmsConstants.JMS_LOG_RESOURCE_BUNDLE,
+                    "UIMAJMS_error_while_sending_msg__WARNING",
+                    new Object[] { "Free Cas Temp Destination", e });
+          }
+        }
+     
+    /*
+     *     Destination freeCASNotificationDestination = 
message.getJMSReplyTo();
+
     if (freeCASNotificationDestination != null) {
       TextMessage msg = createTextMessage();
       msg.setText("");
+     dsa
       setReleaseCASMessage(msg, casReferenceId);
        MessageProducer msgProducer = null;
        try {
@@ -1539,7 +1594,7 @@ public abstract class BaseUIMAAsynchrono
         }
       }
     }
-    
+    */
     // Fetch an entry from the client cache for a given input CAS id. This 
would be an id
     // of the CAS that the client sent out to the service.
     ClientRequest inputCasCachedRequest = (ClientRequest) 
clientCache.get(inputCasReferenceId);
@@ -1735,6 +1790,10 @@ public abstract class BaseUIMAAsynchrono
           } else {
             status = new UimaASProcessStatusImpl(pt, cas, casReferenceId);
           }
+          if ( cachedRequest.getTargetServiceId() != null ) {
+                 status.setServiceTargetID(cachedRequest.getTargetServiceId());
+          }
+          
           if ( message.propertyExists(AsynchAEMessage.CASPerComponentMetrics)) 
{
  
              List<AnalysisEnginePerformanceMetrics> ml = 
@@ -2102,18 +2161,29 @@ public abstract class BaseUIMAAsynchrono
   public String sendAndReceiveCAS(CAS aCAS) throws ResourceProcessException {
     return sendAndReceiveCAS(aCAS, null, null);
   }
+  /**
+   * This method is not part of a public interface and should not be used by 
an application
+   * directly. It is used by a test code internally. 
+   * 
+   * @param aCAS - CAS to process
+   * @param pt - ProcessTrace to aggregate stats
+   * @return - Spring container ID
+   * @throws ResourceProcessException on error
+   */
   public String sendAndReceiveCAS(CAS aCAS, ProcessTrace pt) throws 
ResourceProcessException {
-    return sendAndReceiveCAS(aCAS, pt, null);
+    return sendAndReceiveCAS(aCAS, pt, null, null);
   }
   public String sendAndReceiveCAS(CAS aCAS, 
List<AnalysisEnginePerformanceMetrics> componentMetricsList) throws 
ResourceProcessException {
-    return sendAndReceiveCAS(aCAS, null, componentMetricsList);
+    return sendAndReceiveCAS(aCAS, null, componentMetricsList, null);
   }
-
+  public String sendAndReceiveCAS(CAS aCAS, 
List<AnalysisEnginePerformanceMetrics> componentMetricsList, String 
targetServiceId) throws ResourceProcessException {
+           return sendAndReceiveCAS(aCAS, null, componentMetricsList, 
targetServiceId);
+         }
   /**
    * This is a synchronous method which sends a message to a destination and 
blocks waiting for a
    * reply.
    */
-  public String sendAndReceiveCAS(CAS aCAS, ProcessTrace pt, 
List<AnalysisEnginePerformanceMetrics> componentMetricsList) throws 
ResourceProcessException {
+  public String sendAndReceiveCAS(CAS aCAS, ProcessTrace pt, 
List<AnalysisEnginePerformanceMetrics> componentMetricsList, String 
targetServiceId) throws ResourceProcessException {
     if (!running) {
       throw new ResourceProcessException(new Exception("Uima EE Client Not In 
Running State"));
     }
@@ -2139,7 +2209,7 @@ public abstract class BaseUIMAAsynchrono
 
     ClientRequest cachedRequest = produceNewClientRequestObject();
     cachedRequest.setSynchronousInvocation();
-    
+//    cachedRequest.setTargetServiceId(targetServiceId);
     // save application provided List where the performance stats will be 
copied
     //  when reply comes back
     cachedRequest.setComponentMetricsList(componentMetricsList);
@@ -2176,7 +2246,7 @@ public abstract class BaseUIMAAsynchrono
                 "UIMAJMS_cas_submitting_FINE", new Object[] { casReferenceId, 
String.valueOf(aCAS.hashCode()), Thread.currentThread().getId()});
       }
       // send CAS. This call does not block. Instead we will block the sending 
thread below.
-      casReferenceId = sendCAS(aCAS, cachedRequest);
+      casReferenceId = sendCAS(aCAS, cachedRequest, targetServiceId);
 
     } catch( ResourceProcessException e) {
       
@@ -2211,6 +2281,12 @@ public abstract class BaseUIMAAsynchrono
           // CAS reply is received. Ping reply logic does not change
           // this flag.
           threadMonitor.getMonitor().acquire();
+          // if the semaphore was cleared in the stop() method, the client
+          // must be in a shutdown mode. Throw an exception back to the
+          // caller. The CAS reply has not come back yet.
+          if ( threadMonitor.wasCalledFromStopMethod()) {
+                 throw new ResourceProcessException(new 
UimaAsClientStoppingException("Client is stopping - sendAndReceive() has been 
interrupted"));
+          }
           // Send thread was awoken by either process reply or ping reply
           // If the service is in the ok state and the CAS is in the
           // list of CASes pending dispatch, remove the CAS from the list
@@ -2226,7 +2302,7 @@ public abstract class BaseUIMAAsynchrono
           }
           if (running && serviceDelegate.getState() == Delegate.OK_STATE
                   && 
serviceDelegate.removeCasFromPendingDispatchList(casReferenceId)) {
-            sendCAS(aCAS, cachedRequest);
+            sendCAS(aCAS, cachedRequest, targetServiceId);
           } else {
             break; // done here, received a reply or the client is not running
           }
@@ -2548,7 +2624,17 @@ public abstract class BaseUIMAAsynchrono
     // flag to indicate if the remote service acknowledged receiving a CAS for 
processing
     private volatile boolean receivedServiceACK=false;
     
-    public boolean receivedServiceACK() {
+    private String targetServiceId;
+    
+    public String getTargetServiceId() {
+               return targetServiceId;
+       }
+
+       public void setTargetServiceId(String serviceTargetId) {
+               this.targetServiceId = serviceTargetId;
+       }
+
+       public boolean receivedServiceACK() {
                return receivedServiceACK;
        }
 
@@ -2902,13 +2988,20 @@ public abstract class BaseUIMAAsynchrono
 
   protected static class ThreadMonitor {
     private long threadId;
-
+    private volatile boolean calledFromStop = false;
+    
     private Semaphore monitor = new Semaphore(1);
 
     public ThreadMonitor(long aThreadId) {
       threadId = aThreadId;
     }
 
+    public void calledFromStopMethod() {
+       calledFromStop = true;
+    }
+    public boolean wasCalledFromStopMethod() {
+       return calledFromStop;
+    }
     public long getThreadId() {
       return threadId;
     }
@@ -2963,7 +3056,7 @@ public abstract class BaseUIMAAsynchrono
         //  System.out.println("------------- 
BaseUIMAAsynchronousEngineCommon_impl.recoverSharedConnectionIfClosed() Got new 
connection");
         getDispatcher().setConnection(sharedConnection.getConnection());
         
-        System.out.println("Uima-AS Client Recovered Broker Connection - 
Sending GetMeta Ping");
+        //System.out.println("Uima-AS Client Recovered Broker Connection - 
Sending GetMeta Ping");
         serviceDelegate.setAwaitingPingReply();
 
         try {
@@ -3129,12 +3222,19 @@ public abstract class BaseUIMAAsynchrono
           //System.out.println("------------- 
BaseUIMAAsynchronousEngineCommon_impl.create() - ConnectionFactory is null");
         throw new InstantiationException("UIMA AS Client Unable to Initialize 
SharedConnection Object. ConnectionFactory Has Not Been Provided");
       }
+      if ( connection != null ) {
+         try {
+                 connection.close();
+         } catch( Exception eee) {
+                 
+         }
+      }
       //System.out.println("------------- 
BaseUIMAAsynchronousEngineCommon_impl.create() - Creating new Connection");
       //  Create shared jms connection to a broker
       connection = connectionFactory.createConnection();
+      connection.setClientID("ClientListener-"+UIDGenerator.getGUID());
       state = ConnectionState.OPEN;
       stop = false;      
-      //System.out.println("------------- 
BaseUIMAAsynchronousEngineCommon_impl.create() - Created New Connection");
     }
     private void reinitializeClientListeners() {
       for( BaseUIMAAsynchronousEngineCommon_impl client : clientList ) {
@@ -3196,17 +3296,29 @@ public abstract class BaseUIMAAsynchrono
       //  using this shared object terminate or a connection is recovered
       boolean log = true;
       while( !stop ) {
+         
+         BaseUIMAAsynchronousEngineCommon_impl c = null;
         if ( clientList.size() == 0 ) {
           break; // no more active clients - break out of connection recovery
         } else {
-               BaseUIMAAsynchronousEngineCommon_impl c =
-                               clientList.get(0);
+               
+               c = clientList.get(0);
+               if ( !c.running) {
+                       break;
+               } 
         }
         try {
+               
           //  Attempt a new connection to a broker
           create();
+          if ( c != null && !c.running) {
+                 break;
+          }
           //  Got it, start the connection
           start();
+          if ( c != null && !c.running) {
+                 break;
+          }
           //  Forces clients to drop old Session, Temp Queue, and Consumer 
objects and create 
           //  new ones. This is needs to be done after a new Connection is 
created.
           reinitializeClientListeners();
@@ -3222,7 +3334,7 @@ public abstract class BaseUIMAAsynchrono
                           JmsConstants.JMS_LOG_RESOURCE_BUNDLE, 
"UIMAJMS_client_connection_retry__INFO",
                           new Object[] { brokerURL });
                 }
-                       if ( e instanceof JMSException && 
e.getMessage().endsWith("Connection refused") ) {
+                       if ( e instanceof JMSException && 
e.getMessage().indexOf("Connection refused") > 0) {
                                log = false;
                        System.out.println("Uima AS Client:"+e.getMessage()+" 
Retrying every 5 seconds until successfull");
                     

Modified: 
uima/uv3/uima-as-v3/trunk/uimaj-as-jms/src/main/java/org/apache/uima/adapter/jms/client/ClientServiceDelegate.java
URL: 
http://svn.apache.org/viewvc/uima/uv3/uima-as-v3/trunk/uimaj-as-jms/src/main/java/org/apache/uima/adapter/jms/client/ClientServiceDelegate.java?rev=1849402&r1=1849401&r2=1849402&view=diff
==============================================================================
--- 
uima/uv3/uima-as-v3/trunk/uimaj-as-jms/src/main/java/org/apache/uima/adapter/jms/client/ClientServiceDelegate.java
 (original)
+++ 
uima/uv3/uima-as-v3/trunk/uimaj-as-jms/src/main/java/org/apache/uima/adapter/jms/client/ClientServiceDelegate.java
 Thu Dec 20 14:51:16 2018
@@ -55,7 +55,10 @@ public class ClientServiceDelegate exten
 
   private volatile boolean pingTimeout = false;
   
-  public ClientServiceDelegate(String serviceName, String anApplicationName,
+  private String freeCasSelector = "";
+  
+ 
+public ClientServiceDelegate(String serviceName, String anApplicationName,
           BaseUIMAAsynchronousEngineCommon_impl engine) {
     super.delegateKey = serviceName;
     clientUimaAsEngine = engine;
@@ -63,6 +66,13 @@ public class ClientServiceDelegate exten
       applicationName = anApplicationName;
     }
   }
+public String getFreeCasSelector() {
+       return freeCasSelector;
+}
+
+public void setFreeCasSelector(String freeCasSelector) {
+       this.freeCasSelector = freeCasSelector;
+}
 
   public boolean isSynchronousAPI() {
     return usesSynchronousAPI;

Modified: 
uima/uv3/uima-as-v3/trunk/uimaj-as-jms/src/main/java/org/apache/uima/adapter/jms/message/PendingMessage.java
URL: 
http://svn.apache.org/viewvc/uima/uv3/uima-as-v3/trunk/uimaj-as-jms/src/main/java/org/apache/uima/adapter/jms/message/PendingMessage.java?rev=1849402&r1=1849401&r2=1849402&view=diff
==============================================================================
--- 
uima/uv3/uima-as-v3/trunk/uimaj-as-jms/src/main/java/org/apache/uima/adapter/jms/message/PendingMessage.java
 (original)
+++ 
uima/uv3/uima-as-v3/trunk/uimaj-as-jms/src/main/java/org/apache/uima/adapter/jms/message/PendingMessage.java
 Thu Dec 20 14:51:16 2018
@@ -20,8 +20,10 @@ package org.apache.uima.adapter.jms.mess
 
 import java.util.HashMap;
 
-public class PendingMessage extends HashMap {
-  private int messageType;
+public class PendingMessage extends HashMap<Object, Object> {
+ 
+private static final long serialVersionUID = 3512718154731557413L;
+private int messageType;
 
   public PendingMessage(int aMessageType) {
     messageType = aMessageType;

Modified: 
uima/uv3/uima-as-v3/trunk/uimaj-as-jms/src/main/java/org/apache/uima/adapter/jms/service/Dd2spring.java
URL: 
http://svn.apache.org/viewvc/uima/uv3/uima-as-v3/trunk/uimaj-as-jms/src/main/java/org/apache/uima/adapter/jms/service/Dd2spring.java?rev=1849402&r1=1849401&r2=1849402&view=diff
==============================================================================
--- 
uima/uv3/uima-as-v3/trunk/uimaj-as-jms/src/main/java/org/apache/uima/adapter/jms/service/Dd2spring.java
 (original)
+++ 
uima/uv3/uima-as-v3/trunk/uimaj-as-jms/src/main/java/org/apache/uima/adapter/jms/service/Dd2spring.java
 Thu Dec 20 14:51:16 2018
@@ -19,8 +19,11 @@
 
 package org.apache.uima.adapter.jms.service;
 
+import java.io.BufferedWriter;
 import java.io.File;
+import java.io.FileWriter;
 import java.io.IOException;
+import java.io.StringWriter;
 import java.lang.reflect.Method;
 import java.net.MalformedURLException;
 import java.net.URL;
@@ -28,172 +31,469 @@ import java.net.URLClassLoader;
 import java.util.ArrayList;
 import java.util.List;
 
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.sax.SAXSource;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
 import org.apache.uima.UIMAFramework;
 import org.apache.uima.aae.UIMAEE_Constants;
 import org.apache.uima.adapter.jms.JmsConstants;
+import org.apache.uima.internal.util.XMLUtils;
 import org.apache.uima.util.Level;
+import org.xml.sax.InputSource;
+import org.xml.sax.XMLReader;
 
 public class Dd2spring {
 
-  private static final Class<Dd2spring> THIS_CLASS = Dd2spring.class;
+       private static final Class<Dd2spring> THIS_CLASS = Dd2spring.class;
+
+       private ClassLoader saxonClassLoader;
 
-  private ClassLoader saxonClassLoader;
-  
-  /**
-   * Test driver arg = path_to_source, path_to_xslt, path_to_saxon_jar, 
uima-as-debug flag
-   * 
-   * @param args
-   */
-  public static void main(String[] args) {
-         try {
-                   new Dd2spring().convertDd2Spring(args[0], args[1], args[2], 
args[3]);
+       /**
+        * Test driver arg = path_to_source, path_to_xslt, path_to_saxon_jar,
+        * uima-as-debug flag
+        * 
+        * @param args
+        */
+       public static void main(String[] args) {
+               try {
+                       new Dd2spring()
+                                       .convertDd2Spring(args[0], args[1], 
args[2], args[3]);
+
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+       }
+
+       public File convertDd2Spring(String ddFilePath,
+                       String dd2SpringXsltFilePath, String saxonClasspath,
+                       String uimaAsDebug) throws Exception {
+
+               URL urlForSaxonClassPath;
+               try {
+                       urlForSaxonClassPath = new URL(saxonClasspath);
+               } catch (MalformedURLException e) {
+                       e.printStackTrace();
+                       UIMAFramework
+                                       .getLogger(THIS_CLASS)
+                                       .logrb(Level.CONFIG,
+                                                       THIS_CLASS.getName(),
+                                                       "convertDD2Spring",
+                                                       
JmsConstants.JMS_LOG_RESOURCE_BUNDLE,
+                                                       
"UIMA_dd2spring_Cannot_convert_saxon_classpath_to_a_URL_SEVERE",
+                                                       new Object[] { 
saxonClasspath });
+                       return null;
+               }
+
+               File tempFile;
+               try {
+                       tempFile = File.createTempFile("UIMAdd2springOutput", 
".xml");
+               } catch (IOException e) {
+                       e.printStackTrace();
+                       UIMAFramework.getLogger(THIS_CLASS).logrb(Level.CONFIG,
+                                       THIS_CLASS.getName(), 
"convertDD2Spring",
+                                       JmsConstants.JMS_LOG_RESOURCE_BUNDLE,
+                                       
"UIMA_dd2spring_cant_create_temp_output_file_SEVERE");
+                       return null;
+               }
+
+               // UIMA-5022 No longer capture output and scan for "ERROR: " as 
that hid
+               // errors that Saxon followed by calling exit!
+               // Processing now terminates on the first error.
+               convertDd2Spring(tempFile, ddFilePath, dd2SpringXsltFilePath,
+                               urlForSaxonClassPath);
+
+               // delete the file when terminating if
+               // a) uimaAsDebug is not specified (is null) or
+               // b) uimaAsDebug is specified, but is ""
+               if (null == uimaAsDebug || uimaAsDebug.equals("")) {
+                       tempFile.deleteOnExit();
+               }
+
+               return tempFile;
+       }
+
+       private void testForSaxon9InClasspath() throws Exception {
+               // UIMA-5117 Check for saxon9. If it is in the users's 
classpath an NPE
+               // is thrown in
+               // net.sf.saxon.event.ReceivingContentHandler.getNodeName while 
handling
+               // a getMeta request.
+               try {
+                       Class<?> saxonVersionClass = 
Class.forName("net.sf.saxon.Version");
+                       Method versionMethod = saxonVersionClass
+                                       .getMethod("getProductVersion");
+                       String version = (String) versionMethod.invoke(null);
+                       if (version.startsWith("9")) {
+                               
UIMAFramework.getLogger(THIS_CLASS).logrb(Level.SEVERE,
+                                               THIS_CLASS.getName(), 
"convertDD2Spring",
+                                               
UIMAEE_Constants.JMS_LOG_RESOURCE_BUNDLE,
+                                               "UIMAEE_exception__SEVERE",
+                                               new Object[] { "saxon9 must not 
be in classpath" });
+                               throw new Dd2springException(
+                                               "saxon9 found in classpath - 
dd2spring transformation and UIMA-AS do not support saxon9");
+                       }
+               } catch (ClassNotFoundException e) {
+                       // OK - saxon not in classpath
+               }
+       }
+
+       /**
+        * 
+        * @param tempFile
+        *            file to hold generated Spring from dd2spring transform
+        * @param ddFilePath
+        *            file path to UIMA Deployment Descriptor - passed to saxon
+        * @param dd2SpringXsltFilePath
+        *            file path to dd2spring.xslt transformation file - passed 
to
+        *            saxon
+        * @param saxonClasspathURL
+        *            classpath for saxon8.jar
+        */
+       public void convertDd2Spring(File tempFile, String ddFilePath,
+                       String dd2SpringXsltFilePath, URL saxonClasspathURL)
+                       throws Exception {
+
+               testForSaxon9InClasspath();
+
+               // UIMA-5117 - Add shutdown hook so can log when saxon gives up 
and
+               // calls exit :(
+               ShutdownHook shutdownHook = new ShutdownHook();
+               Runtime.getRuntime().addShutdownHook(shutdownHook);
+
+               // Create a classloader with saxon8 that delegates to the user's
+               // classloader and includes the classes defining xslt helper 
java methods
+               //   org.apache.uima.aae.deploymentDescriptor.XsltGUIDgenerator 
and
+               //   org.apache.uima.aae.deploymentDescriptor.XsltImportByName
+               // We do this by creating a custom class loader, which delegates
+               //   first to the threadlocal class loader, and then to 
+               //   the class loader that loaded this class.
+               //   See https://issues.apache.org/jira/browse/UIMA-5907
+               final ClassLoader tccl = 
Thread.currentThread().getContextClassLoader();
+               ClassLoader tccl_plus_this = new 
ClassLoader(this.getClass().getClassLoader()) {
+                 @Override
+                 protected Class<?> loadClass(String name, boolean resolve) 
throws ClassNotFoundException {
+                   synchronized(Dd2spring.class) {
+                   Class<?> c = null;
+                   try {
+                   c = tccl.loadClass(name);
+                   } catch (ClassNotFoundException e) {
+                     c = getParent().loadClass(name);
+                   }
+                   if (c != null && resolve) {
+                     resolveClass(c);
+                   }
+          return c;
+                 }
+                 }
+                 
+                 @Override
+                 public URL getResource(String name) {
+                   synchronized(Dd2spring.class) {
+                     URL url = tccl.getResource(name);
+                     if (null == url) {
+                       url = getParent().getResource(name);  
+                     }
+               return url;
+                   }
+                 }
                  
-         } catch ( Exception e) {
-                 e.printStackTrace();
-         }
-  }
-
-  public File convertDd2Spring(String ddFilePath, String dd2SpringXsltFilePath,
-          String saxonClasspath, String uimaAsDebug) throws Exception {
-
-    URL urlForSaxonClassPath;
-    try {
-      urlForSaxonClassPath = new URL(saxonClasspath);
-    } catch (MalformedURLException e) {
-      e.printStackTrace();
-      UIMAFramework.getLogger(THIS_CLASS).logrb(Level.CONFIG, 
THIS_CLASS.getName(),
-              "convertDD2Spring", JmsConstants.JMS_LOG_RESOURCE_BUNDLE,
-              "UIMA_dd2spring_Cannot_convert_saxon_classpath_to_a_URL_SEVERE",
-              new Object[] { saxonClasspath });
-      return null;
-    }
-
-    File tempFile;
-    try {
-      tempFile = File.createTempFile("UIMAdd2springOutput", ".xml");
-    } catch (IOException e) {
-      e.printStackTrace();
-      UIMAFramework.getLogger(THIS_CLASS).logrb(Level.CONFIG, 
THIS_CLASS.getName(),
-              "convertDD2Spring", JmsConstants.JMS_LOG_RESOURCE_BUNDLE,
-              "UIMA_dd2spring_cant_create_temp_output_file_SEVERE");
-      return null;
-    }
-
-    // UIMA-5022 No longer capture output and scan for "ERROR: " as that hid
-    // errors that Saxon followed by calling exit!
-    // Processing now terminates on the first error.
-    convertDd2Spring(tempFile, ddFilePath, dd2SpringXsltFilePath, 
urlForSaxonClassPath);
-
-    // delete the file when terminating if
-    // a) uimaAsDebug is not specified (is null) or
-    // b) uimaAsDebug is specified, but is ""
-    if (null == uimaAsDebug || uimaAsDebug.equals("")) {
-      tempFile.deleteOnExit();
-    }
-
-    return tempFile;
-  }
-
-  /**
-   *
-   * @param tempFile
-   *          file to hold generated Spring from dd2spring transform
-   * @param ddFilePath
-   *          file path to UIMA Deployment Descriptor - passed to saxon
-   * @param dd2SpringXsltFilePath
-   *          file path to dd2spring.xslt transformation file - passed to saxon
-   * @param saxonClasspathURL
-   *          classpath for saxon8.jar
-   */
-  public void convertDd2Spring(File tempFile, String ddFilePath, String 
dd2SpringXsltFilePath,
-          URL saxonClasspathURL) throws Exception {
-
-    // UIMA-5117 Check for saxon9.  If it is in the users's classpath an NPE 
is thrown in 
-    // net.sf.saxon.event.ReceivingContentHandler.getNodeName while handling a 
getMeta request.
-    try {
-      Class<?> saxonVersionClass = Class.forName("net.sf.saxon.Version");
-      Method versionMethod = saxonVersionClass.getMethod("getProductVersion");
-      String version = (String) versionMethod.invoke(null);
-      if (version.startsWith("9")) {
-        UIMAFramework.getLogger(THIS_CLASS).logrb(Level.SEVERE, 
THIS_CLASS.getName(), "convertDD2Spring", 
-                UIMAEE_Constants.JMS_LOG_RESOURCE_BUNDLE, 
"UIMAEE_exception__SEVERE",
-                new Object[] { "saxon9 must not be in classpath" });
-        throw new Dd2springException("saxon9 found in classpath - dd2spring 
transformation and UIMA-AS do not support saxon9");
-      }
-    } catch (ClassNotFoundException e) {
-      // OK - saxon not in classpath
-    }
-    
-    // UIMA-5117 - Add shutdown hook so can log when saxon gives up and calls 
exit :(
-    ShutdownHook shutdownHook = new ShutdownHook();
-    Runtime.getRuntime().addShutdownHook(shutdownHook);
-    
-    // Create a classloader with saxon8 that delegates to the user's 
classloader
-    ClassLoader currentClassloader = 
Thread.currentThread().getContextClassLoader();
-    if (null == saxonClassLoader) {
-      URL[] classLoaderUrls = new URL[] { saxonClasspathURL };
-      saxonClassLoader = new URLClassLoader(classLoaderUrls, 
currentClassloader);
-    }
-      
-    // args for saxon
-    // -l -s deployment_descriptor} -o output_file_path 
dd2spring.xsl_file_path <-x sax_parser_class>
-    // If a custom framework includes a custom XML parser we may also need a 
custom parser for Saxon,
-    // so check for the existence of a class with "_SAXParser" appended to the 
framework name.
-
-    List<String> argsForSaxon = new ArrayList<String>();
-    String uimaFrameworkClass = System.getProperty("uima.framework_impl");
-    if (uimaFrameworkClass != null) {
-      String saxonParserClass = uimaFrameworkClass + "_SAXParser";
-      try {
-        saxonClassLoader.loadClass(saxonParserClass);
-        argsForSaxon.add("-x");
-        argsForSaxon.add(saxonParserClass);
-      } catch (ClassNotFoundException e) {
-        // No parser class defined
-      }
-    }
-    argsForSaxon.add("-l"); // turn on line numbers
-    argsForSaxon.add("-s"); // source file
-    argsForSaxon.add(ddFilePath); // source file
-    argsForSaxon.add("-o"); // output file
-    argsForSaxon.add(tempFile.getAbsolutePath()); // output file
-    argsForSaxon.add(dd2SpringXsltFilePath); // xslt transform to apply
-
-    UIMAFramework.getLogger(THIS_CLASS).log(Level.INFO, "Saxon args: " + 
argsForSaxon);
-
-    // Set the thread classloader so that all classes are loaded from this
-    Thread.currentThread().setContextClassLoader(saxonClassLoader);
-    Class<?> mainStartClass = null;
-    try {
-      mainStartClass = Class.forName("net.sf.saxon.Transform", true, 
saxonClassLoader);
-      Method mainMethod = mainStartClass.getMethod("main", String[].class);
-      mainMethod.invoke(null, new Object[] { argsForSaxon.toArray(new 
String[argsForSaxon.size()]) });
-    } catch (ClassNotFoundException e) {
-      System.err.println("Error - can't load Saxon jar from " + 
saxonClasspathURL + " for dd2spring transformation.");
-      e.printStackTrace();
-      UIMAFramework.getLogger(THIS_CLASS).logrb(Level.SEVERE, 
THIS_CLASS.getName(), "convertDD2Spring", 
-              JmsConstants.JMS_LOG_RESOURCE_BUNDLE, 
"UIMA_dd2spring_saxon_missing_SEVERE");
-      throw e;
-    } catch (Exception e) {
-      System.err.println("Error - dd2spring transformation failed:");
-      e.printStackTrace();
-      UIMAFramework.getLogger(THIS_CLASS).logrb(Level.SEVERE, 
THIS_CLASS.getName(), "convertDD2Spring", 
-              JmsConstants.JMS_LOG_RESOURCE_BUNDLE, 
"UIMA_dd2spring_internal_error_calling_saxon");
-      throw e;
-    } finally {
-      // Restore original classloader and remove used shutdown hook
-      Thread.currentThread().setContextClassLoader(currentClassloader);
-      Runtime.getRuntime().removeShutdownHook(shutdownHook);
-    }
-    return;
-  }
-
-  // Shutdown hook that reports when Saxon calls exit!
-  private class ShutdownHook extends Thread {
-    public void run() {
-      System.err.println("ERROR in dd2spring Saxon transformation ... 
System.exit called");
-      System.err.flush();
-    }
-  }
+    };
+               
+               if (null == saxonClassLoader) {
+                       URL[] classLoaderUrls = new URL[] { saxonClasspathURL };
+                       saxonClassLoader = new URLClassLoader(classLoaderUrls,
+                                       tccl_plus_this);
+               }
+               // configure Saxon with these settings
+               SaxonInputs saxonConfig = new SaxonInputs(ddFilePath, tempFile,
+                               dd2SpringXsltFilePath, saxonClassLoader, 
tccl_plus_this);
+               
+               // creates either command line or java based interface to Saxon
+               SaxonInterface saxon = SaxonInterfaceFactory.newSaxonInterface(
+                               saxonConfig);
+
+               try {
+
+                       saxon.convertDD2Spring();
+
+               } catch (ClassNotFoundException e) {
+                       System.err.println("Error - can't load Saxon jar from "
+                                       + saxonClasspathURL + " for dd2spring 
transformation.");
+                       e.printStackTrace();
+                       UIMAFramework.getLogger(THIS_CLASS).logrb(Level.SEVERE,
+                                       THIS_CLASS.getName(), 
"convertDD2Spring",
+                                       JmsConstants.JMS_LOG_RESOURCE_BUNDLE,
+                                       "UIMA_dd2spring_saxon_missing_SEVERE");
+                       throw e;
+               } catch (Exception e) {
+                       System.err.println("Error - dd2spring transformation 
failed:");
+                       e.printStackTrace();
+                       UIMAFramework.getLogger(THIS_CLASS).logrb(Level.SEVERE,
+                                       THIS_CLASS.getName(), 
"convertDD2Spring",
+                                       JmsConstants.JMS_LOG_RESOURCE_BUNDLE,
+                                       
"UIMA_dd2spring_internal_error_calling_saxon");
+                       throw e;
+               } finally {
+                       Runtime.getRuntime().removeShutdownHook(shutdownHook);
+               }
+               return;
+       }
+
+       // Shutdown hook that reports when Saxon calls exit!
+       private class ShutdownHook extends Thread {
+               public void run() {
+                       System.err
+                                       .println("ERROR in dd2spring Saxon 
transformation ... System.exit called");
+                       System.err.flush();
+               }
+       }
+
+       /**
+        * The SaxonInputs class is used to configure Saxon
+        *
+        */
+       private class SaxonInputs {
+               String ddFilePath;
+               File springFilePath;
+               String xsltPath;
+               ClassLoader currentClassLoader;
+               ClassLoader saxonClassLoader;
+               public SaxonInputs(String ddFilePath, File springFilePath,
+                               String xsltPath, ClassLoader saxonClassloader,
+                               ClassLoader currentClassloader) {
+                       super();
+                       this.ddFilePath = ddFilePath;
+                       this.springFilePath = springFilePath;
+                       this.xsltPath = xsltPath;
+                       this.currentClassLoader = currentClassloader;
+                       this.saxonClassLoader = saxonClassloader;
+               }
+
+               public ClassLoader getCurrentClassLoader() {
+                       return currentClassLoader;
+               }
+               public ClassLoader getSaxonClassLoader() {
+                       return saxonClassLoader;
+               }
+
+               public String getDDFilePath() {
+                       return ddFilePath;
+               }
+
+               public File getSpringFilePath() {
+                       return springFilePath;
+               }
+
+               public String getXSLTPath() {
+                       return xsltPath;
+               }
+       }
+       // Factory to produce desired Saxon interface. Currently two
+       // are supported: command line based and java API based. The
+       // default is java API interface. The command line is used
+       // to provide Saxon a custom parser.
+       private static class SaxonInterfaceFactory {
+               public static SaxonInterface newSaxonInterface( SaxonInputs 
saxonConfig) {
+                       SaxonInterface saxon;
+                       if (System.getProperty("uima.framework_impl") != null) {
+                               
UIMAFramework.getLogger(THIS_CLASS).log(Level.INFO,
+                                            "Using Saxon command line 
interface - Java Vendor:"+System.getProperty("java.vendor"));
+                               // The command line based Saxon interface is 
used to plug-in
+                               // custom parser into Saxon
+                               saxon = new 
SaxonCommandLineInterface(saxonConfig);
+                       } else {
+                               
UIMAFramework.getLogger(THIS_CLASS).log(Level.INFO,
+                                    "Using Saxon Java API - Java 
Vendor:"+System.getProperty("java.vendor"));
+                               // Default, use java API based Saxon interface
+                               saxon = new SaxonJavaInterface(saxonConfig);
+                       }
+                       return saxon;
+               }
+       }
+
+       private interface SaxonInterface {
+               public void convertDD2Spring() throws Exception;
+       }
+
+       private static class SaxonCommandLineInterface implements 
SaxonInterface {
+               private List<String> argsForSaxon = new ArrayList<String>();
+               private SaxonInputs saxonConfig;
+               
+               SaxonCommandLineInterface(SaxonInputs saxonConfig) {
+                       // args for saxon
+                       // -l -s deployment_descriptor} -o output_file_path
+                       // dd2spring.xsl_file_path <-x sax_parser_class>
+                       // If a custom framework includes a custom XML parser 
we may also
+                       // need a custom parser for Saxon,
+                       // so check for the existence of a class with 
"_SAXParser" appended
+                       // to the framework name.
+                       this.saxonConfig = saxonConfig;
+                       argsForSaxon.add("-l"); // turn on line numbers
+                       argsForSaxon.add("-s"); // source file
+                       argsForSaxon.add(saxonConfig.getDDFilePath()); // 
source file
+                       argsForSaxon.add("-o"); // output file
+                       
argsForSaxon.add(saxonConfig.getSpringFilePath().getAbsolutePath()); // output
+                                                                               
                                                                                
        // file
+                       argsForSaxon.add(saxonConfig.getXSLTPath()); // xslt 
transform to
+                                                                               
                                        // apply
+                       // test if there is a custom parser defined
+                       String uimaFrameworkClass = System
+                                       .getProperty("uima.framework_impl");
+
+                       if (uimaFrameworkClass != null) {
+                               String saxonParserClass = uimaFrameworkClass + 
"_SAXParser";
+                               try {
+                                       
saxonConfig.getSaxonClassLoader().loadClass(saxonParserClass);
+                                       argsForSaxon.add("-x");
+                                       argsForSaxon.add(saxonParserClass);
+                               } catch (ClassNotFoundException e) {
+                                       // No parser class defined
+                               }
+                       }
+                       UIMAFramework.getLogger(THIS_CLASS).log(Level.INFO,
+                                       "Saxon args: " + argsForSaxon);
+
+               }
+
+               public void convertDD2Spring() throws Exception {
+                       try {
+                               // Set the thread classloader so that all 
classes are loaded from this
+                               
Thread.currentThread().setContextClassLoader(saxonConfig.getSaxonClassLoader());
+                               Class<?> mainStartClass = null;
+                               mainStartClass = 
Class.forName("net.sf.saxon.Transform", true,
+                                               
saxonConfig.getSaxonClassLoader());
+                               Method mainMethod = mainStartClass
+                                               .getMethod("main", 
String[].class);
+                               mainMethod.invoke(null, new Object[] { 
argsForSaxon
+                                               .toArray(new 
String[argsForSaxon.size()]) });
+
+                       } finally {
+                               // Restore original classloader and remove used 
shutdown hook
+                               
Thread.currentThread().setContextClassLoader(saxonConfig.getCurrentClassLoader());
+
+                       }
+               }
+
+       }
+
+       private static class SaxonJavaInterface implements SaxonInterface {
+               private SaxonInputs saxonConfig;
+
+               SaxonJavaInterface(SaxonInputs saxonConfig) {
+                       this.saxonConfig = saxonConfig;
+               }
+               private void setFeature(Method setFeatureMethod, Object 
xmlReaderObject, String feature, boolean flag) {
+                       try{
+                               setFeatureMethod.invoke(xmlReaderObject, 
feature, flag );
+                       } catch( Exception e) {
+                               
UIMAFramework.getLogger(THIS_CLASS).log(Level.WARNING,"XMLReader didn't 
recognize feature "+feature);
+                       }
+               }
+               private void configure(Object xmlReaderObject) throws Exception 
{
+                       Class<?> xmlReaderClass = 
Class.forName("org.xml.sax.XMLReader",
+                                       true, 
saxonConfig.getSaxonClassLoader());
+                       Method setFeatureMethod = 
xmlReaderClass.getMethod("setFeature",
+                                       new Class[] { String.class, 
boolean.class });
+                       
setFeature(setFeatureMethod,xmlReaderObject,"http://xml.org/sax/features/external-general-entities";,
 false);
+                       
setFeature(setFeatureMethod,xmlReaderObject,"http://xml.org/sax/features/external-parameter-entities";,
 false);
+                       
setFeature(setFeatureMethod,xmlReaderObject,"http://apache.org/xml/features/nonvalidating/load-external-dtd";,
 false);
+                       
setFeature(setFeatureMethod,xmlReaderObject,"http://apache.org/xml/features/disallow-doctype-decl";,
 true);
+               }
+
+               private void beforeProcess() {
+                       /* 
***********************************************************************************
 */
+                       /*
+                        * The following properties are required by Saxon. Dont 
remove these
+                        * settings
+                        */
+                       /* 
***********************************************************************************
 */
+
+                       
System.setProperty("javax.xml.transform.TransformerFactory",
+                                       "net.sf.saxon.TransformerFactoryImpl");
+
+               }
+
+               private void afterProcess() {
+                       /* 
***********************************************************************************
 */
+                       /*
+                        * Don't remove both clearProperty() calls below. 
Downstream parsers
+                        * may get confused.
+                        */
+                       /* 
***********************************************************************************
 */
+                       
System.clearProperty("javax.xml.parsers.SAXParserFactory");
+                       
System.clearProperty("javax.xml.transform.TransformerFactory");
+                       /* 
***********************************************************************************
 */
+
+               }
+
+               public void convertDD2Spring() throws Exception {
+                       beforeProcess();
+                       BufferedWriter writer = null;
+                       try {
+                               // Set the thread classloader so that all 
classes are loaded from this
+                               
Thread.currentThread().setContextClassLoader(saxonConfig.getSaxonClassLoader());
+
+                               Class<?> configClass = Class.forName(
+                                               "net.sf.saxon.Configuration", 
true, saxonConfig.getSaxonClassLoader());
+                               Object oc = configClass.newInstance();
+                               Method getXMLReaderMethod = configClass
+                                               .getMethod("getStyleParser");
+
+                               // get Saxon xml parser
+                               Object xmlReaderObject = 
getXMLReaderMethod.invoke(oc);
+                               configure(xmlReaderObject);
+                               StringWriter out = new StringWriter();
+
+                               //TransformerFactory tFactory = 
TransformerFactory.newInstance();
+                               TransformerFactory tFactory = 
+                                       XMLUtils.createSaxTransformerFactory();
+                               StreamSource xslSource = new StreamSource(new 
File(
+                                               saxonConfig.getXSLTPath()));
+                               StreamResult xmlResult = new StreamResult(out);
+                               Transformer transformer = 
tFactory.newTransformer(xslSource);
+                               // Need an absolute file path for the dd. This 
is fed to
+                               // InputSource below
+                               File ddAbsFilePath = new 
File(saxonConfig.getDDFilePath());
+                               // 
System.out.println("DD:"+ddAbsFilePath.getAbsolutePath());
+                               // Must be URI otherwise the transform fails on 
windows with
+                               // DynamicError. 
+                               SAXSource source = new SAXSource(new 
InputSource(
+                                               
ddAbsFilePath.toURI().toString())); 
+
+                               source.setXMLReader((XMLReader) 
xmlReaderObject);
+
+                               transformer.transform(source, xmlResult);
+                               // Save transformed DD for loading into Spring 
Framework
+                               writer = new BufferedWriter(new FileWriter(
+                                               
saxonConfig.getSpringFilePath()));
+                               writer.write(out.toString());
+                               
+                               if ( UIMAFramework
+                                       .getLogger(THIS_CLASS)
+                                       .isLoggable(Level.FINEST) ) {
+                                       System.out.println("Finished Writing to 
temp file:"
+                                                       + 
saxonConfig.getSpringFilePath().getAbsolutePath());
+                                       String result = out.toString();
+                                       System.out.println(result);
+
+                               }
+
+                       } finally {
+                               if ( writer != null ) {
+                                       try {
+                                               writer.close();
+                                       } catch(Exception e){}
+                               }
+
+                               afterProcess();
+                               // Restore original classloader and remove used 
shutdown hook
+                               
Thread.currentThread().setContextClassLoader(saxonConfig.getCurrentClassLoader());
+
+                       }
+
+               }
 
+       }
 }

Modified: 
uima/uv3/uima-as-v3/trunk/uimaj-as-jms/src/main/resources/jms_adapter_messages.properties
URL: 
http://svn.apache.org/viewvc/uima/uv3/uima-as-v3/trunk/uimaj-as-jms/src/main/resources/jms_adapter_messages.properties?rev=1849402&r1=1849401&r2=1849402&view=diff
==============================================================================
--- 
uima/uv3/uima-as-v3/trunk/uimaj-as-jms/src/main/resources/jms_adapter_messages.properties
 (original)
+++ 
uima/uv3/uima-as-v3/trunk/uimaj-as-jms/src/main/resources/jms_adapter_messages.properties
 Thu Dec 20 14:51:16 2018
@@ -247,4 +247,10 @@ UIMAJMS_received_service_info_FINEST = R
 UIMAJMS_debug_msg__FINEST={0}
 UIMAJMS_temp_destination_not_available_retrying__INFO=Service:{0} Unable to 
refresh temp destination - retrying in {1} seconds until success ...
 UIMAJMS_temp_destination_available__INFO=Service:{0} succesfully refreshed 
temp destination:{1} - FreeCas Queue:{2}
-UIMAJMS_client_connection_retry__INFO=UIMA-AS Client Unable to Connect to 
Broker:{0} - Retrying Until Success ...
\ No newline at end of file
+UIMAJMS_client_connection_retry__INFO=UIMA-AS Client Unable to Connect to 
Broker:{0} - Retrying Until Success ...
+UIMAJMS_TARGET_LISTENER__INFO=Target Listener with Selector {0} has been 
Started - Controller: {1}
+UIMAJMS_MSG_INTERCEPTOR__FINEST=Service: {0} Listener  recv'd msg - Priority: 
{1} Selector: {2}
+UIMAJMS_STOP_DISPATCH_THREAD_INFO=Stopping Dispatch Thread
+UIMAJMS_START_DISPATCH_THREAD_INFO=Starting Dispatch Thread
+UIMAJMS_EXIT_DISPATCH_THREAD_INFO=Exiting Dispatch Thread
+


Reply via email to