Source code: com/arranger/jarl/script/jarlsp/JarlSPCompiler.java
1 package com.arranger.jarl.script.jarlsp;
2
3 import com.arranger.jarl.base.IContext;
4 import com.arranger.jarl.script.gsp.GSP;
5 import com.arranger.jarl.script.gsp.GSPException;
6 import com.arranger.jarl.script.gsp.IGSPCompiler;
7 import com.arranger.jarl.util.IOUtil;
8 import com.arranger.jarl.util.StringTools;
9
10 import java.io.*;
11 import java.util.ArrayList;
12 import java.util.HashMap;
13 import java.util.List;
14 import java.util.Map;
15
16 /**
17 * JarlSPCompiler created on Mar 5, 2003
18 */
19 public class JarlSPCompiler implements IGSPCompiler {
20
21 protected static final char PATH_SEPARATOR = File.separatorChar;
22
23 protected GSP m_gsp = new GSP();
24 protected String m_javaCompiler = "javac";
25 protected String m_sourceRoot = System.getProperty("user.dir");
26 protected String m_javaOutput = System.getProperty("user.dir");
27 protected String m_classOutput = System.getProperty("user.dir");
28 protected String m_classPath = System.getProperty("java.class.path");
29
30 public String getJavaCompiler() {
31 return m_javaCompiler;
32 }
33
34 public void setJavaCompiler(String javaCompiler) {
35 m_javaCompiler = javaCompiler;
36 }
37
38 public String getSourceRoot() {
39 return m_sourceRoot;
40 }
41
42 public void setSourceRoot(String sourceRoot) {
43 m_sourceRoot = sourceRoot;
44 }
45
46 public String getJavaOutput() {
47 return m_javaOutput;
48 }
49
50 public void setJavaOutput(String javaOutput) {
51 m_javaOutput = javaOutput;
52 }
53
54 public String getClassOutput() {
55 return m_classOutput;
56 }
57
58 public void setClassOutput(String classOutput) {
59 m_classOutput = classOutput;
60 }
61
62 public String getClassPath() {
63 return m_classPath;
64 }
65
66 public void setClassPath(String classPath) {
67 m_classPath = classPath;
68 }
69
70
71 /**
72 * Parses a specific nbsp ispFile.
73 *
74 * @param ispFile Nbsp ispFile to parse.
75 * @return Parsed java source ispFile path., or null if nothing was parsed
76 * @throws GSPException if an error occured during parsing
77 * @throws java.io.IOException if an error occured reading or writing
78 * to the nbsp or java source files.
79 */
80 public String parse(File ispFile, IContext context) throws GSPException, IOException {
81 String path = getRelativePath(ispFile, m_sourceRoot);
82 String fullClassName = getClassname(path);
83 String className = StringTools.getLastSegment(fullClassName, ".", false);
84 String packageName = StringTools.stripLastSegment(fullClassName, ".");
85 File javaFile = getJavaFile(path, m_javaOutput);
86
87 context.onStatus("parsing: " + ispFile.toString());
88
89 Reader in = null;
90 Writer out = null;
91 JarlSPLanguage language = new JarlSPLanguage();
92 try {
93 in = open(ispFile.toString());
94 m_gsp.parse(in, language, this);
95 out = IOUtil.getWriter(javaFile.toString());
96 language.flush(out,
97 packageName,
98 className,
99 SimpleJarlSPBase.class.getName());
100 } finally {
101 if (in != null) {
102 in.close();
103 }
104 if (out != null) {
105 out.close();
106 }
107 }
108
109 return javaFile.toString();
110 }
111
112 /**
113 * Same as {@link #compile} but a list of files
114 */
115 public void compile(File jarlspFile) throws Exception {
116 //ensure output dir
117 String classOutput = new File(m_classOutput).getCanonicalPath();
118 new File(classOutput).mkdirs();
119
120 // build javac command
121 List command = new ArrayList();
122 command.add(m_javaCompiler);
123 command.add("-classpath");
124 command.add(m_classPath);
125 command.add("-d");
126 command.add(classOutput);
127 command.add("-nowarn");
128 command.add(jarlspFile.toString());
129
130 // execute javac command
131 Process proc = Runtime.getRuntime().exec((String[])command.toArray(new String[command.size()]));
132 byte[] buf = new byte[0x800];
133 StringBuffer err = new StringBuffer(0x2000);
134 int len = proc.getErrorStream().read(buf);
135
136 while (len != -1) {
137 err.append(new String(buf, 0, len));
138 len = proc.getErrorStream().read(buf);
139 }
140
141 if (err.length() > 0) {
142 throw new Exception(err.toString());
143 }
144 }
145
146 /**
147 * Executes the files that are previously compiled
148 *
149 * @param ispJavaLocation this was returned from {@link #parse}
150 * and should have been sent to {@link #compile}
151 * @throws Exception
152 */
153 public String execute(String ispJavaLocation, IContext context) throws Exception {
154 File jarlspJavaFile = new File(ispJavaLocation);
155 String path = getRelativePath(jarlspJavaFile, m_javaOutput);
156 String ispClass = getClassname(path);
157 File xmlFile = getXmlFile(path, m_javaOutput);
158 context.onStatus("executing: " + jarlspJavaFile.toString());
159
160 //get the writer
161 Writer writer = new FileWriter(xmlFile);
162 JarlSPRuntime jarlspRuntime = new SimpleJarlSPRuntime(m_classOutput);
163 Map props = new HashMap(System.getProperties());
164 jarlspRuntime.execute(ispClass, writer, props);
165
166 //close it
167 writer.close();
168 return xmlFile.toString();
169 }
170
171 /**
172 * Gets the inuput stream to the specified file.
173 *
174 * @param file URI specifing file to open.
175 *
176 * @return Input stream of specified file.
177 *
178 * @throws GSPException if file cannot be opened.
179 */
180 public Reader open(String file) throws GSPException {
181 try {
182 String text = IOUtil.toString(file);
183 return new StringReader(text);
184 } catch (IOException e) {
185 throw new GSPException(e);
186 }
187 }
188
189 /**
190 * Gets 'foo/bar/myNbsp' for '/usr/local/ui/foo/bar/myNbsp.nbsp'.
191 */
192 public static String getRelativePath(File file, String root) throws IOException {
193 String path = file.getPath();
194 root = new File(root).getCanonicalPath();
195
196 if (path.startsWith(root)) {
197 int dot = path.lastIndexOf('.');
198 if (dot == -1) {
199 path = path.substring(root.length());
200 } else {
201 path = path.substring(root.length(), dot);
202 }
203 }
204
205 return path;
206 }
207
208 /**
209 * Gets fully qualified class name for 'foo/bar/myNbsp'.
210 */
211 public static String getClassname(String path) {
212 StringBuffer className = new StringBuffer(path.length());
213 int start = 0;
214 int end = path.lastIndexOf('.');
215
216 if (path.charAt(0) == '/' || path.charAt(0) == PATH_SEPARATOR) {
217 start = 1;
218 }
219 if (end == -1) {
220 end = path.length();
221 }
222
223 for (int i = start; i < end; i++) {
224 char ch = path.charAt(i);
225 if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')
226 || (ch >= '0' && ch <= '9') || ch == '_') {
227 className.append(ch);
228 } else if (ch == '/' || ch == PATH_SEPARATOR) {
229 className.append('.');
230 } else {
231 className.append('_');
232 }
233 }
234
235 return className.toString();
236 }
237
238 /**
239 * Gets output file for 'foo/bar/myNbsp'.
240 */
241 public static File getJavaFile(String path, String basePath) throws IOException {
242 return getFile(path, ".java", basePath);
243 }
244
245 public static File getXmlFile(String path, String basePath) throws IOException {
246 return getFile(path, ".xml", basePath);
247 }
248
249 public static File getFile(String path, String ext, String basePath) throws IOException {
250 path = StringTools.stripLastSegment(path, ".");
251 File file = new File(StringTools.appendPath(basePath, path) + ext);
252 file.getParentFile().mkdirs();
253 file.createNewFile();
254 return file;
255 }
256 }