package com.applang.berichtsheft; import java.io.File; import java.io.FileOutputStream; import java.io.OutputStream; import java.io.Reader; import java.io.StringReader; import java.util.Properties; import javax.xml.transform.ErrorListener; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.sax.SAXResult; import javax.xml.transform.sax.SAXSource; import javax.xml.transform.sax.SAXTransformerFactory; import javax.xml.transform.sax.TransformerHandler; import javax.xml.transform.stream.StreamSource; import org.apache.xml.serializer.OutputPropertiesFactory; import org.apache.xml.serializer.Serializer; import org.apache.xml.serializer.SerializerFactory; import org.gjt.sp.jedit.View; import org.gjt.sp.jedit.jEdit; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import org.xml.sax.XMLReader; import org.xml.sax.helpers.XMLReaderFactory; import android.app.Activity; import android.content.Context; import android.content.res.Resources; import android.database.Cursor; import android.net.Uri; import android.os.Environment; import android.util.Log; import com.applang.PluginUtils; import static com.applang.Util.*; import static com.applang.Util1.*; import static com.applang.Util2.*; import static com.applang.PluginUtils.insideJEdit; import static com.applang.SwingUtil.*; import static com.applang.ZipUtil.*; public class BerichtsheftApp { public static String absolutePath(String relPath) { String absPath = insideJEdit() ? jEdit.getSettingsDirectory() : Resources.getCodeSourceLocation(PluginUtils.class).getPath(); int index = absPath.indexOf(".jedit"); String part = index > -1 ? absPath.substring(0, index) : relativePath(); absPath = pathCombine(part, relPath); return absPath; } public static void loadSettings() { System.setProperty("plugin.props", "BerichtsheftPlugin.props"); String path = absolutePath(".jedit"); System.setProperty("jedit.settings.dir", path); String path2 = pathCombine(path, "jars/sqlite4java"); System.setProperty("sqlite4java.library.path", path2); path2 = pathCombine(path, "plugins/" + NAME); System.setProperty("settings.dir", path2); Settings.load(pathCombine(path2, NAME + ".properties")); Log.logConsoleHandling(Log.INFO); path2 = pathCombine(System.getProperty("user.home"), "work/test"); Environment.setDataDir(path2); } /** * @param args */ public static void main(String...args) { loadSettings(); File defaultFile = new File(applicationDataPath("jedit.properties")); try { File file = new File(".jedit/properties"); if (!fileExists(file)) { copyFile(defaultFile, file); } } catch (Exception e) { message(String.format("'%s' could not be copied", defaultFile.getPath())); return; } if (nullOrEmpty(args)) args = strings( "-settings=.jedit", "-run=.jedit/macros/startBerichtsheft.bsh", "-newview", "-noserver", "-nosplash" ); jEdit.main(args); } private static final String TAG = BerichtsheftApp.class.getSimpleName(); public static final String NAME = "berichtsheft"; public static View getJEditView() { return (View)Activity.frame; } public static String applicationDataPath(String...parts) { String settingsDir = System.getProperty("settings.dir", ""); parts = arrayappend(strings(settingsDir), parts); return pathCombine(parts); } public static String parameters(Object... params) { String[] dbFiles = param(strings(), 0, params); return String.format( "<params>" + "<dbfile>%s</dbfile>" + "<dbfile2>%s</dbfile2>" + "<year>%d</year>" + "<weekInYear>%d</weekInYear>" + "<dayInWeek>%s</dayInWeek>" + "</params>", param("", 0, dbFiles), param("", 1, dbFiles), param_Integer(2013, 1, params), param_Integer(1, 2, params), param_String("\\d", 3, params)); } public static boolean manipContent(int phase, String vorlage, String dokument, Job<File> manipulation, Object...params) { boolean begin = phase > -1; boolean end = phase < 1; File tempDir = tempDir(begin, BerichtsheftApp.NAME, "odt"); try { int unzipped = 0; if (begin) { File source = new File(vorlage); if (!source.exists()) throw new Exception(String.format("Vorlage '%s' missing", vorlage)); File archive = new File(tempDir, "Vorlage.zip"); copyFile(source, archive); unzipped = unzipArchive(archive, new UnzipJob( tempDir.getPath()), false); archive.delete(); } if (manipulation != null) manipulation.perform(new File(tempDir, "content.xml"), params); if (end) { File destination = new File(dokument); if (destination.exists()) destination.delete(); int zipped = zipArchive(destination, tempDir.getPath(), tempDir.getPath()); if (phase == 0 && unzipped > zipped) throw new Exception( String.format( "Dokument '%s' is lacking some ingredient after manipulation", dokument)); else if (phase == 0 && unzipped < zipped) throw new Exception( String.format( "Dokument '%s' has more ingredients than before manipulation", dokument)); else Log.i(TAG, String.format("'%s' generated", dokument)); } return true; } catch (Exception e) { handleException(e); return false; } finally { boolean keep = phase == 0 && param_Boolean(false, 0, params); if (end && !keep) deleteDirectory(tempDir); } } public static boolean export(String vorlage, String dokument, final String[] databaseFilenames, Object...params) { final Integer year = param_Integer(2013, 0, params); final Integer weekInYear = param_Integer(1, 1, params); final String dayInWeek = param_String("\\d", 2, params); boolean keep = param_Boolean(false, 3, params); if (dokument.endsWith("_")) dokument = dokument + String.format("%d_%d", year, weekInYear) + ".odt"; return manipContent( 0, vorlage, dokument, new Job<File>() { public void perform(File content, Object[] params) throws Exception { File _content = new File(content.getParent(), "_content.xml"); content.renameTo(_content); for (int i = 0; i < databaseFilenames.length; i++) { databaseFilenames[i] = dbPath(databaseFilenames[i]); File database = new File(databaseFilenames[i]); if (!database.exists()) throw new Exception( String.format("Database '%s' missing", database.getPath())); } String parameters = parameters( databaseFilenames, year, weekInYear, dayInWeek); pipe(_content.getPath(), content.getPath(), new StringReader(parameters)); boolean keep = param_Boolean(false, 0, params); if (keep) { File destDir = _content.getParentFile().getParentFile(); copyFile(_content, new File(destDir, "_content.xml")); } _content.delete(); } }, keep) && piped; } private static boolean piped = true; public static boolean pipe(String inputFilename, String outputFilename, Reader params) throws Exception { piped = true; String className = "org.apache.xalan.processor.TransformerFactoryImpl"; // System.setProperty("javax.xml.transform.TransformerFactory", className); Class.forName(className); TransformerFactory tFactory = TransformerFactory.newInstance(); // Determine whether the TransformerFactory supports the use of SAXSource and SAXResult if (!tFactory.getFeature(SAXSource.FEATURE)) throw new Exception(String.format("TransformerFactory feature '%s' missing", SAXSource.FEATURE)); if (!tFactory.getFeature(SAXResult.FEATURE)) throw new Exception(String.format("TransformerFactory feature '%s' missing", SAXResult.FEATURE)); SAXTransformerFactory saxTFactory = ((SAXTransformerFactory) tFactory); String controlStyleSheet = applicationDataPath("Skripte/control.xsl"); String contentStyleSheet = applicationDataPath("Skripte/content.xsl"); TransformerHandler tHandler1 = saxTFactory.newTransformerHandler(new StreamSource(controlStyleSheet)); TransformerHandler tHandler2 = saxTFactory.newTransformerHandler(new StreamSource(contentStyleSheet)); tHandler2.getTransformer().setParameter("inputfile", inputFilename); tHandler2.getTransformer().setErrorListener(new ErrorListener() { @Override public void warning(TransformerException exception) throws TransformerException { Log.w(TAG, exception.getMessage()); } @Override public void fatalError(TransformerException exception) throws TransformerException { Log.e(TAG, exception.getMessage()); piped = false; } @Override public void error(TransformerException exception) throws TransformerException { Log.e(TAG, exception.getMessage()); piped = false; } }); tHandler1.setResult(new SAXResult(tHandler2)); XMLReader reader = XMLReaderFactory.createXMLReader(); reader.setContentHandler(tHandler1); reader.setProperty("http://xml.org/sax/properties/lexical-handler", tHandler1); Properties xmlProps = OutputPropertiesFactory.getDefaultMethodProperties("xml"); xmlProps.setProperty("indent", "no"); xmlProps.setProperty("standalone", "no"); Serializer serializer = SerializerFactory.getSerializer(xmlProps); OutputStream out = new FileOutputStream(outputFilename); serializer.setOutputStream(out); tHandler2.setResult(new SAXResult(serializer.asContentHandler())); reader.parse(new InputSource(params)); return piped; } public static String odtVorlagePath(String name) { return applicationDataPath("Vorlagen/" + name + ".odt"); } public static String odtDokumentPath(String name, int...weekDate) { if (isAvailable(1, weekDate)) name += String.format("_%d_%d", weekDate[1], weekDate[0]); return applicationDataPath("Dokumente/" + name + ".odt"); } public static void doIndirection(Element element, String attr, String tag, Job<Element> job, Object...params) { int no = toInt(0, element.getAttribute(attr)); if (no > 0) { NodeList nodeList = evaluateXPath(element.getOwnerDocument(), "//" + tag); if (nodeList.getLength() >= no) try { job.perform( (Element) nodeList.item(no - 1), params ); } catch (Exception e) { Log.e(TAG, e.getMessage()); } } } public static void performQueries(String controlFileName) throws Exception { final Context context = BerichtsheftActivity.getInstance(); File file = new File(controlFileName); Document doc = xmlDocument(file); NodeList nodeList = evaluateXPath(doc.getDocumentElement(), "*[@query]"); for (int i = 0; i < nodeList.getLength(); i++) { final Element element = (Element) nodeList.item(i); doIndirection(element, "query", "QUERY", new Job<Element>() { public void perform(Element el, Object[] parms) throws Exception { doIndirection(el, "dbinfo", "DBINFO", new Job<Element>() { public void perform(Element el, Object[] parms) throws Exception { NodeList nodeList = evaluateXPath(el, "dburl"); String url = nodeList.item(0).getTextContent(); String path = url.substring(url.lastIndexOf(":") + 1); Uri uri = fileUri(path, null); Element query = param(null, 0, parms); if (query != null) { ValList list = vlist(); list.add(query.getAttribute("statement")); for (int j = 1; j < element.getAttributes().getLength(); j++) { String param = element.getAttribute("param" + j); if (notNullOrEmpty(param)) list.add(param); } Cursor cursor = context.getContentResolver().rawQuery(uri, toStrings(list)); list = vlist(); traverse(cursor, new Job<Cursor>() { public void perform(Cursor c, Object[] parms) throws Exception { ValList list = param(null, 0, parms); list.add(c.getString(0)); } }, list); String text = join(NEWLINE, list.toArray()); element.setTextContent(text); element.setAttribute("query", "0"); } } }, objects(el)); } }); } xmlNodeToFile(doc, true, file); } }