001: package org.jicengine.builder;
002:
003: import javax.xml.parsers.*;
004: import org.xml.sax.SAXException;
005: import org.jicengine.*;
006: import java.io.File;
007: import java.io.IOException;
008: import java.util.Map;
009: import java.util.Iterator;
010: import org.jicengine.element.Element;
011: import org.jicengine.element.ElementException;
012: import org.jicengine.element.VariableElement;
013: import org.jicengine.element.ActionElement;
014: import org.jicengine.io.Resource;
015: import org.jicengine.io.UrlReadable;
016: import org.jicengine.operation.Context;
017: import org.jicengine.operation.SimpleContext;
018:
019: /**
020: *
021: *
022: *
023: * <p>
024: * Copyright (C) 2004 Timo Laitinen
025: * </p>
026: *
027: * @author Timo Laitinen
028: * @created 2004-09-20
029: * @since JICE-0.10
030: *
031: */
032:
033: public class BuilderImpl implements Builder {
034:
035: private static boolean log = false;
036:
037: //Boolean.valueOf(System.getProperty("org.jicengine.Builder.log", "false")).booleanValue();
038:
039: public BuilderImpl() {
040: }
041:
042: public Object build(Instructions instructions) throws IOException,
043: SAXException, JICException {
044:
045: // parse
046: long begin = System.currentTimeMillis();
047: Element rootElement = parse(instructions);
048: long parseTime = System.currentTimeMillis() - begin;
049:
050: // execute the elements and return the result.
051: begin = System.currentTimeMillis();
052: Object result = execute(rootElement, instructions);
053: long execTime = System.currentTimeMillis() - begin;
054:
055: if (log) {
056: System.out.println("[" + instructions.getFile() + "]:");
057: System.out.println(" parse time : " + parseTime);
058: System.out.println(" exec time : " + execTime);
059: System.out.println(" total time : "
060: + (parseTime + execTime));
061: System.out.println();
062: }
063:
064: return result;
065: }
066:
067: private SAXParser getSAXParser() throws JICException {
068: try {
069: SAXParserFactory factory = SAXParserFactory.newInstance();
070: factory.setNamespaceAware(true);
071: factory.setFeature(
072: "http://xml.org/sax/features/namespaces", true);
073: factory.setFeature(
074: "http://xml.org/sax/features/namespace-prefixes",
075: true);
076: SAXParser parser = factory.newSAXParser();
077: return parser;
078: } catch (Exception e) {
079: throw new JICException("Failed to obtain a SAX parser", e);
080: }
081: }
082:
083: private Element parse(Instructions instructions)
084: throws IOException, SAXException, JICException {
085: SAXParser parser = getSAXParser();
086: Handler handler = new Handler();
087: //XMLReader
088:
089: try {
090: parser.parse(instructions.getFile().getInputStream(),
091: handler, getSystemIdentifier(instructions));
092: return handler.getResult();
093: } catch (org.xml.sax.SAXException e) {
094: Exception cause = e.getException();
095: if (cause != null) {
096: if (cause instanceof JICException) {
097: throw (JICException) cause;
098: } else {
099: throw new JICException(cause);
100: }
101: } else {
102: // a SAX exception without a nested exception. throw it as is.
103: throw e;
104: }
105: }
106: }
107:
108: private static String getSystemIdentifier(Instructions instructions) {
109: Resource resource = instructions.getFile();
110: String systemIdentifier;
111: if (resource instanceof UrlReadable) {
112: try {
113: systemIdentifier = ((UrlReadable) resource).getUrl()
114: .toString();
115: } catch (IOException e) {
116: System.out
117: .println(new java.util.Date()
118: + " [JICE]: failed to create resource URL, using identifier '"
119: + resource.getIdentifier()
120: + "' as system identifier");
121: systemIdentifier = resource.getIdentifier();
122: }
123: } else {
124: systemIdentifier = resource.getIdentifier();
125: }
126:
127: return systemIdentifier;
128: }
129:
130: private Object execute(Element rootElement,
131: Instructions buildInstructions) throws ElementException {
132: Context rootContext = new SimpleContext("//");
133: BuildContext jiceContext = new BuildContextImpl(
134: buildInstructions);
135: rootContext.addObject(BuildContext.VARIABLE_NAME, jiceContext);
136:
137: // reserve the variable names 'true' and 'false' to boolean values.
138: rootContext.addObject("true", Boolean.TRUE);
139: rootContext.addObject("false", Boolean.FALSE);
140:
141: Map buildParameters = buildInstructions.getParameters();
142: for (Iterator it = buildParameters.keySet().iterator(); it
143: .hasNext();) {
144: String key = it.next().toString();
145: rootContext
146: .addObject(
147: org.jicengine.expression.BuildParameterParser.PREFIX
148: + key, buildParameters.get(key));
149: }
150:
151: if (rootElement.isExecuted(rootContext, null)) {
152:
153: if (rootElement instanceof VariableElement) {
154: return ((VariableElement) rootElement).getValue(
155: rootContext, null);
156: } else if (rootElement instanceof ActionElement) {
157: ((ActionElement) rootElement)
158: .execute(rootContext, null);
159: return null;
160: } else {
161: throw new IllegalStateException(
162: "unknown element type: " + rootElement);
163: }
164: } else {
165: // element not executed. return null.
166: return null;
167: }
168: }
169:
170: public static void main(String[] args) throws Exception {
171: if (args.length == 0) {
172: System.out
173: .println("give the org.jicengine-file as an argument.");
174: } else {
175: File file = new File(args[0]);
176: System.out.println("-------------------");
177: System.out.println("Processing file '" + file + "'");
178: System.out.println("-------------------");
179: java.util.Map parameters = new java.util.HashMap();
180: //parameters.put("language.code", "fi");
181: Object result = new BuilderImpl()
182: .build(new Instructions(
183: new org.jicengine.io.FileResource(file),
184: parameters));
185:
186: System.out.println("-------------------");
187: System.out.println("Got object:");
188: System.out.println(" " + result);
189: System.out.println(" (" + result.getClass().getName()
190: + ")");
191: System.out.println("-------------------");
192: }
193:
194: /*
195: javax.swing.JFrame frame = new javax.swing.JFrame("Anne on taas kiva");
196: frame.setLocation(300,300);
197: frame.setSize(200,200);
198: frame.show();
199: */
200: }
201: }
|