001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: * $Header:$
018: */
019: package org.apache.beehive.netui.util.config.parser;
020:
021: import javax.xml.parsers.DocumentBuilderFactory;
022: import javax.xml.parsers.DocumentBuilder;
023: import javax.xml.parsers.ParserConfigurationException;
024: import java.io.InputStream;
025: import java.io.IOException;
026: import java.util.List;
027: import java.util.LinkedList;
028:
029: import org.apache.beehive.netui.util.config.bean.CatalogConfig;
030: import org.apache.beehive.netui.util.config.bean.ChainConfig;
031: import org.apache.beehive.netui.util.config.bean.CommandConfig;
032: import org.apache.beehive.netui.util.config.ConfigInitializationException;
033: import org.apache.beehive.netui.util.config.bean.NetUIConfig;
034: import org.apache.beehive.netui.util.config.bean.JspTagConfig;
035: import org.apache.beehive.netui.util.config.bean.SharedFlowRefConfig;
036: import org.apache.beehive.netui.util.config.bean.PageFlowActionInterceptorsConfig;
037: import org.apache.beehive.netui.util.config.bean.PageFlowConfig;
038: import org.apache.beehive.netui.util.config.bean.TypeConverterConfig;
039: import org.apache.beehive.netui.util.config.bean.ExpressionLanguagesConfig;
040: import org.apache.beehive.netui.util.config.bean.UrlConfig;
041: import org.apache.beehive.netui.util.config.bean.RequestInterceptorsConfig;
042: import org.apache.beehive.netui.util.config.bean.PageFlowFactoriesConfig;
043: import org.apache.beehive.netui.util.config.bean.PageFlowHandlersConfig;
044: import org.apache.beehive.netui.util.config.bean.IteratorFactoryConfig;
045: import org.apache.beehive.netui.util.config.bean.PrefixHandlerConfig;
046: import org.apache.beehive.netui.util.config.bean.GlobalPageFlowActionInterceptorConfig;
047: import org.apache.beehive.netui.util.config.bean.InterceptorConfig;
048: import org.apache.beehive.netui.util.config.bean.SimpleActionInterceptorConfig;
049: import org.apache.beehive.netui.util.config.bean.PerActionInterceptorConfig;
050: import org.apache.beehive.netui.util.config.bean.PerPageFlowActionInterceptorConfig;
051: import org.apache.beehive.netui.util.config.bean.PreventCache;
052: import org.apache.beehive.netui.util.config.bean.MultipartHandler;
053: import org.apache.beehive.netui.util.config.bean.ModuleConfigLocatorConfig;
054: import org.apache.beehive.netui.util.config.bean.PageFlowFactoryConfig;
055: import org.apache.beehive.netui.util.config.bean.DocType;
056: import org.apache.beehive.netui.util.config.bean.IdJavascript;
057: import org.apache.beehive.netui.util.config.bean.ExpressionLanguageConfig;
058: import org.apache.beehive.netui.util.config.bean.BindingContextConfig;
059: import org.apache.beehive.netui.util.config.bean.HandlerConfig;
060: import org.apache.beehive.netui.util.config.bean.CustomPropertyConfig;
061: import org.apache.beehive.netui.util.xml.DomUtils;
062: import org.apache.beehive.netui.util.xml.XmlInputStreamResolver;
063: import org.apache.beehive.netui.util.logging.Logger;
064: import org.apache.beehive.netui.util.config.internal.catalog.CatalogParser;
065: import org.w3c.dom.Document;
066: import org.w3c.dom.NodeList;
067: import org.w3c.dom.Element;
068: import org.w3c.dom.Node;
069: import org.xml.sax.SAXException;
070: import org.xml.sax.InputSource;
071: import org.xml.sax.EntityResolver;
072: import org.xml.sax.ErrorHandler;
073: import org.xml.sax.SAXParseException;
074:
075: /**
076: * <p>
077: * Parser for converting an XML document into a NetUIConfig object.
078: * </p>
079: */
080: public final class NetUIConfigParser {
081:
082: private static final Logger LOGGER = Logger
083: .getInstance(NetUIConfigParser.class);
084:
085: private static final String DEFAULT_CONFIG = "org/apache/beehive/netui/util/config/internal/beehive-netui-config-default.xml";
086: private static final String CONFIG_SCHEMA = "org/apache/beehive/netui/util/config/schema/beehive-netui-config.xsd";
087:
088: private static final XmlInputStreamResolver SCHEMA_RESOLVER = new XmlInputStreamResolver() {
089: public String getResourcePath() {
090: return CONFIG_SCHEMA;
091: }
092:
093: public InputStream getInputStream() {
094: return NetUIConfigParser.class.getClassLoader()
095: .getResourceAsStream(getResourcePath());
096: }
097: };
098:
099: private static final XmlInputStreamResolver DEFAULT_CONFIG_RESOLVER = new XmlInputStreamResolver() {
100: public String getResourcePath() {
101: return DEFAULT_CONFIG;
102: }
103:
104: public InputStream getInputStream() {
105: return NetUIConfigParser.class.getClassLoader()
106: .getResourceAsStream(getResourcePath());
107: }
108: };
109:
110: public NetUIConfig parse(final XmlInputStreamResolver xmlResolver) {
111:
112: NetUIConfig configBean = null;
113: InputStream xmlInputStream = null;
114: XmlInputStreamResolver theXmlResolver = xmlResolver;
115: try {
116: /* use the default XmlInputStream */
117: if (theXmlResolver == null)
118: theXmlResolver = DEFAULT_CONFIG_RESOLVER;
119:
120: xmlInputStream = theXmlResolver.getInputStream();
121:
122: /* the default XmlInputStream could not provide a valid InputStream; try the default */
123: if (xmlInputStream == null) {
124: theXmlResolver = DEFAULT_CONFIG_RESOLVER;
125: xmlInputStream = theXmlResolver.getInputStream();
126:
127: LOGGER
128: .info("Loading the default NetUI config file. The runtime will be configured "
129: + "with a set of minimum parameters.");
130:
131: if (xmlInputStream == null)
132: throw new ConfigInitializationException(
133: "The NetUI runtime could not find the default config file. "
134: + "The webapp may not function properly.");
135: }
136:
137: if (LOGGER.isInfoEnabled())
138: LOGGER.info("NetUIConfigParser -- load config: "
139: + theXmlResolver.getResourcePath());
140:
141: configBean = parse(theXmlResolver.getResourcePath(),
142: xmlInputStream);
143: } finally {
144: try {
145: if (xmlInputStream != null)
146: xmlInputStream.close();
147: } catch (IOException ignore) {
148: }
149: }
150:
151: return configBean;
152: }
153:
154: private NetUIConfig parse(final String resourcePath,
155: final InputStream is) {
156: assert is != null;
157:
158: NetUIConfig netuiConfig = null;
159: InputStream xsdInputStream = null;
160: try {
161: /* parse the config document */
162: xsdInputStream = SCHEMA_RESOLVER.getInputStream();
163: final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema";
164: final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
165: final String JAXP_SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource";
166:
167: DocumentBuilderFactory dbf = DocumentBuilderFactory
168: .newInstance();
169: dbf.setValidating(true);
170: dbf.setNamespaceAware(true);
171: dbf.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA);
172: dbf.setAttribute(JAXP_SCHEMA_SOURCE, xsdInputStream);
173:
174: DocumentBuilder db = dbf.newDocumentBuilder();
175: db.setErrorHandler(new ErrorHandler() {
176: public void warning(SAXParseException exception) {
177: if (LOGGER.isInfoEnabled())
178: LOGGER
179: .info("Validation warning validating config file \""
180: + resourcePath
181: + "\" against XML Schema \""
182: + SCHEMA_RESOLVER
183: .getResourcePath());
184: }
185:
186: public void error(SAXParseException exception) {
187: throw new ConfigInitializationException(
188: "Validation errors occurred parsing the config file \""
189: + resourcePath + "\". Cause: "
190: + exception, exception);
191: }
192:
193: public void fatalError(SAXParseException exception) {
194: throw new ConfigInitializationException(
195: "Validation errors occurred parsing the config file \""
196: + resourcePath + "\". Cause: "
197: + exception, exception);
198: }
199: });
200:
201: db.setEntityResolver(new EntityResolver() {
202: public InputSource resolveEntity(String publicId,
203: String systemId) {
204: if (systemId.endsWith("/beehive-netui-config.xsd")) {
205: InputStream inputStream = NetUIConfigParser.class
206: .getClassLoader().getResourceAsStream(
207: CONFIG_SCHEMA);
208: return new InputSource(inputStream);
209: } else
210: return null;
211: }
212: });
213:
214: Document document = db.parse(is);
215:
216: PageFlowActionInterceptorsConfig pfActionInterceptorsConfig = parsePfActionInterceptorsConfig(document);
217: PageFlowHandlersConfig pfHandlersConfig = parsePfHandlersConfig(document);
218: PageFlowConfig pfConfig = parsePfConfig(document);
219: PageFlowFactoriesConfig pfFactoriesConfig = parsePfFactoriesConfig(document);
220: SharedFlowRefConfig[] sharedFlowRefConfigs = parseSharedFlowRefConfigs(document);
221: RequestInterceptorsConfig requestInterceptorsConfig = parseRequestInterceptorsConfig(document);
222:
223: JspTagConfig jspTagConfig = parseJspTagConfig(document);
224: ExpressionLanguagesConfig elConfig = parseExpressionLanguageConfig(document);
225: TypeConverterConfig[] typeConvertersConfig = parseTypeConvertersConfig(document);
226: UrlConfig urlConfig = parseUrlConfig(document);
227: IteratorFactoryConfig[] iteratorFactories = parseIteratorFactoryConfig(document);
228: PrefixHandlerConfig[] prefixHandlers = parsePrefixHandlerConfig(document);
229:
230: Element catalogElement = DomUtils.getChildElementByName(
231: document.getDocumentElement(), "catalog");
232: CatalogConfig catalogConfig = parseCatalogs(catalogElement);
233:
234: netuiConfig = new NetUIConfig(pfActionInterceptorsConfig,
235: pfHandlersConfig, pfConfig, pfFactoriesConfig,
236: sharedFlowRefConfigs, requestInterceptorsConfig,
237: jspTagConfig, prefixHandlers, elConfig,
238: iteratorFactories, typeConvertersConfig, urlConfig);
239: netuiConfig.setCatalogConfig(catalogConfig);
240: } catch (ParserConfigurationException e) {
241: throw new ConfigInitializationException(
242: "Error occurred parsing the config file \""
243: + resourcePath + "\"", e);
244: } catch (IOException e) {
245: throw new ConfigInitializationException(
246: "Error occurred parsing the config file \""
247: + resourcePath + "\"", e);
248: } catch (SAXException e) {
249: throw new ConfigInitializationException(
250: "Error occurred parsing the config file \""
251: + resourcePath + "\"", e);
252: } finally {
253: try {
254: if (xsdInputStream != null)
255: xsdInputStream.close();
256: } catch (IOException e) {
257: }
258: }
259: return netuiConfig;
260: }
261:
262: private static final PageFlowActionInterceptorsConfig parsePfActionInterceptorsConfig(
263: Document document) {
264: final Element elem = DomUtils.getChildElementByName(document
265: .getDocumentElement(), "pageflow-action-interceptors");
266: if (elem == null)
267: return null;
268:
269: /* global */
270: Element globalElem = DomUtils.getChildElementByName(elem,
271: "global");
272: GlobalPageFlowActionInterceptorConfig global = null;
273: InterceptorConfig[] globalInterceptorConfigs = null;
274: SimpleActionInterceptorConfig[] globalSimpleActionInterceptorConfig = null;
275: if (globalElem != null) {
276: globalSimpleActionInterceptorConfig = parseSimpleActionInterceptorConfigs(DomUtils
277: .getChildElementsByName(globalElem,
278: "simple-action-interceptor"));
279: globalInterceptorConfigs = parseInterceptorConfigs(DomUtils
280: .getChildElementsByName(globalElem,
281: "action-interceptor"));
282: }
283: global = new GlobalPageFlowActionInterceptorConfig(
284: globalSimpleActionInterceptorConfig,
285: globalInterceptorConfigs);
286:
287: /* per page flow */
288: PerPageFlowActionInterceptorConfig[] perPageFlow = null;
289: NodeList perJpfList = elem.getElementsByTagName("per-pageflow");
290: if (perJpfList != null && perJpfList.getLength() > 0) {
291: perPageFlow = new PerPageFlowActionInterceptorConfig[perJpfList
292: .getLength()];
293: for (int i = 0; i < perJpfList.getLength(); i++) {
294: Element perJpfElem = (Element) perJpfList.item(i);
295:
296: PerActionInterceptorConfig[] perActionInterceptorConfigs = null;
297: NodeList perAction = perJpfElem
298: .getElementsByTagName("per-action");
299: if (perAction != null && perAction.getLength() > 0) {
300: perActionInterceptorConfigs = new PerActionInterceptorConfig[perAction
301: .getLength()];
302: for (int j = 0; j < perAction.getLength(); j++) {
303: perActionInterceptorConfigs[j] = new PerActionInterceptorConfig(
304: DomUtils.getChildElementText(
305: (Element) perAction.item(j),
306: "action-name"),
307: parseSimpleActionInterceptorConfigs(DomUtils
308: .getChildElementsByName(
309: (Element) perAction
310: .item(j),
311: "simple-action-interceptor")),
312: parseInterceptorConfigs(DomUtils
313: .getChildElementsByName(
314: (Element) perAction
315: .item(j),
316: "action-interceptor")));
317: }
318: }
319:
320: perPageFlow[i] = new PerPageFlowActionInterceptorConfig(
321: DomUtils.getChildElementText(perJpfElem,
322: "pageflow-uri"),
323: parseSimpleActionInterceptorConfigs(DomUtils
324: .getChildElementsByName(perJpfElem,
325: "simple-action-interceptor")),
326: parseInterceptorConfigs(DomUtils
327: .getChildElementsByName(perJpfElem,
328: "action-interceptor")),
329: perActionInterceptorConfigs);
330: }
331: }
332:
333: return new PageFlowActionInterceptorsConfig(global, perPageFlow);
334: }
335:
336: private static final SimpleActionInterceptorConfig[] parseSimpleActionInterceptorConfigs(
337: List list) {
338: if (list == null || list.size() == 0)
339: return null;
340:
341: SimpleActionInterceptorConfig[] simpleActionInterceptorConfigs = new SimpleActionInterceptorConfig[list
342: .size()];
343: for (int i = 0; i < list.size(); i++) {
344: Boolean afterAction = null;
345:
346: String tmp = DomUtils.getChildElementText((Element) list
347: .get(i), "after-action");
348: if (tmp != null)
349: afterAction = new Boolean(Boolean.parseBoolean(tmp));
350:
351: simpleActionInterceptorConfigs[i] = new SimpleActionInterceptorConfig(
352: afterAction, DomUtils.getChildElementText(
353: (Element) list.get(i), "intercept-path"));
354: }
355: return simpleActionInterceptorConfigs;
356: }
357:
358: private static final PageFlowHandlersConfig parsePfHandlersConfig(
359: Document document) {
360: Element elem = DomUtils.getChildElementByName(document
361: .getDocumentElement(), "pageflow-handlers");
362: if (elem == null)
363: return null;
364:
365: return new PageFlowHandlersConfig(
366: parseHandlerConfig(elem
367: .getElementsByTagName("action-forward-handler")),
368: parseHandlerConfig(elem
369: .getElementsByTagName("exceptions-handler")),
370: parseHandlerConfig(elem
371: .getElementsByTagName("forward-redirect-handler")),
372: parseHandlerConfig(elem
373: .getElementsByTagName("login-handler")),
374: parseHandlerConfig(elem
375: .getElementsByTagName("storage-handler")),
376: parseHandlerConfig(elem
377: .getElementsByTagName("reloadable-class-handler")));
378: }
379:
380: private static final PageFlowConfig parsePfConfig(Document document) {
381: Element elem = DomUtils.getChildElementByName(document
382: .getDocumentElement(), "pageflow-config");
383:
384: if (elem == null)
385: return new PageFlowConfig();
386:
387: PageFlowConfig pfConfig = null;
388:
389: Boolean enableSelfNesting = null;
390: Boolean ensureSecureForwards = null;
391: Boolean throwSessionExpiredException = null;
392: Integer maxForwardsPerRequest = null;
393: Integer maxNestingStackDepth = null;
394: MultipartHandler mpHandler = null;
395: PreventCache preventCache = null;
396: ModuleConfigLocatorConfig[] moduleConfigLocators = null;
397:
398: String tmp = null;
399:
400: tmp = DomUtils.getChildElementText(elem, "enable-self-nesting");
401: if (tmp != null)
402: enableSelfNesting = new Boolean(Boolean.parseBoolean(tmp));
403:
404: tmp = DomUtils.getChildElementText(elem,
405: "ensure-secure-forwards");
406: if (tmp != null)
407: ensureSecureForwards = new Boolean(Boolean
408: .parseBoolean(tmp));
409:
410: tmp = DomUtils.getChildElementText(elem,
411: "throw-session-expired-exception");
412: if (tmp != null)
413: throwSessionExpiredException = new Boolean(Boolean
414: .parseBoolean(tmp));
415:
416: tmp = DomUtils.getChildElementText(elem,
417: "max-forwards-per-request");
418: if (tmp != null)
419: maxForwardsPerRequest = new Integer(Integer.parseInt(tmp));
420:
421: tmp = DomUtils.getChildElementText(elem,
422: "max-nesting-stack-depth");
423: if (tmp != null)
424: maxNestingStackDepth = new Integer(Integer.parseInt(tmp));
425:
426: tmp = DomUtils.getChildElementText(elem, "multipart-handler");
427: if (tmp != null) {
428: if (tmp.equals("disabled"))
429: mpHandler = MultipartHandler.DISABLED;
430: else if (tmp.equals("disk"))
431: mpHandler = MultipartHandler.DISK;
432: else if (tmp.equals("memory"))
433: mpHandler = MultipartHandler.MEMORY;
434: }
435:
436: tmp = DomUtils.getChildElementText(elem, "prevent-cache");
437: if (tmp != null) {
438: if (tmp.equals("always"))
439: preventCache = PreventCache.ALWAYS;
440: else if (tmp.equals("default"))
441: preventCache = PreventCache.DEFAULT;
442: else if (tmp.equals("inDevMode"))
443: preventCache = PreventCache.IN_DEV_MODE;
444: }
445:
446: moduleConfigLocators = parseModuleConfigLocators(DomUtils
447: .getChildElementByName(elem, "module-config-locators"));
448:
449: pfConfig = new PageFlowConfig(enableSelfNesting,
450: ensureSecureForwards, throwSessionExpiredException,
451: maxForwardsPerRequest, maxNestingStackDepth, mpHandler,
452: preventCache, moduleConfigLocators);
453:
454: return pfConfig;
455: }
456:
457: private static final ModuleConfigLocatorConfig[] parseModuleConfigLocators(
458: Element element) {
459: if (element == null)
460: return null;
461:
462: NodeList list = element
463: .getElementsByTagName("module-config-locator");
464: if (list == null || list.getLength() == 0)
465: return null;
466:
467: ModuleConfigLocatorConfig[] mclConfig = new ModuleConfigLocatorConfig[list
468: .getLength()];
469: for (int i = 0; i < list.getLength(); i++) {
470: mclConfig[i] = new ModuleConfigLocatorConfig(DomUtils
471: .getChildElementText((Element) list.item(i),
472: "locator-class"), DomUtils
473: .getChildElementText((Element) list.item(i),
474: "description"));
475: }
476: return mclConfig;
477: }
478:
479: private static final PageFlowFactoriesConfig parsePfFactoriesConfig(
480: Document document) {
481: Element elem = DomUtils.getChildElementByName(document
482: .getDocumentElement(), "pageflow-factories");
483: if (elem == null)
484: return null;
485:
486: PageFlowFactoryConfig pfFactory = parsePageFlowFactoryConfig(DomUtils
487: .getChildElementByName(elem, "flowcontroller-factory"));
488: PageFlowFactoryConfig fbbFactoyr = parsePageFlowFactoryConfig(DomUtils
489: .getChildElementByName(elem,
490: "faces-backing-bean-factory"));
491:
492: return new PageFlowFactoriesConfig(pfFactory, fbbFactoyr);
493: }
494:
495: private static final SharedFlowRefConfig[] parseSharedFlowRefConfigs(
496: Document document) {
497: Element elem = DomUtils.getChildElementByName(document
498: .getDocumentElement(), "default-shared-flow-refs");
499: if (elem == null)
500: return null;
501:
502: NodeList list = elem.getElementsByTagName("shared-flow-ref");
503: if (list == null || list.getLength() == 0)
504: return null;
505:
506: SharedFlowRefConfig[] sharedFlowRefConfigs = new SharedFlowRefConfig[list
507: .getLength()];
508: for (int i = 0; i < list.getLength(); i++) {
509: Node node = list.item(i);
510: sharedFlowRefConfigs[i] = new SharedFlowRefConfig(
511: DomUtils
512: .getChildElementText((Element) node, "name"),
513: DomUtils
514: .getChildElementText((Element) node, "type"));
515: }
516:
517: return sharedFlowRefConfigs;
518: }
519:
520: private static final RequestInterceptorsConfig parseRequestInterceptorsConfig(
521: Document document) {
522:
523: Element elem = DomUtils.getChildElementByName(document
524: .getDocumentElement(), "request-interceptors");
525: if (elem == null)
526: return null;
527:
528: RequestInterceptorsConfig requestInterceptorsConfig = null;
529: Element global = DomUtils.getChildElementByName(elem, "global");
530: if (global == null)
531: return null;
532:
533: InterceptorConfig[] interceptorConfigs = parseInterceptorConfigs(DomUtils
534: .getChildElementsByName(global, "request-interceptor"));
535: if (interceptorConfigs != null)
536: requestInterceptorsConfig = new RequestInterceptorsConfig(
537: interceptorConfigs);
538:
539: return requestInterceptorsConfig;
540: }
541:
542: private static final JspTagConfig parseJspTagConfig(
543: Document document) {
544: DocType docType = null;
545: IdJavascript idJavascript = null;
546: String treeImageLocation = null;
547: String treeRendererClass = null;
548:
549: String tmp = null;
550: Element elem = DomUtils.getChildElementByName(document
551: .getDocumentElement(), "jsp-tag-config");
552:
553: if (elem == null)
554: return new JspTagConfig();
555:
556: tmp = DomUtils.getChildElementText(elem, "doctype");
557: if (tmp != null) {
558: if (tmp.equals("html4-loose"))
559: docType = DocType.HTML4_LOOSE;
560: else if (tmp.equals("html4-loose-quirks"))
561: docType = DocType.HTML4_LOOSE_QUIRKS;
562: else if (tmp.equals("xhtml1-transitional"))
563: docType = DocType.XHTML1_TRANSITIONAL;
564: }
565:
566: tmp = DomUtils.getChildElementText(elem, "id-javascript");
567: if (tmp != null) {
568: if (tmp.equals("default"))
569: idJavascript = IdJavascript.DEFAULT;
570: else if (tmp.equals("legacy"))
571: idJavascript = IdJavascript.LEGACY;
572: else if (tmp.equals("legacyOnly"))
573: idJavascript = IdJavascript.LEGACY_ONLY;
574: }
575:
576: treeImageLocation = DomUtils.getChildElementText(elem,
577: "tree-image-location");
578: treeRendererClass = DomUtils.getChildElementText(elem,
579: "tree-renderer-class");
580:
581: return new JspTagConfig(docType, idJavascript,
582: treeImageLocation, treeRendererClass);
583: }
584:
585: private static final PrefixHandlerConfig[] parsePrefixHandlerConfig(
586: Document document) {
587: Element elem = DomUtils.getChildElementByName(document
588: .getDocumentElement(), "prefix-handlers");
589: if (elem == null)
590: return null;
591:
592: NodeList list = elem.getElementsByTagName("prefix-handler");
593: if (list == null || list.getLength() == 0)
594: return null;
595:
596: PrefixHandlerConfig[] prefixHandlers = new PrefixHandlerConfig[list
597: .getLength()];
598: for (int i = 0; i < list.getLength(); i++) {
599: Node node = list.item(i);
600: prefixHandlers[i] = new PrefixHandlerConfig(DomUtils
601: .getChildElementText((Element) node, "name"),
602: DomUtils.getChildElementText((Element) node,
603: "handler-class"));
604: }
605:
606: return prefixHandlers;
607: }
608:
609: private static final ExpressionLanguagesConfig parseExpressionLanguageConfig(
610: Document document) {
611:
612: Element elem = DomUtils.getChildElementByName(document
613: .getDocumentElement(), "expression-languages");
614: if (elem == null)
615: return null;
616:
617: String defaultLanguage = DomUtils.getChildElementText(elem,
618: "default-language");
619: ExpressionLanguageConfig[] elConfigs = null;
620:
621: NodeList list = elem
622: .getElementsByTagName("expression-language");
623: if (list != null && list.getLength() > 0) {
624: elConfigs = new ExpressionLanguageConfig[list.getLength()];
625: for (int i = 0; i < list.getLength(); i++) {
626: Node node = list.item(i);
627:
628: BindingContextConfig[] bindingContextConfig = null;
629: Node bindingContexts = DomUtils.getChildElementByName(
630: (Element) node, "binding-contexts");
631: if (bindingContexts != null) {
632: NodeList bcList = ((Element) bindingContexts)
633: .getElementsByTagName("binding-context");
634: if (bcList != null && bcList.getLength() > 0) {
635: bindingContextConfig = new BindingContextConfig[bcList
636: .getLength()];
637: for (int j = 0; j < bcList.getLength(); j++) {
638: bindingContextConfig[j] = new BindingContextConfig(
639: DomUtils.getChildElementText(
640: (Element) bcList.item(j),
641: "name"), DomUtils
642: .getChildElementText(
643: (Element) bcList
644: .item(j),
645: "factory-class"));
646: }
647: }
648: }
649:
650: elConfigs[i] = new ExpressionLanguageConfig(DomUtils
651: .getChildElementText((Element) node, "name"),
652: DomUtils.getChildElementText((Element) node,
653: "factory-class"), bindingContextConfig);
654: }
655: }
656:
657: return new ExpressionLanguagesConfig(defaultLanguage, elConfigs);
658: }
659:
660: private static final TypeConverterConfig[] parseTypeConvertersConfig(
661: Document document) {
662: Element elem = DomUtils.getChildElementByName(document
663: .getDocumentElement(), "type-converters");
664: if (elem == null)
665: return null;
666:
667: NodeList list = elem.getElementsByTagName("type-converter");
668: if (list == null || list.getLength() == 0)
669: return null;
670:
671: TypeConverterConfig[] typeConverterConfig = new TypeConverterConfig[list
672: .getLength()];
673: for (int i = 0; i < list.getLength(); i++) {
674: Node node = list.item(i);
675: typeConverterConfig[i] = new TypeConverterConfig(DomUtils
676: .getChildElementText((Element) node, "type"),
677: DomUtils.getChildElementText((Element) node,
678: "converter-class"));
679: }
680:
681: return typeConverterConfig;
682: }
683:
684: private static final IteratorFactoryConfig[] parseIteratorFactoryConfig(
685: Document document) {
686: Element elem = DomUtils.getChildElementByName(document
687: .getDocumentElement(), "iterator-factories");
688: if (elem == null)
689: return null;
690:
691: NodeList list = elem.getElementsByTagName("iterator-factory");
692: if (list == null || list.getLength() == 0)
693: return null;
694:
695: IteratorFactoryConfig[] iteratorFactoryConfig = new IteratorFactoryConfig[list
696: .getLength()];
697: for (int i = 0; i < list.getLength(); i++) {
698: Node node = list.item(i);
699: iteratorFactoryConfig[i] = new IteratorFactoryConfig(
700: DomUtils
701: .getChildElementText((Element) node, "name"),
702: DomUtils.getChildElementText((Element) node,
703: "factory-class"));
704: }
705: return iteratorFactoryConfig;
706: }
707:
708: private static final UrlConfig parseUrlConfig(Document document) {
709: Element elem = DomUtils.getChildElementByName(document
710: .getDocumentElement(), "url-config");
711: if (elem == null)
712: return new UrlConfig();
713:
714: Boolean urlEncodeUrls = null;
715: Boolean htmlAmpEntity = null;
716: String templatedUrlFormatterClass = null;
717:
718: String tmp = null;
719:
720: tmp = DomUtils.getChildElementText(elem, "url-encode-urls");
721: if (tmp != null)
722: urlEncodeUrls = new Boolean(Boolean.parseBoolean(tmp));
723:
724: tmp = DomUtils.getChildElementText(elem, "html-amp-entity");
725: if (tmp != null)
726: htmlAmpEntity = new Boolean(Boolean.parseBoolean(tmp));
727:
728: templatedUrlFormatterClass = DomUtils.getChildElementText(elem,
729: "templated-url-formatter-class");
730:
731: return new UrlConfig(urlEncodeUrls, htmlAmpEntity,
732: templatedUrlFormatterClass);
733: }
734:
735: /* -----------------------------------------------------------------------------------
736:
737: Utilities used to parse reused NetUI config types
738:
739: ----------------------------------------------------------------------------------
740: */
741:
742: private static final HandlerConfig[] parseHandlerConfig(
743: NodeList list) {
744: if (list == null || list.getLength() == 0)
745: return null;
746:
747: HandlerConfig[] handlerConfigs = new HandlerConfig[list
748: .getLength()];
749: for (int i = 0; i < handlerConfigs.length; i++) {
750: handlerConfigs[i] = new HandlerConfig(DomUtils
751: .getChildElementText((Element) list.item(i),
752: "handler-class"),
753: parseCustomProperties(((Element) list.item(i))
754: .getElementsByTagName("custom-property")));
755: }
756: return handlerConfigs;
757: }
758:
759: private static final InterceptorConfig[] parseInterceptorConfigs(
760: List list) {
761: if (list == null || list.size() == 0)
762: return null;
763:
764: InterceptorConfig[] interceptorConfigs = new InterceptorConfig[list
765: .size()];
766: for (int i = 0; i < list.size(); i++) {
767: interceptorConfigs[i] = new InterceptorConfig(DomUtils
768: .getChildElementText((Element) list.get(i),
769: "interceptor-class"),
770: parseCustomProperties(((Element) list.get(i))
771: .getElementsByTagName("custom-property")));
772: }
773: return interceptorConfigs;
774: }
775:
776: private static final CustomPropertyConfig[] parseCustomProperties(
777: NodeList customProperties) {
778: if (customProperties == null
779: || customProperties.getLength() == 0)
780: return null;
781:
782: CustomPropertyConfig[] cpConfig = new CustomPropertyConfig[customProperties
783: .getLength()];
784: for (int i = 0; i < cpConfig.length; i++) {
785: cpConfig[i] = new CustomPropertyConfig(DomUtils
786: .getChildElementText((Element) customProperties
787: .item(i), "name"), DomUtils
788: .getChildElementText((Element) customProperties
789: .item(i), "value"));
790: }
791: return cpConfig;
792: }
793:
794: private static final PageFlowFactoryConfig parsePageFlowFactoryConfig(
795: Node node) {
796: if (node != null) {
797: return new PageFlowFactoryConfig(DomUtils
798: .getChildElementText((Element) node,
799: "factory-class"),
800: parseCustomProperties((((Element) node)
801: .getElementsByTagName("custom-property"))));
802: } else
803: return null;
804: }
805:
806: /*
807: -----------------------------------------------------------------------------------
808: Parsing support: <catalogs>
809: ----------------------------------------------------------------------------------
810: */
811: private static CatalogConfig parseCatalogs(Element catalogElement) {
812: return CatalogParser.getInstance().parse(catalogElement);
813: }
814: }
|