package org.objectstyle.wolips.eogenerator.core.runner; import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.util.Calendar; import java.util.Date; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.runtime.log.LogSystem; import org.apache.velocity.tools.generic.ListTool; import org.apache.velocity.tools.generic.SetTool; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.OperationCanceledException; import org.objectstyle.wolips.eogenerator.core.Activator; import org.objectstyle.wolips.eogenerator.core.model.EOGeneratorModel; import org.objectstyle.wolips.eogenerator.core.model.EOGeneratorModel.Define; import org.objectstyle.wolips.eogenerator.core.model.EOModelReference; import org.objectstyle.wolips.eogenerator.core.model.IEOGeneratorRunner; import org.objectstyle.wolips.eomodeler.core.model.EOEntity; import org.objectstyle.wolips.eomodeler.core.model.EOModel; import org.objectstyle.wolips.eomodeler.core.model.EOModelException; import org.objectstyle.wolips.eomodeler.core.model.EOModelGroup; import org.objectstyle.wolips.eomodeler.core.model.EOModelRenderContext; import org.objectstyle.wolips.eomodeler.core.model.EOModelVerificationFailure; import org.objectstyle.wolips.eomodeler.core.model.IEOModelGroupFactory; import org.objectstyle.wolips.eomodeler.core.utils.BooleanUtils; import org.objectstyle.wolips.thirdparty.velocity.WOLipsVelocityUtils; import org.objectstyle.wolips.thirdparty.velocity.resourceloader.ResourceLoader; import org.osgi.framework.Bundle; public class VelocityEOGeneratorRunner implements IEOGeneratorRunner { @SuppressWarnings("deprecation") public static class ConsoleLogger implements LogSystem { public void init(RuntimeServices runtimeservices) throws Exception { // DO NOTHING } public void logVelocityMessage(int i, String s) { System.out.println("ConsoleLogger.logVelocityMessage: " + i + ", " + s); } } private boolean _insideEclipse; private boolean _useStdout = false; public VelocityEOGeneratorRunner() { this(true); } public VelocityEOGeneratorRunner(boolean insideEclipse) { _insideEclipse = insideEclipse; } public boolean generate(EOGeneratorModel eogeneratorModel, StringBuffer results, IProgressMonitor monitor) throws Exception { return generate(eogeneratorModel, results, null, null, ResourceLoader.class, monitor); } public boolean generate(EOGeneratorModel eogeneratorModel, StringBuffer results, EOModelGroup preloadedModelGroup, IProgressMonitor monitor) throws Exception { return generate(eogeneratorModel, results, preloadedModelGroup, null, ResourceLoader.class, monitor); } public boolean generate(EOGeneratorModel eogeneratorModel, StringBuffer results, EOModelGroup preloadedModelGroup, List<String> entityList, Class resourceLoaderClass, IProgressMonitor monitor) throws Exception { boolean showResults = false; String superclassTemplateName = eogeneratorModel.getJavaTemplate(); String subclassTemplateName = eogeneratorModel.getSubclassJavaTemplate(); boolean eogeneratorJava14 = eogeneratorModel.isJava14(); if (eogeneratorJava14) { if (superclassTemplateName == null || superclassTemplateName.length() == 0) { superclassTemplateName = "_Entity14.java"; } if (subclassTemplateName == null || subclassTemplateName.length() == 0) { subclassTemplateName = "Entity14.java"; } } else { if (superclassTemplateName == null || superclassTemplateName.length() == 0) { superclassTemplateName = "_Entity.java"; } if (subclassTemplateName == null || subclassTemplateName.length() == 0) { subclassTemplateName = "Entity.java"; } } Bundle templateBundle = _insideEclipse ? Activator.getDefault().getBundle() : null; VelocityEngine velocityEngine = WOLipsVelocityUtils.createVelocityEngine("EOGenerator", templateBundle, eogeneratorModel.getTemplateDir(), eogeneratorModel.getProjectPath(), _insideEclipse, resourceLoaderClass); List<EOModel> models = new LinkedList<EOModel>(); EOModelRenderContext renderContext = new EOModelRenderContext(); try { String prefix = eogeneratorModel.getPrefix(); if (prefix != null) { renderContext.setPrefix(prefix); } renderContext.setSuperclassPackage(eogeneratorModel.getSuperclassPackage()); String eogenericRecordClassName = eogeneratorModel.getDefineValueNamed("EOGenericRecord"); if (eogenericRecordClassName != null) { renderContext.setEOGenericRecordClassName(eogenericRecordClassName); } renderContext.setJavaClientCommon(eogeneratorModel.isJavaClientCommon() != null && eogeneratorModel.isJavaClientCommon().booleanValue()); renderContext.setJavaClient(eogeneratorModel.isJavaClient() != null && eogeneratorModel.isJavaClient().booleanValue()); EOModelRenderContext.setRenderContext(renderContext); EOModelGroup modelGroup; if (preloadedModelGroup == null) { modelGroup = new EOModelGroup(); Set<EOModelVerificationFailure> failures = new HashSet<EOModelVerificationFailure>(); if (BooleanUtils.isTrue(eogeneratorModel.isLoadModelGroup())) { for (EOModelReference eomodelReference : eogeneratorModel.getModels()) { EOModelGroup generatingModelGroup = new EOModelGroup(); URL modelURL = getModelURL(eogeneratorModel, eomodelReference); IEOModelGroupFactory.Utility.loadModelGroup(modelURL, generatingModelGroup, failures, true, modelURL, monitor); if (monitor.isCanceled()) { throw new OperationCanceledException("EOGenerator canceled."); } EOModel generatingModel = generatingModelGroup.getEditingModel(); models.add(generatingModel); for (EOModel model : generatingModelGroup.getModels()) { if (!modelGroup.containsModelNamed(model.getName())) { modelGroup.addModel(model); } } } } else { loadModels(eogeneratorModel, modelGroup, eogeneratorModel.getModels(), models, monitor); loadModels(eogeneratorModel, modelGroup, eogeneratorModel.getRefModels(), new LinkedList<EOModel>(), monitor); modelGroup.resolve(failures); modelGroup.verify(failures); } for (EOModelVerificationFailure failure : failures) { if (!failure.isWarning()) { results.append("Error: " + failure.getMessage() + "\n"); showResults = true; } } } else { modelGroup = preloadedModelGroup; for (EOModelReference modelRef : eogeneratorModel.getModels()) { String modelName = modelRef.getName(); EOModel model = modelGroup.getModelNamed(modelName); if (model == null) { throw new RuntimeException("There was no model named '" + modelName + "' in this model group."); } models.add(model); } } File superclassDestination = new File(eogeneratorModel.getDestination()); if (!superclassDestination.isAbsolute()) { IPath projectPath = eogeneratorModel.getProjectPath(); if (projectPath != null) { superclassDestination = new File(projectPath.toFile(), eogeneratorModel.getDestination()); } } if (!superclassDestination.exists()) { if (!superclassDestination.mkdirs()) { throw new IOException("Failed to create destination '" + superclassDestination + "'."); } } File subclassDestination = new File(eogeneratorModel.getSubclassDestination()); if (!subclassDestination.isAbsolute()) { IPath projectPath = eogeneratorModel.getProjectPath(); if (projectPath != null) { subclassDestination = new File(projectPath.toFile(), eogeneratorModel.getSubclassDestination()); } } if (!subclassDestination.exists()) { if (!subclassDestination.mkdirs()) { throw new IOException("Failed to create subclass destination '" + subclassDestination + "'."); } } // String filePathTemplate = eogeneratorModel.getFilenameTemplate(); // if (filePathTemplate == null || filePathTemplate.trim().length() // == 0) { // } String extension = eogeneratorModel.getExtension(); Set<String> entitySet = new HashSet<String>(); if (entityList != null) { entitySet.addAll(entityList); } Date date = new Date(); for (EOModel model : models) { if (monitor.isCanceled()) { throw new OperationCanceledException("EOGenerator canceled."); } // System.out.println("Generating " + model.getName() + " ..."); for (EOEntity entity : model.getEntities()) { VelocityContext context = new VelocityContext(); context.put("eogeneratorModel", eogeneratorModel); context.put("date", date); context.put("calendar", Calendar.getInstance()); for (Define define : eogeneratorModel.getDefines()) { context.put(define.getName(), define.getValue()); } context.put("list", new ListTool()); context.put("set", new SetTool()); //context.put("sorter", new SortTool()); context.put("model", model); if (entitySet.size() != 0 && !entitySet.contains(entity.getName())) { continue; } if (monitor.isCanceled()) { throw new OperationCanceledException("EOGenerator canceled."); } // System.out.println("Generating " + model.getName() + "." // + entity.getName() + " ..."); context.put("entity", entity); String classNameWithPackage = renderContext.getClassNameForEntity(entity); boolean eogenericRecord = classNameWithPackage == null || (classNameWithPackage.endsWith("GenericRecord") && !entity.getName().endsWith("GenericRecord")); if (entity.isGenerateSource() && !eogenericRecord) { String prefixClassNameWithPackage = entity.getPrefixClassName(); context.put("className", classNameWithPackage); context.put("prefixClassName", prefixClassNameWithPackage); context.put("packageName", entity.getPackageName()); context.put("classNameWithoutPackage", entity.getClassNameWithoutPackage()); context.put("prefixClassNameWithoutPackage", entity.getPrefixClassNameWithoutPackage()); if (_useStdout) { WOLipsVelocityUtils.writeTemplate(velocityEngine, context, superclassTemplateName, System.out); WOLipsVelocityUtils.writeTemplate(velocityEngine, context, subclassTemplateName, System.out); } else { String superclassFileTemplate; // StringWriter superclassFilePathWriter = new // StringWriter(); // velocityEngine.evaluate(context, // superclassFilePathWriter, "LOG", // superclassFileTemplate); if (BooleanUtils.isFalse(eogeneratorModel.isPackageDirs())) { superclassFileTemplate = entity.getPrefixClassNameWithoutPackage(); } else { superclassFileTemplate = prefixClassNameWithPackage.toString().replace('.', '/'); } String superclassFilePath = superclassFileTemplate + "." + extension; File superclassFile = new File(superclassDestination, superclassFilePath); File superclassFolder = superclassFile.getParentFile(); if (!superclassFolder.exists()) { if (!superclassFolder.mkdirs()) { throw new IOException("Unable to make superclass folder '" + superclassFolder + "'."); } } WOLipsVelocityUtils.writeTemplate(velocityEngine, context, superclassTemplateName, superclassFile); String subclassFileTemplate; // StringWriter subclassFilePathWriter = new // StringWriter(); // velocityEngine.evaluate(context, // subclassFilePathWriter, "LOG", subclassFileTemplate); if (BooleanUtils.isFalse(eogeneratorModel.isPackageDirs())) { subclassFileTemplate = entity.getClassNameWithoutPackage(); } else { subclassFileTemplate = classNameWithPackage.toString().replace('.', '/'); } String subclassFilePath = subclassFileTemplate + "." + extension; File subclassFile = new File(subclassDestination, subclassFilePath); File subclassFolder = subclassFile.getParentFile(); if (!subclassFolder.exists()) { if (!subclassFolder.mkdirs()) { throw new IOException("Unable to make subclass folder '" + superclassFolder + "'."); } } if (!subclassFile.exists()) { WOLipsVelocityUtils.writeTemplate(velocityEngine, context, subclassTemplateName, subclassFile); } } } } } } finally { EOModelRenderContext.clearRenderContext(); } return showResults; } public URL getModelURL(EOGeneratorModel eogeneratorModel, EOModelReference modelRef) throws MalformedURLException { String modelPath = modelRef.getPath((IPath) null); File modelFile = new File(modelPath); if (!modelFile.isAbsolute()) { IPath projectPath = eogeneratorModel.getProjectPath(); if (projectPath != null) { modelFile = new File(projectPath.toFile(), modelPath); } } return modelFile.toURL(); } public void loadModels(EOGeneratorModel eogeneratorModel, EOModelGroup modelGroup, List<EOModelReference> modelReferences, List<EOModel> loadedModels, IProgressMonitor monitor) throws MalformedURLException, IOException, EOModelException { for (EOModelReference modelRef : modelReferences) { if (monitor.isCanceled()) { throw new OperationCanceledException("EOGenerator canceled."); } URL modelURL = getModelURL(eogeneratorModel, modelRef); EOModel model = modelGroup.loadModelFromURL(modelURL); loadedModels.add(model); } } public void setUseStdout(boolean useStdout) { _useStdout = useStdout; } }