/*
This file is part of the software framework JStatCom,
a library for building applications for data based analysis.
Copyright (C) 2000-2005 Markus Kraetzig
This library 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 2.1 of the
License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA
*/
package com.jstatcom.engine;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.jstatcom.engine.gauss.GaussEngineType;
import com.jstatcom.engine.grte.GRTEType;
import com.jstatcom.engine.matlab.MatlabEngineType;
import com.jstatcom.engine.mlab.StubMlabEngineType;
import com.jstatcom.engine.ox.OxEngineType;
import com.jstatcom.engine.stub.StubEngineType;
import com.jstatcom.model.JSCConstants;
/**
* This class is a Mediator that binds the various classes and resources
* together that belong to an engine implementation. It also contains an
* enumeration of engine types that are implemented for convenience.
*
* Every Engine implementation define its corresponding concrete
* engine type. The name of an engine type must be unique. If it already exists
* for a different instance of EngineTypes, the constructor will
* throw an exception.
*
* Engine types should always be implemented as Singletons.
*
* The name of an engine type also defines the resource directory to be used for
* everything related to that engine. Therefore the conventions for variable
* names defined in com.jstatcom.model.JSCConstants are enforced
* for engine type names as well.
*
* This class implements the typesave enum pattern (Joshua Bloch,
* "Effective Java", Item 21) . If you compare EngineTypes,
* always use the == operator.
*
* @author Markus Kraetzig
*/
public abstract class EngineTypes {
private static final Map typeMap = new HashMap();
/**
* The name of this runtype.
*/
public final String name;
public final String DIR_NAME;
private final String cfgFile;
private AbstractConfigPanel configPanel = null;
private static final String cfg_filename = "engine_config.xml";
/**
* Reference to the GAUSS engine type. This used to manage communication
* with the GAUSS software by Aptech. The software has to be installed on
* the machine.
*/
public static final EngineTypes GAUSS = GaussEngineType.INSTANCE;
/**
* Reference to the Gauss Runtime Engine type. This can be used to execute
* GAUSS code that has been compiled with the matching Gauss Engine.
*/
public static final EngineTypes GRTE = GRTEType.INSTANCE;
/**
* Reference to the Stub Engine type. This can be used to execute methods in
* arbitrary system libraries without the need for a distinguished JNI
* wrapper.
*/
public static final EngineTypes STUB = StubEngineType.INSTANCE;
/**
* Reference to the newer Matlab Engine type. This can be used to execute
* methods in system libraries that have been generated from Matlab .m files
* with Matlab Compiler versions release 4 and later.
*/
public static final EngineTypes MATLAB = MatlabEngineType.INSTANCE;
/**
* Reference to the older Matlab Engine type. This can be used to execute
* methods in system libraries that have been generated from Matlab .m files
* with Matlab Compiler versions prior to release 4.
*/
public static final EngineTypes MLAB = StubMlabEngineType.INSTANCE;
/**
* Reference to the Ox Engine type. This can be used to execute methods in
* .ox or .oxo modules.
*/
public static final EngineTypes OX = OxEngineType.INSTANCE;
private static List loadedEngines = new ArrayList();
/**
* Creates an engine type with name.
*
* @param name
* the unique name of this type
* @throws IllegalArgumentException
* if (name == null) or if name is
* not valid according to JSCConstants
* @throws IllegalStateException
* if another engine type with name already
* exists
*
* @see com.jstatcom.model.JSCConstants#isValidName
*/
protected EngineTypes(String name) {
if (name == null)
throw new IllegalArgumentException("Argument was null.");
JSCConstants.checkNameThrowEx(name);
this.name = name;
this.DIR_NAME = "j" + name.toLowerCase();
this.cfgFile = DIR_NAME + "/" + cfg_filename;
if (valueOf(name) != null)
throw new IllegalStateException("Engine type \"" + name
+ "\" already exists.");
typeMap.put(name.toUpperCase(), this);
}
/**
* Checks all configuration data for validity. This method performs a
* general check that should be true for all engines:
*
* - test whether all necessary keys are there
*
- test whether the self tests of all
ConfigKeys are ok
*
* One can add further tests by overriding the method:
*
*
* public String checkSettings()
*
*
* It is called from this method after all other checks succeeded and can be
* used to validate conditions between engine settings.
*
* @param configHolder
* the config settings to check
* @return null if ok, error string otherwise
* @throws IllegalArgumentException
* if (configHolder == null)
*/
public final String checkConfig(ConfigHolder configHolder) {
if (configHolder == null)
throw new IllegalArgumentException("Argument was null.");
// Check whether all necessary keys are there.
Set keySet = configHolder.getConfigKeys();
if (keySet == null)
return null;
if (!keySet.containsAll(getConfigKeys().values()))
return "Some information is missing to run engine of type " + this
+ ".";
// Check whether the self tests of all ConfigKeys are ok.
for (Iterator iter = keySet.iterator(); iter.hasNext();) {
ConfigKeys currentKey = (ConfigKeys) iter.next();
String value = configHolder.getConfig(currentKey);
String error = currentKey.isValid(value);
if (error != null)
return error;
}
return checkSettings(configHolder);
}
/**
* This method should be overwritten by clients, if further checks of the
* settings have to be specified.
*
* @param configHolder
* the config settings to check
* @return null if ok, error string otherwise
*/
public abstract String checkSettings(ConfigHolder configHolder);
/**
* Override prevention method to enforce a.equals(b) if and
* only if a==b.
*
* @param o
* object to compare with
* @return true if equal, false otherwise
*/
public final boolean equals(Object o) {
return super.equals(o);
}
/**
* Returns the config file location for the respective engine. The filename
* is constructed as:
*
* "j" + name.toLowerCase() + "/" + CONFIG_FILE;
*
* If the directory "j" + name.toLowerCase() does not exist
* yet in the resource path, it will be created by this method.
*
* Subclasses can overwrite this method if this is not the desired
* behaviour.
*
* @return the relative location of the XML config file to the resource
* directory
*/
public String getConfigFile() {
File dir = new File(DIR_NAME);
if (!dir.isDirectory())
dir.mkdir();
return cfgFile;
}
/**
* Gets a map with all config keys for that specific engine.
*
* Example:
* Implementations of a Foo engine this class could use:
*
* return ConfigKeys.getAllKeys(FooConfigKeys.class);
*
* where Foo stands for the name of the engine and
* FooConfigKeys is the engine specific implementation of
* ConfigKeys.
*
* @return Map containing the ConfigKeys with
* the respective names as keys
*/
public abstract Map getConfigKeys();
/**
* Gets the configuration panel for the respective engine. This default
* implementation creates an edit dialog for the XML file. It works for all
* settings. This can be overwritten to provide a costumized settings
* dialogs for a specific engine.
*
* @return the user panel containing the user input mask for configuration
*/
public AbstractConfigPanel getConfigPanel() {
if (configPanel == null)
configPanel = new DefaultConfigPanel();
return configPanel;
}
/**
* Gets a concrete implementation of the Engine interface.
*
* @return engine that is initialized and ready to run
*/
public abstract Engine getEngine();
/**
* Override prevention method invokes super method.
*
* @return hash code
*/
public final int hashCode() {
return super.hashCode();
}
/**
* Returns a string that represents the value of this object.
*
* @return a string representation of this
*/
public final String toString() {
return this.name;
}
/**
* Gets the type for the given name. The case of name makes
* no difference.
*
* @param name
* the name of the type
* @return reference to an instance of EngineTypes with
* name or null if it does not exist
* @throws IllegalArgumentException
* if (name == null)
*/
public static EngineTypes valueOf(String name) {
if (name == null)
throw new IllegalArgumentException("Argument was null");
Object o = typeMap.get(name.toUpperCase());
if (o instanceof EngineTypes)
return (EngineTypes) o;
return null;
}
/**
* Gets an iterator over all loaded engines.
*
* @return iterator
*/
public static Iterator engineIterator() {
return loadedEngines.iterator();
}
/**
* Adds engine to the list of loaded engines if it was not
* contained yet.
*
* @param engine
* the instance to add
* @throws IllegalArgumentException
* if (engine == null)
*/
protected static void addLoadedEngine(Engine engine) {
if (engine == null)
throw new IllegalArgumentException("Argument was null");
if (!loadedEngines.contains(engine))
loadedEngines.add(engine);
}
}
Ads help maintain this website.