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 is...@apache.org on 2009/09/08 10:35:33 UTC

svn commit: r812388 - in /webservices/axis2/trunk/java/modules: jaxws/src/org/apache/axis2/jaxws/framework/ kernel/src/org/apache/axis2/deployment/ kernel/src/org/apache/axis2/deployment/util/ kernel/test-resources/deployment/hierarchicalServiceRepo/ k...

Author: isurues
Date: Tue Sep  8 08:35:32 2009
New Revision: 812388

URL: http://svn.apache.org/viewvc?rev=812388&view=rev
Log:
Implementing hierarchical service deployment support

* This is basically implemented by adding recursion into the service finding logics in RepositoryListener class. So the hierarchical support is there for AAR services and any
other type of service which is comming from the axis2.xml (ex: pojo, jaxws etc..)
* This includes deployment test cases for hierarchial services
* And also this fixes a bug which was there when undeploying jaxws services


Added:
    webservices/axis2/trunk/java/modules/kernel/test-resources/deployment/hierarchicalServiceRepo/
    webservices/axis2/trunk/java/modules/kernel/test-resources/deployment/hierarchicalServiceRepo/axis2.xml
    webservices/axis2/trunk/java/modules/kernel/test-resources/deployment/hierarchicalServiceRepo/services/
    webservices/axis2/trunk/java/modules/kernel/test-resources/deployment/hierarchicalServiceRepo/services/foo/
    webservices/axis2/trunk/java/modules/kernel/test-resources/deployment/hierarchicalServiceRepo/services/foo/bar/
    webservices/axis2/trunk/java/modules/kernel/test-resources/deployment/hierarchicalServiceRepo/services/foo/bar/1.0.0/
    webservices/axis2/trunk/java/modules/kernel/test-resources/deployment/hierarchicalServiceRepo/services/foo/bar/1.0.0/testService/
    webservices/axis2/trunk/java/modules/kernel/test-resources/deployment/hierarchicalServiceRepo/services/foo/bar/1.0.0/testService/META-INF/
    webservices/axis2/trunk/java/modules/kernel/test-resources/deployment/hierarchicalServiceRepo/services/foo/bar/1.0.0/testService/META-INF/services.xml
    webservices/axis2/trunk/java/modules/kernel/test-resources/deployment/hierarchicalServiceRepo/services/foo/bar/1.0.1/
    webservices/axis2/trunk/java/modules/kernel/test-resources/deployment/hierarchicalServiceRepo/services/foo/bar/1.0.1/testService/
    webservices/axis2/trunk/java/modules/kernel/test-resources/deployment/hierarchicalServiceRepo/services/foo/bar/1.0.1/testService/META-INF/
    webservices/axis2/trunk/java/modules/kernel/test-resources/deployment/hierarchicalServiceRepo/services/foo/bar/1.0.1/testService/META-INF/services.xml
    webservices/axis2/trunk/java/modules/kernel/test/org/apache/axis2/deployment/HierarchicalServiceTest.java
Modified:
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/framework/JAXWSDeployer.java
    webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/deployment/DeploymentEngine.java
    webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/deployment/POJODeployer.java
    webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/deployment/RepositoryListener.java
    webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/deployment/ServiceDeployer.java
    webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/deployment/util/Utils.java

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/framework/JAXWSDeployer.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/framework/JAXWSDeployer.java?rev=812388&r1=812387&r2=812388&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/framework/JAXWSDeployer.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/framework/JAXWSDeployer.java Tue Sep  8 08:35:32 2009
@@ -72,6 +72,7 @@
 
     protected ConfigurationContext configCtx;
     protected AxisConfiguration axisConfig;
