View Javadoc

1   package acegifier;
2   
3   import java.io.IOException;
4   import java.io.InputStream;
5   import java.util.List;
6   
7   import javax.xml.transform.Source;
8   import javax.xml.transform.Transformer;
9   import javax.xml.transform.TransformerConfigurationException;
10  import javax.xml.transform.TransformerException;
11  import javax.xml.transform.TransformerFactory;
12  import javax.xml.transform.stream.StreamSource;
13  
14  import org.dom4j.Document;
15  import org.dom4j.DocumentException;
16  import org.dom4j.DocumentHelper;
17  import org.dom4j.Node;
18  import org.dom4j.io.DocumentResult;
19  import org.dom4j.io.DocumentSource;
20  import org.dom4j.io.SAXReader;
21  import org.springframework.core.io.ClassPathResource;
22  import org.springframework.util.Assert;
23  
24  /***
25   * A utility to translate a web.xml file into a set of acegi security spring beans.
26   *
27   * Also produces a new "acegified" web.xml file with the necessary filters installed
28   * and the security elements defined by the servlet DTD removed.
29   *
30   * <p>
31   * This class wraps the XSL transform which actually does most of the work.
32   * </p>
33   *
34   * @author Luke Taylor
35   * @version $Id: WebXmlConverter.java,v 1.1 2005/11/29 02:33:40 benalex Exp $
36   */
37  public class WebXmlConverter {
38      private static final String WEB_TO_SPRING_XSL_FILE = "web-to-spring.xsl";
39      private static final String NEW_WEB_XSLT_FILE = "acegi-web.xsl";
40  
41      private Transformer acegiSecurityTransformer, newWebXmlTransformer;
42  
43      /***
44       * The name of the spring-beans file which the beans will be stored in.
45       * This is required when writing the new web.xml content.
46       */
47      private String acegiOutputFileName = "applicationContext-acegi-security.xml";
48  
49      /*** The web.xml content to be converted */
50      private Source xmlSource;
51      /*** The results of the conversion */
52      private Document newWebXml, acegiBeansXml;
53  
54      public WebXmlConverter() throws IOException, TransformerConfigurationException {
55      	TransformerFactory tf = TransformerFactory.newInstance();
56      	Source source = createTransformerSource(WEB_TO_SPRING_XSL_FILE);
57      	System.out.println("1");
58          acegiSecurityTransformer = tf.newTransformer(source);
59          System.out.println("2");
60          newWebXmlTransformer = tf.newTransformer(createTransformerSource(NEW_WEB_XSLT_FILE));
61          System.out.println("3");
62      }
63  
64      private Source createTransformerSource(String fileName) throws IOException {
65          ClassPathResource resource = new ClassPathResource(fileName);
66          Source source = new StreamSource(resource.getInputStream());
67          return source;
68      }
69  
70      /***
71       * Performs the transformations on the input source.
72       * Creates new web.xml content and a set of acegi-security Spring beans which can be
73       * accessed through the appropriate getter methods.
74       */
75      public void doConversion() throws IOException, TransformerException {
76          Assert.notNull(xmlSource, "The XML input must be set");
77  
78          // Create the modified web.xml file
79          newWebXmlTransformer.setParameter("acegi-security-context-file", acegiOutputFileName);
80  //        newWebXmlTransformer.setParameter("cas-proxy-url", "http://localhost:8433/cas/proxy");
81          DocumentResult result = new DocumentResult();
82          newWebXmlTransformer.transform(xmlSource, result);
83          newWebXml = result.getDocument();
84  
85          result = new DocumentResult();
86          acegiSecurityTransformer.transform(xmlSource, result);
87          acegiBeansXml = result.getDocument();
88      }
89  
90      /*** Set the input as an xml string */
91      public void setInput(String xml) throws DocumentException {
92          setInput(DocumentHelper.parseText(xml));
93      }
94  
95      /*** Set the input as a stream */
96      public void setInput(InputStream in) throws DocumentException {
97          SAXReader reader = new SAXReader();
98          setInput(reader.read(in));
99      }
100 
101     /*** set the input as a dom4j document */
102     public void setInput(Document document) throws DocumentException {
103         validateWebXml(document);
104         xmlSource = new DocumentSource(document);
105     }
106 
107     /*** Checks the web.xml to make sure it contains correct data */
108     private void validateWebXml(Document document) throws DocumentException {
109         Node authMethodNode =
110                 document.selectSingleNode("/web-app/login-config/auth-method");
111         if(authMethodNode == null)
112             throw new DocumentException("login-config and auth-method must be present");
113         String authMethod =  authMethodNode.getStringValue().toUpperCase();
114         if(!authMethod.equals("BASIC") && !authMethod.equals("FORM")) {
115             throw new DocumentException("unsupported auth-method: " + authMethod);
116         }
117         List roles = document.selectNodes("/web-app/security-role");
118         if(roles.isEmpty()) {
119             throw new DocumentException("Each role used must be defined in a security-role element");
120         }
121     }
122 
123     public String getAcegiOutputFileName() {
124         return acegiOutputFileName;
125     }
126 
127     public void setAcegiOutputFileName(String acegiOutputFileName) {
128         this.acegiOutputFileName = acegiOutputFileName;
129     }
130 
131     /*** Returns the converted web.xml content */
132     public Document getNewWebXml() {
133         return newWebXml;
134     }
135 
136     /***
137      * Returns the created spring-beans xml content which should be used in
138      * the application context file.
139      */
140     public Document getAcegiBeans() {
141         return acegiBeansXml;
142     }
143 }