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.HashSet;
024: import java.util.Properties;
025: import java.util.Set;
026:
027: import javax.xml.parsers.ParserConfigurationException;
028: import javax.xml.parsers.SAXParser;
029: import javax.xml.parsers.SAXParserFactory;
030:
031: import org.apache.commons.digester.Digester;
032: import org.apache.commons.digester.Rule;
033: import org.apache.commons.digester.RulesBase;
034: import org.apache.commons.digester.WithDefaultsRulesWrapper;
035: import org.w3c.dom.Document;
036: import org.xml.sax.InputSource;
037: import org.xml.sax.SAXException;
038:
039: import de.schlund.pfixcore.scriptedflow.ScriptedFlowConfigImpl;
040: import de.schlund.pfixcore.workflow.State;
041: import de.schlund.pfixxml.config.ContextXMLServletConfig;
042: import de.schlund.pfixxml.config.CustomizationHandler;
043: import de.schlund.pfixxml.config.includes.FileIncludeEvent;
044: import de.schlund.pfixxml.config.includes.FileIncludeEventListener;
045: import de.schlund.pfixxml.config.includes.IncludesResolver;
046: import de.schlund.pfixxml.resources.FileResource;
047: import de.schlund.pfixxml.util.Xml;
048:
049: /**
050: * Stores configuration for a Pustefix servlet
051: *
052: * @author Sebastian Marsching <sebastian.marsching@1und1.de>
053: */
054: public class ContextXMLServletConfigImpl extends
055: AbstractXMLServletConfigImpl implements SSLOption,
056: ContextXMLServletConfig {
057: private final static Class<de.schlund.pfixcore.workflow.app.DefaultIWrapperState> DEFAULT_IHANDLER_STATE = de.schlund.pfixcore.workflow.app.DefaultIWrapperState.class;
058:
059: private final static Class<de.schlund.pfixcore.workflow.app.StaticState> DEFAULT_STATIC_STATE = de.schlund.pfixcore.workflow.app.StaticState.class;
060:
061: public final static String CONFIG_NS = "http://pustefix.sourceforge.net/properties200401";
062:
063: private final static String CUS_NS = "http://www.schlund.de/pustefix/customize";
064:
065: private Class<? extends State> defaultStateClass = DEFAULT_STATIC_STATE;
066:
067: private Class<? extends State> defaultIHandlerStateClass = DEFAULT_IHANDLER_STATE;
068:
069: private ContextConfigImpl contextConfig;
070:
071: private ScriptedFlowConfigImpl scriptedFlowConfig = new ScriptedFlowConfigImpl();
072:
073: private Set<FileResource> fileDependencies = new HashSet<FileResource>();
074:
075: private long loadTime = 0;
076:
077: public static ContextXMLServletConfigImpl readFromFile(
078: FileResource file, Properties globalProperties)
079: throws SAXException, IOException {
080: final ContextXMLServletConfigImpl config = new ContextXMLServletConfigImpl();
081:
082: // Initialize configuration properties with global default properties
083: config.setProperties(globalProperties);
084:
085: // Create digester and register default rule
086: Digester digester = new Digester();
087: WithDefaultsRulesWrapper rules = new WithDefaultsRulesWrapper(
088: new RulesBase());
089: digester.setRules(rules);
090: rules.addDefault(new DefaultMatchRule());
091: digester.setRuleNamespaceURI(CONFIG_NS);
092:
093: Rule servletInfoRule = new ServletInfoRule(config);
094: Rule servletInfoEditModeRule = new ServletInfoEditModeRule(
095: config);
096: Rule servletInfoDefaultStateRule = new ServletInfoDefaultStateRule(
097: config);
098: Rule servletInfoDefaultIHandlerStateRule = new ServletInfoDefaultIHandlerStateRule(
099: config);
100: Rule sslRule = new SSLRule();
101: Rule contextRule = new ContextRule(config);
102: Rule contextResourceRule = new ContextResourceRule(config);
103: Rule contextResourceInterfaceRule = new ContextResourceInterfaceRule(
104: config);
105: Rule contextResourcePropertyRule = new ContextResourcePropertyRule(
106: config);
107: Rule scriptedFlowRule = new ScriptedFlowRule(config);
108: Rule pageflowRule = new PageflowRule(config);
109: Rule pageflowVariantRule = new PageflowVariantRule(config);
110: Rule pageflowStepRule = new PageflowStepRule(config);
111: Rule pageflowStepOnContinueRule = new PageflowStepOnContinueRule(
112: config);
113: Rule pageflowStepConditionRule = new PageflowStepConditionRule(
114: config);
115: Rule pageflowStepActionRule = new PageflowStepActionRule(config);
116: Rule pagerequestRule = new PagerequestRule(config);
117: Rule pagerequestVariantRule = new PagerequestVariantRule(config);
118: Rule pagerequestStateRule = new PagerequestStateRule(config);
119: Rule pagerequestDefaultFlowRule = new PageRequestDefaultFlowRule(
120: config);
121: Rule pagerequestFinalizerRule = new PagerequestFinalizerRule(
122: config);
123: Rule pagerequestInputRule = new PagerequestInputRule(config);
124: Rule pagerequestInputInterfaceRule = new PagerequestInputInterfaceRule(
125: config);
126: Rule pagerequestAuthInterfaceRule = new PagerequestAuthInterfaceRule(
127: config);
128: Rule pagerequestAuxInterfaceRule = new PagerequestAuxInterfaceRule(
129: config);
130: Rule pagerequestOutputResourceRule = new PagerequestOutputResourceRule(
131: config);
132: Rule pagerequestPropertyRule = new PagerequestPropertyRule(
133: config);
134: Rule contextStartInterceptorRule = new ContextInterceptorRule(
135: config, "start");
136: Rule contextEndInterceptorRule = new ContextInterceptorRule(
137: config, "end");
138: Rule roleRule = new RoleRule(config);
139: Rule servletPropertyRule = new ServletPropertyRule(config);
140: Rule authConstraintRule = new AuthConstraintRule(config, false);
141: Rule topLevelAuthConstraintRule = new AuthConstraintRule(
142: config, true);
143: Rule conditionRule = new ConditionRule(config);
144:
145: // Rule doing nothing
146: Rule dummyRule = new Rule() {
147: };
148:
149: digester.addRule("contextxmlserver", dummyRule);
150: digester.addRule("contextxmlserver/servletinfo",
151: servletInfoRule);
152: digester.addRule("contextxmlserver/servletinfo/editmode",
153: servletInfoEditModeRule);
154: digester.addRule("contextxmlserver/servletinfo/defaultstate",
155: servletInfoDefaultStateRule);
156: digester.addRule(
157: "contextxmlserver/servletinfo/defaultihandlerstate",
158: servletInfoDefaultIHandlerStateRule);
159: digester.addRule("contextxmlserver/servletinfo/ssl", sslRule);
160: digester.addRule("contextxmlserver/context", contextRule);
161: digester.addRule("contextxmlserver/context/resource",
162: contextResourceRule);
163: digester.addRule(
164: "contextxmlserver/context/resource/implements",
165: contextResourceInterfaceRule);
166: digester.addRule(
167: "contextxmlserver/context/resource/properties",
168: dummyRule);
169: digester.addRule(
170: "contextxmlserver/context/resource/properties/prop",
171: contextResourcePropertyRule);
172: digester.addRule("contextxmlserver/scriptedflow",
173: scriptedFlowRule);
174: digester.addRule("contextxmlserver/pageflow", pageflowRule);
175: digester
176: .addRule("contextxmlserver/pageflow/default", dummyRule);
177: digester.addRule("contextxmlserver/pageflow/variant",
178: pageflowVariantRule);
179: digester.addRule("contextxmlserver/pageflow/flowstep",
180: pageflowStepRule);
181: digester.addRule("contextxmlserver/pageflow/default/flowstep",
182: pageflowStepRule);
183: digester.addRule("contextxmlserver/pageflow/variant/flowstep",
184: pageflowStepRule);
185: digester.addRule(
186: "contextxmlserver/pageflow/flowstep/oncontinue",
187: pageflowStepOnContinueRule);
188: digester
189: .addRule(
190: "contextxmlserver/pageflow/default/flowstep/oncontinue",
191: pageflowStepOnContinueRule);
192: digester
193: .addRule(
194: "contextxmlserver/pageflow/variant/flowstep/oncontinue",
195: pageflowStepOnContinueRule);
196: digester.addRule(
197: "contextxmlserver/pageflow/flowstep/oncontinue/when",
198: pageflowStepConditionRule);
199: digester
200: .addRule(
201: "contextxmlserver/pageflow/default/flowstep/oncontinue/when",
202: pageflowStepConditionRule);
203: digester
204: .addRule(
205: "contextxmlserver/pageflow/variant/flowstep/oncontinue/when",
206: pageflowStepConditionRule);
207: digester
208: .addRule(
209: "contextxmlserver/pageflow/flowstep/oncontinue/when/action",
210: pageflowStepActionRule);
211: digester
212: .addRule(
213: "contextxmlserver/pageflow/default/flowstep/oncontinue/when/action",
214: pageflowStepActionRule);
215: digester
216: .addRule(
217: "contextxmlserver/pageflow/variant/flowstep/oncontinue/when/action",
218: pageflowStepActionRule);
219: digester.addRule("contextxmlserver/pagerequest",
220: pagerequestRule);
221: digester.addRule("contextxmlserver/pagerequest/default",
222: dummyRule);
223: digester.addRule("contextxmlserver/pagerequest/variant",
224: pagerequestVariantRule);
225: digester.addRule("contextxmlserver/pagerequest/ssl", sslRule);
226: digester.addRule("contextxmlserver/pagerequest/default/ssl",
227: sslRule);
228: digester.addRule("contextxmlserver/pagerequest/variant/ssl",
229: sslRule);
230: digester.addRule("contextxmlserver/pagerequest/defaultflow",
231: pagerequestDefaultFlowRule);
232: digester.addRule(
233: "contextxmlserver/pagerequest/default/defaultflow",
234: pagerequestDefaultFlowRule);
235: digester.addRule(
236: "contextxmlserver/pagerequest/variant/defaultflow",
237: pagerequestDefaultFlowRule);
238: digester.addRule("contextxmlserver/pagerequest/state",
239: pagerequestStateRule);
240: digester.addRule("contextxmlserver/pagerequest/default/state",
241: pagerequestStateRule);
242: digester.addRule("contextxmlserver/pagerequest/variant/state",
243: pagerequestStateRule);
244: digester.addRule("contextxmlserver/pagerequest/finalizer",
245: pagerequestFinalizerRule);
246: digester.addRule(
247: "contextxmlserver/pagerequest/default/finalizer",
248: pagerequestFinalizerRule);
249: digester.addRule(
250: "contextxmlserver/pagerequest/variant/finalizer",
251: pagerequestFinalizerRule);
252: digester.addRule("contextxmlserver/pagerequest/input",
253: pagerequestInputRule);
254: digester.addRule("contextxmlserver/pagerequest/default/input",
255: pagerequestInputRule);
256: digester.addRule("contextxmlserver/pagerequest/variant/input",
257: pagerequestInputRule);
258: digester.addRule(
259: "contextxmlserver/pagerequest/input/interface",
260: pagerequestInputInterfaceRule);
261: digester.addRule(
262: "contextxmlserver/pagerequest/default/input/interface",
263: pagerequestInputInterfaceRule);
264: digester.addRule(
265: "contextxmlserver/pagerequest/variant/input/interface",
266: pagerequestInputInterfaceRule);
267: digester
268: .addRule("contextxmlserver/pagerequest/auth", dummyRule);
269: digester.addRule("contextxmlserver/pagerequest/default/auth",
270: dummyRule);
271: digester.addRule("contextxmlserver/pagerequest/variant/auth",
272: dummyRule);
273: digester.addRule(
274: "contextxmlserver/pagerequest/auth/authinterface",
275: pagerequestAuthInterfaceRule);
276: digester
277: .addRule(
278: "contextxmlserver/pagerequest/default/auth/authinterface",
279: pagerequestAuthInterfaceRule);
280: digester
281: .addRule(
282: "contextxmlserver/pagerequest/variant/auth/authinterface",
283: pagerequestAuthInterfaceRule);
284: digester.addRule(
285: "contextxmlserver/pagerequest/auth/auxinterface",
286: pagerequestAuxInterfaceRule);
287: digester
288: .addRule(
289: "contextxmlserver/pagerequest/default/auth/auxinterface",
290: pagerequestAuxInterfaceRule);
291: digester
292: .addRule(
293: "contextxmlserver/pagerequest/variant/auth/auxinterface",
294: pagerequestAuxInterfaceRule);
295: digester.addRule("contextxmlserver/pagerequest/output",
296: dummyRule);
297: digester.addRule(
298: "contextxmlserver/pagerequest/output/resource",
299: pagerequestOutputResourceRule);
300: digester.addRule("contextxmlserver/pagerequest/default/output",
301: dummyRule);
302: digester.addRule(
303: "contextxmlserver/pagerequest/default/output/resource",
304: pagerequestOutputResourceRule);
305: digester.addRule("contextxmlserver/pagerequest/variant/output",
306: dummyRule);
307: digester.addRule(
308: "contextxmlserver/pagerequest/variant/output/resource",
309: pagerequestOutputResourceRule);
310: digester.addRule("contextxmlserver/pagerequest/properties",
311: dummyRule);
312: digester.addRule(
313: "contextxmlserver/pagerequest/properties/prop",
314: pagerequestPropertyRule);
315: digester.addRule(
316: "contextxmlserver/pagerequest/default/properties",
317: dummyRule);
318: digester.addRule(
319: "contextxmlserver/pagerequest/default/properties/prop",
320: pagerequestPropertyRule);
321: digester.addRule(
322: "contextxmlserver/pagerequest/variant/properties",
323: dummyRule);
324: digester.addRule(
325: "contextxmlserver/pagerequest/variant/properties/prop",
326: pagerequestPropertyRule);
327: digester.addRule("contextxmlserver/pagerequest/authconstraint",
328: authConstraintRule);
329: digester.addRule(
330: "contextxmlserver/pagerequest/authconstraint/*",
331: conditionRule);
332: digester.addRule("contextxmlserver/authconstraint",
333: topLevelAuthConstraintRule);
334: digester.addRule("*/hasrole", conditionRule);
335: digester.addRule("*/not", conditionRule);
336: digester.addRule("*/and", conditionRule);
337: digester.addRule("*/or", conditionRule);
338: digester.addRule("contextxmlserver/interceptors", dummyRule);
339: digester.addRule("contextxmlserver/interceptors/start",
340: dummyRule);
341: digester
342: .addRule("contextxmlserver/interceptors/end", dummyRule);
343: digester.addRule(
344: "contextxmlserver/interceptors/start/interceptor",
345: contextStartInterceptorRule);
346: digester.addRule(
347: "contextxmlserver/interceptors/end/interceptor",
348: contextEndInterceptorRule);
349: digester.addRule("contextxmlserver/role", roleRule);
350: digester.addRule("contextxmlserver/properties", dummyRule);
351: digester.addRule("contextxmlserver/properties/prop",
352: servletPropertyRule);
353:
354: CustomizationHandler cushandler = new CustomizationHandler(
355: digester,
356: CONFIG_NS,
357: CUS_NS,
358: new String[] {
359: "/contextxmlserver/servletinfo",
360: "/contextxmlserver/pagerequest",
361: "/contextxmlserver/pagerequest/properties",
362: "/contextxmlserver/pagerequest/default",
363: "/contextxmlserver/pagerequest/variant",
364: "/contextxmlserver/pagerequest/default/properties",
365: "/contextxmlserver/pagerequest/variant/properties",
366: "/contextxmlserver/properties" });
367: String confDocXml = null;
368: config.loadTime = System.currentTimeMillis();
369:
370: Document confDoc = Xml.parseMutable(file);
371: IncludesResolver iresolver = new IncludesResolver(CONFIG_NS,
372: "config-include");
373: // Make sure list of dependencies only contains the file itself
374: config.fileDependencies.clear();
375: config.fileDependencies.add(file);
376: FileIncludeEventListener listener = new FileIncludeEventListener() {
377:
378: public void fileIncluded(FileIncludeEvent event) {
379: config.fileDependencies.add(event.getIncludedFile());
380: }
381:
382: };
383: iresolver.registerListener(listener);
384: iresolver.resolveIncludes(confDoc);
385: confDocXml = Xml.serialize(confDoc, false, true);
386:
387: SAXParser parser;
388: try {
389: SAXParserFactory spfac = SAXParserFactory.newInstance();
390: spfac.setNamespaceAware(true);
391: parser = spfac.newSAXParser();
392: parser.parse(new InputSource(new StringReader(confDocXml)),
393: cushandler);
394: } catch (ParserConfigurationException e) {
395: throw new RuntimeException(
396: "Could not initialize SAXParser!");
397: }
398:
399: // Set edit mode property for compatibility reasons
400: if (config.isEditMode()) {
401: config.getProperties().setProperty(
402: "xmlserver.noeditmodeallowed", "false");
403: }
404:
405: // Set reference to server properties in context config
406: config.getContextConfig().setProperties(config.getProperties());
407:
408: // Do some finishing
409: config.getContextConfig().doFinishing();
410:
411: return config;
412: }
413:
414: public void setDefaultStaticState(Class<? extends State> clazz) {
415: this .defaultStateClass = clazz;
416: }
417:
418: public Class<? extends State> getDefaultStaticState() {
419: return this .defaultStateClass;
420: }
421:
422: public void setDefaultIHandlerState(Class<? extends State> clazz) {
423: this .defaultIHandlerStateClass = clazz;
424: }
425:
426: public Class<? extends State> getDefaultIHandlerState() {
427: return this .defaultIHandlerStateClass;
428: }
429:
430: public void setContextConfig(ContextConfigImpl config) {
431: this .contextConfig = config;
432: }
433:
434: /* (non-Javadoc)
435: * @see de.schlund.pfixxml.config.ContextXMLServletConfig#getContextConfig()
436: */
437: public ContextConfigImpl getContextConfig() {
438: return this .contextConfig;
439: }
440:
441: public ScriptedFlowConfigImpl getScriptedFlowConfig() {
442: return this .scriptedFlowConfig;
443: }
444:
445: /* (non-Javadoc)
446: * @see de.schlund.pfixxml.config.ContextXMLServletConfig#needsReload()
447: */
448: public boolean needsReload() {
449: for (FileResource file : fileDependencies) {
450: if (file.lastModified() > loadTime) {
451: return true;
452: }
453: }
454: return false;
455: }
456: }
|