Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/sitemesh/mapper/DefaultDecoratorMapper.java


1   package com.sitemesh.mapper;
2   
3   import java.io.File;
4   import java.io.IOException;
5   import java.util.*;
6   import javax.servlet.Config;
7   import javax.servlet.ServletException;
8   import javax.servlet.http.HttpServletRequest;
9   import javax.xml.parsers.DocumentBuilder;
10  import javax.xml.parsers.DocumentBuilderFactory;
11  import javax.xml.parsers.ParserConfigurationException;
12  import org.w3c.dom.*;
13  import org.xml.sax.SAXException;
14  import com.sitemesh.*;
15  
16  // ---------------- PLEASE REFACTOR ME!!! --------------------
17  
18  /**
19   * Default implementation of DecoratorMapper. Reads decorators and
20   * mappings from <code>/WEB-INF/decorators.xml</code>.
21   *
22   * @author <a href="joe@truemesh.com">Joe Walnes</a>
23   * @author <a href="mcannon@internet.com">Mike Cannon-Brookes</a>
24   * @version $Revision: 1.5 $
25   *
26   * @see com.sitemesh.DecoratorMapper
27   * @see com.sitemesh.mapper.DefaultDecorator
28   */
29  public class DefaultDecoratorMapper implements DecoratorMapper, RequestConstants {
30  
31    private Map decorators;
32    private Map mappings;
33    private long configLastModified;
34    private File configFile;
35  
36    /**
37     * @label constructs
38     * @directed 
39     */
40    /*#private DefaultDecorator lnkDefaultDecorator;*/
41  
42    public void init(Config config, Properties properties) throws InstantiationException {
43      try {
44        String fileName = config.getInitParameter("decorators.config");
45        if (fileName == null) fileName = "/WEB-INF/decorators.xml";
46        configFile = new File( config.getServletContext().getRealPath(fileName) );
47        loadConfig();
48      }
49      catch (Exception e) {
50        throw new InstantiationException(e.toString());
51      }
52    }
53  
54    public Decorator getDecorator(HttpServletRequest request, Page page) {
55      Decorator result = null;
56      if ( page instanceof HTMLPage ) {
57        // Only try and find a Decorator if instance of HTMLPage
58        if ( request.getAttribute(DECORATOR) != null ) {
59          // Retrieve name of decorator to use from request
60          String decoratorName = (String)request.getAttribute(DECORATOR);
61          result = ( Decorator )decorators.get( decoratorName );
62        }
63        else {
64          // If that doesn't work, get the decorator-mapping for the url.
65          String key = findKey( request.getServletPath() );
66          result = ( Decorator )decorators.get( ( String )mappings.get( key ) );
67        }
68      }
69      return result;
70    }
71  
72    private String findKey( String path ) {
73      String result = findExactKey( path );
74      if ( result == null ) result = findDirectoryKey( path );
75      if ( result == null ) result = findExtentionKey( path );
76      if ( result == null ) result = findDefaultKey( path );
77      return result;
78    }
79  
80    private String findExactKey( String path ) {
81      if ( mappings.containsKey( path ) ) return path;
82      return null;
83    }
84  
85    private String findDirectoryKey( String path ) {
86      if (path.lastIndexOf("/") <= 0) return null;
87      String tempPath = path.substring(0, path.lastIndexOf("/"));
88      while (!tempPath.equals("/") && tempPath.length() > 0) {
89        if ( mappings.containsKey( tempPath + "/*" ) ) return tempPath + "/*";
90        tempPath = tempPath.substring(0, tempPath.lastIndexOf("/"));
91      }
92      return null;
93    }
94  
95    private String findExtentionKey( String path ) {
96      if ( path.indexOf( "." ) == -1 ) return null;
97      String ext = path.substring( path.lastIndexOf( "." ) + 1 );
98      String[] extKeys = {"*."+ext , "/*."+ext};
99      for ( int i = 0; i < extKeys.length; i++ ) {
100       if ( mappings.containsKey( extKeys[i] ) ) return extKeys[i];
101     }
102     return null;
103   }
104 
105   private String findDefaultKey( String path ) {
106     String[] defaultKeys = {"/","*","/*"};
107     for ( int i = 0; i < defaultKeys.length; i++ ) {
108       if ( mappings.containsKey( defaultKeys[i] ) ) return defaultKeys[i];
109     }
110     return null;
111   }
112 
113   private synchronized void loadConfig() throws ServletException {
114     try {
115       // Clear previous config
116       mappings = new HashMap();
117       decorators = new HashMap();
118       // Parse file
119       DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
120       DocumentBuilder builder        = factory.newDocumentBuilder();
121       configLastModified             = configFile.lastModified();
122       Document document              = builder.parse( configFile );
123       Element root                   = document.getDocumentElement();
124       // Verify root element
125       if ( !root.getTagName().equals( "decorators" ) ) {
126         throw new ServletException( "Root element of decorators config file not <decorators>" );
127       }
128       // Get decorators
129       NodeList decoratorNodes = root.getElementsByTagName( "decorator" );
130       for ( int i = 0; i < decoratorNodes.getLength(); i++ ) {
131         String name         = getContainedText( decoratorNodes.item( i ), "decorator-name" );
132         String page         = getContainedText( decoratorNodes.item( i ), "jsp-file" );
133         Map params          = new HashMap();
134         NodeList paramNodes = ( ( Element )decoratorNodes.item( i ) ).getElementsByTagName( "init-param" );
135         for ( int ii = 0; ii < paramNodes.getLength(); ii++ ) {
136           String paramName = getContainedText( paramNodes.item( ii ), "param-name" );
137           String paramValue = getContainedText( paramNodes.item( ii ), "param-value" );
138           params.put( paramName, paramValue );
139         }
140         storeDecorator( new DefaultDecorator( name, page, params ) );
141       }
142       // Get decorator-mappings
143       NodeList mappingNodes = root.getElementsByTagName( "decorator-mapping" );
144       for ( int i = 0; i < mappingNodes.getLength(); i++ ) {
145         Element n      = ( Element )mappingNodes.item( i );
146         String name    = getContainedText( mappingNodes.item( i ), "decorator-name" );
147         String pattern = getContainedText( mappingNodes.item( i ), "url-pattern" );
148         storeMapping( name, pattern );
149       }
150     }
151     catch ( ParserConfigurationException e ) {
152       throw new ServletException( "Could not get XML parser", e );
153     }
154     catch ( IOException e ) {
155       throw new ServletException( "Could not read config file", e );
156     }
157     catch ( SAXException e ) {
158       throw new ServletException( "Could not parse config file", e );
159     }
160   }
161 
162   private String getContainedText( Node parent, String childTagName ) {
163     try {
164       Node tag = ( ( Element )parent ).getElementsByTagName( childTagName ).item( 0 );
165       String text = ( ( Text )tag.getFirstChild() ).getData();
166       return text;
167     }
168     catch ( Exception e ) {
169       return null;
170     }
171   }
172 
173   private void storeDecorator( Decorator d ) {
174     decorators.put( d.getName(), d );
175   }
176 
177   private void storeMapping( String name, String pattern ) {
178     mappings.put( pattern, name );
179   }
180 
181   /** Check if configuration file has been updated, and if so, reload. */
182   public synchronized void refresh() throws ServletException {
183     if (configLastModified != configFile.lastModified()) loadConfig();
184   }
185 
186 }