1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.woopi.ant.taskdefs.junit;
18 import java.io.BufferedOutputStream;
19 import java.io.ByteArrayOutputStream;
20 import java.io.File;
21 import java.io.FileOutputStream;
22 import java.io.IOException;
23 import java.io.OutputStream;
24 import java.io.PrintWriter;
25 import java.io.StringWriter;
26 import java.lang.reflect.Field;
27 import org.apache.tools.ant.BuildException;
28 import org.apache.tools.ant.Project;
29 import org.apache.tools.ant.util.JavaEnvUtils;
30
31 /***
32 * Command class that encapsulate specific behavior for each
33 * Xalan version. The right executor will be instantiated at
34 * runtime via class lookup. For instance, it will check first
35 * for Xalan2/XSLTC, then for Xalan1.
36 */
37 abstract class XalanExecutor {
38 private static final String pack =
39 "org.woopi.ant.taskdefs.junit.";
40
41 /*** the transformer caller */
42 protected AggregateTransformer caller;
43
44 /*** set the caller for this object. */
45 private final void setCaller(AggregateTransformer caller) {
46 this.caller = caller;
47 }
48
49 /*** get the appropriate stream based on the format (frames/noframes) */
50 protected final OutputStream getOutputStream() throws IOException {
51 if (AggregateTransformer.FRAMES.equals(caller.format)) {
52
53
54 return new ByteArrayOutputStream();
55 } else {
56 return new BufferedOutputStream(new FileOutputStream(new File(caller.toDir, "junit-noframes.html")));
57 }
58 }
59
60 /*** override to perform transformation */
61 abstract void execute() throws Exception;
62
63 /***
64 * Create a valid Xalan executor. It checks first if Xalan2 is
65 * present, if not it checks for xalan1. If none is available, it
66 * fails.
67 * @param caller object containing the transformation information.
68 * @throws BuildException thrown if it could not find a valid xalan
69 * executor.
70 */
71 static XalanExecutor newInstance(AggregateTransformer caller)
72 throws BuildException {
73 XalanExecutor executor = null;
74 try {
75 Class clazz = Class.forName(pack + "Xalan2Executor");
76 executor = (XalanExecutor)clazz.newInstance();
77 } catch (Exception xsltcApacheMissing){
78 caller.task.log(xsltcApacheMissing.toString());
79 try {
80 Class clazz = Class.forName(pack + "Xalan1Executor");
81 executor = (XalanExecutor) clazz.newInstance();
82 } catch (Exception xalan1Missing){
83 caller.task.log(xalan1Missing.toString());
84 throw new BuildException("Could not find xstlc nor xalan2 nor "
85 + "xalan1 in the classpath. Check "
86 + "http://xml.apache.org/xalan-j");
87 }
88 }
89 String classNameImpl = executor.getImplementation();
90 String version = executor.getProcVersion(classNameImpl);
91 caller.task.log("Using " + version, Project.MSG_VERBOSE);
92 executor.setCaller(caller);
93 return executor;
94 }
95
96 /***
97 * This methods should return the classname implementation of the
98 * underlying xslt processor
99 * @return the classname of the implementation, for example:
100 * org.apache.xalan.processor.TransformerFactoryImpl
101 * @see #getProcVersion(String)
102 */
103 protected abstract String getImplementation();
104
105 /***
106 * Try to discover the xslt processor version based on the
107 * className. There is nothing carved in stone and it can change
108 * anytime, so this is just for the sake of giving additional
109 * information if we can find it.
110 * @param classNameImpl the classname of the underlying xslt processor
111 * @return a string representing the implementation version.
112 * @throws BuildException
113 */
114 protected abstract String getProcVersion(String classNameImpl)
115 throws BuildException;
116
117 /*** a bit simplistic but xsltc data are conveniently private non final */
118 protected final String getXSLTCVersion(String procVersionClassName)
119 throws ClassNotFoundException {
120
121
122 Class procVersion = Class.forName(procVersionClassName);
123 Package pkg = procVersion.getPackage();
124 return pkg.getName() + " " + pkg.getImplementationTitle()
125 + " " + pkg.getImplementationVersion();
126 }
127
128 /*** pretty useful data (Xalan version information) to display. */
129 protected final String getXalanVersion(String procVersionClassName)
130 throws ClassNotFoundException {
131 Class procVersion = Class.forName(procVersionClassName);
132 String pkg = procVersion.getPackage().getName();
133 try {
134 Field f = procVersion.getField("S_VERSION");
135 return pkg + " " + f.get(null).toString();
136 } catch (Exception e) {
137 return pkg + " ?.?";
138 }
139 }
140 }