/**
* Speedo: an implementation of JDO compliant personality on top of JORM generic
* I/O sub-system.
* Copyright (C) 2001-2004 France Telecom R&D
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
*
* Contact: speedo@objectweb.org
*
* Authors: S.Chassande-Barrioz.
*
*/
package org.objectweb.speedo.generation.generator;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.app.VelocityEngine;
import org.objectweb.speedo.api.SpeedoException;
import org.objectweb.speedo.api.SpeedoProperties;
import org.objectweb.speedo.generation.generator.fields.FieldsGenerator;
import org.objectweb.speedo.generation.generator.home.HomeGenerator;
import org.objectweb.speedo.generation.generator.lib.AbstractVelocityGenerator;
import org.objectweb.speedo.generation.generator.objectid.ObjectIdGenerator;
import org.objectweb.speedo.generation.lib.AbstractGeneratorComponent;
import org.objectweb.speedo.generation.lib.NamingRules;
import org.objectweb.speedo.lib.Personality;
import org.objectweb.speedo.metadata.SpeedoClass;
import org.objectweb.speedo.metadata.SpeedoPackage;
import org.objectweb.speedo.metadata.SpeedoXMLDescriptor;
import org.objectweb.util.monolog.api.BasicLevel;
import org.objectweb.util.monolog.api.Logger;
import org.objectweb.util.monolog.wrapper.velocity.VelocityLogger;
import java.io.File;
import java.util.Collection;
import java.util.Iterator;
/**
* This class generates files "po", "manager" and "fields" for persistence capable classes.
* @author S. Chassande-Barrioz
*/
public abstract class AbstractGenerator extends AbstractGeneratorComponent {
public final static String LOGGER_NAME
= SpeedoProperties.LOGGER_NAME + ".generation.generator";
private static final String CLASS_RESOURCE_LOADER_DESCRIPTION_PROP
= "class.resource.loader.description";
private static final String CLASS_RESOURCE_LOADER_DESCRIPTION_VALUE
= "Velocity Classpath Resource Loader";
private static final String CLASS_RESOURCE_LOADER_CLASS_PROP
= "class.resource.loader.class";
private static final String CLASS_RESOURCE_LOADER_CLASS_VALUE
= "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader";
int generatedFiles;
/**
* Provides the list of generators to be used in the code generation for
* a particular persistent class.
*
* @return The list as an array of generators.
*/
protected abstract AbstractVelocityGenerator[] getGenerators();
public AbstractGenerator(Personality p) {
super(p);
}
// IMPLEMENTATION OF THE GeneratorComponent INTERFACE //
//----------------------------------------------------//
public boolean init() {
logger = scp.loggerFactory.getLogger(LOGGER_NAME);
generatedFiles = 0;
return !scp.getXmldescriptor().isEmpty();
}
public String getTitle() {
return "Generating Speedo files...";
}
public String getSummary() {
return generatedFiles + " generates files";
}
/**
* Generation all files <className>, and <className>Fields.
* If a previous task on a class has failed, the methods doesn't create
* files for this class.
*
* @exception SpeedoException if there is a problem during writing
* the new files and the boolean failsonerror is set on true.
*/
public void process() throws SpeedoException {
if (scp.getXmldescriptor().isEmpty())
return;
//separator for file names
char fs = File.separatorChar;
//for each package
VelocityLogger vl = new VelocityLogger(logger);
VelocityEngine ve = new VelocityEngine();
ve.setProperty(Velocity.RUNTIME_LOG_LOGSYSTEM, vl);
AbstractVelocityGenerator[] vgs = getGenerators();
Logger[] loggers = new Logger[vgs.length];
String strlibs = "";
boolean first = true;
for (int i = 0; i < vgs.length; i++) {
vgs[i].setSpeedoCompilerParameter(scp);
vgs[i].init();
Collection col = vgs[i].getExternalsTemplate();
if (col != null && col.size() > 0) {
for (Iterator it = col.iterator(); it.hasNext();) {
strlibs += (first ? "" : ",") + it.next();
first = false;
}
}
vgs[i].setVelocityEngine(ve);
loggers[i] = scp.loggerFactory.getLogger(
vgs[i].getLogger().getName() + ".velocity");
}
ve.setProperty(Velocity.RESOURCE_LOADER, "class");
ve.setProperty(CLASS_RESOURCE_LOADER_DESCRIPTION_PROP,
CLASS_RESOURCE_LOADER_DESCRIPTION_VALUE);
ve.setProperty(CLASS_RESOURCE_LOADER_CLASS_PROP,
CLASS_RESOURCE_LOADER_CLASS_VALUE);
ve.setProperty(Velocity.VM_LIBRARY, strlibs);
try {
ve.init();
} catch (Exception e) {
throw new SpeedoException(
"Impossible to initialize the VelocityEngine", e);
}
for (Iterator itDesc = scp.getXmldescriptor().values().iterator(); itDesc.hasNext();) {
SpeedoXMLDescriptor desc = (SpeedoXMLDescriptor) itDesc.next();
for (Iterator itPack = desc.packages.values().iterator(); itPack.hasNext();) {
SpeedoPackage sp = (SpeedoPackage) itPack.next();
//base directory for new files
String baseDir = scp.output + fs + sp.name.replace('.', fs) + fs;
for (Iterator itclass = sp.classes.values().iterator(); itclass.hasNext();) {
SpeedoClass sClass = (SpeedoClass) itclass.next();
//asm has not failed on this class
if (sClass.enhancementFailed())
continue;
String[] filenames = {
baseDir + NamingRules.fieldsName(sClass.name) + ".java",
baseDir + NamingRules.homeName(sClass.name) + ".class",
baseDir + sClass.identity.objectidClass + ".java"};
try {
//fields
vl.setLog(loggers[0]);
vgs[0].generate(sClass, filenames[0]);
generatedFiles ++;
//home
vl.setLog(loggers[1]);
vgs[1].generate(sClass, filenames[1]);
generatedFiles ++;
//oid
if (sClass.identity.oidClassAutoCalculated) {
vl.setLog(loggers[2]);
vgs[2].generate(sClass, filenames[2]);
generatedFiles ++;
logger.log(BasicLevel.WARN,
"No object id class defined for the class '"
+ sClass.getFQName()
+ "': use the generated class: '"
+ NamingRules.generatedObjectIdName(sClass.getFQName()) + "'");
}
logger.log(BasicLevel.INFO, "Classes generated for "
+ sClass.getFQName());
} catch (SpeedoException e) {
logger.log(BasicLevel.ERROR,
"ERROR during the speedo generation of files "
+ filenames[0] + ", " + filenames[1] + " or "
+ filenames[2], e);
throw e;
}
}
}
}
}
}