001: /*
002: * This file is part of PFIXCORE.
003: *
004: * PFIXCORE is free software; you can redistribute it and/or modify
005: * it under the terms of the GNU Lesser General Public License as published by
006: * the Free Software Foundation; either version 2 of the License, or
007: * (at your option) any later version.
008: *
009: * PFIXCORE is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: * GNU Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public License
015: * along with PFIXCORE; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: */
018:
019: package de.schlund.pfixxml.config.impl;
020:
021: import java.io.IOException;
022: import java.io.StringReader;
023: import java.util.ArrayList;
024: import java.util.Collections;
025: import java.util.HashMap;
026: import java.util.HashSet;
027: import java.util.Iterator;
028: import java.util.List;
029: import java.util.Properties;
030: import java.util.Set;
031: import java.util.Map.Entry;
032:
033: import javax.xml.parsers.ParserConfigurationException;
034: import javax.xml.parsers.SAXParser;
035: import javax.xml.parsers.SAXParserFactory;
036:
037: import org.apache.commons.digester.Digester;
038: import org.apache.commons.digester.Rule;
039: import org.apache.commons.digester.RulesBase;
040: import org.apache.commons.digester.WithDefaultsRulesWrapper;
041: import org.apache.log4j.Logger;
042: import org.w3c.dom.Document;
043: import org.xml.sax.InputSource;
044: import org.xml.sax.SAXException;
045:
046: import de.schlund.pfixxml.config.CustomizationHandler;
047: import de.schlund.pfixxml.config.DirectOutputServletConfig;
048: import de.schlund.pfixxml.config.includes.FileIncludeEvent;
049: import de.schlund.pfixxml.config.includes.FileIncludeEventListener;
050: import de.schlund.pfixxml.config.includes.IncludesResolver;
051: import de.schlund.pfixxml.resources.FileResource;
052: import de.schlund.pfixxml.util.Xml;
053:
054: /**
055: * Stores configuration for a Pustefix servlet
056: *
057: * @author Sebastian Marsching <sebastian.marsching@1und1.de>
058: */
059: public class DirectOutputServletConfigImpl extends
060: ServletManagerConfigImpl implements SSLOption,
061: DirectOutputServletConfig {
062: private final static String CONFIG_NS = "http://pustefix.sourceforge.net/properties200401";
063:
064: private final static String CUS_NS = "http://www.schlund.de/pustefix/customize";
065:
066: private final static Logger LOG = Logger
067: .getLogger(DirectOutputServletConfigImpl.class);
068:
069: private String servletName = null;
070:
071: private boolean editMode = false;
072:
073: private String externalName;
074:
075: private boolean sync = true;
076:
077: private HashMap<String, DirectOutputPageRequestConfigImpl> pages = new HashMap<String, DirectOutputPageRequestConfigImpl>();
078:
079: private List<DirectOutputPageRequestConfigImpl> cachePages = null;
080:
081: private Set<FileResource> fileDependencies = new HashSet<FileResource>();
082:
083: private long loadTime = 0;
084:
085: public static DirectOutputServletConfigImpl readFromFile(
086: FileResource file, Properties globalProperties)
087: throws SAXException, IOException {
088: final DirectOutputServletConfigImpl config = new DirectOutputServletConfigImpl();
089:
090: // Initialize configuration properties with global default properties
091: config.setProperties(globalProperties);
092:
093: Digester digester = new Digester();
094: WithDefaultsRulesWrapper rules = new WithDefaultsRulesWrapper(
095: new RulesBase());
096: digester.setRules(rules);
097: rules.addDefault(new DefaultMatchRule());
098: digester.setRuleNamespaceURI(CONFIG_NS);
099:
100: Rule servletInfoRule = new DirectOutputServletInfoRule(config);
101: Rule sslRule = new SSLRule();
102: Rule foreignContextRule = new DirectForeignContextRule(config);
103: Rule pagerequestRule = new DirectPagerequestRule(config);
104: Rule pagerequestStateRule = new DirectPagerequestStateRule(
105: config);
106: Rule pagerequestPropertyRule = new DirectPagerequestPropertyRule(
107: config);
108: Rule servletPropertyRule = new ServletPropertyRule(config);
109: // Dummy rule doing nothing
110: Rule dummyRule = new Rule() {
111: };
112:
113: digester.addRule("directoutputserver", dummyRule);
114: digester.addRule("directoutputserver/directoutputservletinfo",
115: servletInfoRule);
116: // Still allowed for compatibility reasons
117: digester.addRule(
118: "directoutputserver/directoutputservletinfo/editmode",
119: dummyRule);
120: digester.addRule(
121: "directoutputserver/directoutputservletinfo/ssl",
122: sslRule);
123: digester.addRule("directoutputserver/foreigncontext",
124: foreignContextRule);
125: digester.addRule("directoutputserver/directoutputpagerequest",
126: pagerequestRule);
127: digester
128: .addRule(
129: "directoutputserver/directoutputpagerequest/directoutputstate",
130: pagerequestStateRule);
131: digester
132: .addRule(
133: "directoutputserver/directoutputpagerequest/properties",
134: dummyRule);
135: digester
136: .addRule(
137: "directoutputserver/directoutputpagerequest/properties/prop",
138: pagerequestPropertyRule);
139: digester.addRule("directoutputserver/properties", dummyRule);
140: digester.addRule("directoutputserver/properties/prop",
141: servletPropertyRule);
142:
143: CustomizationHandler cushandler = new CustomizationHandler(
144: digester,
145: CONFIG_NS,
146: CUS_NS,
147: new String[] {
148: "/directoutputserver/directoutputservletinfo",
149: "/directoutputserver/directoutputpagerequest/properties",
150: "/directoutputserver/properties" });
151:
152: String confDocXml = null;
153: config.loadTime = System.currentTimeMillis();
154:
155: Document confDoc = Xml.parseMutable(file);
156: IncludesResolver iresolver = new IncludesResolver(CONFIG_NS,
157: "config-include");
158: // Make sure list of dependencies only contains the file itself
159: config.fileDependencies.clear();
160: config.fileDependencies.add(file);
161: FileIncludeEventListener listener = new FileIncludeEventListener() {
162:
163: public void fileIncluded(FileIncludeEvent event) {
164: config.fileDependencies.add(event.getIncludedFile());
165: }
166:
167: };
168: iresolver.registerListener(listener);
169: iresolver.resolveIncludes(confDoc);
170: confDocXml = Xml.serialize(confDoc, false, true);
171:
172: SAXParser parser;
173: try {
174: SAXParserFactory spfac = SAXParserFactory.newInstance();
175: spfac.setNamespaceAware(true);
176: parser = spfac.newSAXParser();
177: parser.parse(new InputSource(new StringReader(confDocXml)),
178: cushandler);
179: } catch (ParserConfigurationException e) {
180: throw new RuntimeException(
181: "Could not initialize SAXParser!");
182: }
183:
184: return config;
185: }
186:
187: public void setServletName(String name) {
188: this .servletName = name;
189: }
190:
191: public String getServletName() {
192: return this .servletName;
193: }
194:
195: public void setEditMode(boolean enabled) {
196: this .editMode = enabled;
197: }
198:
199: public boolean isEditMode() {
200: return this .editMode;
201: }
202:
203: public void setExternalServletName(String externalName) {
204: this .externalName = externalName;
205: }
206:
207: /* (non-Javadoc)
208: * @see de.schlund.pfixxml.config.DirectOutputServletConfig#getExternalServletName()
209: */
210: public String getExternalServletName() {
211: return this .externalName;
212: }
213:
214: public void setSynchronized(boolean sync) {
215: this .sync = sync;
216: }
217:
218: /* (non-Javadoc)
219: * @see de.schlund.pfixxml.config.DirectOutputServletConfig#isSynchronized()
220: */
221: public boolean isSynchronized() {
222: return sync;
223: }
224:
225: public void addPageRequest(DirectOutputPageRequestConfigImpl config) {
226: if (this .pages.containsKey(config.getPageName())) {
227: LOG
228: .warn("Overwriting configuration for direct output pagerequest"
229: + config.getPageName());
230: }
231: this .pages.put(config.getPageName(), config);
232: this .cachePages = null;
233: }
234:
235: /* (non-Javadoc)
236: * @see de.schlund.pfixxml.config.DirectOutputServletConfig#getPageRequests()
237: */
238: public List<DirectOutputPageRequestConfigImpl> getPageRequests() {
239: List<DirectOutputPageRequestConfigImpl> list = this .cachePages;
240: if (list == null) {
241: list = new ArrayList<DirectOutputPageRequestConfigImpl>();
242: for (Iterator<Entry<String, DirectOutputPageRequestConfigImpl>> i = this .pages
243: .entrySet().iterator(); i.hasNext();) {
244: Entry<String, DirectOutputPageRequestConfigImpl> entry = i
245: .next();
246: list.add(entry.getValue());
247: }
248: list = Collections.unmodifiableList(list);
249: this .cachePages = list;
250: }
251: return list;
252: }
253:
254: /* (non-Javadoc)
255: * @see de.schlund.pfixxml.config.DirectOutputServletConfig#getPageRequest(java.lang.String)
256: */
257: public DirectOutputPageRequestConfigImpl getPageRequest(String page) {
258: return this .pages.get(page);
259: }
260:
261: public boolean needsReload() {
262: for (FileResource file : fileDependencies) {
263: if (file.lastModified() > loadTime) {
264: return true;
265: }
266: }
267: return false;
268: }
269: }
|