All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.nuiton.eugene.plugin.Xmi2Model Maven / Gradle / Ivy

/* *##% 
 * EUGene :: Maven plugin
 * Copyright (C) 2006 - 2009 CodeLutin
 *
 * This program 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 3 of the
 * License, or (at your option) any later version.
 *
 * This program 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 General Lesser Public License for more details.
 *
 * You should have received a copy of the GNU General Lesser Public
 * License along with this program.  If not, see
 * .
 * ##%*/
package org.nuiton.eugene.plugin;

import org.nuiton.plugin.PluginIOContext;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

import java.util.Map.Entry;
import java.util.Set;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.URIResolver;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.project.MavenProject;
import org.nuiton.plugin.PluginHelper;
import org.nuiton.util.FasterCachedResourceResolver;
import org.nuiton.util.FileUtil;
import org.nuiton.util.Resource;
import org.nuiton.util.ResourceResolver;
import org.nuiton.util.StringUtil;

/**
 * Converti les fichiers XMI en fichier Model via une transformation XSLT a
 * définir.
 * 
 * Class abstraite sans feuille de style ni extension.
 * 
 * @author ruchaud
 * @version $Revision: 755 $
 *
 * Last update: $Date: 2009-12-15 00:50:27 +0100 (mar., 15 déc. 2009) $
 * by : $Author: tchemit $
 */
public abstract class Xmi2Model extends EugeneAbstractMojo {

