1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
88
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
104
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
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 }