diff --git a/core/src/main/java/org/acegisecurity/util/WebXmlSecurityToSpringBeansTranslator.java b/core/src/main/java/org/acegisecurity/util/WebXmlSecurityToSpringBeansTranslator.java
new file mode 100644
index 0000000000..b57b0bf17d
--- /dev/null
+++ b/core/src/main/java/org/acegisecurity/util/WebXmlSecurityToSpringBeansTranslator.java
@@ -0,0 +1,108 @@
+package net.sf.acegisecurity.util;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.DOMImplementation;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.FileSystemResource;
+import org.springframework.beans.factory.BeanFactory;
+import org.springframework.beans.factory.support.DefaultListableBeanFactory;
+import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
+import org.xml.sax.SAXException;
+
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.Source;
+import javax.xml.transform.Result;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.dom.DOMResult;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.ParserConfigurationException;
+import java.io.IOException;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+
+
+/**
+ * A utility to translate a web.xml file into a set of
+ * acegi security spring beans.
+ *
+ *
+ * This class wraps the XSL transform which actually does
+ * most of the work. It also tests the result by
+ * loading it into a Spring bean factory.
+ *
+ *
+ * @author Luke Taylor
+ * @version $Id$
+ */
+public class WebXmlSecurityToSpringBeansTranslator {
+ private String webToSpringXsltFile = "web-to-spring.xsl";
+ private String outputFileName = "applicationContext-acegi-security.xml";
+ private Transformer transformer, identityTransformer;
+ private DefaultListableBeanFactory beanFactory;
+ DocumentBuilderFactory dbf;
+
+ public WebXmlSecurityToSpringBeansTranslator() throws Exception {
+ ClassPathResource resource = new ClassPathResource(webToSpringXsltFile);
+ Source xsltSource = new StreamSource(resource.getInputStream());
+ dbf = DocumentBuilderFactory.newInstance();
+ dbf.setNamespaceAware(true);
+ TransformerFactory tf = TransformerFactory.newInstance();
+ transformer = tf.newTransformer(xsltSource);
+ identityTransformer = tf.newTransformer();
+ identityTransformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, "-//SPRING//DTD BEAN//EN");
+ identityTransformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, "http://www.springframework.org/dtd/spring-beans.dtd");
+ }
+
+ public void translate(InputStream in) throws TransformerException, IOException, ParserConfigurationException, SAXException {
+ DocumentBuilder db = dbf.newDocumentBuilder();
+ Document d = db.parse(in);
+ translate(d);
+ }
+
+ /**
+ * Converts the web.xml supplied as a DOM Node
+ *
+ * @param webXml the web application xml
+ */
+ public void translate(Node webXml) throws IOException, TransformerException, ParserConfigurationException {
+ Source xmlSource = new DOMSource(webXml);
+ DOMResult domResult = new DOMResult();
+
+ transformer.transform(xmlSource, domResult);
+
+ // Obtain DOM for additional manipulation here.
+ Node document = domResult.getNode();
+
+ // Tranform DOM with identity transform to get the output file
+ Result streamResult = new StreamResult(new FileOutputStream(outputFileName));
+ xmlSource = new DOMSource(document);
+ identityTransformer.transform(xmlSource, streamResult);
+ beanFactory = new DefaultListableBeanFactory();
+ XmlBeanDefinitionReader beanReader = new XmlBeanDefinitionReader(beanFactory);
+ beanReader.loadBeanDefinitions(new FileSystemResource(outputFileName));
+ }
+
+ public String getOutputFileName() {
+ return outputFileName;
+ }
+
+ public void setOutputFileName(String outputFileName) {
+ this.outputFileName = outputFileName;
+ }
+
+ /**
+ * Mainly intended for testing
+ * @return the bean factory built from the created acegi security application context file
+ *
+ */
+ public BeanFactory getBeanFactory() {
+ return beanFactory;
+ }
+}
diff --git a/core/src/main/resources/web-to-spring.xsl b/core/src/main/resources/web-to-spring.xsl
new file mode 100644
index 0000000000..7c55d133e9
--- /dev/null
+++ b/core/src/main/resources/web-to-spring.xsl
@@ -0,0 +1,258 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ROLE_
+
+ ,
+
+
+
+
+
+/**=httpSessionContextIntegrationFilter
+
+
+ ,authenticationProcessingFilter
+
+
+ ,basicProcessingFilter
+
+
+ Unsupported auth-method in web.xml, must be FORM or BASIC
+
+
+,rememberMeProcessingFilter,anonymousProcessingFilter,securityEnforcementFilter
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ======================== AUTHENTICATION =======================
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ superuser=password,
+
+
+
+
+
+
+ foobar
+ anonymousUser,ROLE_ANONYMOUS
+
+
+
+ foobar
+
+
+
+
+
+
+
+
+
+
+
+ springRocks
+
+
+
+ springRocks
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Your Realm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ======================== FILTER CHAIN =======================
+
+ if you wish to use channel security, add "channelProcessingFilter," in front
+ of "httpSessionContextIntegrationFilter" in the list below
+
+
+
+ CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
+ PATTERN_TYPE_APACHE_ANT
+
+
+
+
+
+
+
+
+
+ Processing form login configuration
+ Remember to switch your login form action from "j_security_check" to "j_acegi_security_check"
+
+
+
+
+
+ /j_acegi_security_check
+
+
+
+
+
+ false
+
+
+
+
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+ Note the order that entries are placed against the objectDefinitionSource is critical.
+ The FilterSecurityInterceptor will work from the top of the list down to the FIRST pattern that matches the request URL.
+ Accordingly, you should place MOST SPECIFIC (ie a/b/c/d.*) expressions first, with LEAST SPECIFIC (ie a/.*) expressions last
+
+
+
+
+
+
+
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
+ PATTERN_TYPE_APACHE_ANT
+
+
+
+
+
+
+
+
+ =
+
+
+
+
+
+
+ ROLE_
+
+
+
+ ,
+
+
+
+
+
+
+ ROLE_
+
+ ,
+
+
+
+
diff --git a/core/src/test/java/org/acegisecurity/util/WebXmlSecurityToSpringBeansTranslatorTests.java b/core/src/test/java/org/acegisecurity/util/WebXmlSecurityToSpringBeansTranslatorTests.java
new file mode 100644
index 0000000000..1c8625c0ac
--- /dev/null
+++ b/core/src/test/java/org/acegisecurity/util/WebXmlSecurityToSpringBeansTranslatorTests.java
@@ -0,0 +1,59 @@
+package net.sf.acegisecurity.util;
+
+import junit.framework.TestCase;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
+import org.springframework.beans.factory.BeanFactory;
+
+import net.sf.acegisecurity.providers.ProviderManager;
+import net.sf.acegisecurity.providers.dao.DaoAuthenticationProvider;
+import net.sf.acegisecurity.providers.dao.memory.InMemoryDaoImpl;
+import net.sf.acegisecurity.UserDetails;
+import net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter;
+
+import net.sf.acegisecurity.intercept.web.FilterSecurityInterceptor;
+
+/**
+ * Tests the WebXmlSecurityToSpringBeansTranslator by applying it
+ * to a test sample web.xml file.
+ *
+ * @author Luke Taylor
+ * @version $Id$
+ */
+public class WebXmlSecurityToSpringBeansTranslatorTests extends TestCase {
+
+ public void testFileTranslation() throws Exception {
+ WebXmlSecurityToSpringBeansTranslator t = new WebXmlSecurityToSpringBeansTranslator();
+
+ Resource r = new ClassPathResource("test-web.xml");
+ t.translate(r.getInputStream());
+
+ BeanFactory bf = t.getBeanFactory();
+ assertNotNull(bf.getBean("filterChainProxy"));
+
+ ProviderManager pm = (ProviderManager) bf.getBean("authenticationManager");
+ assertNotNull(pm);
+ assertEquals(3, pm.getProviders().size());
+
+ DaoAuthenticationProvider dap =
+ (DaoAuthenticationProvider) bf.getBean("daoAuthenticationProvider");
+ assertNotNull(dap);
+
+ InMemoryDaoImpl dao = (InMemoryDaoImpl) dap.getAuthenticationDao();
+ UserDetails user = dao.loadUserByUsername("superuser");
+ assertEquals("password",user.getPassword());
+ assertEquals(2, user.getAuthorities().length);
+ assertNotNull(bf.getBean("anonymousProcessingFilter"));
+ assertNotNull(bf.getBean("anonymousAuthenticationProvider"));
+ assertNotNull(bf.getBean("httpSessionContextIntegrationFilter"));
+ assertNotNull(bf.getBean("rememberMeProcessingFilter"));
+ assertNotNull(bf.getBean("rememberMeAuthenticationProvider"));
+
+ SecurityEnforcementFilter sef =
+ (SecurityEnforcementFilter) bf.getBean("securityEnforcementFilter");
+ assertNotNull(sef);
+ assertNotNull(sef.getAuthenticationEntryPoint());
+ FilterSecurityInterceptor fsi = sef.getFilterSecurityInterceptor();
+
+ }
+}
diff --git a/core/src/test/resources/test-web.xml b/core/src/test/resources/test-web.xml
new file mode 100644
index 0000000000..0e7f2ffb12
--- /dev/null
+++ b/core/src/test/resources/test-web.xml
@@ -0,0 +1,54 @@
+
+ login-xml
+
+
+ index.jsp
+ index.html
+
+
+
+
+ /home.jsp
+
+
+ *
+
+
+
+
+
+ /admin/*
+
+
+ admin
+
+
+
+
+
+ /user/*
+
+
+ user
+ admin
+
+
+
+
+ form
+
+ /login.jsp
+ /login.jsp?login_error=1
+
+
+
+
+
+ user
+
+
+
+ admin
+
+
+
\ No newline at end of file