View Javadoc

1   /*
2    * $Id: StrutsXmlConfigurationProvider.java 762875 2009-04-07 17:56:30Z musachy $
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  package org.apache.struts2.config;
23  
24  import java.io.File;
25  import java.io.IOException;
26  import java.net.MalformedURLException;
27  import java.net.URL;
28  import java.util.ArrayList;
29  import java.util.HashMap;
30  import java.util.Iterator;
31  import java.util.List;
32  import java.util.Map;
33  
34  import javax.servlet.ServletContext;
35  
36  import com.opensymphony.xwork2.ActionContext;
37  import com.opensymphony.xwork2.config.ConfigurationException;
38  import com.opensymphony.xwork2.config.providers.XmlConfigurationProvider;
39  import com.opensymphony.xwork2.inject.ContainerBuilder;
40  import com.opensymphony.xwork2.inject.Context;
41  import com.opensymphony.xwork2.inject.Factory;
42  import com.opensymphony.xwork2.util.location.LocatableProperties;
43  import com.opensymphony.xwork2.util.logging.Logger;
44  import com.opensymphony.xwork2.util.logging.LoggerFactory;
45  
46  /***
47   * Override Xwork class so we can use an arbitrary config file
48   */
49  public class StrutsXmlConfigurationProvider extends XmlConfigurationProvider {
50  
51      private static final Logger LOG = LoggerFactory.getLogger(StrutsXmlConfigurationProvider.class);
52      private File baseDir = null;
53      private String filename;
54      private String reloadKey;
55      private ServletContext servletContext;
56  
57      /***
58       * Constructs the configuration provider
59       *
60       * @param errorIfMissing If we should throw an exception if the file can't be found
61       */
62      public StrutsXmlConfigurationProvider(boolean errorIfMissing) {
63          this("struts.xml", errorIfMissing, null);
64      }
65  
66      /***
67       * Constructs the configuration provider
68       *
69       * @param filename The filename to look for
70       * @param errorIfMissing If we should throw an exception if the file can't be found
71       * @param ctx Our ServletContext
72       */
73      public StrutsXmlConfigurationProvider(String filename, boolean errorIfMissing, ServletContext ctx) {
74          super(filename, errorIfMissing);
75          this.servletContext = ctx;
76          this.filename = filename;
77          reloadKey = "configurationReload-"+filename;
78          Map<String,String> dtdMappings = new HashMap<String,String>(getDtdMappings());
79          dtdMappings.put("-//Apache Software Foundation//DTD Struts Configuration 2.0//EN", "struts-2.0.dtd");
80          dtdMappings.put("-//Apache Software Foundation//DTD Struts Configuration 2.1//EN", "struts-2.1.dtd");
81          dtdMappings.put("-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN", "struts-2.1.7.dtd");
82          setDtdMappings(dtdMappings);
83          File file = new File(filename);
84          if (file.getParent() != null) {
85              this.baseDir = file.getParentFile();
86          }
87      }
88      
89      /* (non-Javadoc)
90       * @see com.opensymphony.xwork2.config.providers.XmlConfigurationProvider#register(com.opensymphony.xwork2.inject.ContainerBuilder, java.util.Properties)
91       */
92      @Override
93      public void register(ContainerBuilder containerBuilder, LocatableProperties props) throws ConfigurationException {
94          if (servletContext != null && !containerBuilder.contains(ServletContext.class)) {
95              containerBuilder.factory(ServletContext.class, new Factory<ServletContext>() {
96                  public ServletContext create(Context context) throws Exception {
97                      return servletContext;
98                  }
99              });
100         }
101         super.register(containerBuilder, props);
102     }
103 
104     /* (non-Javadoc)
105      * @see com.opensymphony.xwork2.config.providers.XmlConfigurationProvider#init(com.opensymphony.xwork2.config.Configuration)
106      */
107     @Override
108     public void loadPackages() {
109         ActionContext ctx = ActionContext.getContext();
110         ctx.put(reloadKey, Boolean.TRUE);
111         super.loadPackages();
112     }
113 
114     /***
115      * Look for the configuration file on the classpath and in the file system
116      *
117      * @param fileName The file name to retrieve
118      * @see com.opensymphony.xwork2.config.providers.XmlConfigurationProvider#getConfigurationUrls
119      */
120     @Override
121     protected Iterator<URL> getConfigurationUrls(String fileName) throws IOException {
122         URL url = null;
123         if (baseDir != null) {
124             url = findInFileSystem(fileName);
125             if (url == null) {
126                 return super.getConfigurationUrls(fileName);
127             }
128         }
129         if (url != null) {
130             List<URL> list = new ArrayList<URL>();
131             list.add(url);
132             return list.iterator();
133         } else {
134             return super.getConfigurationUrls(fileName);
135         }
136     }
137 
138     protected URL findInFileSystem(String fileName) throws IOException {
139         URL url = null;
140         File file = new File(fileName);
141         if (LOG.isDebugEnabled()) {
142             LOG.debug("Trying to load file " + file);
143         }
144 
145         // Trying relative path to original file
146         if (!file.exists()) {
147             file = new File(baseDir, fileName);
148         }
149         if (file.exists()) {
150             try {
151                 url = file.toURI().toURL();
152             } catch (MalformedURLException e) {
153                 throw new IOException("Unable to convert "+file+" to a URL");
154             }
155         }
156         return url;
157     }
158 
159     /***
160      * Overrides needs reload to ensure it is only checked once per request
161      */
162     @Override
163     public boolean needsReload() {
164         ActionContext ctx = ActionContext.getContext();
165         if (ctx != null) {
166             return ctx.get(reloadKey) == null && super.needsReload();
167         } else {
168             return super.needsReload();
169         }
170 
171     }
172     
173     public String toString() {
174         return ("Struts XML configuration provider ("+filename+")");
175     }
176 }