View Javadoc

1   /*
2    * $Id: StrutsXmlConfigurationProvider.java 651946 2008-04-27 13:41:38Z apetrelli $
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          setDtdMappings(dtdMappings);
81          File file = new File(filename);
82          if (file.getParent() != null) {
83              this.baseDir = file.getParentFile();
84          }
85      }
86      
87      /* (non-Javadoc)
88       * @see com.opensymphony.xwork2.config.providers.XmlConfigurationProvider#register(com.opensymphony.xwork2.inject.ContainerBuilder, java.util.Properties)
89       */
90      @Override
91      public void register(ContainerBuilder containerBuilder, LocatableProperties props) throws ConfigurationException {
92          if (servletContext != null && !containerBuilder.contains(ServletContext.class)) {
93              containerBuilder.factory(ServletContext.class, new Factory() {
94                  public Object create(Context context) throws Exception {
95                      return servletContext;
96                  }
97                  
98              });
99          }
100         super.register(containerBuilder, props);
101     }
102 
103     /* (non-Javadoc)
104      * @see com.opensymphony.xwork2.config.providers.XmlConfigurationProvider#init(com.opensymphony.xwork2.config.Configuration)
105      */
106     @Override
107     public void loadPackages() {
108         ActionContext ctx = ActionContext.getContext();
109         ctx.put(reloadKey, Boolean.TRUE);
110         super.loadPackages();
111     }
112 
113     /***
114      * Look for the configuration file on the classpath and in the file system
115      *
116      * @param fileName The file name to retrieve
117      * @see com.opensymphony.xwork2.config.providers.XmlConfigurationProvider#getConfigurationUrls
118      */
119     @Override
120     protected Iterator<URL> getConfigurationUrls(String fileName) throws IOException {
121         URL url = null;
122         if (baseDir != null) {
123             url = findInFileSystem(fileName);
124             if (url == null) {
125                 return super.getConfigurationUrls(fileName);
126             }
127         }
128         if (url != null) {
129             List<URL> list = new ArrayList<URL>();
130             list.add(url);
131             return list.iterator();
132         } else {
133             return super.getConfigurationUrls(fileName);
134         }
135     }
136 
137     protected URL findInFileSystem(String fileName) throws IOException {
138         URL url = null;
139         File file = new File(fileName);
140         if (LOG.isDebugEnabled()) {
141             LOG.debug("Trying to load file " + file);
142         }
143 
144         // Trying relative path to original file
145         if (!file.exists()) {
146             file = new File(baseDir, fileName);
147         }
148         if (file.exists()) {
149             try {
150                 url = file.toURL();
151             } catch (MalformedURLException e) {
152                 throw new IOException("Unable to convert "+file+" to a URL");
153             }
154         }
155         return url;
156     }
157 
158     /***
159      * Overrides needs reload to ensure it is only checked once per request
160      */
161     @Override
162     public boolean needsReload() {
163         ActionContext ctx = ActionContext.getContext();
164         if (ctx != null) {
165             return ctx.get(reloadKey) == null && super.needsReload();
166         } else {
167             return super.needsReload();
168         }
169 
170     }
171     
172     public String toString() {
173         return ("Struts XML configuration provider ("+filename+")");
174     }
175 
176 
177 }