view src/kryshen/tema/Tema.java @ 1:548a93c24e55

Tema 0.1jk - Javakonkurs edition (imported from CVS).
author Mikhail Kryshen <mikhail@kryshen.net>
date Thu, 14 Dec 2006 23:22:05 +0300
parents 1d2fe61a3a62
children 6c41a0b43e58
line source
1 /*
2 * Copyright (C) 2005, 2006 Mikhail A. Kryshen
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * $Id: Tema.java,v 1.17 2006/12/14 19:44:31 mikhail Exp $
19 */
21 package kryshen.tema;
23 import java.sql.Driver;
24 import java.sql.DriverManager;
25 import java.sql.Connection;
26 import java.sql.Statement;
27 import java.sql.PreparedStatement;
28 import java.sql.ResultSet;
29 import java.sql.ResultSetMetaData;
30 import java.sql.SQLException;
32 import java.util.Map;
33 import java.util.HashMap;
34 import java.util.Properties;
35 import java.util.List;
36 import java.util.Collections;
38 import java.io.*;
40 import kryshen.tema.demo.DemoFrame;
42 /**
43 * Tema main class.
44 *
45 * @author Mikhail A. Kryshen
46 */
47 public class Tema {
48 public static final String TITLE = "TEMA";
49 public static final String VERSION = "0.1";
50 public static final String AUTHOR = "Mikhail A. Kryshen";
52 private static final String CONFIG_FILE = "tema.properties";
53 private static final String ENV_PREFIX = "kryshen.tema.";
55 private static Properties config = new Properties();
56 private static Connection connection = null;
58 private static String inputEncoding;
59 private static String outputEncoding;
61 private static Map<File, String> fileCache = null;
63 public static void main(String[] args)
64 throws IOException, SQLException,
65 ClassNotFoundException, InstantiationException,
66 IllegalAccessException {
68 boolean demo = false;
69 boolean version = false;
70 boolean help = false;
72 // Parse arguments.
73 for (int i = 0; i < args.length; i++) {
74 if ("-demo".equals(args[i]) ||
75 "-d".equals(args[i])) {
76 demo = true;
77 } else if ("-version".equals(args[i]) ||
78 "-v".equals(args[i])) {
79 version = true;
80 } else if ("-help".equals(args[i]) ||
81 "-h".equals(args[i]) ||
82 "-usage".equals(args[i]) ||
83 "-u".equals(args[i])) {
84 help = true;
85 } else {
86 System.err.println("Invalid option: " + args[i]);
87 return;
88 }
89 }
91 if (version || help) {
92 System.err.println(TITLE + " " + VERSION + " by " + AUTHOR);
94 if (help) {
95 PrintStream err = System.err;
97 err.println();
98 err.println("Usage: tema [OPTIONS]");
99 err.println();
100 err.println("Options:");
101 err.println(" -d[emo] Demo mode");
102 err.println(" -v[ersion] Print version");
103 err.println(" -h[help] -u[sage] Print this help message");
104 }
105 return;
106 }
108 if (demo) {
109 // Run in demo mode.
110 DemoFrame df = new DemoFrame();
111 df.pack();
112 df.setVisible(true);
113 return;
114 }
116 process();
117 }
119 /**
120 * Standard execution.
121 */
122 private static void process()
123 throws IOException, SQLException,
124 ClassNotFoundException, InstantiationException,
125 IllegalAccessException {
127 InputStream configIn = new FileInputStream(CONFIG_FILE);
128 config.load(configIn);
129 configIn.close();
131 configure();
133 String main = getProperty("main_template");
134 String output = getProperty("output");
136 Writer out;
138 if ("stderr".equals(output))
139 out = new OutputStreamWriter(System.err);
140 else
141 out = new OutputStreamWriter(System.out);
143 TemplateReader in = createTemplateReader(new File(main));
144 TemplateParser p = new TemplateParser();
145 TemplateException te = null;
147 try {
148 p.parse(in, out);
149 } catch (TemplateException e) {
150 te = e;
151 } finally {
152 in.close();
153 out.flush();
154 }
156 if (te != null) {
157 System.err.println(te.getMessage());
158 if (te.getCause() != null) {
159 System.err.println("Caused by " + te.getCause());
160 }
161 } else {
162 System.err.println("Done");
163 }
164 }
166 private static void configure()
167 throws IOException, SQLException, IllegalAccessException,
168 ClassNotFoundException, InstantiationException {
170 String logFile = getProperty("log");
171 if (logFile != null && logFile.length() > 0)
172 System.setErr(new PrintStream(new FileOutputStream(logFile)));
174 if (Boolean.parseBoolean(getProperty("cache_read")) == true)
175 fileCache = new HashMap<File, String>();
177 inputEncoding = getProperty("input_encoding", "iso-8859-1");
178 outputEncoding = getProperty("output_encoding", "iso-8859-1");
180 String resourceProperty = getProperty("resource");
182 if (resourceProperty != null) {
183 String driverProperty = getProperty("driver");
184 if (driverProperty != null) {
185 // Register driver.
186 Driver d = (Driver)Class.forName(driverProperty).newInstance();
187 }
189 // Open connection.
190 connection = DriverManager.getConnection(resourceProperty);
191 }
192 }
196 /**
197 * Get configuration property.
198 */
199 public static String getProperty(String name) {
200 String value = System.getProperty(ENV_PREFIX + name);
201 if (value != null) return value;
202 return config.getProperty(name);
203 }
205 /**
206 * Get configuration property.
207 */
208 public static String getProperty(String name, String fallback) {
209 String value = getProperty(name);
210 if (value != null) return value;
211 return fallback;
212 }
214 /**
215 * Process database query.
216 *
217 * @param templateReader reader for the template
218 * to fill with data.
219 * @param ps query statement to execute.
220 * @param args list of query parameters.
221 * @param superParser invoking object.
222 * @param out Writer to output processed data.
223 *
224 * @return number of processed rows in query result.
225 */
226 public static int query(TemplateReader templateReader,
227 PreparedStatement ps,
228 List<String> args,
229 TemplateParser superParser,
230 Writer out)
231 throws IOException, SQLException, TemplateException {
233 int i = 1;
235 for (String arg : args) {
236 ps.setString(i++, arg);
237 }
239 ResultSet r = ps.executeQuery();
240 ResultSetMetaData rm = r.getMetaData();
241 int columnCount = rm.getColumnCount();
243 String[] names = new String[columnCount];
245 for (int j = 0; j < columnCount; j++) {
246 names[j] = rm.getColumnName(j + 1);
247 }
249 final TemplateParser p = new TemplateParser(superParser);
250 final HashMap<String, Object> fields = new HashMap<String, Object>();
252 p.registerFunction("db", new Function() {
253 public int invoke(FunctionDataParser fdp,
254 final Writer out)
255 throws IOException, TemplateException {
257 String name = fdp.getData();
258 Object value = fields.get(name);
260 return p.parseValue(value, out);
261 }
262 });
264 for (i = 1; r.next(); i++) {
266 for (int j = 0; j < columnCount; j++) {
267 Object value = r.getObject(j + 1);
268 if (r.wasNull()) value = null;
270 fields.put(names[j], value);
271 }
273 p.setValue("number", i);
274 p.parse(templateReader, out);
275 templateReader.reset();
276 fields.clear();
277 }
279 r.close();
280 ps.clearParameters();
281 return i - 1;
282 }
284 public static BufferedWriter createFileWriter(String filename)
285 throws IOException {
287 OutputStream os = new FileOutputStream(filename);
288 return new BufferedWriter
289 (new OutputStreamWriter(os, Tema.outputEncoding));
290 }
292 public static BufferedReader createFileReader(File file)
293 throws IOException {
295 InputStream is = new FileInputStream(file);
296 return new BufferedReader
297 (new InputStreamReader(is, Tema.inputEncoding));
298 }
300 public static TemplateReader createTemplateReader(File file)
301 throws IOException {
303 return new TemplateReader
304 (new LineNumberReader(createCachedFileReader(file)), file.getPath());
305 }
307 /**
308 * Creates StringReader for a cached file if caching is enabled or
309 * a BufferedReader.
310 *
311 * @param file File to read.
312 * @return Reader for a file.
313 */
314 public static Reader createCachedFileReader(File file)
315 throws IOException {
317 if (fileCache != null) return new StringReader(readFile(file));
318 else return createFileReader(file);
319 }
321 /**
322 * Read text file.
323 *
324 * @return file contents.
325 */
326 public static String readFile(File file) throws IOException {
327 String data;
329 if (fileCache != null) {
330 data = fileCache.get(file);
331 if (data != null) return data;
332 }
334 Reader r = new BufferedReader(createFileReader(file));
336 // FIXME: possible overflow (long -> int).
337 StringBuffer sb = new StringBuffer((int)file.length());
339 try {
340 for (int c = r.read(); c >= 0; c = r.read()) {
341 sb.append((char)c);
342 }
343 } finally {
344 r.close();
345 }
347 data = sb.toString();
349 if (fileCache != null) {
350 fileCache.put(file, data);
351 }
353 return data;
354 }
356 /**
357 * Get database connection.
358 *
359 * @return database connection if any was configured.
360 */
361 public static Connection getDbConnection() {
362 return connection;
363 }
364 }