001: /*
002: * $Id: StrutsXmlConfigurationProvider.java 476106 2006-11-17 10:56:40Z mrdon $
003: *
004: * Licensed to the Apache Software Foundation (ASF) under one
005: * or more contributor license agreements. See the NOTICE file
006: * distributed with this work for additional information
007: * regarding copyright ownership. The ASF licenses this file
008: * to you under the Apache License, Version 2.0 (the
009: * "License"); you may not use this file except in compliance
010: * with the License. You may obtain a copy of the License at
011: *
012: * http://www.apache.org/licenses/LICENSE-2.0
013: *
014: * Unless required by applicable law or agreed to in writing,
015: * software distributed under the License is distributed on an
016: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017: * KIND, either express or implied. See the License for the
018: * specific language governing permissions and limitations
019: * under the License.
020: */
021: package org.apache.struts2.config;
022:
023: import java.io.File;
024: import java.io.IOException;
025: import java.net.MalformedURLException;
026: import java.net.URL;
027: import java.util.ArrayList;
028: import java.util.HashMap;
029: import java.util.Iterator;
030: import java.util.List;
031: import java.util.Map;
032: import java.util.Properties;
033:
034: import javax.servlet.ServletContext;
035:
036: import org.apache.commons.logging.Log;
037: import org.apache.commons.logging.LogFactory;
038:
039: import com.opensymphony.xwork2.ActionContext;
040: import com.opensymphony.xwork2.config.ConfigurationException;
041: import com.opensymphony.xwork2.config.providers.XmlConfigurationProvider;
042: import com.opensymphony.xwork2.inject.ContainerBuilder;
043: import com.opensymphony.xwork2.inject.Context;
044: import com.opensymphony.xwork2.inject.Factory;
045: import com.opensymphony.xwork2.util.location.LocatableProperties;
046:
047: /**
048: * Override Xwork class so we can use an arbitrary config file
049: */
050: public class StrutsXmlConfigurationProvider extends
051: XmlConfigurationProvider {
052:
053: private static final Log LOG = LogFactory
054: .getLog(StrutsXmlConfigurationProvider.class);
055: private File baseDir = null;
056: private String filename;
057: private String reloadKey;
058: private ServletContext servletContext;
059:
060: /**
061: * Constructs the configuration provider
062: *
063: * @param errorIfMissing If we should throw an exception if the file can't be found
064: */
065: public StrutsXmlConfigurationProvider(boolean errorIfMissing) {
066: this ("struts.xml", errorIfMissing, null);
067: }
068:
069: /**
070: * Constructs the configuration provider
071: *
072: * @param filename The filename to look for
073: * @param errorIfMissing If we should throw an exception if the file can't be found
074: * @param ctx Our ServletContext
075: */
076: public StrutsXmlConfigurationProvider(String filename,
077: boolean errorIfMissing, ServletContext ctx) {
078: super (filename, errorIfMissing);
079: this .servletContext = ctx;
080: this .filename = filename;
081: reloadKey = "configurationReload-" + filename;
082: Map<String, String> dtdMappings = new HashMap<String, String>(
083: getDtdMappings());
084: dtdMappings
085: .put(
086: "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN",
087: "struts-2.0.dtd");
088: setDtdMappings(dtdMappings);
089: File file = new File(filename);
090: if (file.getParent() != null) {
091: this .baseDir = file.getParentFile();
092: }
093: }
094:
095: /* (non-Javadoc)
096: * @see com.opensymphony.xwork2.config.providers.XmlConfigurationProvider#register(com.opensymphony.xwork2.inject.ContainerBuilder, java.util.Properties)
097: */
098: @Override
099: public void register(ContainerBuilder containerBuilder,
100: LocatableProperties props) throws ConfigurationException {
101: if (servletContext != null
102: && !containerBuilder.contains(ServletContext.class)) {
103: containerBuilder.factory(ServletContext.class,
104: new Factory() {
105: public Object create(Context context)
106: throws Exception {
107: return servletContext;
108: }
109:
110: });
111: }
112: super .register(containerBuilder, props);
113: }
114:
115: /* (non-Javadoc)
116: * @see com.opensymphony.xwork2.config.providers.XmlConfigurationProvider#init(com.opensymphony.xwork2.config.Configuration)
117: */
118: @Override
119: public void loadPackages() {
120: ActionContext ctx = ActionContext.getContext();
121: ctx.put(reloadKey, Boolean.TRUE);
122: super .loadPackages();
123: }
124:
125: /**
126: * Look for the configuration file on the classpath and in the file system
127: *
128: * @param fileName The file name to retrieve
129: * @see com.opensymphony.xwork2.config.providers.XmlConfigurationProvider#getConfigurationUrls
130: */
131: @Override
132: protected Iterator<URL> getConfigurationUrls(String fileName)
133: throws IOException {
134: URL url = null;
135: if (baseDir != null) {
136: url = findInFileSystem(fileName);
137: if (url == null) {
138: return super .getConfigurationUrls(fileName);
139: }
140: }
141: if (url != null) {
142: List<URL> list = new ArrayList<URL>();
143: list.add(url);
144: return list.iterator();
145: } else {
146: return super .getConfigurationUrls(fileName);
147: }
148: }
149:
150: protected URL findInFileSystem(String fileName) throws IOException {
151: URL url = null;
152: File file = new File(fileName);
153: if (LOG.isDebugEnabled()) {
154: LOG.debug("Trying to load file " + file);
155: }
156:
157: // Trying relative path to original file
158: if (!file.exists()) {
159: file = new File(baseDir, fileName);
160: }
161: if (file.exists()) {
162: try {
163: url = file.toURL();
164: } catch (MalformedURLException e) {
165: throw new IOException("Unable to convert " + file
166: + " to a URL");
167: }
168: }
169: return url;
170: }
171:
172: /**
173: * Overrides needs reload to ensure it is only checked once per request
174: */
175: @Override
176: public boolean needsReload() {
177: ActionContext ctx = ActionContext.getContext();
178: return ctx.get(reloadKey) == null && super .needsReload();
179:
180: }
181:
182: public String toString() {
183: return ("Struts XML configuration provider (" + filename + ")");
184: }
185:
186: }
|