001: /*
002: * Copyright (c) 2004-2006, Jean-François Brazeau. All rights reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions are met:
006: *
007: * 1. Redistributions of source code must retain the above copyright notice,
008: * this list of conditions and the following disclaimer.
009: *
010: * 2. Redistributions in binary form must reproduce the above copyright
011: * notice, this list of conditions and the following disclaimer in the
012: * documentation and/or other materials provided with the distribution.
013: *
014: * 3. The name of the author may not be used to endorse or promote products
015: * derived from this software without specific prior written permission.
016: *
017: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
018: * IMPLIEDWARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
019: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
020: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
021: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
022: * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
023: * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
024: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
025: * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
026: * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
027: */
028: package jfb.tools.activitymgr.report;
029:
030: import java.io.File;
031: import java.io.FileInputStream;
032: import java.io.FileOutputStream;
033: import java.io.IOException;
034: import java.io.PrintWriter;
035: import java.util.Properties;
036:
037: import jfb.tools.activitymgr.core.ModelMgr;
038: import jfb.tools.activitymgr.ui.util.CfgMgr;
039:
040: import org.apache.log4j.Logger;
041: import org.apache.log4j.PropertyConfigurator;
042: import org.apache.velocity.Template;
043: import org.apache.velocity.VelocityContext;
044: import org.apache.velocity.app.VelocityEngine;
045: import org.apache.velocity.runtime.log.SimpleLog4JLogSystem;
046:
047: /**
048: * Générateur de rapports.
049: *
050: * <p>Consulter le fichier de configuration <code>reports.properties</code>
051: * pour plus de détails sur la configuration des rapports.</p>
052: */
053: public class ReportMgr {
054:
055: /** Logger */
056: private static Logger log = Logger.getLogger(ReportMgr.class);
057:
058: /**
059: * Méthode principale.
060: * @param args argument de la méthode principale.
061: */
062: public static void main(String[] args) {
063: try {
064: // Initialisation des logs et chargement de la config
065: PropertyConfigurator.configure("cfg/log4j.properties");
066: CfgMgr.load();
067:
068: // Chargement du fichier de config
069: Properties reportProps = new Properties();
070: reportProps.load(new FileInputStream(
071: "cfg/reports.properties"));
072:
073: // Initialisation de la connexion à la base de données
074: String jdbcDriver = CfgMgr.get(CfgMgr.JDBC_DRIVER);
075: String jdbcUrl = CfgMgr.get(CfgMgr.JDBC_URL);
076: String jdbcUser = CfgMgr.get(CfgMgr.JDBC_USER);
077: String jdbcPassword = CfgMgr.get(CfgMgr.JDBC_PASSWORD);
078: ModelMgr.initDatabaseAccess(jdbcDriver, jdbcUrl, jdbcUser,
079: jdbcPassword);
080:
081: // Quels sont les identifiants des rapports à générer ?
082: String reportList = reportProps.getProperty("reports.list");
083: String[] reportIds = reportList.split(",");
084: // Itération sur les rapports
085: for (int i = 0; i < reportIds.length; i++) {
086: // Récupération de l'ID du rapport et de son implémentation
087: String reportId = reportIds[i].trim();
088: log.info("Processing report '" + reportId + "'");
089: if (!"".equals(reportId)) {
090: // Génération du fichier
091: build(reportId, reportProps);
092: }
093: }
094:
095: } catch (Throwable t) {
096: t.printStackTrace();
097: System.exit(-1);
098: }
099: }
100:
101: /**
102: * Lance la génération d'un rapport.
103: * @param reportId l'identifiant du rapport.
104: * @param props le dictionnaire de propritétés.
105: * @throws ReportException levé en cas d'incident inattendu lors de la
106: * génération du rapport.
107: * @throws IOException levé en cas d'incident I/O en écriture sur le fichier.
108: */
109: public static void build(String reportId, Properties props)
110: throws ReportException, IOException {
111: PropertiesHelper propsHelper = new PropertiesHelper(reportId,
112: props);
113: // Récupération du nom du template
114: String reportType = propsHelper.getProperty("type");
115: String reportTemplate = propsHelper.getProperty("template");
116: // Absence des 2 propriétés => erreur
117: if (reportType == null && reportTemplate == null)
118: throw new ReportException(
119: "A type or a template path must be specified for identifier '"
120: + reportId + "'", null);
121: // Si le type est spécifié, utilisation du répertoire par défaut
122: if (reportType != null)
123: reportTemplate = "templates/" + reportType + ".vm";
124: // Vérification du type de rapport
125: if (!new File(reportTemplate).exists())
126: throw new ReportException("Report template not found : '"
127: + reportTemplate + "'", null);
128:
129: // Récupération du nom de fichier de sortie
130: String outputFileName = propsHelper
131: .getProperty("outputFileName");
132: if (outputFileName == null)
133: throw new ReportException(
134: "An output file name must be specified for identifier '"
135: + reportId + "'", null);
136: PrintWriter out = openOutputFile(outputFileName);
137:
138: // Initialisation du contexte Velocity
139: VelocityContext context = new VelocityContext();
140: context.put("model", new ModelMgr());
141: context.put("dates", new DateHelper());
142: context.put("sums", new SumHelper());
143: context.put("fmt", new FormatHelper());
144: context.put("test", new TestHelper());
145: context.put("props", propsHelper);
146:
147: // Initialisation du moteur Velocity
148: VelocityEngine engine = new VelocityEngine();
149: // Désactivation du chargement dans le CLASSPATH
150: //engine.setProperty(VelocityEngine.RESOURCE_LOADER, "classpath");
151: //engine.setProperty(
152: // "classpath." + VelocityEngine.RESOURCE_LOADER + ".class",
153: // ClasspathResourceLoader.class.getName());
154: // Définition de la politique de gestion des traces (afin que les
155: // logs Velocity soient avec ceux de l'appli)
156: engine.setProperty(VelocityEngine.RUNTIME_LOG_LOGSYSTEM_CLASS,
157: SimpleLog4JLogSystem.class.getName());
158: engine.setProperty("runtime.log.logsystem.log4j.category",
159: ReportMgr.class.getName());
160: try {
161: // Initialisation
162: engine.init();
163: // Chargement du template
164: Template t = engine.getTemplate(reportTemplate);
165: // Merge
166: t.merge(context, out);
167: } catch (Exception e) {
168: log.error("Unexpected error", e);
169: throw new ReportException("Unexpected error", e);
170: }
171: // Fermeture du fichier généré
172: out.close();
173: }
174:
175: /**
176: * Ouvre en écriture le fichier de sortie du rapport.
177: * @param fileName le nom du fichier à ouvrir.
178: * @return le flux d'écriture.
179: * @throws ReportException levé en cas d'incident inattendu lors de la
180: * génération du rapport.
181: * @throws IOException levé en cas d'incident I/O en écriture sur le fichier.
182: */
183: private static PrintWriter openOutputFile(String fileName)
184: throws ReportException, IOException {
185: fileName = fileName.replace('\\', '/');
186: log.info(" opening file '" + fileName + "'");
187: int idx = fileName.lastIndexOf('/');
188: if (idx > 0) {
189: String dir = fileName.substring(0, idx);
190: File _dir = new File(dir);
191: if (!_dir.exists() && !_dir.mkdirs())
192: throw new IOException("Couldn't create directories ("
193: + dir + ")");
194:
195: }
196: FileOutputStream fout = new FileOutputStream(fileName);
197: PrintWriter out = new PrintWriter(fout);
198: return out;
199: }
200:
201: }
|