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