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 dtdMappings.put("-//Apache Software Foundation//DTD Struts Configuration 2.1//EN", "struts-2.1.dtd");
81 setDtdMappings(dtdMappings);
82 File file = new File(filename);
83 if (file.getParent() != null) {
84 this.baseDir = file.getParentFile();
85 }
86 }
87
88
89
90
91 @Override
92 public void register(ContainerBuilder containerBuilder, LocatableProperties props) throws ConfigurationException {
93 if (servletContext != null && !containerBuilder.contains(ServletContext.class)) {
94 containerBuilder.factory(ServletContext.class, new Factory() {
95 public Object create(Context context) throws Exception {
96 return servletContext;
97 }
98
99 });
100 }
101 super.register(containerBuilder, props);
102 }
103
104
105
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
146 if (!file.exists()) {
147 file = new File(baseDir, fileName);
148 }
149 if (file.exists()) {
150 try {
151 url = file.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
177
178 }