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 }