+    private String directory;
 
     //To initialize the deployer
     public void init(ConfigurationContext configCtx) {
@@ -139,7 +140,7 @@
             String groupName = deploymentFileData.getName();
             URL location = deploymentFileData.getFile().toURL();
             if (isJar(deploymentFileData.getFile())) {
-                log.info("Deploying artifact : " + deploymentFileData.getName());
+                log.info("Deploying artifact : " + deploymentFileData.getAbsolutePath());
                 ArrayList urls = new ArrayList();
                 urls.add(deploymentFileData.getFile().toURL());
                 urls.add(axisConfig.getRepository());
@@ -157,7 +158,7 @@
                 Thread.currentThread().setContextClassLoader(classLoader);
 
                 ArrayList classList = getListOfClasses(deploymentFileData);
-                AxisServiceGroup serviceGroup = deployClasses(groupName, location, classLoader, classList); 
+                AxisServiceGroup serviceGroup = deployClasses(groupName, location, classLoader, classList);
                 
                 if(serviceGroup == null) {
                     String msg = "Error:\n No annotated classes found in the jar: " +
@@ -181,6 +182,8 @@
     protected AxisServiceGroup deployClasses(String groupName, URL location, ClassLoader classLoader, List classList)
             throws ClassNotFoundException, InstantiationException, IllegalAccessException, AxisFault {
         ArrayList axisServiceList = new ArrayList();
+        // Get the hierarchical path of the service
+        String serviceHierarchy = Utils.getServiceHierarchy(location.getPath(), this.directory);
         for (int i = 0, size = classList.size(); i < size; i++) {
             String className = (String) classList.get(i);
             Class pojoClass;
@@ -206,7 +209,8 @@
                                 className,
                                 location);
                 if(axisService != null) {
-                    log.info("Deploying JAXWS annotated class " + className + " as a service - " + axisService.getName());
+                    log.info("Deploying JAXWS annotated class " + className + " as a service - "
+                            + serviceHierarchy + axisService.getName());
                     axisServiceList.add(axisService);
                 }
             }
@@ -215,10 +219,12 @@
         if (size <= 0) {
             return null;
         }
+        //creating service group by considering the hierarchical path also
         AxisServiceGroup serviceGroup = new AxisServiceGroup();
-        serviceGroup.setServiceGroupName(groupName);
+        serviceGroup.setServiceGroupName(serviceHierarchy + groupName);
         for (int i = 0; i < size; i++) {
             AxisService axisService = (AxisService) axisServiceList.get(i);
+            axisService.setName(serviceHierarchy + axisService.getName());
             serviceGroup.addService(axisService);
             Utils.addEndpointsToService(axisService, axisConfig);
         }
@@ -300,35 +306,36 @@
     }
 
     public void setDirectory(String directory) {
+        this.directory = directory;
     }
 
     public void setExtension(String extension) {
     }
 
     public void unDeploy(String fileName) {
-        fileName = Utils.getShortFileName(fileName);
-        if (isJar(new File(fileName))) {
-            try {
-                AxisServiceGroup serviceGroup =
-                        axisConfig.removeServiceGroup(fileName);
-                if(configCtx != null) {
-                    configCtx.removeServiceGroupContext(serviceGroup);
-                }
-                log.info(Messages.getMessage(DeploymentErrorMsgs.SERVICE_REMOVED,
-                        fileName));
-            } catch (AxisFault axisFault) {
-                //May be a faulty service
-                log.debug(Messages.getMessage(DeploymentErrorMsgs.FAULTY_SERVICE_REMOVAL, 
-                        axisFault.getMessage()), axisFault);
-                axisConfig.removeFaultyService(fileName);
-            }
+        //find the hierarchical part of the service group name
+        String serviceHierarchy = Utils.getServiceHierarchy(fileName, this.directory);
+        fileName = serviceHierarchy + Utils.getShortFileName(fileName);
+        try {
+            AxisServiceGroup serviceGroup =
+                    axisConfig.removeServiceGroup(fileName);
+            if(configCtx != null) {
+                configCtx.removeServiceGroupContext(serviceGroup);
+            }
+            log.info(Messages.getMessage(DeploymentErrorMsgs.SERVICE_REMOVED,
+                    fileName));
+        } catch (AxisFault axisFault) {
+            //May be a faulty service
+            log.debug(Messages.getMessage(DeploymentErrorMsgs.FAULTY_SERVICE_REMOVAL,
+                    axisFault.getMessage()), axisFault);
+            axisConfig.removeFaultyService(fileName);
         }
     }
 
     /**
      * Check if this inputstream is a jar/zip
      *
-     * @param is
+     * @param f - file
      * @return true if inputstream is a jar
      */
     public static boolean isJar(File f) {

Modified: webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/deployment/DeploymentEngine.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/deployment/DeploymentEngine.java?rev=812388&r1=812387&r2=812388&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/deployment/DeploymentEngine.java (original)
+++ webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/deployment/DeploymentEngine.java Tue Sep  8 08:35:32 2009
@@ -1124,7 +1124,10 @@
 
     private void initializeDeployers(ConfigurationContext configContext) {
         serviceDeployer = new ServiceDeployer();
-        serviceDeployer.init(configContext);        
+        serviceDeployer.init(configContext);
+        if (this.servicesDir != null) {
+            serviceDeployer.setDirectory(this.servicesDir.getName());
+        }
         for (Map<String, Deployer> extensionMap : deployerMap.values()) {
             for (Deployer deployer : extensionMap.values()) {
                 deployer.init(configContext);

Modified: webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/deployment/POJODeployer.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/deployment/POJODeployer.java?rev=812388&r1=812387&r2=812388&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/deployment/POJODeployer.java (original)
+++ webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/deployment/POJODeployer.java Tue Sep  8 08:35:32 2009
@@ -53,6 +53,7 @@
     private static Log log = LogFactory.getLog(POJODeployer.class);
 
     private ConfigurationContext configCtx;
+    private String directory;
 
     //To initialize the deployer
     public void init(ConfigurationContext configCtx) {
@@ -61,6 +62,9 @@
 
     public void deploy(DeploymentFileData deploymentFileData) {
         ClassLoader threadClassLoader = Thread.currentThread().getContextClassLoader();
+        // Get the hierarchical path of the service
+        String serviceHierarchy = Utils.getServiceHierarchy(deploymentFileData.getAbsolutePath(), 
+                this.directory);
         try {
             String extension = DeploymentFileData.getFileExtension(deploymentFileData.getName());
             if ("class".equals(extension)) {
@@ -76,7 +80,7 @@
                 className = className.replaceAll(".class", "");
                 Class clazz = Loader.loadClass(className);
                 log.info(Messages.getMessage(DeploymentErrorMsgs.DEPLOYING_POJO,
-                        className,
+                        serviceHierarchy + className,
                         deploymentFileData.getFile().getAbsolutePath()));
 
 
@@ -90,22 +94,23 @@
                  */
                 WebServiceAnnotation annotation =
                         JSR181Helper.INSTANCE.getWebServiceAnnotation(clazz);
+                AxisService axisService;
                 if (annotation != null) {
                     // try to see whether JAX-WS jars in the class path , if so use them
                     // to process annotated pojo else use annogen to process the pojo class
-                    AxisService axisService;
                     axisService =
                             createAxisService(classLoader,
                                     className,
                                     deploymentFileData.getFile().toURL());
-                    configCtx.getAxisConfiguration().addService(axisService);
                 } else {
-                    AxisService axisService =
+                    axisService =
                             createAxisServiceUsingAnnogen(className,
                                     classLoader,
                                     deploymentFileData.getFile().toURL());
-                    configCtx.getAxisConfiguration().addService(axisService);
                 }
+                //add the hierarchical path to the service name
+                axisService.setName(serviceHierarchy + axisService.getName());
+                configCtx.getAxisConfiguration().addService(axisService);
 
             } else if ("jar".equals(extension)) {
                 ArrayList classList;
@@ -178,10 +183,13 @@
                 }
 
                 if (axisServiceList.size() > 0) {
+                    //create the service group considering the hierarchical path also
                     AxisServiceGroup serviceGroup = new AxisServiceGroup();
-                    serviceGroup.setServiceGroupName(deploymentFileData.getName());
+                    serviceGroup.setServiceGroupName(serviceHierarchy +
+                            deploymentFileData.getName());
                     for (Object anAxisServiceList : axisServiceList) {
                         AxisService axisService = (AxisService)anAxisServiceList;
+                        axisService.setName(serviceHierarchy + axisService.getName());
                         serviceGroup.addService(axisService);
                     }
                     configCtx.getAxisConfiguration().addServiceGroup(serviceGroup);
@@ -329,27 +337,32 @@
     }
 
     public void setDirectory(String directory) {
+        this.directory = directory;
     }
 
     public void setExtension(String extension) {
     }
 
     public void unDeploy(String fileName) {
+        //find the hierarchical part of the service group name
+        String serviceHierarchy = Utils.getServiceHierarchy(fileName, this.directory);
         fileName = Utils.getShortFileName(fileName);
         if (fileName.endsWith(".class")) {
             String className = fileName.replaceAll(".class", "");
+            className = serviceHierarchy + className;
             try {
                 AxisServiceGroup serviceGroup =
                         configCtx.getAxisConfiguration().removeServiceGroup(className);
                 configCtx.removeServiceGroupContext(serviceGroup);
                 log.info(Messages.getMessage(DeploymentErrorMsgs.SERVICE_REMOVED,
-                        fileName));
+                        className));
             } catch (AxisFault axisFault) {
                 //May be a faulty service
                 log.debug(Messages.getMessage(DeploymentErrorMsgs.FAULTY_SERVICE_REMOVAL,axisFault.getMessage()),axisFault);
                 configCtx.getAxisConfiguration().removeFaultyService(fileName);
             }
         } else if (fileName.endsWith(".jar")) {
+            fileName = serviceHierarchy + fileName;
             try {
                 AxisServiceGroup serviceGroup =
                         configCtx.getAxisConfiguration().removeServiceGroup(fileName);

Modified: webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/deployment/RepositoryListener.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/deployment/RepositoryListener.java?rev=812388&r1=812387&r2=812388&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/deployment/RepositoryListener.java (original)
+++ webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/deployment/RepositoryListener.java Tue Sep  8 08:35:32 2009
@@ -25,6 +25,7 @@
 import org.apache.axis2.deployment.repository.util.WSInfoList;
 import org.apache.axis2.deployment.util.Utils;
 import org.apache.axis2.util.Loader;
+import org.apache.axis2.i18n.Messages;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
@@ -248,7 +249,7 @@
 
     /** Finds a list of services in the folder and adds to wsInfoList. */
     public void checkServices() {
-        findServicesInDirectory();
+        findServicesInDirectory(deploymentEngine.getServicesDir());
         loadOtherDirectories();
         update();
     }
@@ -270,19 +271,22 @@
             String directory = entry.getKey();
             Map<String, Deployer> extensionMap = entry.getValue();
             for (String extension : extensionMap.keySet()) {
-                findFileForGivenDirectory(directory, extension);
+                String[] strings = directory.split("/");
+                File dirToSearch = new File(deploymentEngine.getRepositoryDir(),
+                        strings[strings.length - 1]);
+                findFileForGivenDirectory(dirToSearch, extension, directory);
             }
         }
     }
 
-    private void findFileForGivenDirectory(String dir, String extension) {
+    /**
+     * Recursively finds files with the provided extension and adds them to be deployed
+     * @param directory - directory to search
+     * @param extension - extension to look for
+     * @param dir - dir given in the axis2.xml this is used to find the correct deployer
+     */
+    private void findFileForGivenDirectory(File directory, String extension, String dir) {
         try {
-            File directory = deploymentEngine.getRepositoryDir();
-            String[] strings = dir.split("/");
-            for (int i = 0; i < strings.length; i++) {
-                directory = new File(directory, strings[i]);
-            }
-
             if (directory.exists()) {
                 File[] files = directory.listFiles();
                 if (files != null && files.length > 0) {
@@ -293,9 +297,12 @@
                         }
                         if (!file.isDirectory() && extension
                                 .equals(DeploymentFileData.getFileExtension(file.getName()))) {
-                            addFileToDeploy(file,
-                                            deploymentEngine.getDeployer(dir, extension),
-                                            WSInfo.TYPE_CUSTOM);
+                            Deployer deployer = deploymentEngine.getDeployer(dir, extension);
+                            deployer.setDirectory(dir);
+                            addFileToDeploy(file, deployer, WSInfo.TYPE_CUSTOM);
+                        } else if (file.isDirectory()) {
+                            //look in the child directory also
+                            findFileForGivenDirectory(file, extension, dir);
                         }
                     }
                 }
@@ -305,14 +312,29 @@
         }
     }
 
-    /** Searches a given folder for jar files and adds them to a list in the WSInfolist class. */
-    protected void findServicesInDirectory() {
-        File root = deploymentEngine.getServicesDir();
+    /**
+     * Searches a given folder for jar files and adds them to a list in the WSInfolist class.
+     * If sub folders found, those are also searched for services.
+     * Ex : repository/services/foo/1.0.0/echo.aar
+     *      repository/services/foo/1.0.1/echo.aar
+     *      repository/services/echo.aar 
+     * @param root - directory from which we start searching for services
+     */
+    protected void findServicesInDirectory(File root) {
+        // flag to identify whether this is the services folder
+        boolean servicesDir = false;
+        if (deploymentEngine.getServicesDir().getAbsolutePath().equals(root.getAbsolutePath())) {
+            servicesDir = true;
+        }
         File[] files = root.listFiles();
 
         if (files != null && files.length > 0) {
-            for (int i = 0; i < files.length; i++) {
-                File file = files[i];
+            /**
+             * This undeployableDir flag is used to check whether this folder (root) doesn't contain
+             * any deployable artifacts.
+             */
+            boolean undeployableDir = true;
+            for (File file : files) {
                 if (isSourceControlDir(file)) {
                     continue;
                 }
@@ -320,22 +342,38 @@
                     if (DeploymentFileData.isServiceArchiveFile(file.getName())) {
                         addFileToDeploy(file, deploymentEngine.getServiceDeployer(),
                                         WSInfo.TYPE_SERVICE);
+                        undeployableDir = false;
                     } else {
                         String ext = DeploymentFileData.getFileExtension(file.getName());
                         Deployer deployer = deploymentEngine.getDeployerForExtension(ext);
                         // If we found a deployer for this type of file, use it.  Otherwise
                         // ignore the file.
                         if (deployer != null) {
+                            deployer.setDirectory(deploymentEngine.getServicesDir().getName());
                             addFileToDeploy(file, deployer, WSInfo.TYPE_SERVICE);
+                            undeployableDir = false;
                         }
                     }
                 } else {
-                    if (!"lib".equalsIgnoreCase(file.getName())) {
-                        addFileToDeploy(file, deploymentEngine.getServiceDeployer(),
-                                        WSInfo.TYPE_SERVICE);
+                    if (!(servicesDir && "lib".equalsIgnoreCase(file.getName()))) {
+                        File servicesXML = new File(file, DeploymentConstants.SERVICES_XML);
+                        if (!servicesXML.exists()) {
+                            servicesXML =
+                                    new File(file, DeploymentConstants.SERVICES_XML.toLowerCase());
+                        }
+                        if (servicesXML.exists()) {
+                            addFileToDeploy(file, deploymentEngine.getServiceDeployer(),
+                                    WSInfo.TYPE_SERVICE);
+                        } else {
+                            findServicesInDirectory(file);
+                        }
+                        undeployableDir = false;
                     }
                 }
             }
+            if (undeployableDir) {
+                log.error(Messages.getMessage(DeploymentErrorMsgs.SERVICE_XML_NOT_FOUND));
+            }
         }
     }
 
@@ -351,7 +389,7 @@
     }
 
     public void updateRemote() throws Exception {
-        findServicesInDirectory();
+        findServicesInDirectory(deploymentEngine.getServicesDir());
         update();
     }
 

Modified: webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/deployment/ServiceDeployer.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/deployment/ServiceDeployer.java?rev=812388&r1=812387&r2=812388&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/deployment/ServiceDeployer.java (original)
+++ webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/deployment/ServiceDeployer.java Tue Sep  8 08:35:32 2009
@@ -45,6 +45,7 @@
     private static final Log log = LogFactory.getLog(ServiceDeployer.class);
     private AxisConfiguration axisConfig;
     private ConfigurationContext configCtx;
+    private String directory;
 
     //To initialize the deployer
     public void init(ConfigurationContext configCtx) {
@@ -84,6 +85,20 @@
                     serviceGroup, isDirectory, wsdlservice,
                     configCtx);
             URL location = deploymentFileData.getFile().toURL();
+
+            // Add the hierarchical path to the service group
+            if (location != null) {
+                String serviceHierarchy = Utils.getServiceHierarchy(location.getPath(),
+                        this.directory);
+                if (!"".equals(serviceHierarchy)) {
+                    serviceGroup.setServiceGroupName(serviceHierarchy
+                            + serviceGroup.getServiceGroupName());
+                    for (Object o : serviceList) {
+                        AxisService axisService = (AxisService) o;
+                        axisService.setName(serviceHierarchy + axisService.getName());
+                    }
+                }
+            }
             DeploymentEngine.addServiceGroup(serviceGroup,
                                              serviceList,
                                              location,
@@ -154,6 +169,7 @@
     }
 
     public void setDirectory(String directory) {
+        this.directory = directory;
     }
 
     public void setExtension(String extension) {
@@ -161,8 +177,11 @@
 
     public void unDeploy(String fileName) throws DeploymentException {
         try {
+            //find the hierarchical part of the service group name
+            String serviceHierarchy = Utils.getServiceHierarchy(fileName, this.directory);
             fileName = Utils.getShortFileName(fileName);
             fileName = DeploymentEngine.getAxisServiceName(fileName);
+            fileName = serviceHierarchy + fileName;
             AxisServiceGroup serviceGroup = axisConfig.removeServiceGroup(fileName);
             if (serviceGroup != null) {
                 configCtx.removeServiceGroupContext(serviceGroup);

Modified: webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/deployment/util/Utils.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/deployment/util/Utils.java?rev=812388&r1=812387&r2=812388&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/deployment/util/Utils.java (original)
+++ webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/deployment/util/Utils.java Tue Sep  8 08:35:32 2009
@@ -1875,4 +1875,41 @@
             }
         }
     }
+
+    /**
+     * Computes the hierarchical part of the service name if this is such a service path.
+     * In this hierarchical path, we use '!' instead of '/'.
+     * Ex:  filePath = .../repository/services/foo/1.0.0/version.aar -> "foo!1.0.0"
+     *      filePath = .../repository/services/version.aar -> ""
+     * @param filePath - input file path of the deploying file
+     * @param serviceDir - 'services', 'pojo', 'servicejars' etc..
+     * @return hierarchical path. either "" or a '/' separated string (Ex: foo!1.0.0)
+     */
+    public static String getServiceHierarchy(String filePath, String serviceDir) {
+        if (filePath == null || serviceDir == null) {
+            return "";
+        }
+        String[] splited = filePath.split(serviceDir + "/");
+        String serviceHierarchy = null;
+        if (splited.length > 1) {
+            String temp = splited[splited.length - 1];
+            //if this is a directory, there can be a '/' at the end. Remove it..
+            if (temp.endsWith("/")) {
+                temp = temp.substring(0, temp.length() - 1);
+            }
+            //if this is not a hierarchical path, return a 0 length string
+            if (temp.lastIndexOf('/') == -1) {
+                return "";
+            }
+            serviceHierarchy = temp.substring(0, temp.lastIndexOf('/') + 1);
+
+            /**
+             * Now replace '/' using the special charactor '!'. This is to overcome the issues
+             * in dispatching. If we use '/', it is hard to find service and operation by looking
+             * at the EPR, in dispatch time.
+             */
+            serviceHierarchy = serviceHierarchy.replace('/', '!');
+        }
+        return serviceHierarchy;
+    }
 }

Added: webservices/axis2/trunk/java/modules/kernel/test-resources/deployment/hierarchicalServiceRepo/axis2.xml
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/kernel/test-resources/deployment/hierarchicalServiceRepo/axis2.xml?rev=812388&view=auto
==============================================================================
--- webservices/axis2/trunk/java/modules/kernel/test-resources/deployment/hierarchicalServiceRepo/axis2.xml (added)
+++ webservices/axis2/trunk/java/modules/kernel/test-resources/deployment/hierarchicalServiceRepo/axis2.xml Tue Sep  8 08:35:32 2009
@@ -0,0 +1,97 @@
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  -->
+
+<axisconfig name="AxisJava2.0">
+    <!-- ================================================= -->
+    <!-- Parameters -->
+    <!-- ================================================= -->
+    <parameter name="hotdeployment">true</parameter>
+    <parameter name="hotupdate">false</parameter>
+    <parameter name="enableMTOM">true</parameter>
+
+    <parameter name="userName">admin</parameter>
+    <parameter name="password">axis2</parameter>
+
+    <parameter name="seralizeLocation">./target</parameter>
+
+    <!-- ================================================= -->
+    <!-- Message Receivers -->
+    <!-- ================================================= -->
+    <!-- This is the Deafult Message Receiver for the Request Response style Operations -->
+    <messageReceiver mep="INOUT" class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/>
+
+    <!-- ================================================= -->
+    <!-- Transport Ins -->
+    <!-- ================================================= -->
+
+    <phaseOrder type="InFlow">
+        <!--  System pre defined phases       -->
+         <phase name="Transport">
+            <handler name="RequestURIBasedDispatcher"
+                     class="org.apache.axis2.dispatchers.RequestURIBasedDispatcher"/>
+            <handler name="SOAPActionBasedDispatcher"
+                     class="org.apache.axis2.dispatchers.SOAPActionBasedDispatcher"/>
+        </phase>
+        <phase name="Security"/>
+        <phase name="PreDispatch"/>
+        <phase name="Dispatch" class="org.apache.axis2.engine.DispatchPhase">
+            <handler name="AddressingBasedDispatcher"
+                     class="org.apache.axis2.dispatchers.AddressingBasedDispatcher"/>
+
+            <handler name="SOAPMessageBodyBasedDispatcher"
+                     class="org.apache.axis2.dispatchers.SOAPMessageBodyBasedDispatcher"/>
+        </phase>
+        <!--  System pre defined phases       -->
+        <!--   After Postdispatch phase module author or or service author can add any phase he want      -->
+        <phase name="OperationInPhase"/>
+    </phaseOrder>
+    <phaseOrder type="OutFlow">
+        <!--      user can add his own phases to this area  -->
+        <phase name="OperationOutPhase"/>
+        <!--system predefined phase-->
+        <!--these phase will run irrespective of the service-->
+        <phase name="PolicyDetermination"/>
+        <phase name="MessageOut"/>
+    </phaseOrder>
+    <phaseOrder type="InFaultFlow">
+        <phase name="PreDispatch"/>
+        <phase name="Dispatch" class="org.apache.axis2.engine.DispatchPhase">
+            <handler name="RequestURIBasedDispatcher"
+                     class="org.apache.axis2.dispatchers.RequestURIBasedDispatcher"/>
+
+            <handler name="SOAPActionBasedDispatcher"
+                     class="org.apache.axis2.dispatchers.SOAPActionBasedDispatcher"/>
+
+            <handler name="AddressingBasedDispatcher"
+                     class="org.apache.axis2.dispatchers.AddressingBasedDispatcher"/>
+
+            <handler name="SOAPMessageBodyBasedDispatcher"
+                     class="org.apache.axis2.dispatchers.SOAPMessageBodyBasedDispatcher"/>
+        </phase>
+        <!--      user can add his own phases to this area  -->
+        <phase name="OperationInFaultPhase"/>
+    </phaseOrder>
+    <phaseOrder type="OutFaultFlow">
+        <!--      user can add his own phases to this area  -->
+        <phase name="OperationOutFaultPhase"/>
+        <phase name="PolicyDetermination"/>
+        <phase name="MessageOut"/>
+    </phaseOrder>
+</axisconfig>
+

Added: webservices/axis2/trunk/java/modules/kernel/test-resources/deployment/hierarchicalServiceRepo/services/foo/bar/1.0.0/testService/META-INF/services.xml
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/kernel/test-resources/deployment/hierarchicalServiceRepo/services/foo/bar/1.0.0/testService/META-INF/services.xml?rev=812388&view=auto
==============================================================================
--- webservices/axis2/trunk/java/modules/kernel/test-resources/deployment/hierarchicalServiceRepo/services/foo/bar/1.0.0/testService/META-INF/services.xml (added)
+++ webservices/axis2/trunk/java/modules/kernel/test-resources/deployment/hierarchicalServiceRepo/services/foo/bar/1.0.0/testService/META-INF/services.xml Tue Sep  8 08:35:32 2009
@@ -0,0 +1,33 @@
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  -->
+<serviceGroup>
+    <service name="Hie100Service1">
+        <operation name="op1">
+        </operation>
+        <operation name="op2">
+        </operation>
+    </service>
+    <service name="Hie100Service2">
+        <operation name="op1">
+        </operation>
+        <operation name="op2">
+        </operation>
+    </service>
+    <parameter name="ServiceClass">org.apache.axis2.Echo2</parameter>
+</serviceGroup>
\ No newline at end of file

Added: webservices/axis2/trunk/java/modules/kernel/test-resources/deployment/hierarchicalServiceRepo/services/foo/bar/1.0.1/testService/META-INF/services.xml
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/kernel/test-resources/deployment/hierarchicalServiceRepo/services/foo/bar/1.0.1/testService/META-INF/services.xml?rev=812388&view=auto
==============================================================================
--- webservices/axis2/trunk/java/modules/kernel/test-resources/deployment/hierarchicalServiceRepo/services/foo/bar/1.0.1/testService/META-INF/services.xml (added)
+++ webservices/axis2/trunk/java/modules/kernel/test-resources/deployment/hierarchicalServiceRepo/services/foo/bar/1.0.1/testService/META-INF/services.xml Tue Sep  8 08:35:32 2009
@@ -0,0 +1,33 @@
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  -->
+<serviceGroup>
+    <service name="Hie101Service1">
+        <operation name="op1">
+        </operation>
+        <operation name="op2">
+        </operation>
+    </service>
+    <service name="Hie101Service2">
+        <operation name="op1">
+        </operation>
+        <operation name="op2">
+        </operation>
+    </service>
+    <parameter name="ServiceClass">org.apache.axis2.Echo2</parameter>
+</serviceGroup>
\ No newline at end of file

Added: webservices/axis2/trunk/java/modules/kernel/test/org/apache/axis2/deployment/HierarchicalServiceTest.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/kernel/test/org/apache/axis2/deployment/HierarchicalServiceTest.java?rev=812388&view=auto
==============================================================================
--- webservices/axis2/trunk/java/modules/kernel/test/org/apache/axis2/deployment/HierarchicalServiceTest.java (added)
+++ webservices/axis2/trunk/java/modules/kernel/test/org/apache/axis2/deployment/HierarchicalServiceTest.java Tue Sep  8 08:35:32 2009
@@ -0,0 +1,40 @@
+package org.apache.axis2.deployment;
+
+import junit.framework.TestCase;
+import org.apache.axis2.engine.AxisConfiguration;
+import org.apache.axis2.AbstractTestCase;
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.description.AxisServiceGroup;
+import org.apache.axis2.description.AxisService;
+import org.apache.axis2.context.ConfigurationContextFactory;
+
+
+public class HierarchicalServiceTest extends TestCase {
+    AxisConfiguration axisConfig;
+    String repo = AbstractTestCase.basedir + "/test-resources/deployment/hierarchicalServiceRepo";
+
+
+    protected void setUp() throws Exception {
+        axisConfig = ConfigurationContextFactory.createConfigurationContextFromFileSystem(repo,
+                repo + "/axis2.xml").getAxisConfiguration();
+    }
+
+    public void testHierarchicalServices() throws AxisFault {
+        //Test for foo/bar/1.0.0 hierarchy
+        AxisServiceGroup sg100 = axisConfig.getServiceGroup("foo!bar!1.0.0!testService");
+        assertNotNull(sg100);
+        AxisService hie100service1 = axisConfig.getService("foo!bar!1.0.0!Hie100Service1");
+        assertNotNull(hie100service1);
+        AxisService hie100service2 = axisConfig.getService("foo!bar!1.0.0!Hie100Service2");
+        assertNotNull(hie100service2);
+
+        //Test for foo/bar/1.0.1 hierarchy
+        AxisServiceGroup sg101 = axisConfig.getServiceGroup("foo!bar!1.0.1!testService");
+        assertNotNull(sg101);
+        AxisService hie101service1 = axisConfig.getService("foo!bar!1.0.1!Hie101Service1");
+        assertNotNull(hie101service1);
+        AxisService hie101service2 = axisConfig.getService("foo!bar!1.0.1!Hie101Service2");
+        assertNotNull(hie101service2);
+    }
+
+}