/*
* Copyright (c) 2012, Fromentin Xavier, Schnell Michaël, Dervin Cyrielle, Brabant Quentin
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * The names of its contributors may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL Fromentin Xavier, Schnell Michaël, Dervin Cyrielle OR Brabant Quentin
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package kameleon.plugin;
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import kameleon.exception.KameleonException;
import kameleon.util.FileConstants;
import kameleon.util.IOObject;
import kameleon.util.IOPlugIn;
import kameleon.util.WorkSpaceManager;
/**
* Utility class handling the plug-ins.
*
* <p>Provides methods to manage (add, load and remove) different plug-ins
* (analyzers as well as generators).
*
* @author Schnell Michaël
* @version 1.0
*/
public class PlugInManager implements FileConstants {
/**
* Default debug mode.
*/
public static final boolean DEFAULT_DEBUG_MODE = false ;
/**
* Utility constant, contains only a line feed ({@code \n}).
*/
public static final String LINE_FEED = "\n" ; //$NON-NLS-1$
/**
* Utility constant, contains only a tab ({@code \t}).
*/
public static final String TAB = "\t" ; //$NON-NLS-1$
/**
* Replacement text for tabs a exception stack trace.
*/
public static final String TAB_REPLACEMENT = " " ; //$NON-NLS-1$
/**
* Used to map extensions to their latching analyzer.
*/
protected AnalyzerManager am ;
/**
* List of the known analyzers of this instance.
*/
protected List<PlugInInfo> knownAnalyzers ;
/**
* List of the known generators of this instance.
*/
protected List<PlugInInfo> knownGenerators ;
/**
* Utility class used for reading and writing the plug-in files
*/
protected IOPlugIn iop ;
/**
* Current mode for debugging.
*/
protected boolean debugMode ;
/**
* Builds an empty instance with the given debug mode flag.
*
* <p>The lists of plug-ins are not filled.
*
* @param debugMode
* debug mode flag (use {@code true} to activate the debug mode)
*/
public PlugInManager(boolean debugMode) {
super() ;
this.knownAnalyzers = new ArrayList<PlugInInfo>() ;
this.knownGenerators = new ArrayList<PlugInInfo>() ;
this.am = new AnalyzerManager() ;
this.debugMode = debugMode ;
this.iop = new IOPlugIn(this.am,
ANALYSER_FOLDER, GENERATOR_FOLDER,
CONFIG_ANALYSER_FILE, CONFIG_GENERATOR_FILE,
PLUG_IN_RESOURCES_FOLDER) ;
}// PlugInManager()
/**
* Reads the default configuration files to fill the lists of plug-ins.
*
* @throws KameleonException
* if the configuration files could not be read or interpreted successfully
*/
protected void initializePlugIns() throws KameleonException {
this.readAnalyzers() ;
this.readGenerators() ;
this.initAM() ;
}// initializePlugIns()
/**
* Reads the default configuration file for the installed analyzers and initializes the
* list of known analyzers (any previous elements in the list are discarded).
*
* @throws KameleonException
* if the configuration file could not be read or interpreted successfully
*/
private void readAnalyzers() throws KameleonException {
this.knownAnalyzers = IOObject.readList(CONFIG_ANALYSER_FILE) ;
}// readAnalyzers()
/**
* Reads the default configuration file for the installed generators and initializes the
* list of known generators (any previous elements in the list are discarded).
*
* @throws KameleonException
* if the configuration file could not be read or interpreted successfully
*/
private void readGenerators() throws KameleonException {
this.knownGenerators = IOObject.readList(CONFIG_GENERATOR_FILE) ;
}// readGenerators()
/**
* Initializes the analyzer manager using the current list of analyzers.
* Any previous mappings are discarded.
*/
private void initAM() {
this.am = new AnalyzerManager() ;
for(PlugInInfo a : this.knownAnalyzers) {
this.am.addAnalyzerInfo(a) ;
}// for
}// initAM()
/**
* Display debug informations on the standard output if the debug mode is activated.
*
* @param ke
* exception containing debug information
*/
protected void displayDebugInformation(KameleonException ke) {
//TODO Remove hardcoded message
if (this.debugMode) {
System.out.printf(" Details: %s\n%s", ke.getMessage(), //$NON-NLS-1$
KameleonException.getStackTraceAsString(ke)) ;
}// if
}// displayDebugInformation(KameleonException)
/**
* Adds a new plug-in.
*
* <p>Copies the executable code for the plug-in and update the (default)
* configuration files.
*
* @param plugin
* file containing the new plug-in
*
* @return {@code PlugInInfo} about the newly added plug-in
*
* @throws KameleonException
* if the plug-in could not be added
*/
public PlugInInfo addPlugIn(File plugin) throws KameleonException {
WorkSpaceManager.ensureWorkSpace() ;
PlugInInfo info = this.iop.addPlugIn(plugin) ;
if (info.isAnalyzer) {
this.readAnalyzers() ;
this.initAM() ;
} else {
this.readGenerators() ;
}// if
return info ;
}// addPlugIn(File)
/**
* Adds a new plug-in.
*
* @param pluginPath
* absolute path of the file containing the new plug-in
*
* @return {@code PlugInInfo} about the newly added plug-in
*
* @throws KameleonException
* if the plug-in could not be added
*
* @see #addPlugIn(File)
*/
public PlugInInfo addPlugIn(String pluginPath) throws KameleonException {
return this.addPlugIn(new File(pluginPath)) ;
}// addPlugIn(String)
/**
* Removes an analyzer plug-in.
*
* @param analyzerId
* identifier of the analyzer which should be removed
*
* @throws KameleonException
* if the plug-in could not be removed
*/
public void removeAnalyzer(String analyzerId) throws KameleonException {
PlugInInfo analyzerInfo = this.getAnalyzer(analyzerId) ;
if (analyzerInfo != null) {
this.removePlugIn(this.getAnalyzer(analyzerId)) ;
}// if
}// removeAnalyzer(String)
/**
* Removes a generator plug-in.
*
* @param generatorId
* identifier of the generator which should be removed
*
* @throws KameleonException
* if the plug-in could not be removed
*/
public void removeGenerator(String generatorId) throws KameleonException {
this.removePlugIn(this.getGenerator(generatorId)) ;
}// removeGenerator(String)
/**
* Removes a plug-in.
*
* @param info
* information about the plug-in which should be removed
*
* @throws KameleonException
* if the plug-in could not be removed
*/
public void removePlugIn(PlugInInfo info) throws KameleonException {
WorkSpaceManager.ensureWorkSpace() ;
this.iop.removePlugIn(info) ;
this.initializePlugIns() ;
}// removePlugIn(PlugInInfo)
/**
* Returns the list of known (installed) analyzer plug-ins.
*
* @return instance of {@code List<PlugInInfo>} which contains information
* about the installed analyzers
*/
public List<PlugInInfo> getKnownAnalyzers() {
return this.knownAnalyzers;
}// getKnownAnalysers()
/**
* Returns the list of known (installed) generator plug-ins.
*
* @return instance of {@code List<PlugInInfo>} which contains information
* about the installed generators
*/
public List<PlugInInfo> getKnownGenerators() {
return this.knownGenerators;
}// getKnownGenerators()
/**
* Returns information about the generator plug-in with the given id.
*
* @param id
* identifier of the searched plug-in
*
* @return instance of {@code PlugInInfo} for the generator plug-in
* with the given id, or {@code null} if no match was found
*/
public PlugInInfo getGenerator(String id) {
boolean trouve = (id == null) ;
PlugInInfo generator = null ;
Iterator<PlugInInfo> iter = this.knownGenerators.iterator() ;
while(!trouve && iter.hasNext()) {
generator = iter.next() ;
trouve = generator.getId().equals(id) ;
}// while
return generator ;
}// getGenerator(String)
/**
* Returns information about the analyzer plug-in with the given id.
*
* @param id
* identifier of the searched plug-in
*
* @return instance of {@code PlugInInfo} for the analyzer plug-in
* with the given id, or {@code null} if no match was found
*/
public PlugInInfo getAnalyzer(String id) {
boolean found = (id == null) ;
PlugInInfo analyzer = null ;
Iterator<PlugInInfo> iter = this.knownAnalyzers.iterator() ;
while(!found && iter.hasNext()) {
analyzer = iter.next() ;
found = analyzer.getId().equals(id) ;
}// while
if (found) {
return analyzer ;
}// if
return null ;
}// getAnalyzer(String)
}// class PlugInManager