    /**
     * Les entrées sorties du plugin.
     *
     * 

* * En entrée on demande des répertoires où chercher les fichiers xmi a convertir. *

* En sortie on demande le répertoire ou extraire les xmi et copier les resources. *

* Par défaut on a les valeurs suivantes : *

*
     * <xmiResources>
     * 

* <input>target/generated-sources/xmi<\input> *

* <output>target/generated-sources/models<\output> *

* </xmiResources> *
* *

* * Note: si {@link #testPhase} est activée, les valeurs par défaut sont : *

*
     * <xmiResources>
     * 

* <input>target/generated-sources/xmi<\input> *

* <output>target/generated-sources/test-models<\output> *

* </xmiResources> *

*
* * @parameter * @since 1.0.0-rc-8 */ protected PluginIOContext xmiResources; /** * Nom du paquetage pour les fichiers générés * * @parameter expression="${generator.fullPackagePath}" default-value="${project.groupId}.${project.artifactId}" * @since 0.50 */ protected String fullPackagePath; /** * Nom du paquetage à généré * * @parameter expression="${generator.extractedPackages}" default-value="${project.groupId}.${project.artifactId}" * @since 0.50 */ protected String extractedPackages; /** * Liste des types de modeles acceptés séparés par des vigules. * * @parameter expression="${generator.acceptedXmiTypes}" default-value="xmi,uml" * @since 1.0.0-rc-4 */ protected String acceptedXmiTypes; /** * Nom du resolver a utiliser * * @parameter expression="${generator.resolver}" default-value="org.nuiton.util.ResourceResolver" * @since 1.0.0-rc-4 */ protected String resolver; /** * An extra directory to be added to the classpath. * * @parameter expression="${eugene.extraClassPathDirectory}" * @since 1.0.0-rc-4 */ protected File extraClassPathDirectory; /** * Get extension. * * @return the extension */ protected abstract String getExtension(); /** * Get style sheet. * * @param model the model file used to determine the stylesheet to use * @return the stylesheet name */ protected abstract String getStyleSheet(File model); @Override public void doAction() throws MojoExecutionException, MojoFailureException { long t0 = System.nanoTime(); try { getLog().info("Processing XSL tranformation"); getLog().info(" with fullPackagePath : " + fullPackagePath); getLog().info(" with extractedPackages : " + extractedPackages); getLog().info(" with acceptedXmiTypes : " + acceptedXmiTypes); getLog().info(" with resolver : " + resolver); TransformerFactory factory = TransformerFactory.newInstance(); ClassLoader fixedClassLoader = fixClassLoader(); String[] includes = getSuffixPattern("*"); String[] acceptedTypesAsArray = getAcceptedTypesAsArray(); for (File dir : xmiResources.getInputs()) { // recuperation des fichiers a traiter List files = PluginHelper.getIncludedFiles(dir, includes, null); // lancement des traitements xsl sur les fichiers trouvés // dans le repertoire actionXsl(dir, files, factory, fixedClassLoader, acceptedTypesAsArray); } } finally { getLog().info("xsl done in " + StringUtil.convertTime(System.nanoTime() - t0)); } getLog().info("Copy resources files"); try { String[] excludes = getSuffixPattern("**/*"); PluginHelper.copyFiles(xmiResources, null, excludes, overwrite); } catch (IOException ex) { throw new MojoExecutionException("could not copy some files for reason " + ex.getMessage(), ex); } } @Override protected PluginIOContext getResources() { return xmiResources; } @Override protected PluginIOContext initResources() { File defaultIn = getFileFromBasedir("target", "generated-sources", "xmi"); File defaultOut = getFileFromBasedir("target", "generated-sources", "models"); File defaultTestIn = getFileFromBasedir("target", "generated-sources", "test-xmi"); File defaultTestOut = getFileFromBasedir("target", "generated-sources", "test-models"); xmiResources = initResources(defaultIn, defaultOut, defaultTestIn, defaultTestOut); return xmiResources; } protected String[] getSuffixPattern(String prefix) { String[] acceptedSuffixes = getAcceptedTypesAsArray(); int max = acceptedSuffixes.length; final String[] patterns = new String[max]; for (int i = 0; i < max; i++) { patterns[i] = prefix + acceptedSuffixes[i]; } return patterns; } protected void actionXsl(File dir, List files, TransformerFactory factory, ClassLoader fixedClassLoader, String[] acceptedSuffixes) throws MojoExecutionException { for (File file : files) { try { if (getLog().isDebugEnabled()) { getLog().debug("treate file : " + file); } // Prepare resolver, stylesheet URIResolver fileResolver = getUriResolver(file, fixedClassLoader); String styleSheet = getStyleSheet(file); URL xsl = Resource.getURL(styleSheet); //TC-20090820 : using recursive for xmi // File result = new File(destDirModel, FileUtil.basename(file, // acceptedSuffixes).concat(".").concat(getExtension())); String filename = FileUtil.basename(file, acceptedSuffixes).concat(".").concat(getExtension()); String relatifPath = file.getParentFile().getAbsolutePath().substring(dir.getAbsolutePath().length()); File dstDir = xmiResources.getOutput(); if (!relatifPath.isEmpty()) { dstDir = new File(dstDir, relatifPath); dstDir.mkdirs(); } File result = new File(dstDir, filename); if (!overwrite && file.lastModified() < result.lastModified()) { getLog().info("file up-to-date : " + result); continue; } if (getLog().isDebugEnabled()) { getLog().debug("generate " + result); } // Create the xsl transformer and set parameters Transformer transformer = factory.newTransformer(new StreamSource(xsl.openStream())); transformer.setParameter("fullPackagePath", fullPackagePath); transformer.setParameter("extraPackages", extractedPackages); transformer.setURIResolver(fileResolver); transformer.transform(new StreamSource(file), new StreamResult( new FileOutputStream(result))); } catch (Exception e) { throw new MojoExecutionException(e.getMessage(), e); } } } /** * Look for the types declared in property "acceptedXmiTypes", split it * on ',' and check for the leading '.'. * * @return an array with all the accepted xmi types and a leading '.' */ protected String[] getAcceptedTypesAsArray() { String[] splittedTypes = acceptedXmiTypes.split(","); String[] result = new String[splittedTypes.length]; for (int i = 0; i < splittedTypes.length; i++) { String type = splittedTypes[i]; if (!type.startsWith(".")) { type = "." + type; } result[i] = type; } return result; } protected URIResolver getUriResolver(File model, ClassLoader cl) { URIResolver result = null; try { Class clazz = Class.forName(resolver, true, cl); // Try to set the base using the constructor try { // Look for a constructor with a String parameter (base) Constructor withBaseConstructor = clazz.getConstructor(String.class); // Set the xmi folder as the base String base = model.getParentFile().getAbsolutePath(); // Instantiate result = (URIResolver) withBaseConstructor.newInstance(base); } catch (Exception eee) { getLog().warn("Unable to instantiate resolver with String parameter", eee); } // If resolver is still not created, create it using the default // constructor if (result == null) { result = (URIResolver) clazz.newInstance(); } if (result instanceof ResourceResolver) { ((ResourceResolver) result).setVerbose(verbose); ((ResourceResolver) result).setCl(cl); if (result instanceof FasterCachedResourceResolver) { boolean offline = settings.isOffline(); getLog().debug("using offline mode ? : " + offline); ((FasterCachedResourceResolver) result).setOffline(offline); } } } catch (Exception eee) { getLog().warn("Unable to instantiate resolver using the default constructor", eee); } return result; } /** * Prepare le classLoader a utiliser dans le generateur. *

* Si un {@link #extraClassPathDirectory} a été renseigné, il est rajouté. *

* Si des références à des sibling modules, ils seront rajoutés aussi. * * @return le class loader modifie * @throws MojoExecutionException if any pb */ protected ClassLoader fixClassLoader() throws MojoExecutionException { Set urlsAsString = new HashSet(); List urls = new ArrayList(); try { ClassLoader loader; if (extraClassPathDirectory != null) { if (verbose) { getLog().info("Add extra directory in generator's classLoader : " + extraClassPathDirectory); } addDirectoryToUrlsList(extraClassPathDirectory,urls,urlsAsString); } if (project.getProjectReferences() != null) { // this case is for multi-module when calling from a parent module for (Object o : project.getProjectReferences().entrySet()) { Entry entry = (Entry) o; MavenProject relatedProject = (MavenProject) entry.getValue(); if (verbose) { getLog().info("Add project reference in generator's classLoader : '" + relatedProject.getArtifact() + "'"); } //TODO il faudrait peut-etre aussi ajouter les dependances ? addDirectoryToUrlsList(relatedProject.getArtifact().getFile(), urls, urlsAsString); } } if (!project.getArtifacts().isEmpty()) { // this is a special case when artifacts were resolved (for example in site phase) if (verbose) { getLog().info("Use resolved artifacts to build class-path"); } for (Object o : project.getArtifacts()) { Artifact a = (Artifact) o; if (!a.getScope().equals("provided")) { addDirectoryToUrlsList(a.getFile(), urls, urlsAsString); } } } // we ask to add the directory in classloader loader = getClass().getClassLoader(); if (getLog().isDebugEnabled()) { getLog().info("original classloader " + loader); } if (loader instanceof URLClassLoader) { // on reinjecte les urls de loader de base // car sinon on risque de ne pas retrouver les resources... for (URL u : ((URLClassLoader) loader).getURLs()) { addUrlToUrlsList(u, urls, urlsAsString); if (getLog().isDebugEnabled()) { getLog().debug("original cp entry: " + u); } } // et on force l'utilisation du classloader parent // s'il existe if (loader.getParent() != null) { loader = loader.getParent(); } } if (!urls.isEmpty()) { loader = new URLClassLoader(urls.toArray(new URL[urls.size()]), loader); } if (getLog().isDebugEnabled()) { for (URL u : urls) { getLog().debug("cp entry: " + u); } } return loader; } catch (MalformedURLException e) { throw new MojoExecutionException(e.getMessage()); } finally { urls.clear(); urlsAsString.clear(); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy