Commits

Anonymous committed 02b06dc

allow wildcard includes in xwork.xml files
o patch applied

Issue Number: XW-543
Submitted by: Wes Wannemacher

git-svn-id: http://svn.opensymphony.com/svn/xwork/trunk@1643e221344d-f017-0410-9bd5-d282ab1896d7

Comments (0)

Files changed (5)

src/java/com/opensymphony/xwork2/config/providers/XmlConfigurationProvider.java

 
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.File;
 import java.lang.reflect.Modifier;
 import java.net.URL;
+import java.net.URLClassLoader;
+import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
     private Map<String, String> dtdMappings;
     private Configuration configuration;
     private boolean throwExceptionOnDuplicateBeans = true;
-
+    
     public XmlConfigurationProvider() {
         this("xwork.xml", true);
     }
 
                         if (nodeName.equals("include")) {
                             String includeFileName = child.getAttribute("file");
-                            docs.addAll(loadConfigurationFiles(includeFileName, child));
+                            if(includeFileName.indexOf('*') != -1 ) {
+                                handleWildCardIncludes(includeFileName, docs, child);
                         }
+                            else {
+                                docs.addAll(loadConfigurationFiles(includeFileName, child));    
+                            }    
                     }
                 }
+                }
                 docs.add(doc);
                 loadedFileUrls.add(url.toString());
             }
         return docs;
     }
 
+    private void handleWildCardIncludes(String includeFileName, List<Document> docs, Element child) {
+        // check for star*, pedantic
+        if( includeFileName.indexOf('*') == -1 ) {
+            throw new XWorkException("handleWildCardIncludes called with name not containing wildcard");
+        }
+        LOG.info("encountered wildcard include, checking for - " + includeFileName);
+        URL [] curDirUrls ;
+
+           // curDirUrls = ClassLoaderUtil.getResources("/", this.getClass(), true);
+           ClassLoader cl = XmlConfigurationProvider.class.getClassLoader();
+           URLClassLoader ucl ;
+           if (cl instanceof URLClassLoader) {
+               ucl = (URLClassLoader) cl;
+           }
+           else {
+               throw new XWorkException("cannot create an URLClassLoader from current classloader");
+           }
+           curDirUrls = ucl.getURLs();
+
+        String fileNamePrefix = null;
+        if (! includeFileName.startsWith("*")) {
+            fileNamePrefix = includeFileName.substring(0, includeFileName.indexOf('*'));    
+        }
+        
+        String fileNameSuffix = null;
+        if( ! includeFileName.endsWith("*")) {
+            fileNameSuffix = includeFileName.substring(includeFileName.lastIndexOf('*') +1 );
+        }
+        
+        String relativeDir = null;
+        
+        if(includeFileName.indexOf("/") != -1) {
+            if(LOG.isDebugEnabled() ) {
+                LOG.debug("includeFileName contains a /");
+            }
+            if(includeFileName.lastIndexOf('/') > includeFileName.indexOf('*')) {
+                throw new XWorkException("wildcard includes does not support wildcard directories");
+            }
+            fileNamePrefix = includeFileName.substring(includeFileName.lastIndexOf('/') +1, includeFileName.indexOf('*'));
+            relativeDir = includeFileName.substring(0,includeFileName.lastIndexOf('/'));
+            if(LOG.isDebugEnabled() ) {
+                LOG.debug("relativeDir = " + relativeDir + ", fileNameMask = " + fileNamePrefix);
+            }
+        }
+        
+        for(URL baseSearchURL : curDirUrls ) {
+            if (! baseSearchURL.getProtocol().equals("file")) {
+                continue;
+            }
+            
+            File searchDir ;
+            
+            if (relativeDir != null ) {
+                if (relativeDir.startsWith("/")) {
+                    relativeDir = relativeDir.substring(relativeDir.indexOf('/') + 1);
+                }
+                File parent ;
+                try {
+                    parent = new File(baseSearchURL.toURI());
+                } catch (URISyntaxException e) {
+                    throw new XWorkException("bad URI for searchDir - " + baseSearchURL.toString());
+                }
+                if( ! parent.isDirectory()) {
+                    continue;
+                }
+                searchDir = new File(parent, relativeDir);
+            }
+            else {
+                try {
+                    searchDir = new File(baseSearchURL.toURI());
+                } catch (URISyntaxException e) {
+                    throw new XWorkException("bad URI for searchDir - " + baseSearchURL.toString());
+                }
+            }
+            if(LOG.isDebugEnabled() ) {
+                LOG.debug("using - " + searchDir.toURI().toString() + ", as searchDir");
+            }
+            if( searchDir != null && searchDir.isDirectory() ) {
+                if(LOG.isDebugEnabled() ) {
+                    LOG.debug("getting searchDir file list");
+                }
+                String [] filesInDir = searchDir.list();
+                if (filesInDir == null ) {
+                    throw new XWorkException("unable to find any files in include directory");
+                }
+                for (String fileInDir: filesInDir) {
+                    if(LOG.isDebugEnabled() ) {
+                        LOG.debug("checking - " + fileInDir);
+                    }
+                    boolean fileMatches = false ;
+                    if (fileNameSuffix != null || fileNamePrefix != null) {
+                        fileMatches = ( fileNameSuffix != null && fileNamePrefix != null &&
+                                        fileNameSuffix.length() + fileNamePrefix.length() < fileInDir.length() && 
+                                        fileInDir.startsWith(fileNamePrefix) && fileInDir.endsWith(fileNameSuffix ) ) ;
+                        fileMatches = fileMatches || 
+                                    ( fileNamePrefix == null &&
+                                      fileInDir.endsWith(fileNameSuffix) );
+                        fileMatches = fileMatches || 
+                                    ( fileNameSuffix == null &&
+                                      fileInDir.startsWith(fileNamePrefix) );
+                    }
+                    
+                    if( fileMatches ) {
+                        if (relativeDir != null ) {
+                            if (!relativeDir.endsWith("/")) {
+                                relativeDir = relativeDir.concat("/");
+                            }
+                            if(LOG.isDebugEnabled() ) {
+                                LOG.debug("calling load on - " + relativeDir + fileInDir);
+                            }
+                            docs.addAll(loadConfigurationFiles(relativeDir + fileInDir, child));
+                        }
+                        else {
+                            if(LOG.isDebugEnabled() ) {
+                                LOG.debug("calling load on - " + fileInDir);
+                            }
+                            docs.addAll(loadConfigurationFiles(fileInDir, child));
+                        }
+                    }
+                }
+            }
+        }
+    }
+    
     protected Iterator<URL> getConfigurationUrls(String fileName) throws IOException {
         return ClassLoaderUtil.getResources(fileName, XmlConfigurationProvider.class, false);
     }

