1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.apache.struts2.config;
22
23 import java.io.File;
24 import java.io.IOException;
25 import java.net.MalformedURLException;
26 import java.net.URL;
27 import java.util.ArrayList;
28 import java.util.HashMap;
29 import java.util.Iterator;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.Properties;
33
34 import javax.servlet.ServletContext;
35
36 import org.apache.commons.logging.Log;
37 import org.apache.commons.logging.LogFactory;
38
39 import com.opensymphony.xwork2.ActionContext;
40 import com.opensymphony.xwork2.config.ConfigurationException;
41 import com.opensymphony.xwork2.config.providers.XmlConfigurationProvider;
42 import com.opensymphony.xwork2.inject.ContainerBuilder;
43 import com.opensymphony.xwork2.inject.Context;
44 import com.opensymphony.xwork2.inject.Factory;
45 import com.opensymphony.xwork2.util.location.LocatableProperties;
46
47 /***
48 * Override Xwork class so we can use an arbitrary config file
49 */
50 public class StrutsXmlConfigurationProvider extends XmlConfigurationProvider {
51
52 private static final Log LOG = LogFactory.getLog(StrutsXmlConfigurationProvider.class);
53 private File baseDir = null;
54 private String filename;
55 private String reloadKey;
56 private ServletContext servletContext;
57
58 /***
59 * Constructs the configuration provider
60 *
61 * @param errorIfMissing If we should throw an exception if the file can't be found
62 */
63 public StrutsXmlConfigurationProvider(boolean errorIfMissing) {
64 this("struts.xml", errorIfMissing, null);
65 }
66
67 /***
68 * Constructs the configuration provider
69 *
70 * @param filename The filename to look for
71 * @param errorIfMissing If we should throw an exception if the file can't be found
72 * @param ctx Our ServletContext
73 */
74 public StrutsXmlConfigurationProvider(String filename, boolean errorIfMissing, ServletContext ctx) {
75 super(filename, errorIfMissing);
76 this.servletContext = ctx;
77 this.filename = filename;
78 reloadKey = "configurationReload-"+filename;
79 Map<String,String> dtdMappings = new HashMap<String,String>(getDtdMappings());
80 dtdMappings.put("-//Apache Software Foundation//DTD Struts Configuration 2.0//EN", "struts-2.0.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 return ctx.get(reloadKey) == null && super.needsReload();
166
167 }
168
169 public String toString() {
170 return ("Struts XML configuration provider ("+filename+")");
171 }
172
173
174 }