001: package org.objectweb.celtix.tools.common.toolspec;
002:
003: import java.io.InputStream;
004: import java.io.OutputStream;
005: import java.util.ArrayList;
006: import java.util.Collections;
007: import java.util.List;
008: import java.util.logging.Level;
009: import java.util.logging.Logger;
010:
011: import javax.xml.transform.Transformer;
012: import javax.xml.transform.TransformerException;
013: import javax.xml.transform.TransformerFactory;
014: import javax.xml.transform.dom.DOMSource;
015: import javax.xml.transform.stream.StreamResult;
016: import javax.xml.transform.stream.StreamSource;
017:
018: import org.w3c.dom.Document;
019: import org.w3c.dom.Element;
020: import org.w3c.dom.Node;
021: import org.w3c.dom.NodeList;
022:
023: import org.objectweb.celtix.common.i18n.Message;
024: import org.objectweb.celtix.common.logging.LogUtils;
025: import org.objectweb.celtix.tools.common.ToolException;
026: import org.objectweb.celtix.tools.common.dom.ExtendedDocumentBuilder;
027:
028: public class ToolSpec {
029:
030: private static final Logger LOG = LogUtils
031: .getL7dLogger(ToolSpec.class);
032:
033: private final ExtendedDocumentBuilder builder = new ExtendedDocumentBuilder();
034: private Document doc;
035: private Tool handler;
036:
037: public ToolSpec() {
038: }
039:
040: public ToolSpec(InputStream in) throws ToolException {
041: this (in, true);
042: }
043:
044: public ToolSpec(InputStream in, boolean validate)
045: throws ToolException {
046: if (in == null) {
047: throw new NullPointerException(
048: "Cannot create a ToolSpec object from a null stream");
049: }
050: try {
051: builder.setValidating(validate);
052: this .doc = builder.parse(in);
053: } catch (Exception ex) {
054: Message message = new Message(
055: "FAIL_TO_PARSING_TOOLSPCE_STREAM", LOG);
056: throw new ToolException(message, ex);
057: }
058: }
059:
060: public ToolSpec(Document d) {
061: if (d == null) {
062: throw new NullPointerException(
063: "Cannot create a ToolSpec object from "
064: + "a null org.w3c.dom.Document");
065: }
066: this .doc = d;
067: }
068:
069: public ExtendedDocumentBuilder getDocumentBuilder() {
070: return builder;
071: }
072:
073: public boolean isValidInputStream(String id) {
074: Element streams = getStreams();
075:
076: if (streams == null) {
077: return false;
078: }
079: NodeList nl = streams.getElementsByTagNameNS(
080: Tool.TOOL_SPEC_PUBLIC_ID, "instream");
081:
082: for (int i = 0; i < nl.getLength(); i++) {
083: if (((Element) nl.item(i)).getAttribute("id").equals(id)) {
084: return true;
085: }
086: }
087: return false;
088: }
089:
090: public Element getElementById(String id) {
091: return doc.getElementById(id);
092: }
093:
094: public boolean hasHandler() {
095: return doc.getDocumentElement().hasAttribute("handler");
096: }
097:
098: public Tool getHandler() throws ToolException {
099: if (!hasHandler()) {
100: return null;
101: }
102:
103: if (handler == null) {
104: String handlerClz = doc.getDocumentElement().getAttribute(
105: "handler");
106:
107: try {
108: handler = (Tool) Class.forName(handlerClz)
109: .newInstance();
110: } catch (Exception ex) {
111: Message message = new Message(
112: "FAIL_TO_INSTANTIATE_HANDLER", LOG, handlerClz);
113: throw new ToolException(message, ex);
114: }
115: }
116: return handler;
117: }
118:
119: public Tool getHandler(ClassLoader loader) throws ToolException {
120: if (!hasHandler()) {
121: return null;
122: }
123:
124: if (handler == null) {
125: String handlerClz = doc.getDocumentElement().getAttribute(
126: "handler");
127:
128: try {
129: handler = (Tool) Class
130: .forName(handlerClz, true, loader)
131: .newInstance();
132: } catch (Exception ex) {
133: Message message = new Message(
134: "FAIL_TO_INSTANTIATE_HANDLER", LOG, handlerClz);
135: throw new ToolException(message, ex);
136: }
137: }
138: return handler;
139: }
140:
141: public Element getStreams() {
142: NodeList nl = doc.getDocumentElement().getElementsByTagNameNS(
143: Tool.TOOL_SPEC_PUBLIC_ID, "streams");
144:
145: if (nl.getLength() > 0) {
146: return (Element) nl.item(0);
147: } else {
148: return null;
149: }
150: }
151:
152: public List getInstreamIds() {
153: List<Object> res = new ArrayList<Object>();
154: Element streams = getStreams();
155:
156: if (streams != null) {
157: NodeList nl = streams.getElementsByTagNameNS(
158: Tool.TOOL_SPEC_PUBLIC_ID, "instream");
159:
160: for (int i = 0; i < nl.getLength(); i++) {
161: res.add(((Element) nl.item(i)).getAttribute("id"));
162: }
163: }
164: return Collections.unmodifiableList(res);
165: }
166:
167: public List getOutstreamIds() {
168: List<Object> res = new ArrayList<Object>();
169: Element streams = getStreams();
170:
171: if (streams != null) {
172: NodeList nl = streams.getElementsByTagNameNS(
173: Tool.TOOL_SPEC_PUBLIC_ID, "outstream");
174:
175: for (int i = 0; i < nl.getLength(); i++) {
176: res.add(((Element) nl.item(i)).getAttribute("id"));
177: }
178: }
179: return Collections.unmodifiableList(res);
180: }
181:
182: public Element getUsage() {
183: return (Element) doc.getDocumentElement()
184: .getElementsByTagNameNS(Tool.TOOL_SPEC_PUBLIC_ID,
185: "usage").item(0);
186: }
187:
188: public void transform(InputStream stylesheet, OutputStream out)
189: throws TransformerException {
190: Transformer trans = TransformerFactory.newInstance()
191: .newTransformer(new StreamSource(stylesheet));
192: trans.transform(new DOMSource(doc), new StreamResult(out));
193: }
194:
195: public Element getPipeline() {
196: NodeList nl = doc.getDocumentElement().getElementsByTagNameNS(
197: Tool.TOOL_SPEC_PUBLIC_ID, "pipeline");
198:
199: if (nl.getLength() > 0) {
200: return (Element) nl.item(0);
201: } else {
202: return null;
203: }
204: }
205:
206: public NodeList getUsageForms() {
207: return getUsage().getElementsByTagNameNS(
208: Tool.TOOL_SPEC_PUBLIC_ID, "form");
209: }
210:
211: /**
212: * Arguments can have streamref attributes which associate them with a
213: * stream. Tools usually request streams and rely on them being ready. If an
214: * argument is given a streamref, then the container constructs a stream
215: * from the argument value. This would usually be a simple FileInputStream
216: * or FileOutputStream. The mechanics of this are left for the container to
217: * sort out, but that is the reason why this getter method exists.
218: */
219: public String getStreamRefName(String streamId) {
220: if (getUsage() != null) {
221: NodeList nl = getUsage().getElementsByTagNameNS(
222: Tool.TOOL_SPEC_PUBLIC_ID, "associatedArgument");
223:
224: for (int i = 0; i < nl.getLength(); i++) {
225: if (((Element) nl.item(i)).getAttribute("streamref")
226: .equals(streamId)) {
227: return ((Element) nl.item(i).getParentNode())
228: .getAttribute("id");
229: }
230: }
231: nl = getUsage().getElementsByTagNameNS(
232: Tool.TOOL_SPEC_PUBLIC_ID, "argument");
233: for (int i = 0; i < nl.getLength(); i++) {
234: if (((Element) nl.item(i)).getAttribute("streamref")
235: .equals(streamId)) {
236: return ((Element) nl.item(i)).getAttribute("id");
237: }
238: }
239: }
240: return null;
241: }
242:
243: public String getParameterDefault(String name) {
244: Element el = getElementById(name);
245: if (LOG.isLoggable(Level.FINE)) {
246: LOG.fine("Element with id " + name + " is " + el);
247: }
248: if (el != null) {
249: if (LOG.isLoggable(Level.FINE)) {
250: LOG.fine("local name is " + el.getLocalName());
251: }
252: if ("argument".equals(el.getLocalName())) {
253: if (el.hasAttribute("default")) {
254: return el.getAttribute("default");
255: }
256: } else if ("option".equals(el.getLocalName())) {
257: NodeList assArgs = el.getElementsByTagNameNS(
258: "http://www.xsume.com/Xpipe/ToolSpecification",
259: "associatedArgument");
260:
261: if (assArgs.getLength() > 0) {
262: Element assArg = (Element) assArgs.item(0);
263:
264: if (assArg.hasAttribute("default")) {
265: return assArg.getAttribute("default");
266: }
267: }
268: }
269: }
270: return null;
271: }
272:
273: public String getAnnotation() {
274: String result = null;
275: Element element = doc.getDocumentElement();
276: NodeList list = element.getChildNodes();
277:
278: for (int i = 0; i < list.getLength(); i++) {
279: if ((list.item(i).getNodeType() == Node.ELEMENT_NODE)
280: && ("annotation".equals(list.item(i).getNodeName()))) {
281: result = list.item(i).getFirstChild().getNodeValue();
282: break;
283: }
284: }
285: return result;
286: }
287:
288: }
|