src/test/com/opensymphony/xwork2/config/providers/XmlConfigurationProviderWildCardIncludeTest.java

+/*
+ * Copyright (c) 2002-2003 by OpenSymphony
+ * All rights reserved.
+ */
+package com.opensymphony.xwork2.config.providers;
+
+import com.opensymphony.xwork2.config.ConfigurationProvider;
+import com.opensymphony.xwork2.config.entities.PackageConfig;
+
+public class XmlConfigurationProviderWildCardIncludeTest extends ConfigurationTestBase {
+
+    
+    public void testWildCardInclude() throws Exception {
+        final String filename = "com/opensymphony/xwork2/config/providers/xwork-test-wildcard-include.xml";
+        ConfigurationProvider provider = buildConfigurationProvider(filename);
+
+        provider.init(configuration);
+        provider.loadPackages();
+
+        PackageConfig defaultWildcardPackage = configuration.getPackageConfig("default-wildcard");
+        assertNotNull(defaultWildcardPackage);
+        assertEquals("default-wildcard", defaultWildcardPackage.getName());
+
+
+        PackageConfig defaultOnePackage = configuration.getPackageConfig("default-1");
+        assertNotNull(defaultOnePackage);
+        assertEquals("default-1", defaultOnePackage.getName());
+        
+        PackageConfig defaultTwoPackage = configuration.getPackageConfig("default-2");
+        assertNotNull(defaultTwoPackage);
+        assertEquals("default-2", defaultTwoPackage.getName());       
+
+        configurationManager.addConfigurationProvider(provider);
+        configurationManager.reload();
+
+    }
+}

src/test/com/opensymphony/xwork2/config/providers/xwork-test-wildcard-1.xml

+<!DOCTYPE xwork PUBLIC
+    "-//OpenSymphony Group//XWork 1.1.1//EN"
+    "http://www.opensymphony.com/xwork/xwork-1.1.1.dtd"
+ >
+
+<xwork>
+    <package name="default-1" />
+</xwork>

src/test/com/opensymphony/xwork2/config/providers/xwork-test-wildcard-2.xml

+<!DOCTYPE xwork PUBLIC
+    "-//OpenSymphony Group//XWork 1.1.1//EN"
+    "http://www.opensymphony.com/xwork/xwork-1.1.1.dtd"
+ >
+
+<xwork>
+    <package name="default-2" />
+</xwork>

src/test/com/opensymphony/xwork2/config/providers/xwork-test-wildcard-include.xml

+<!DOCTYPE xwork PUBLIC
+    "-//OpenSymphony Group//XWork 1.1.1//EN"
+    "http://www.opensymphony.com/xwork/xwork-1.1.1.dtd"
+ >
+
+<xwork>
+    <include file="xwork-test-beans.xml" />
+    <include file="com/opensymphony/xwork2/config/providers/xwork-test-wildcard-*.xml" />
+    <package name="default-wildcard" />
+</xwork>
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.