de.invation.code.toval.misc.wd.AbstractComponentContainer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of TOVAL Show documentation
Show all versions of TOVAL Show documentation
TOVAL comprises a set of java classes for common programming issues. It includes utils for arrays, lists, sets and collections for convenient handling and modification, but also support for mathematic definitions concerning logic (clauses + resolution) together with some algorithms for permutations, powersets and resolution. Additionally it contains a number of types for multisets, matrices with object keys and much more.
The newest version!
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package de.invation.code.toval.misc.wd;
import de.invation.code.toval.debug.SimpleDebugger;
import de.invation.code.toval.file.FileUtils;
import de.invation.code.toval.misc.NamedComponent;
import de.invation.code.toval.validate.ExceptionDialog;
import de.invation.code.toval.validate.ParameterException;
import de.invation.code.toval.validate.ParameterException.ErrorCode;
import de.invation.code.toval.validate.Validate;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
*
* @author stocker
* @param
*/
public abstract class AbstractComponentContainer {
public static final boolean DEFAULT_IGNORE_INCOMPATIBLE_FILES = true;
public static final boolean DEFAULT_NOTIFY_LISTENERS = true;
public static final boolean DEFAULT_USE_SUBDIRECTORIES_FOR_COMPONENTS = false;
public static final String DEFAULT_FILE_ENDING = "";
private static final String componentDirectoryFormat = "%s%s/";
private static final String componentFileFormat = "%s%s%s";
private boolean ignoreIncompatibleFiles = DEFAULT_IGNORE_INCOMPATIBLE_FILES;
private final Map components = new HashMap<>();
private final Map componentFiles = new HashMap<>();
private String basePath = null;
private SimpleDebugger debugger = null;
private boolean useSubdirectoriesForComponents = DEFAULT_USE_SUBDIRECTORIES_FOR_COMPONENTS;
protected final ComponentListenerSupport listenerSupport = new ComponentListenerSupport<>();
public AbstractComponentContainer(String basePath) {
this(basePath, null);
}
public AbstractComponentContainer(String basePath, SimpleDebugger debugger) {
if (mandatoryDirectory()) {
Validate.directory(basePath);
}
this.basePath = basePath;
this.debugger = debugger;
}
protected SimpleDebugger getDebugger(){
return debugger;
}
public String getBasePath(){
return basePath;
}
public void setUseSubdirectoriesForComponents(boolean useSubdirectoriesForComponents){
this.useSubdirectoriesForComponents = useSubdirectoriesForComponents;
}
public void setIgnoreIncompatibleFiles(boolean ignoreIncompatibleFiles) {
this.ignoreIncompatibleFiles = ignoreIncompatibleFiles;
}
public abstract String getComponentDescriptor();
public boolean addComponentListener(ComponentListener listener) {
return listenerSupport.addListener(listener);
}
public boolean removeComponentListener(ComponentListener listener) {
return listenerSupport.removeListener(listener);
}
public Set getComponentNames() {
return new HashSet<>(components.keySet());
}
public Collection getComponents() {
return Collections.unmodifiableCollection(components.values());
}
public List getComponentsSorted(Comparator comparator) {
List netList = new ArrayList(getComponents());
Collections.sort(netList, comparator);
return netList;
}
public Map getComponentMap() {
return Collections.unmodifiableMap(components);
}
public O getComponent(String componentName) throws ProjectComponentException {
validateComponent(componentName);
return components.get(componentName);
}
public final File getComponentFile(String componentName) throws ProjectComponentException {
validateComponent(componentName);
return componentFiles.get(componentName);
}
protected boolean mandatoryDirectory() {
return true;
}
public void loadComponents() throws ProjectComponentException {
if (!mandatoryDirectory() && !new File(basePath).exists()) {
return;
}
if (useSubdirectoriesForComponents) {
Collection subDirectories = null;
try {
subDirectories = FileUtils.getSubdirectories(basePath);
} catch (Exception e) {
debugMessage("Exception: Cannot identify subdirectories: " + e.getMessage());
return;
}
for (File subDirectory : subDirectories) {
try {
loadComponentsFromDirectory(subDirectory.getAbsolutePath());
} catch (Exception e) {
throw new ProjectComponentException("Cannot load components from directory " + FileUtils.getDirName(subDirectory), e);
}
}
} else {
try {
loadComponentsFromDirectory(basePath);
} catch (Exception e) {
throw new ProjectComponentException("Cannot load components from directory " + FileUtils.getDirName(basePath), e);
}
}
}
public final void loadComponentsFromDirectory(String directory) throws Exception {
Collection fileNames = null;
try {
boolean allFiles = getAcceptedFileEndings().size() == 1 && getAcceptedFileEndings().iterator().next().isEmpty();
if (allFiles) {
fileNames = FileUtils.getFileNamesInDirectory(directory, true);
} else {
fileNames = FileUtils.getFileNamesInDirectory(directory, true, getAcceptedFileEndings());
}
} catch (Exception e) {
debugMessage("Exception: Cannot extract file names: " + e.getMessage());
return;
}
for (String fileName : fileNames) {
debugMessage("Trying to load " + getComponentDescriptor() + " from file \"" + FileUtils.getFileWithoutEnding(fileName) + "\"");
O component = null;
try {
component = loadComponentFromFile(fileName);
} catch (ParameterException e) {
if (ignoreIncompatibleFiles && e.getErrorCode() == ErrorCode.INCOMPATIBILITY) {
debugMessage(e.getMessage());
debugMessage("Ignoring file \"" + FileUtils.getFileWithoutEnding(fileName) + "\"");
continue;
} else {
debugMessage("Exception: Error while loading " + getComponentDescriptor() + " from file: " + e.getMessage());
continue;
}
} catch (Exception e) {
debugMessage("Exception: Error while loading " + getComponentDescriptor() + " from file: " + e.getMessage());
continue;
}
if (component == null) {
debugMessage("Exception: Cannot load " + getComponentDescriptor() + " from file");
continue;
}
debugMessage("Successfully loaded " + getComponentDescriptor() + " from file.");
try {
addComponent(component, false);
} catch (Exception e) {
debugMessage("Exception: Cannot add " + getComponentDescriptor() + " to container: " + e.getMessage());
continue;
}
debugMessage("Successfully added " + getComponentDescriptor() + " to container.");
}
}
protected void debugMessage(String message) {
if (debugger != null) {
if (message == null) {
debugger.newLine();
} else {
debugger.message(message);
}
}
}
protected abstract O loadComponentFromFile(String file) throws Exception;
public Set getAcceptedFileEndings() {
return new HashSet(Arrays.asList(""));
}
public void removeComponents(boolean removeFilesFromDisk) throws ProjectComponentException {
removeComponents(removeFilesFromDisk, DEFAULT_NOTIFY_LISTENERS);
}
public void removeComponents(boolean removeFilesFromDisk, boolean notifyListeners) throws ProjectComponentException {
for (String componentName : getComponentNames()) {
removeComponent(componentName, removeFilesFromDisk, notifyListeners);
}
}
public boolean removeComponent(String componentName, boolean removeFromDisk) throws ProjectComponentException {
return removeComponent(componentName, removeFromDisk, DEFAULT_NOTIFY_LISTENERS);
}
public boolean removeComponent(String componentName, boolean removeFromDisk, boolean notifyListeners) throws ProjectComponentException {
validateComponent(componentName);
if (components.remove(componentName) != null) {
if (removeFromDisk) {
if (useSubdirectoriesForComponents) {
try {
FileUtils.deleteDirectory(FileUtils.getPath(getComponentFile(componentName)), true);
} catch (Exception e) {
throw new ProjectComponentException("Cannot delete "+getComponentDescriptor()+" directory from disk.", e);
}
} else {
try {
FileUtils.deleteFile(basePath + getSerializationFileName(getComponent(componentName)));
} catch (Exception e) {
throw new ProjectComponentException("Cannot delete "+getComponentDescriptor()+" file from disk.", e);
}
}
}
componentFiles.remove(componentName);
if (notifyListeners) {
listenerSupport.notifyComponentRemoved(getComponent(componentName));
}
return true;
}
return false;
}
public void storeComponents() throws ProjectComponentException {
for (String componentName : getComponentNames()) {
storeComponent(componentName);
}
}
public void storeComponent(String componentName) throws ProjectComponentException {
validateComponent(componentName);
try {
serializeComponent(getComponent(componentName), getComponentDirectory(componentName).getCanonicalPath(), getSerializationFileName(getComponent(componentName)).concat(getFileEndingForComponent(getComponent(componentName))));
} catch (Exception e) {
throw new ProjectComponentException("Cannot store component.", e);
}
}
/**
* Checks, if there are components.
*
* @return true if there is at least one component model;
* false otherwise.
*/
public boolean containsComponents() {
return !components.isEmpty();
}
/**
* Checks, if there is a component with the given name.
*
* @param name Name of the component in question
* @return true if there is at least one component model;
* false otherwise.
*/
public boolean containsComponent(String name) {
return components.containsKey(name);
}
/**
* Adds a new component.
* The component is also stores as property-file in the working directory.
*
* @param component The component to add.
* @throws de.invation.code.toval.misc.wd.ProjectComponentException
*/
public void addComponent(O component) throws ProjectComponentException {
addComponent(component, true);
}
/**
* Adds a new component.
* Depending on the value of the store-parameter, the component is also
* stored in the serialization directory.
*
* @param component The new component to add.
* @param storeToFile Indicates if the net should be stored to disk.
* @throws de.invation.code.toval.misc.wd.ProjectComponentException
*/
public void addComponent(O component, boolean storeToFile) throws ProjectComponentException {
addComponent(component, storeToFile, DEFAULT_NOTIFY_LISTENERS);
}
/**
* Adds a new component.
* Depending on the value of the store-parameter, the component is also
* stored in the serialization directory.
*
* @param component The new component to add.
* @param storeToFile Indicates if the net should be stored to disk.
* @throws de.invation.code.toval.misc.wd.ProjectComponentException
*/
public void addComponent(O component, boolean storeToFile, boolean notifyListeners) throws ProjectComponentException {
Validate.notNull(component);
Validate.notNull(storeToFile);
String componentName = component.getName();
Validate.notNull(componentName);
if(containsComponent(componentName))
throw new ProjectComponentException("Container already contains component with name \"" +componentName+ "\"");
File componentFile = null;
try {
File pathFile = getComponentDirectory(componentName);
pathFile.mkdir();
componentFile = getComponentFile(pathFile, componentName);
} catch (Exception e) {
ExceptionDialog.showException(null, "", e, true);
throw new ProjectComponentException("Cannot create component file.", e);
}
components.put(componentName, component);
componentFiles.put(componentName, componentFile);
if (storeToFile) {
try{
storeComponent(component.getName());
} catch(Exception e){
throw new ProjectComponentException("Cannot store created component to disk.", e);
}
}
if(notifyListeners){
listenerSupport.notifyComponentAdded(component);
}
}
protected abstract void serializeComponent(O component, String basePath, String fileName) throws Exception;
protected String getSerializationFileName(O component) {
return component.getName();
}
public void renameComponent(String oldName, String newName) throws ProjectComponentException {
renameComponent(oldName, newName, DEFAULT_NOTIFY_LISTENERS);
}
public void renameComponent(String oldName, String newName, boolean notifyListeners) throws ProjectComponentException {
validateComponent(oldName);
if(containsComponent(newName))
throw new ProjectComponentException("Container already contains " + getComponentDescriptor() + " with name \"" + newName + "\"");
O component = getComponent(oldName);
component.setName(newName);
removeComponent(oldName, true, false);
addComponent(component, true, false);
if (notifyListeners) {
listenerSupport.notifyComponentRenamed(component, oldName, newName);
}
}
public void validateComponent(String componentName) throws ProjectComponentException {
if (!components.containsKey(componentName)) {
throw new ProjectComponentException("No " + getComponentDescriptor() + " with name \"" + componentName + "\"");
}
if (!componentFiles.containsKey(componentName)) {
throw new ProjectComponentException("No file for " + getComponentDescriptor() + " with name \"" + componentName + "\"");
}
}
public final File getComponentDirectory(String componentName) throws ProjectComponentException {
if(!useSubdirectoriesForComponents){
File path = new File(basePath);
Validate.directory(path);
return path;
}
try {
File path = new File(String.format(componentDirectoryFormat, basePath, componentName));
Validate.directory(path);
return path;
} catch (Exception e) {
throw new ProjectComponentException("Cannot compose component directory.", e);
}
}
private File getComponentFile(File pathFile, String componentName) throws ProjectComponentException {
try {
return new File(String.format(componentFileFormat, pathFile.getCanonicalPath(), componentName, ".pnml"));
} catch (IOException e) {
throw new ProjectComponentException("Cannot compose component file.", e);
}
}
protected String getFileEndingForComponent(O component){
return DEFAULT_FILE_ENDING;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy