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

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

/*
 * #%L
 * EUGene :: Maven plugin
 * 
 * $Id: Xmi2Model.java 863 2010-04-15 14:22:49Z tchemit $
 * $HeadURL: http://svn.nuiton.org/svn/eugene/tags/eugene-2.0.2/maven-eugene-plugin/src/main/java/org/nuiton/eugene/plugin/Xmi2Model.java $
 * %%
 * Copyright (C) 2006 - 2010 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
 * .
 * #L%
 */

package org.nuiton.eugene.plugin;

import org.nuiton.plugin.PluginIOContext;
import java.io.File;
import java.io.FileOutputStream;
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.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: 863 $
 *
 * Last update: $Date: 2010-04-15 16:22:49 +0200 (jeu., 15 avril 2010) $
 * by : */
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 Exception { 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"); String[] excludes = getSuffixPattern("**/*"); PluginHelper.copyFiles(xmiResources, null, excludes, overwrite); } @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; 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); createDirectoryIfNecessary(dstDir); // 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