Skip to content

Commit

Permalink
Merge pull request #116 from HPI-Information-Systems/algorithm_loading
Browse files Browse the repository at this point in the history
scanning recursively for interfaces when loading algorithms
  • Loading branch information
jakob-zwiener committed Jun 16, 2014
2 parents 2672408 + aeee6a6 commit 9d938df
Show file tree
Hide file tree
Showing 17 changed files with 498 additions and 166 deletions.
2 changes: 1 addition & 1 deletion algorithm_integration/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>15.0</version>
<version>17.0</version>
<scope>compile</scope>
</dependency>
<dependency>
Expand Down
21 changes: 17 additions & 4 deletions backend/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,13 @@
<overWrite>true</overWrite>
<outputDirectory>src/test/resources/algorithms</outputDirectory>
</artifactItem>
<artifactItem>
<groupId>de.uni-potsdam.hpi.metanome</groupId>
<artifactId>example_indirect_interfaces_algorithm</artifactId>
<type>jar</type>
<overWrite>true</overWrite>
<outputDirectory>src/test/resources/algorithms</outputDirectory>
</artifactItem>
<artifactItem>
<groupId>de.uni-potsdam.hpi.metanome</groupId>
<artifactId>example_ucc_algorithm</artifactId>
Expand Down Expand Up @@ -214,6 +221,12 @@
<version>0.0.2-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>de.uni-potsdam.hpi.metanome</groupId>
<artifactId>example_indirect_interfaces_algorithm</artifactId>
<version>0.0.2-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>de.uni-potsdam.hpi.metanome</groupId>
<artifactId>example_ucc_algorithm</artifactId>
Expand Down Expand Up @@ -241,7 +254,7 @@
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>15.0</version>
<version>17.0</version>
<scope>compile</scope>
</dependency>
<dependency>
Expand All @@ -251,9 +264,9 @@
<scope>compile</scope>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.4</version>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.3.2</version>
<scope>compile</scope>
</dependency>
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,15 @@
import de.uni_potsdam.hpi.metanome.configuration.ConfigurationValue;
import de.uni_potsdam.hpi.metanome.configuration.ConfigurationValueFactory;
import de.uni_potsdam.hpi.metanome.result_receiver.CloseableOmniscientResultReceiver;
import org.apache.commons.lang3.ClassUtils;

import java.io.Closeable;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

