/** * Copyright (C) 2008-2010, Squale Project - http://www.squale.org * * This file is part of Squale. * * Squale 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 any later version. * * Squale 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 Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Squale. If not, see <http://www.gnu.org/licenses/>. */ package org.squale.squalix.tools.compiling.java; import java.io.File; import java.io.FileFilter; import java.io.FileInputStream; import java.util.ArrayList; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.squale.squalecommon.enterpriselayer.businessobject.component.parameters.ParametersConstants; import org.squale.squalecommon.enterpriselayer.businessobject.component.parameters.StringParameterBO; import org.squale.squalix.core.TaskData; import org.squale.squalix.core.TaskException; import org.squale.squalix.core.exception.ConfigurationException; import org.squale.squalix.tools.compiling.MockCompilingTask; import org.squale.squalix.tools.compiling.CompilingMessages; import org.squale.squalix.tools.compiling.configuration.MockCompilingConf; import org.squale.squalix.util.file.FileUtility; /** * Met � jour les param�tres temporaires li�s � la t�che de compilation Java : <br/> * <ul> * <li> CLASSES_DIR : le r�pertoire racine contenant les .class du projet * <li> CLASSPATH : le classpath du projet * </ul> */ public class JavaMockCompilingTask extends MockCompilingTask { /** * Logger */ private static final Log LOGGER = LogFactory.getLog( JavaMockCompilingTask.class ); /** configuration de la t�che */ private MockCompilingConf mConfiguration; /** Le classpath */ private StringBuffer mClasspath; /** * Constructeur par d�faut */ public JavaMockCompilingTask() { mName = "JavaMockCompilingTask"; mConfiguration = new MockCompilingConf(); mClasspath = new StringBuffer(); } /** * {@inheritDoc} * * @see org.squale.squalix.core.AbstractTask#execute() */ public void execute() throws TaskException { try { // on ex�cute la partie commune super.execute(); // on construit le classpath String userClasspath = mClasspath.toString(); mClasspath = buildClasspath( userClasspath ); // On l'ajoute aux param�tres temporaires mData.putData( TaskData.CLASSPATH, mClasspath.toString() ); LOGGER.debug( "classpath = " + mClasspath.toString() ); // positionne les donn�es sur la taille du file System affectFileSystemSize( mData.getData( TaskData.CLASSES_DIRS ), true ); } catch ( Exception e ) { throw new TaskException( e ); } } /** * Il faut parcourir tout le classpath afin de mettre les chemins en absolu et v�rifier qu'ils existent * * @param pUserClasspath le classpath que l'utilisateur a donn� * @return le classpath bien construit et v�rifi� * @throws ConfigurationException si le classpath n'est pas bien construit */ private StringBuffer buildClasspath( String pUserClasspath ) throws ConfigurationException { // On r�cup�re le view path String viewPath = (String) mData.getData( TaskData.VIEW_PATH ); if ( viewPath == null ) { String message = CompilingMessages.getString( "exception.view_path.not_found" ); LOGGER.error( message ); // Renvoi d'une exception de configuration throw new ConfigurationException( message ); } StringBuffer classpath = new StringBuffer(); // On s�pare les �l�ments String[] elements = pUserClasspath.split( ";" ); // Pour chaque �l�ment, on construit son chemin absolu, on v�rifie qu'il existe // et on construit le classpath for ( int i = 0; i < elements.length; i++ ) { if ( elements[i].length() > 0 ) { File file = new File( elements[i] ); file = FileUtility.getAbsoluteFile( viewPath, file ); if ( file.exists() ) { classpath.append( file.getAbsolutePath() ); classpath.append( ";" ); } else { // On log un warning un car cela peut perturber l'ex�cution de mccabe String message = CompilingMessages.getString( "exception.element_does_not_exist", elements[i] ); LOGGER.warn( message ); initError( message ); } } } /* * on cr�e un buffer pour d�finir le chemin du dossier contenant les ressources n�cessaires � la compilation */ // On r�cup�re la version de java StringParameterBO versionParam = (StringParameterBO) mProject.getParameters().getParameters().get( ParametersConstants.DIALECT ); if ( versionParam == null ) { String message = CompilingMessages.getString( "java.exception.task.dialect_not_set" ); LOGGER.error( message ); // Renvoi d'une exception de configuration throw new ConfigurationException( message ); } StringBuffer path = new StringBuffer( CompilingMessages.getString( "dir.root.java" ) ); path.append( "/" ); path.append( versionParam.getValue() ); path.append( "/" ); addCompilingRessourcesToClasspath( classpath, new File( path.toString().replace( '.', '_' ) ) ); return classpath; } /** * {@inheritDoc} Place le param�tre temporaire <code>CLASSES_DIR</code> * * @see org.squale.squalix.tools.compiling.MockCompilingTask#setCompiledDirInTempMap(java.util.List) */ protected void setCompiledDirInTempMap( List pDirs ) throws TaskException { try { // R�cup�re le classpath StringParameterBO classpathParam = (StringParameterBO) mTaskParam.getParameters().get( ParametersConstants.CLASSPATH ); if ( classpathParam == null ) { String message = CompilingMessages.getString( "exception.classpath_not_set" ); LOGGER.error( message ); // Renvoi d'une exception de configuration throw new ConfigurationException( message ); } // On remplace les s�parateurs unix par ceux de windows en cas // car c'est de cette fa�on qu'il est r�cup�r� par la t�che de compilation Java mClasspath = new StringBuffer( classpathParam.getValue().replace( ':', ';' ) ); if ( mClasspath.length() > 0 && !mClasspath.toString().endsWith( ";" ) ) { mClasspath.append( ";" ); } // On r�cup�re le chemin absolu du r�pertoire qui va contenir // nos .class mConfiguration.parse( new FileInputStream( "config/mockcompiling-config.xml" ) ); // On le cr�e File root = new File( mConfiguration.getRootDirectory() ); root.mkdirs(); // On copie tous les .class qui se trouvent dans la liste donn�e // en param�tre dans le r�pertoire racine for ( int i = 0; i < pDirs.size(); i++ ) { StringParameterBO pathParam = (StringParameterBO) pDirs.get( i ); String path = pathParam.getValue(); // On enl�ve ce chemin du classpath car on va rajouter le r�pertorie global mClasspath = new StringBuffer( mClasspath.toString().replaceAll( path, "" ) ); // On r�cup�re le fichier si il existe et qu'il peut �tre lu File compiledDir = verifyPath( new File( path ) ); // On copie tous les .class de ce r�pertoire (ou fichier compress�) // dans le r�pertoire de la configuration if ( compiledDir.isDirectory() ) { // On copie tous les fichiers File[] files = compiledDir.listFiles(); for ( int j = 0; j < files.length; j++ ) { FileUtility.copyIntoDir( files[j], root ); } } else { FileUtility.copyAndExtractInto( compiledDir, root ); } } // On ajoute le r�pertoire au classpath mClasspath.append( root.getAbsolutePath() ); mClasspath.append( ";" ); // On ajoute le param�tre � la map temporaire List classesDirs = new ArrayList(); classesDirs.add( root.getAbsolutePath() ); mData.putData( TaskData.CLASSES_DIRS, classesDirs ); } catch ( Exception e ) { throw new TaskException( e ); } } /** * @param pPath le chemin relatif ou absolu d'un r�pertoire de fichiers compil�s * @return le r�pertoire de fichiers compil�s si il existe et peut-�tre lu * @throws ConfigurationException si erreur de configuration */ private File verifyPath( File pPath ) throws ConfigurationException { File result = null; if ( pPath.isAbsolute() && pPath.exists() ) { result = pPath; } else { // Le fichier est suppos� �tre relatif � la vue String viewPath = (String) getData().getData( TaskData.VIEW_PATH ); if ( viewPath == null ) { String message = CompilingMessages.getString( "exception.view_path.not_found" ); LOGGER.error( message ); // Renvoi d'une exception de configuration throw new ConfigurationException( message ); } result = new File( viewPath, pPath.getPath() ); if ( !result.exists() ) { String message = CompilingMessages.getString( "error.file.not_found", result.getAbsolutePath() ); LOGGER.error( message ); // Renvoi d'une exception de configuration throw new ConfigurationException( message ); } } // Si on a pas le droit de lecture sur le fichier, on lance une exception if ( !result.canRead() ) { String message = CompilingMessages.getString( "error.cannot_read_file", result.getAbsolutePath() ); LOGGER.error( message ); // Renvoi d'une exception de configuration throw new ConfigurationException( message ); } return result; } /** * Ajoute tous les .jar, .zip et .class au classpath contenu dans le r�pertoire pass� en param�tre * * @param pClasspath le classpath * @param pRessource le fichier � ajouter ou le r�pertoire � parcourir */ private void addCompilingRessourcesToClasspath( StringBuffer pClasspath, File pRessource ) { // V�rification du classpath if ( pClasspath.length() > 0 && !pClasspath.toString().endsWith( ";" ) ) { pClasspath.append( ";" ); } // On va r�cup�rer tous les .jar, .zip ou .classes if ( null != pRessource && pRessource.isDirectory() && pRessource.canRead() ) { File[] files = pRessource.listFiles( new ExtensionsFileFilter() ); for ( int i = 0; i < files.length; i++ ) { addCompilingRessourcesToClasspath( pClasspath, files[i] ); } } else if ( pRessource.exists() ) { // On l'ajoute directement au classpath pClasspath.append( pRessource.getAbsolutePath() ); } } /** * Classe de filtre sur les extensions .jar, .zip et .class */ private class ExtensionsFileFilter implements FileFilter { /** La liste des extensions */ private List mExtensions; /** * Le constructeur par d�faut */ public ExtensionsFileFilter() { mExtensions = new ArrayList(); mExtensions.add( "jar" ); mExtensions.add( "zip" ); mExtensions.add( "class" ); } /** * {@inheritDoc} * * @see java.io.FileFilter#accept(java.io.File) */ public boolean accept( File pFile ) { boolean result = pFile.isDirectory(); if ( pFile.isFile() ) { // on r�cup�re l'extension String fileExtension = pFile.getName(); fileExtension = fileExtension.substring( fileExtension.lastIndexOf( "." ) + 1, fileExtension.length() ); result = mExtensions.contains( fileExtension ); } return result; } } }