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: package org.apache.cocoon.bean.helpers;
018:
019: import java.io.BufferedReader;
020: import java.io.FileNotFoundException;
021: import java.io.FileReader;
022: import java.io.IOException;
023: import java.util.ArrayList;
024: import java.util.List;
025:
026: import org.apache.cocoon.bean.CocoonBean;
027: import org.apache.cocoon.bean.helpers.OutputStreamListener;
028: import org.apache.commons.io.IOUtils;
029: import org.apache.commons.lang.BooleanUtils;
030:
031: import org.w3c.dom.Document;
032: import org.w3c.dom.NamedNodeMap;
033: import org.w3c.dom.Node;
034: import org.w3c.dom.NodeList;
035:
036: /**
037: * Static class for configuring a CocoonBean from a DOM Document object
038: *
039: * @author <a href="mailto:uv@upaya.co.uk">Upayavira</a>
040: * @version CVS $Id: BeanConfigurator.java 433543 2006-08-22 06:22:54Z crossley $
041: */
042: public class BeanConfigurator {
043:
044: private static final String NODE_ROOT = "cocoon";
045: private static final String ATTR_VERBOSE = "verbose";
046:
047: private static final String NODE_LOGGING = "logging";
048: private static final String ATTR_LOG_KIT = "log-kit";
049: private static final String ATTR_LOG_LEVEL = "level";
050: private static final String ATTR_LOGGER = "logger";
051:
052: private static final String NODE_CONTEXT_DIR = "context-dir";
053: private static final String NODE_DEST_DIR = "dest-dir";
054: private static final String NODE_WORK_DIR = "work-dir";
055: private static final String NODE_CONFIG_FILE = "config-file";
056: private static final String NODE_URI_FILE = "uri-file";
057: private static final String NODE_CHECKSUMS_URI = "checksums-uri";
058:
059: private static final String ATTR_CONTEXT_DIR = "context-dir";
060: private static final String ATTR_DEST_DIR = "dest-dir";
061: private static final String ATTR_WORK_DIR = "work-dir";
062: private static final String ATTR_CONFIG_FILE = "config-file";
063: private static final String ATTR_URI_FILE = "uri-file";
064: private static final String ATTR_CHECKSUMS_URI = "checksums-uri";
065: private static final String ATTR_AGENT = "user-agent";
066: private static final String ATTR_ACCEPT = "accept";
067: private static final String ATTR_DEFAULT_FILENAME = "default-filename";
068:
069: private static final String NODE_BROKEN_LINKS = "broken-links";
070: private static final String ATTR_BROKEN_LINK_REPORT_TYPE = "type";
071: private static final String ATTR_BROKEN_LINK_REPORT_FILE = "file";
072: private static final String ATTR_BROKEN_LINK_GENERATE = "generate";
073: private static final String ATTR_BROKEN_LINK_EXTENSION = "extension";
074:
075: private static final String NODE_AGENT = "user-agent";
076: private static final String NODE_ACCEPT = "accept";
077:
078: private static final String ATTR_FOLLOW_LINKS = "follow-links";
079: private static final String ATTR_PRECOMPILE_ONLY = "precompile-only";
080: private static final String ATTR_CONFIRM_EXTENSIONS = "confirm-extensions";
081: private static final String NODE_LOAD_CLASS = "load-class";
082: private static final String NODE_DEFAULT_FILENAME = "default-filename";
083:
084: private static final String NODE_INCLUDE = "include";
085: private static final String NODE_EXCLUDE = "exclude";
086: private static final String ATTR_INCLUDE_EXCLUDE_PATTERN = "pattern";
087:
088: private static final String NODE_INCLUDE_LINKS = "include-links";
089: private static final String ATTR_LINK_EXTENSION = "extension";
090:
091: private static final String NODE_URI = "uri";
092: private static final String ATTR_URI_TYPE = "type";
093: private static final String ATTR_URI_SOURCEPREFIX = "src-prefix";
094: private static final String ATTR_URI_SOURCEURI = "src";
095: private static final String ATTR_URI_DESTURI = "dest";
096:
097: private static final String NODE_URIS = "uris";
098: private static final String ATTR_NAME = "name";
099:
100: public static String configure(Document xconf, CocoonBean cocoon,
101: String destDir, String uriGroup,
102: OutputStreamListener listener)
103: throws IllegalArgumentException {
104:
105: Node root = xconf.getDocumentElement();
106: if (!NODE_ROOT.equals(root.getNodeName())) {
107: throw new IllegalArgumentException("Expected root node of "
108: + NODE_ROOT);
109: }
110:
111: if (hasAttribute(root, ATTR_VERBOSE)) {
112: cocoon.setVerbose(getBooleanAttributeValue(root,
113: ATTR_VERBOSE));
114: }
115: if (hasAttribute(root, ATTR_FOLLOW_LINKS)) {
116: cocoon.setFollowLinks(getBooleanAttributeValue(root,
117: ATTR_FOLLOW_LINKS));
118: }
119: if (hasAttribute(root, ATTR_PRECOMPILE_ONLY)) {
120: cocoon.setPrecompileOnly(getBooleanAttributeValue(root,
121: ATTR_PRECOMPILE_ONLY));
122: }
123: if (hasAttribute(root, ATTR_CONFIRM_EXTENSIONS)) {
124: cocoon.setConfirmExtensions(getBooleanAttributeValue(root,
125: ATTR_CONFIRM_EXTENSIONS));
126: }
127: if (hasAttribute(root, ATTR_CONTEXT_DIR)) {
128: cocoon.setContextDir(getAttributeValue(root,
129: ATTR_CONTEXT_DIR));
130: }
131: if (hasAttribute(root, ATTR_DEST_DIR)) {
132: destDir = getAttributeValue(root, ATTR_DEST_DIR);
133: }
134: if (hasAttribute(root, ATTR_WORK_DIR)) {
135: cocoon.setWorkDir(getAttributeValue(root, ATTR_WORK_DIR));
136: }
137: if (hasAttribute(root, ATTR_CONFIG_FILE)) {
138: cocoon.setConfigFile(getAttributeValue(root,
139: ATTR_CONFIG_FILE));
140: }
141: if (hasAttribute(root, ATTR_URI_FILE)) {
142: cocoon.addTargets(processURIFile(getAttributeValue(root,
143: ATTR_URI_FILE)), destDir);
144: }
145: if (hasAttribute(root, ATTR_CHECKSUMS_URI)) {
146: cocoon.setChecksumURI(getAttributeValue(root,
147: ATTR_CHECKSUMS_URI));
148: }
149: if (hasAttribute(root, ATTR_AGENT)) {
150: cocoon.setAgentOptions(getAttributeValue(root, ATTR_AGENT));
151: }
152: if (hasAttribute(root, ATTR_ACCEPT)) {
153: cocoon
154: .setAcceptOptions(getAttributeValue(root,
155: ATTR_ACCEPT));
156: }
157: if (hasAttribute(root, ATTR_DEFAULT_FILENAME)) {
158: cocoon.setDefaultFilename(getAttributeValue(root,
159: ATTR_DEFAULT_FILENAME));
160: }
161:
162: if (destDir == null || destDir.length() == 0) {
163: destDir = getNodeValue(root, NODE_DEST_DIR);
164: }
165:
166: NodeList nodes = root.getChildNodes();
167: for (int i = 0; i < nodes.getLength(); i++) {
168: Node node = nodes.item(i);
169: if (node.getNodeType() == Node.ELEMENT_NODE) {
170: String nodeName = node.getNodeName();
171: if (nodeName.equals(NODE_BROKEN_LINKS)) {
172: parseBrokenLinkNode(cocoon, node, listener);
173:
174: } else if (nodeName.equals(NODE_LOAD_CLASS)) {
175: cocoon.addLoadedClass(getNodeValue(node));
176:
177: } else if (nodeName.equals(NODE_LOGGING)) {
178: parseLoggingNode(cocoon, node);
179:
180: } else if (nodeName.equals(NODE_CONTEXT_DIR)) {
181: if (hasAttribute(root, ATTR_CONTEXT_DIR)) {
182: throw new IllegalArgumentException(
183: "Cannot have "
184: + NODE_CONTEXT_DIR
185: + " as both element and attribute");
186: } else {
187: cocoon.setContextDir(getNodeValue(node));
188: }
189:
190: } else if (nodeName.equals(NODE_CONFIG_FILE)) {
191: if (hasAttribute(root, ATTR_CONFIG_FILE)) {
192: throw new IllegalArgumentException(
193: "Cannot have "
194: + NODE_CONFIG_FILE
195: + " as both element and attribute");
196: } else {
197: cocoon.setConfigFile(getNodeValue(node));
198: }
199: } else if (nodeName.equals(NODE_DEST_DIR)) {
200: // Ignore
201:
202: } else if (nodeName.equals(NODE_WORK_DIR)) {
203: if (hasAttribute(root, ATTR_WORK_DIR)) {
204: throw new IllegalArgumentException(
205: "Cannot have "
206: + NODE_WORK_DIR
207: + " as both element and attribute");
208: } else {
209: cocoon.setWorkDir(getNodeValue(node));
210: }
211: } else if (nodeName.equals(NODE_CHECKSUMS_URI)) {
212: if (hasAttribute(root, ATTR_CHECKSUMS_URI)) {
213: throw new IllegalArgumentException(
214: "Cannot have "
215: + NODE_CHECKSUMS_URI
216: + " as both element and attribute");
217: } else {
218: cocoon.setChecksumURI(getNodeValue(node));
219: }
220: } else if (nodeName.equals(NODE_AGENT)) {
221: cocoon.setAgentOptions(getNodeValue(node));
222:
223: } else if (nodeName.equals(NODE_ACCEPT)) {
224: cocoon.setAcceptOptions(getNodeValue(node));
225:
226: } else if (nodeName.equals(NODE_DEFAULT_FILENAME)) {
227: cocoon.setDefaultFilename(getNodeValue(node));
228:
229: } else if (nodeName.equals(NODE_INCLUDE)) {
230: String pattern = parseIncludeExcludeNode(cocoon,
231: node, NODE_INCLUDE);
232: cocoon.addIncludePattern(pattern);
233:
234: } else if (nodeName.equals(NODE_EXCLUDE)) {
235: String pattern = parseIncludeExcludeNode(cocoon,
236: node, NODE_EXCLUDE);
237: cocoon.addExcludePattern(pattern);
238:
239: } else if (nodeName.equals(NODE_INCLUDE_LINKS)) {
240: parseIncludeLinksNode(cocoon, node);
241:
242: } else if (nodeName.equals(NODE_URI)) {
243: parseURINode(cocoon, node, destDir);
244:
245: } else if (nodeName.equals(NODE_URIS)) {
246: parseURIsNode(cocoon, node, destDir, uriGroup);
247:
248: } else if (nodeName.equals(NODE_URI_FILE)) {
249: if (hasAttribute(root, ATTR_URI_FILE)) {
250: throw new IllegalArgumentException(
251: "Cannot have "
252: + NODE_URI_FILE
253: + " as both element and attribute");
254: } else {
255: cocoon.addTargets(
256: processURIFile(getNodeValue(node)),
257: destDir);
258: }
259: } else {
260: throw new IllegalArgumentException(
261: "Unknown element: <" + nodeName + ">");
262: }
263: }
264: }
265: return destDir;
266: }
267:
268: private static void parseLoggingNode(CocoonBean cocoon, Node node)
269: throws IllegalArgumentException {
270: if (hasAttribute(node, ATTR_LOG_KIT)) {
271: cocoon.setLogKit(getAttributeValue(node, ATTR_LOG_KIT));
272: }
273: if (hasAttribute(node, ATTR_LOGGER)) {
274: cocoon.setLogger(getAttributeValue(node, ATTR_LOGGER));
275: }
276: if (hasAttribute(node, ATTR_LOG_LEVEL)) {
277: cocoon.setLogLevel(getAttributeValue(node, ATTR_LOG_LEVEL));
278: }
279: NodeList nodes = node.getChildNodes();
280: if (nodes.getLength() != 0) {
281: throw new IllegalArgumentException(
282: "Unexpected children of <" + NODE_LOGGING
283: + "> node");
284: }
285: }
286:
287: private static void parseIncludeLinksNode(CocoonBean cocoon,
288: Node node) throws IllegalArgumentException {
289: if (hasAttribute(node, ATTR_LINK_EXTENSION)) {
290: cocoon.addIncludeLinkExtension(getAttributeValue(node,
291: ATTR_LINK_EXTENSION));
292: }
293: }
294:
295: private static void parseBrokenLinkNode(CocoonBean cocoon,
296: Node node, OutputStreamListener listener)
297: throws IllegalArgumentException {
298: if (hasAttribute(node, ATTR_BROKEN_LINK_REPORT_FILE)) {
299: listener.setReportFile(getAttributeValue(node,
300: ATTR_BROKEN_LINK_REPORT_FILE));
301: }
302: if (hasAttribute(node, ATTR_BROKEN_LINK_REPORT_TYPE)) {
303: listener.setReportType(getAttributeValue(node,
304: ATTR_BROKEN_LINK_REPORT_TYPE));
305: }
306: if (hasAttribute(node, ATTR_BROKEN_LINK_GENERATE)) {
307: cocoon.setBrokenLinkGenerate(getBooleanAttributeValue(node,
308: ATTR_BROKEN_LINK_GENERATE));
309: }
310: if (hasAttribute(node, ATTR_BROKEN_LINK_EXTENSION)) {
311: cocoon.setBrokenLinkExtension(getAttributeValue(node,
312: ATTR_BROKEN_LINK_EXTENSION));
313: }
314: NodeList nodes = node.getChildNodes();
315: if (nodes.getLength() != 0) {
316: throw new IllegalArgumentException(
317: "Unexpected children of <" + NODE_BROKEN_LINKS
318: + "> node");
319: }
320: }
321:
322: private static String parseIncludeExcludeNode(CocoonBean cocoon,
323: Node node, final String NODE_TYPE)
324: throws IllegalArgumentException {
325: NodeList nodes = node.getChildNodes();
326: if (nodes.getLength() != 0) {
327: throw new IllegalArgumentException(
328: "Unexpected children of <" + NODE_INCLUDE
329: + "> node");
330: }
331:
332: if (hasAttribute(node, ATTR_INCLUDE_EXCLUDE_PATTERN)) {
333: return getAttributeValue(node, ATTR_INCLUDE_EXCLUDE_PATTERN);
334: } else {
335: throw new IllegalArgumentException("Expected a "
336: + ATTR_INCLUDE_EXCLUDE_PATTERN + " attribute for <"
337: + NODE_TYPE + "> node");
338: }
339: }
340:
341: private static void parseURIsNode(CocoonBean cocoon, Node node,
342: String destDir, String uriGroup)
343: throws IllegalArgumentException {
344:
345: boolean followLinks = cocoon.followLinks();
346: boolean confirmExtensions = cocoon.confirmExtensions();
347: String logger = cocoon.getLoggerName();
348: String destURI = destDir;
349: String root = null;
350: String type = null;
351: String name = null;
352:
353: if (hasAttribute(node, ATTR_FOLLOW_LINKS)) {
354: followLinks = getBooleanAttributeValue(node,
355: ATTR_FOLLOW_LINKS);
356: }
357: if (hasAttribute(node, ATTR_CONFIRM_EXTENSIONS)) {
358: confirmExtensions = getBooleanAttributeValue(node,
359: ATTR_CONFIRM_EXTENSIONS);
360: }
361: if (hasAttribute(node, ATTR_URI_TYPE)) {
362: type = getAttributeValue(node, ATTR_URI_TYPE);
363: }
364: if (hasAttribute(node, ATTR_URI_SOURCEPREFIX)) {
365: root = getAttributeValue(node, ATTR_URI_SOURCEPREFIX);
366: }
367: if (hasAttribute(node, ATTR_URI_DESTURI)) {
368: destURI = getAttributeValue(node, ATTR_URI_DESTURI);
369: }
370: if (hasAttribute(node, ATTR_LOGGER)) {
371: logger = getAttributeValue(node, ATTR_LOGGER);
372: }
373: if (hasAttribute(node, ATTR_NAME)) {
374: name = getAttributeValue(node, ATTR_NAME);
375: if (name != null && uriGroup != null
376: && !name.equals(uriGroup)) {
377: // The user has not selected this URI group, so ignore it.
378: return;
379: }
380: }
381: NodeList nodes = node.getChildNodes();
382: for (int i = 0; i < nodes.getLength(); i++) {
383: Node child = nodes.item(i);
384: if (child.getNodeType() == Node.ELEMENT_NODE) {
385: String childName = child.getNodeName();
386: if (childName.equals(NODE_URI)) {
387: String _sourceURI = null;
388: String _destURI = destURI;
389: String _root = root;
390: String _type = type;
391:
392: if (child.getAttributes().getLength() == 0) {
393: _sourceURI = getNodeValue(child);
394: //destURI is inherited
395: } else {
396: _sourceURI = getAttributeValue(child,
397: ATTR_URI_SOURCEURI);
398:
399: if (hasAttribute(child, ATTR_URI_TYPE)) {
400: _type = getAttributeValue(child,
401: ATTR_URI_TYPE);
402: }
403: if (hasAttribute(child, ATTR_URI_SOURCEPREFIX)) {
404: _root = getAttributeValue(child,
405: ATTR_URI_SOURCEPREFIX);
406: }
407: if (hasAttribute(child, ATTR_URI_DESTURI)) {
408: _destURI = getAttributeValue(child,
409: ATTR_URI_DESTURI);
410: }
411: }
412: cocoon.addTarget(_type, _root, _sourceURI,
413: _destURI, followLinks, confirmExtensions,
414: logger);
415: } else {
416: throw new IllegalArgumentException(
417: "Unknown element: <" + childName + ">");
418: }
419: }
420: }
421: }
422:
423: private static void parseURINode(CocoonBean cocoon, Node node,
424: String destDir) throws IllegalArgumentException {
425: NodeList nodes = node.getChildNodes();
426:
427: if (node.getAttributes().getLength() == 0
428: && nodes.getLength() != 0) {
429: cocoon.addTarget(getNodeValue(node), destDir);
430: } else if (node.getAttributes().getLength() != 0
431: && nodes.getLength() == 0) {
432:
433: String src = getAttributeValue(node, ATTR_URI_SOURCEURI);
434:
435: String type = null;
436: if (hasAttribute(node, ATTR_URI_TYPE)) {
437: type = getAttributeValue(node, ATTR_URI_TYPE);
438: }
439: String root = null;
440: if (hasAttribute(node, ATTR_URI_SOURCEPREFIX)) {
441: root = getAttributeValue(node, ATTR_URI_SOURCEPREFIX);
442: }
443: String dest = null;
444: if (hasAttribute(node, ATTR_URI_DESTURI)) {
445: dest = getAttributeValue(node, ATTR_URI_DESTURI);
446: }
447:
448: if (root != null && type != null && dest != null) {
449: cocoon.addTarget(type, root, src, dest);
450: } else if (root != null && dest != null) {
451: cocoon.addTarget(root, src, dest);
452: } else if (dest != null) {
453: cocoon.addTarget(src, dest);
454: } else {
455: cocoon.addTarget(src, destDir);
456: }
457: } else if (node.getAttributes().getLength() != 0
458: && nodes.getLength() != 0) {
459: throw new IllegalArgumentException(
460: "Unexpected children of <" + NODE_URI + "> node");
461: } else {
462: throw new IllegalArgumentException(
463: "Not enough information for <" + NODE_URI
464: + "> node");
465: }
466: }
467:
468: private static String getNodeValue(Node root, String name)
469: throws IllegalArgumentException {
470: NodeList nodes = root.getChildNodes();
471: for (int i = 0; i < nodes.getLength(); i++) {
472: Node node = nodes.item(i);
473: if (node.getNodeType() == Node.ELEMENT_NODE) {
474: String nodeName = node.getNodeName();
475: if (nodeName.equals(name)) {
476: return getNodeValue(node);
477: }
478: }
479: }
480: return null;
481: }
482:
483: private static String getNodeValue(Node node)
484: throws IllegalArgumentException {
485: StringBuffer s = new StringBuffer();
486: NodeList children = node.getChildNodes();
487: boolean found = false;
488:
489: for (int i = 0; i < children.getLength(); i++) {
490: Node child = children.item(i);
491: if (child.getNodeType() == Node.TEXT_NODE) {
492: s.append(child.getNodeValue());
493: found = true;
494: } else {
495: throw new IllegalArgumentException("Unexpected node:"
496: + child.getLocalName());
497: }
498: }
499: if (!found) {
500: throw new IllegalArgumentException("Expected value for "
501: + node.getLocalName() + " node");
502: }
503: return s.toString();
504: }
505:
506: private static String getAttributeValue(Node node, String attr)
507: throws IllegalArgumentException {
508: NamedNodeMap nodes = node.getAttributes();
509: if (nodes != null) {
510: Node attribute = nodes.getNamedItem(attr);
511: if (attribute != null && attribute.getNodeValue() != null) {
512: return attribute.getNodeValue();
513: }
514: }
515: throw new IllegalArgumentException("Missing " + attr
516: + " attribute on <" + node.getNodeName() + "> node");
517: }
518:
519: private static boolean hasAttribute(Node node, String attr) {
520: NamedNodeMap nodes = node.getAttributes();
521: if (nodes != null) {
522: Node attribute = nodes.getNamedItem(attr);
523: return (attribute != null);
524: }
525: return false;
526: }
527:
528: private static boolean getBooleanAttributeValue(Node node,
529: String attr) {
530: NamedNodeMap nodes = node.getAttributes();
531: if (nodes != null) {
532: Node attribute = nodes.getNamedItem(attr);
533:
534: if (attribute != null) {
535: String value = attribute.getNodeValue();
536: return BooleanUtils.toBoolean(value);
537: }
538: }
539: return false;
540: }
541:
542: /**
543: * <code>processURIFile</code> method.
544: *
545: * @param filename a <code>String</code> value
546: * @return uris a <code>List</code> of URIs
547: */
548: public static List processURIFile(String filename) {
549: List uris = new ArrayList();
550: FileReader fr = null;
551: BufferedReader uriFile = null;
552: try {
553: fr = new FileReader(filename);
554: uriFile = new BufferedReader(fr);
555: String uri;
556: while ((uri = uriFile.readLine()) != null) {
557: uri = uri.trim();
558: if (!uri.equals("") && !uri.startsWith("#")) {
559: uris.add(uri.trim());
560: }
561: }
562: } catch (FileNotFoundException e) {
563: // nothing to do
564: } catch (IOException e) {
565: // nothing to do
566: } finally {
567: IOUtils.closeQuietly(uriFile);
568: IOUtils.closeQuietly(fr);
569: }
570: return uris;
571: }
572: }
|