public class AlgorithmExecutor implements Closeable {

Expand Down Expand Up @@ -163,9 +167,7 @@ public long executeAlgorithmWithValues(String algorithmFileName,
}

protected Set<Class<?>> getInterfaces(Object object) {
Set<Class<?>> interfaces = new HashSet<>();
Collections.addAll(interfaces, object.getClass().getInterfaces());
return interfaces;
return new HashSet<>(ClassUtils.getAllInterfaces(object.getClass()));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

import de.uni_potsdam.hpi.metanome.algorithm_integration.algorithm_execution.FileCreationException;
import de.uni_potsdam.hpi.metanome.algorithm_integration.algorithm_execution.FileGenerator;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang3.RandomStringUtils;

import java.io.File;
import java.io.IOException;
Expand All @@ -34,50 +34,50 @@
*/
public class TempFileGenerator implements FileGenerator {

public static final String TEMP_FILE_PATH = "temp_files";
public static final int FILE_NAME_LENGTH = 30;
public static final String TEMP_FILE_PATH = "temp_files";
public static final int FILE_NAME_LENGTH = 30;

protected String pathToFolder;
protected List<File> createdFiles;
protected String pathToFolder;
protected List<File> createdFiles;

public TempFileGenerator() throws UnsupportedEncodingException {
// Get path to resource dir.
String pathToFolder = Thread.currentThread().getContextClassLoader().getResource("").getPath();
pathToFolder += "/" + TEMP_FILE_PATH;
this.pathToFolder = URLDecoder.decode(pathToFolder, "utf-8");
// Create subdir.
new File(this.pathToFolder).mkdirs();
public TempFileGenerator() throws UnsupportedEncodingException {
// Get path to resource dir.
String pathToFolder = Thread.currentThread().getContextClassLoader().getResource("").getPath();
pathToFolder += "/" + TEMP_FILE_PATH;
this.pathToFolder = URLDecoder.decode(pathToFolder, "utf-8");
// Create subdir.
new File(this.pathToFolder).mkdirs();

this.createdFiles = new LinkedList<>();
}
this.createdFiles = new LinkedList<>();
}

@Override
public File getTemporaryFile() throws FileCreationException {
String fileName = RandomStringUtils.randomAlphanumeric(FILE_NAME_LENGTH).toLowerCase();
File tempFile = new File(pathToFolder + "/" + fileName);
@Override
public File getTemporaryFile() throws FileCreationException {
String fileName = RandomStringUtils.randomAlphanumeric(FILE_NAME_LENGTH).toLowerCase();
File tempFile = new File(pathToFolder + "/" + fileName);

try {
tempFile.createNewFile();
} catch (IOException e) {
throw new FileCreationException("Could not create temporary file.");
}
try {
tempFile.createNewFile();
} catch (IOException e) {
throw new FileCreationException("Could not create temporary file.");
}

// Mark the file for deletion on vm exit.
tempFile.deleteOnExit();
// Remember the file to be deleted on close.
createdFiles.add(tempFile);
// Mark the file for deletion on vm exit.
tempFile.deleteOnExit();
// Remember the file to be deleted on close.
createdFiles.add(tempFile);

return tempFile;
}
return tempFile;
}

@Override
public void close() {
for (File tempFile : createdFiles) {
try {
tempFile.delete();
} catch (Exception e) {
System.out.println("A file could not be deleted.");
}
}
}
@Override
public void close() {
for (File tempFile : createdFiles) {
try {
tempFile.delete();
} catch (Exception e) {
System.out.println("A file could not be deleted.");
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package de.uni_potsdam.hpi.metanome.algorithm_loading;

import de.uni_potsdam.hpi.metanome.algorithm_integration.Algorithm;
import org.apache.commons.lang3.ClassUtils;

import java.io.File;
import java.io.FilenameFilter;
Expand All @@ -25,7 +26,6 @@
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLDecoder;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;
Expand Down Expand Up @@ -124,6 +124,6 @@ public Set<Class<?>> getAlgorithmInterfaces(File algorithmJarFile) throws IOExce
jar.close();
}

return new HashSet<>(Arrays.asList(algorithmClass.getInterfaces()));
return new HashSet<>(ClassUtils.getAllInterfaces(algorithmClass));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,30 +67,30 @@ public void setUp() throws UnsupportedEncodingException {
executor = new AlgorithmExecutor(resultReceiver, progressCache, fileGenerator);
}

/**
* Test method for {@link de.uni_potsdam.hpi.metanome.algorithm_execution.AlgorithmExecutor#executeAlgorithm(String, List)}
* <p/>
* Tests the execution of an fd algorithm. The elapsed time should be greater than 0ns.
*
* @throws de.uni_potsdam.hpi.metanome.algorithm_loading.AlgorithmLoadingException
* @throws AlgorithmConfigurationException
* @throws AlgorithmExecutionException
* @throws NoSuchMethodException
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws InstantiationException
* @throws ClassNotFoundException
* @throws IOException
* @throws SecurityException
* @throws IllegalArgumentException
*/
@Test
public void executeFunctionalDependencyAlgorithmTest() throws AlgorithmLoadingException, AlgorithmExecutionException, IllegalArgumentException, SecurityException, IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
// Setup
List<ConfigurationValue> configs = new ArrayList<>();
configs.add(new ConfigurationValueString("pathToOutputFile", "path/to/file"));
String[] selectedValues = {"second"};
configs.add(new ConfigurationValueListBox("column names", selectedValues));
/**
* Test method for {@link de.uni_potsdam.hpi.metanome.algorithm_execution.AlgorithmExecutor#executeAlgorithm(String, List)}
* <p/>
* Tests the execution of an fd algorithm. The elapsed time should be greater than 0ns.
*
* @throws de.uni_potsdam.hpi.metanome.algorithm_loading.AlgorithmLoadingException
* @throws AlgorithmConfigurationException
* @throws AlgorithmExecutionException
* @throws NoSuchMethodException
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws InstantiationException
* @throws ClassNotFoundException
* @throws IOException
* @throws SecurityException
* @throws IllegalArgumentException
*/
@Test
public void executeFunctionalDependencyAlgorithmTest() throws AlgorithmLoadingException, AlgorithmExecutionException, IllegalArgumentException, SecurityException, IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
// Setup
List<ConfigurationValue> configs = new ArrayList<>();
configs.add(new ConfigurationValueString("pathToOutputFile", "path/to/file"));
String[] selectedValues = {"second"};
configs.add(new ConfigurationValueListBox("column names", selectedValues));

// Execute functionality
long elapsedTime = executor.executeAlgorithmWithValues("example_fd_algorithm.jar", configs);
Expand All @@ -102,7 +102,7 @@ public void executeFunctionalDependencyAlgorithmTest() throws AlgorithmLoadingEx

/**
* Test method for {@link de.uni_potsdam.hpi.metanome.algorithm_execution.AlgorithmExecutor#executeAlgorithmWithValues(String, java.util.List)}
*
* <p/>
* Tests the execution of an ind algorithm.
*
* @throws AlgorithmConfigurationException
Expand All @@ -121,12 +121,12 @@ public void executeFunctionalDependencyAlgorithmTest() throws AlgorithmLoadingEx
public void executeInclusionDependencyTest() throws AlgorithmLoadingException, AlgorithmExecutionException, IllegalArgumentException, SecurityException, IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
// Setup
List<ConfigurationValue> configs = new ArrayList<>();
configs.add(new ConfigurationValueString(ExampleAlgorithm.STRING_IDENTIFIER, "table1"));
configs.add(new ConfigurationValueInteger(ExampleAlgorithm.INTEGER_IDENTIFIER, 7));
configs.add(new ConfigurationValueRelationalInputGenerator(
ExampleAlgorithm.CSV_FILE_IDENTIFIER,
mock(RelationalInputGenerator.class),
mock(RelationalInputGenerator.class)));
configs.add(new ConfigurationValueString(ExampleAlgorithm.STRING_IDENTIFIER, "table1"));
configs.add(new ConfigurationValueInteger(ExampleAlgorithm.INTEGER_IDENTIFIER, 7));
configs.add(new ConfigurationValueRelationalInputGenerator(
ExampleAlgorithm.CSV_FILE_IDENTIFIER,
mock(RelationalInputGenerator.class),
mock(RelationalInputGenerator.class)));

// Execute functionality
executor.executeAlgorithmWithValues("example_ind_algorithm.jar", configs);
Expand All @@ -137,7 +137,7 @@ public void executeInclusionDependencyTest() throws AlgorithmLoadingException, A

/**
* Test method for {@link de.uni_potsdam.hpi.metanome.algorithm_execution.AlgorithmExecutor#executeAlgorithmWithValues(String, java.util.List)}
*
* <p/>
* Tests the execution of an ucc algorithm.
*
* @throws AlgorithmConfigurationException
Expand Down Expand Up @@ -169,7 +169,7 @@ public void executeUniqueColumnCombinationsAlgorithmTest() throws AlgorithmLoadi

/**
* Test method for {@link de.uni_potsdam.hpi.metanome.algorithm_execution.AlgorithmExecutor#executeAlgorithmWithValues(String, java.util.List)}
*
* <p/>
* Tests the execution of an holistic algorithm.
*
* @throws AlgorithmExecutionException
Expand Down Expand Up @@ -198,6 +198,33 @@ public void testExecuteHolisticAlgorithm() throws AlgorithmLoadingException, Alg
verify(resultReceiver).receiveResult(isA(UniqueColumnCombination.class));
}

/**
* Test method for {@link de.uni_potsdam.hpi.metanome.algorithm_execution.AlgorithmExecutor#executeAlgorithmWithValues(String, java.util.List)}
* <p/>
* Algorithms that do not implement the metanome interfaces directly should still be executable.
*
* @throws IllegalAccessException
* @throws IOException
* @throws InstantiationException
* @throws AlgorithmExecutionException
* @throws NoSuchMethodException
* @throws InvocationTargetException
* @throws ClassNotFoundException
*/
@Test
public void testExecuteIndirectInterfaceAlgorithm() throws IllegalAccessException, IOException, InstantiationException, AlgorithmExecutionException, NoSuchMethodException, InvocationTargetException, ClassNotFoundException {
// Setup
List<ConfigurationValue> configurationValues = new LinkedList<>();
configurationValues.add(new ConfigurationValueRelationalInputGenerator("identifier", mock(RelationalInputGenerator.class)));

// Execute functionality
executor.executeAlgorithmWithValues("example_indirect_interfaces_algorithm.jar", configurationValues);

// Check result
verify(resultReceiver).receiveResult(isA(UniqueColumnCombination.class));

}

//FIXME add test for incorrect file name

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ public void testRetrieveUniqueColumnCombinationJarFiles() throws IOException, Cl
String[] algos = algoFinder.getAvailableAlgorithmFileNames(UniqueColumnCombinationsAlgorithm.class);

//Check
assertEquals(2, algos.length); //TODO determine number of expected algorithms dynamically
assertEquals(3, algos.length); //TODO determine number of expected algorithms dynamically
//TODO make sure no wrong algorithms are returned
}
}
2 changes: 1 addition & 1 deletion testing_algorithms/example_fd_algorithm/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>12.0</version>
<version>17.0</version>
</dependency>
</dependencies>

Expand Down
2 changes: 1 addition & 1 deletion testing_algorithms/example_holistic_algorithm/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>12.0</version>
<version>17.0</version>
</dependency>
</dependencies>

Expand Down
4 changes: 2 additions & 2 deletions testing_algorithms/example_ind_algorithm/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>12.0</version>
<scope>compile</scope>
<version>17.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>commons-io</groupId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/target
/.settings
.classpath
.project
Loading

0 comments on commit 9d938df

Please sign in to comment.