Index: lutingenerator-demo/src/main/java/org/codelutin/generator/demo/controller/ChooseGeneratorController.java diff -u /dev/null lutingenerator-demo/src/main/java/org/codelutin/generator/demo/controller/ChooseGeneratorController.java:1.1 --- /dev/null Wed Apr 30 12:31:15 2008 +++ lutingenerator-demo/src/main/java/org/codelutin/generator/demo/controller/ChooseGeneratorController.java Wed Apr 30 12:31:08 2008 @@ -0,0 +1,107 @@ +package org.codelutin.generator.demo.controller; + +import java.io.File; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.codelutin.generator.Generator; +import org.codelutin.generator.demo.files.FileHandler; +import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.servlet.mvc.Controller; + +/** + * Ce controller enregistre le générator choisi. C'est la fin de la première étape. + * Ensuite, on ira sur {@link ListModelsController} + * + * @author thimel + */ +public class ChooseGeneratorController implements Controller { + + protected final Log log = LogFactory.getLog(getClass()); + + public ModelAndView handleRequest(HttpServletRequest request, + HttpServletResponse response) throws Exception { + + if (log.isDebugEnabled()) { + log.debug("chooseGenerator called"); + } + + String id = request.getParameter("id"); + if (id == null) { + if (log.isDebugEnabled()) { + log.debug("no ID specified"); + } + return sendError(null); + } + + FileHandler handler = FileHandler.getInstance(); + String isolator; + String key; + if (id.startsWith("static-")) { + isolator = "_statics"; + key = id.substring(7); + } else { + isolator = request.getSession().getId(); + if (id.startsWith("user-")) { + key = id.substring(5); + } else { + key = id; + } + } + if (log.isDebugEnabled()) { + log.debug("isolator: " + isolator); + log.debug("key: " + key); + } + + if (key.startsWith("class-")) { + String className = key.substring(6); + try { + if (log.isDebugEnabled()) { + log.debug("Trying to load class: " + className); + } + Class clazz = Class.forName(className); + if (log.isDebugEnabled()) { + log.debug("Class loaded: " + clazz.getName()); + } + if (!Generator.class.isAssignableFrom(clazz)) { + return sendError("errors.generatorClassNotCompatible"); + } + try { + clazz.getConstructor((Class[])null); + } catch (NoSuchMethodException nsme) { + return sendError("errors.generatorNeedsDefaulConstructor"); + } + } catch (Exception eee) { + return sendError("errors.generatorClassNotFound"); + } + } else { + File f = handler.getGenerator(isolator, key); + if (log.isDebugEnabled()) { + log.debug("model: " + f.getAbsolutePath()); + } + if (!f.exists()) { + return sendError("errors.generatorNotFound"); + } + } + + HttpSession session = request.getSession(); + session.setAttribute("generatorIsolator", isolator); + session.setAttribute("generatorKey", key); + + return new ModelAndView("forward:/listModels.htm"); + } + + private ModelAndView sendError(String error) { + if (error != null) { + String[] errors = {error}; + return new ModelAndView("forward:/listGenerators.htm", "errors", errors); + } else { + return new ModelAndView("forward:/listGenerators.htm"); + } + } + +} //ChooseGeneratorController Index: lutingenerator-demo/src/main/java/org/codelutin/generator/demo/controller/ChooseModelController.java diff -u /dev/null lutingenerator-demo/src/main/java/org/codelutin/generator/demo/controller/ChooseModelController.java:1.1 --- /dev/null Wed Apr 30 12:31:16 2008 +++ lutingenerator-demo/src/main/java/org/codelutin/generator/demo/controller/ChooseModelController.java Wed Apr 30 12:31:08 2008 @@ -0,0 +1,74 @@ +package org.codelutin.generator.demo.controller; + +import java.io.File; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.codelutin.generator.demo.files.FileHandler; +import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.servlet.mvc.Controller; + +/** + * Ce controller enregistre le choix du modèle. C'est la fin de la deuxième étape. + * Ensuite, on ira sur {@link GenerateController} + * + * @author thimel + */ +public class ChooseModelController implements Controller { + + protected final Log log = LogFactory.getLog(getClass()); + + public ModelAndView handleRequest(HttpServletRequest request, + HttpServletResponse response) throws Exception { + if (log.isDebugEnabled()) { + log.debug("chooseModel called"); + } + + String id = request.getParameter("id"); + if (id == null) { + if (log.isDebugEnabled()) { + log.debug("no ID specified"); + } + return new ModelAndView("redirect:/listModels.htm"); + } + + FileHandler handler = FileHandler.getInstance(); + String isolator; + String key; + if (id.startsWith("static-")) { + isolator = "_statics"; + key = id.substring(7); + } else { + isolator = request.getSession().getId(); + if (id.startsWith("user-")) { + key = id.substring(5); + } else { + key = id; + } + } + if (log.isDebugEnabled()) { + log.debug("isolator: " + isolator); + log.debug("key: " + key); + } + + File f = handler.getModel(isolator, key); + if (log.isDebugEnabled()) { + log.debug("model: " + f.getAbsolutePath()); + } + if (!f.exists()) { + String[] errors = {"errors.modelNotFound"}; + return new ModelAndView("forward:/listModels.htm", "errors", errors); + } + + HttpSession session = request.getSession(); + session.setAttribute("modelIsolator", isolator); + session.setAttribute("modelKey", key); + + return new ModelAndView("forward:/generate.htm"); + } + +} //ChooseModelController Index: lutingenerator-demo/src/main/java/org/codelutin/generator/demo/controller/FileUploadController.java diff -u /dev/null lutingenerator-demo/src/main/java/org/codelutin/generator/demo/controller/FileUploadController.java:1.1 --- /dev/null Wed Apr 30 12:31:16 2008 +++ lutingenerator-demo/src/main/java/org/codelutin/generator/demo/controller/FileUploadController.java Wed Apr 30 12:31:08 2008 @@ -0,0 +1,128 @@ +package org.codelutin.generator.demo.controller; + +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.codelutin.generator.demo.entities.FileUploadBean; +import org.codelutin.generator.demo.files.FileHandler; +import org.codelutin.generator.demo.files.FileHandlerException; +import org.codelutin.util.FileUtil; +import org.codelutin.util.ZipUtil; +import org.springframework.validation.BindException; +import org.springframework.web.bind.ServletRequestDataBinder; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.support.ByteArrayMultipartFileEditor; +import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.servlet.mvc.SimpleFormController; + +public class FileUploadController extends SimpleFormController { + + protected final Log log = LogFactory.getLog(getClass()); + + protected ModelAndView onSubmit( + HttpServletRequest request, + HttpServletResponse response, + Object command, + BindException errors) throws ServletException, IOException { + + // cast the bean + FileUploadBean bean = (FileUploadBean) command; + +// let's see if there's content there + MultipartFile file = bean.getFile(); + log.info("File name: " + file.getName()); + log.info("File has: " + file.getSize() + " bytes"); + log.info("File was: " + file.getOriginalFilename()); + log.info("File content type: " + file.getContentType()); + log.info("Type: " + bean.getType()); + + String extension = FileUtil.extension(file.getOriginalFilename(), null); + + String isolatorKey = request.getSession().getId(); + + File tmpFile = File.createTempFile(bean.getType() + "Upload", "." + extension); + file.transferTo(tmpFile); + + try { + if ("model".equals(bean.getType())) { + addModel(isolatorKey, tmpFile, file.getOriginalFilename(), extension); + } else { + FileHandler fh = FileHandler.getInstance(); + fh.addGenerator(isolatorKey, file.getOriginalFilename(), tmpFile); + } + } catch (FileHandlerException fhe) { + log.error(fhe); + } + if ("model".equals(bean.getType())) { + return new ModelAndView("forward:/listModels.htm"); + } else { + return new ModelAndView("forward:/listGenerators.htm"); + } + } + + private static final int BUFFER_SIZE = 8 * 1024; + + protected void addModel(String isolatorKey, File file, String originalFilename, String extension) throws FileHandlerException, IOException { + if (log.isDebugEnabled()) { + log.debug("Attempt to add a new model from: " + originalFilename); + } + FileHandler fh = FileHandler.getInstance(); + File target = file; + if ("zargo".equals(extension) || "zuml".equals(extension) || "zip".equals(extension)) { + if (log.isDebugEnabled()) { + log.debug("\tFile needs to be extracted"); + } + ZipInputStream in = new ZipInputStream(new FileInputStream(file)); + ZipEntry entry; + while ((entry = in.getNextEntry()) != null) { + String name = ZipUtil.convertToLocalEntryName(entry.getName()); + if (name.endsWith(".xmi")) { + if (log.isDebugEnabled()) { + log.debug("\tModel found: " + name); + } + target = File.createTempFile("zipExtract", name); + if (log.isDebugEnabled()) { + log.debug("\tExtracting to: " + target.getAbsolutePath()); + } + originalFilename = name; + OutputStream out = new BufferedOutputStream(new FileOutputStream(target)); + byte[] buffer = new byte[BUFFER_SIZE]; + int len; + while ((len = in.read(buffer, 0, BUFFER_SIZE)) != -1) { + out.write(buffer, 0, len); + } + out.close(); + } + } + in.close(); + //Zip file must be deleted + file.delete(); + } + if (log.isDebugEnabled()) { + log.debug("\tAdding new model: " + target.getAbsolutePath() + " as " + originalFilename); + } + fh.addModel(isolatorKey, originalFilename, target); + } + + protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) + throws ServletException { + // to actually be able to convert Multipart instance to byte[] + // we have to register a custom editor + binder.registerCustomEditor(byte[].class, new ByteArrayMultipartFileEditor()); + // now Spring knows how to handle multipart object and convert them + } + +} \ No newline at end of file Index: lutingenerator-demo/src/main/java/org/codelutin/generator/demo/controller/GenerateController.java diff -u /dev/null lutingenerator-demo/src/main/java/org/codelutin/generator/demo/controller/GenerateController.java:1.1 --- /dev/null Wed Apr 30 12:31:21 2008 +++ lutingenerator-demo/src/main/java/org/codelutin/generator/demo/controller/GenerateController.java Wed Apr 30 12:31:08 2008 @@ -0,0 +1,166 @@ +package org.codelutin.generator.demo.controller; + +import static org.codelutin.generator.demo.LutinGenDemoProperties.getProperties; + +import java.io.File; +import java.io.FileFilter; +import java.io.IOException; +import java.net.URL; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.codelutin.generator.Generator; +import org.codelutin.generator.ObjectModelGenerator; +import org.codelutin.generator.StateModelGenerator; +import org.codelutin.generator.demo.files.FileHandler; +import org.codelutin.util.FileUtil; +import org.codelutin.util.Resource; +import org.springframework.core.io.UrlResource; +import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.servlet.mvc.Controller; + +/** + * Ce controller prend le générateur et le modèle choisi. Si besoin, il applique + * les transformations XSL puis excécute la génération. + * + * @author thimel + */ +public class GenerateController implements Controller { + + public static final String GEN_DIR_NAME = getProperties().getProperty("GEN_DIR_NAME", "/tmp/lutingen-demo-files"); + public static final File GEN_DIR; + static { + GEN_DIR = new File(GEN_DIR_NAME); + if (!GEN_DIR.exists()) { + GEN_DIR.mkdirs(); + } + } + + protected final Log log = LogFactory.getLog(getClass()); + + public ModelAndView handleRequest(HttpServletRequest request, + HttpServletResponse response) throws Exception { + Map args = new HashMap(); + + HttpSession session = request.getSession(); + + String isolator = (String)session.getAttribute("modelIsolator"); + String key = (String)session.getAttribute("modelKey"); + File model = FileHandler.getInstance().getModel(isolator, key); + + String className = ObjectModelGenerator.class.getName(); //default + String tplKey = (String)session.getAttribute("generatorKey"); + if (tplKey.startsWith("class-")) { + className = tplKey.substring(6); + } + + if (log.isDebugEnabled()) { + log.debug("Trying to load class: " + className); + } + Class clazz = Class.forName(className); + Generator generator = (Generator)clazz.newInstance(); + + boolean generateForObjectModel = true; + boolean generateForStateModel = true; + + if (!ObjectModelGenerator.class.isAssignableFrom(clazz)) { + generateForObjectModel = false; + } + if (!StateModelGenerator.class.isAssignableFrom(clazz)) { + generateForStateModel = false; + } + + String suffix = "" + System.currentTimeMillis(); + File destDir = new File(GEN_DIR, getPrefix(session.getId()) + suffix); + destDir.mkdir(); + if (log.isDebugEnabled()) { + log.debug("Output folder ready: " + destDir.getAbsolutePath()); + log.debug("\texists: " + destDir.exists()); + log.debug("\tisDirectory: " + destDir.isDirectory()); + } + if (generateForObjectModel) { + File output = applyXSL(model, "objectmodel", destDir.getName()); + args.put("objectmodel", FileUtil.readAsString(output)); + generator.generate(output, destDir); + } + if (generateForStateModel) { + File output = applyXSL(model, "statemodel", destDir.getName()); + args.put("statemodel", FileUtil.readAsString(output)); + generator.generate(output, destDir); + } + + args.put("id", suffix); + List files = FileUtil.getFilteredElements(destDir, ALL_FILE_FILTER, true); + args.put("files", files); + args.put("dirPath", destDir.getAbsolutePath() + File.separator); + if (log.isDebugEnabled()) { + log.debug("Generation done. " + files.size() + " files/directories generated."); +// for (File file : files) { +// if (!file.isDirectory()) { +// log.debug("\t" + file.getCanonicalPath()); +// } +// } + } + + return new ModelAndView("generationResult", args); + } + + static private FileFilter ALL_FILE_FILTER = new FileFilter() { + public boolean accept(File pathname) { + return true; + } + }; + + public static String getPrefix(String isolator) { + return "model-" + isolator + "-"; + } + + private File applyXSL(File model, String type, String path) throws IOException, TransformerException { + TransformerFactory factory = TransformerFactory.newInstance(); + + URL url; + if ("objectmodel".equals(type)) { + url = Resource.getURL("xmi1.2ToObjectModel.xsl"); + } else if("statemodel".equals(type)) { + url = Resource.getURL("xmi1.2ToStateModel.xsl"); + } else { + //Default + url = Resource.getURL("xmi1.2ToObjectModel.xsl"); + } + if (log.isInfoEnabled()) { + log.info("xsl: " + url.getPath()); + } + StreamSource source = new StreamSource(new UrlResource(url).getInputStream()); + + File output = new File(GEN_DIR, path + "." + type); + + if (log.isDebugEnabled()) { + log.debug("Ready to apply " + type + " XSL"); + log.debug("\tSource: " + model.getAbsolutePath()); + log.debug("\tOutput: " + output.getAbsolutePath()); + } + if (!output.exists()) { + output.createNewFile(); + } + Transformer tranformer = factory.newTransformer(source); + tranformer.transform(new StreamSource(model), new StreamResult(output)); + + if (log.isDebugEnabled()) { + log.debug(type + " XSLT done"); + } + return output; + } + +} //GenerateController Index: lutingenerator-demo/src/main/java/org/codelutin/generator/demo/controller/ListGeneratorsController.java diff -u /dev/null lutingenerator-demo/src/main/java/org/codelutin/generator/demo/controller/ListGeneratorsController.java:1.1 --- /dev/null Wed Apr 30 12:31:21 2008 +++ lutingenerator-demo/src/main/java/org/codelutin/generator/demo/controller/ListGeneratorsController.java Wed Apr 30 12:31:08 2008 @@ -0,0 +1,56 @@ +package org.codelutin.generator.demo.controller; + +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.codelutin.generator.demo.entities.GeneratorMgr; +import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.servlet.mvc.Controller; + +/** + * Ce controller liste les générators disponibles. C'est la première étape. + * Ensuite, on ira sur {@link ChooseGeneratorController} + * + * @author thimel + */ +public class ListGeneratorsController implements Controller { + + protected final Log log = LogFactory.getLog(getClass()); + + private GeneratorMgr generatorMgr; + + public GeneratorMgr getGeneratorMgr() { + return generatorMgr; + } + + public void setGeneratorMgr(GeneratorMgr templateMgr) { + this.generatorMgr = templateMgr; + } + + public ModelAndView handleRequest(HttpServletRequest request, + HttpServletResponse response) throws Exception { + if (log.isDebugEnabled()) { + log.debug("listGenerators called"); + } + + HttpSession session = request.getSession(); + session.removeAttribute("generatorIsolator"); + session.removeAttribute("generatorKey"); + //On est à la première étape alors on vide tous les paramètres + session.removeAttribute("modelIsolator"); + session.removeAttribute("modelKey"); + + Map args = new HashMap(2); + args.put("staticGenerators", generatorMgr.getStaticGenerators()); + args.put("userGenerators", generatorMgr.getUserGenerators()); + + return new ModelAndView("listGenerators", args); + } + +} //ListGeneratorsController Index: lutingenerator-demo/src/main/java/org/codelutin/generator/demo/controller/ListModelsController.java diff -u /dev/null lutingenerator-demo/src/main/java/org/codelutin/generator/demo/controller/ListModelsController.java:1.1 --- /dev/null Wed Apr 30 12:31:25 2008 +++ lutingenerator-demo/src/main/java/org/codelutin/generator/demo/controller/ListModelsController.java Wed Apr 30 12:31:08 2008 @@ -0,0 +1,53 @@ +package org.codelutin.generator.demo.controller; + +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.codelutin.generator.demo.entities.ModelMgr; +import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.servlet.mvc.Controller; + +/** + * Ce controller liste les modèles disponibles. C'est la deuxième étape. + * Ensuite, on ira sur {@link ChooseModelController} + * + * @author thimel + */ +public class ListModelsController implements Controller { + + protected final Log log = LogFactory.getLog(getClass()); + + private ModelMgr modelMgr; + + public ModelMgr getModelMgr() { + return modelMgr; + } + + public void setModelMgr(ModelMgr modelMgr) { + this.modelMgr = modelMgr; + } + + public ModelAndView handleRequest(HttpServletRequest request, + HttpServletResponse reponse) throws Exception { + if (log.isDebugEnabled()) { + log.debug("listModels called"); + } + + HttpSession session = request.getSession(); + session.removeAttribute("modelIsolator"); + session.removeAttribute("modelKey"); + + Map args = new HashMap(2); + args.put("staticModels", modelMgr.getStaticModels()); + args.put("userModels", modelMgr.getUserModels(request.getSession().getId())); + + return new ModelAndView("listModels", args); + } + +} //ListModelsController