From 81aec527d02534b8c815f79c944bada61dff0e84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20B=C3=B6hme?= Date: Tue, 30 Apr 2013 13:31:20 +0200 Subject: [PATCH 1/2] Improved specification of modules directory. Flux now looks for a modules directory in the following locations: 1. A modules directory in the current working directory 2. A modules directory in the same directory as the metafacture-core jar file 3. If the first commandline argument is -modules=PATH, this is used as the modules directory --- src/main/java/org/culturegraph/mf/Flux.java | 86 ++++++++++++++++----- 1 file changed, 65 insertions(+), 21 deletions(-) diff --git a/src/main/java/org/culturegraph/mf/Flux.java b/src/main/java/org/culturegraph/mf/Flux.java index 8dc323d0d..ba0cd43be 100644 --- a/src/main/java/org/culturegraph/mf/Flux.java +++ b/src/main/java/org/culturegraph/mf/Flux.java @@ -18,6 +18,8 @@ import java.io.File; import java.io.FilenameFilter; import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URISyntaxException; import java.net.URL; import java.net.URLClassLoader; import java.util.HashMap; @@ -34,13 +36,19 @@ /** * @author Markus Michael Geipel - * + * */ public final class Flux { public static final String MODULES_DIR = "modules"; + + private static final String JAR_FILE_EXTENSION = ".jar"; + private static final String CLASS_FILE_EXTENSION = ".class"; + private static final Pattern VAR_PATTERN = Pattern.compile("([^=]*)=(.*)"); private static final String SCRIPT_HOME = "FLUX_DIR"; + private static final String MODULES_DIR_ARG = "-modules="; + private Flux() { // no instances } @@ -49,34 +57,27 @@ private Flux() { * @param args * @throws IOException * @throws RecognitionException + * @throws URISyntaxException */ public static void main(final String[] args) throws IOException, RecognitionException { - final File modulesDir = new File(MODULES_DIR); - if (modulesDir.exists()) { - final FilenameFilter filter = new FilenameFilter() { - @Override - public boolean accept(final File dir, final String name) { - return name.endsWith(".jar") || name.endsWith(".class"); - } - }; - final List moduleURLs = new LinkedList(); - for (File file : modulesDir.listFiles(filter)) { - moduleURLs.add(file.getAbsoluteFile().toURI().toURL()); - } - final URLClassLoader moduleLoader = new URLClassLoader(moduleURLs.toArray(new URL[0]), Thread - .currentThread().getContextClassLoader()); - Thread.currentThread().setContextClassLoader(moduleLoader); + loadModules(getModulesDir(args)); + + final int fileArg; + if (args.length > 0 && args[0].startsWith(MODULES_DIR_ARG)) { + fileArg = 1; + } else { + fileArg = 0; } - if (args.length < 1) { + if (args.length < (fileArg + 1)) { Flow.printHelp(System.out); System.exit(2); } else { - final File fluxFile = new File(args[0]); + final File fluxFile = new File(args[fileArg]); if (!fluxFile.exists()) { - System.err.println("File not found: " + args[0]); + System.err.println("File not found: " + args[fileArg]); System.exit(1); return; } @@ -85,7 +86,10 @@ public boolean accept(final File dir, final String name) { final Map vars = new HashMap(); vars.put(SCRIPT_HOME, fluxFile.getAbsoluteFile().getParent() + System.getProperty("file.separator")); - for (int i = 1; i < args.length; ++i) { + for (int i = fileArg + 1; i < args.length; ++i) { + if (args[i].startsWith(MODULES_DIR_ARG)) { + continue; + } final Matcher matcher = VAR_PATTERN.matcher(args[i]); if (!matcher.find()) { Flow.printHelp(System.err); @@ -96,11 +100,51 @@ public boolean accept(final File dir, final String name) { // run parser and builder final List flows = FluxCompiler.compile(ResourceUtil.getStream(fluxFile), vars); - for (Flow flow : flows) { + for (final Flow flow : flows) { flow.start(); } } } + private static File getModulesDir(final String[] args) { + File modulesDir = new File(MODULES_DIR); + + File programDir = null; + try { + programDir = new File(Flux.class.getProtectionDomain().getCodeSource().getLocation().toURI()); + } catch (final URISyntaxException e) { + // Ignore the programDir, if it is not available + } + if (programDir != null) { + if (programDir.getName().endsWith(JAR_FILE_EXTENSION)) { + programDir = programDir.getParentFile(); + } + modulesDir = new File(programDir, MODULES_DIR); + } + + if (args.length > 0 && args[0].startsWith(MODULES_DIR_ARG)) { + modulesDir = new File(args[0].substring(MODULES_DIR_ARG.length())); + } + + return modulesDir; + } + + private static void loadModules(final File modulesDir) throws MalformedURLException { + if (modulesDir.exists()) { + final FilenameFilter filter = new FilenameFilter() { + @Override + public boolean accept(final File dir, final String name) { + return name.endsWith(JAR_FILE_EXTENSION) || name.endsWith(CLASS_FILE_EXTENSION); + } + }; + final List moduleURLs = new LinkedList(); + for (final File file : modulesDir.listFiles(filter)) { + moduleURLs.add(file.getAbsoluteFile().toURI().toURL()); + } + final URLClassLoader moduleLoader = new URLClassLoader(moduleURLs.toArray(new URL[0]), Thread + .currentThread().getContextClassLoader()); + Thread.currentThread().setContextClassLoader(moduleLoader); + } + } } \ No newline at end of file From 3551526a145d910c62e8243a7b7f6fc5ca986415 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20B=C3=B6hme?= Date: Thu, 2 May 2013 14:10:59 +0200 Subject: [PATCH 2/2] Added a metamorph collector to output ranges. The collector interprets the first literal it receives as a range start and the second as a range end. The values are converted to integers and for each number between the two an additional literal is generated. Usage: --- .../mf/morph/collectors/Range.java | 71 ++++++++ .../resources/morph-collectors.properties | 3 +- src/main/resources/schemata/metamorph.xsd | 17 +- .../mf/morph/collectors/CollectorTest.java | 2 +- .../mf/morph/collectors/RangeTest.xml | 164 ++++++++++++++++++ 5 files changed, 253 insertions(+), 4 deletions(-) create mode 100644 src/main/java/org/culturegraph/mf/morph/collectors/Range.java create mode 100644 src/test/java/org/culturegraph/mf/morph/collectors/RangeTest.xml diff --git a/src/main/java/org/culturegraph/mf/morph/collectors/Range.java b/src/main/java/org/culturegraph/mf/morph/collectors/Range.java new file mode 100644 index 000000000..314ab7e6e --- /dev/null +++ b/src/main/java/org/culturegraph/mf/morph/collectors/Range.java @@ -0,0 +1,71 @@ +/* + * Copyright 2013 Deutsche Nationalbibliothek + * + * Licensed under the Apache License, Version 2.0 the "License"; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.culturegraph.mf.morph.collectors; + +import java.util.SortedSet; +import java.util.TreeSet; + +import org.culturegraph.mf.morph.Metamorph; +import org.culturegraph.mf.morph.NamedValueSource; + + +/** + * Corresponds to the <range> tag. + * + * @author Christoph Böhme + */ +public final class Range extends AbstractCollect { + private final SortedSet values = new TreeSet(); + + private Integer first; + + public Range(final Metamorph metamorph) { + super(metamorph); + setNamedValueReceiver(metamorph); + } + + @Override + protected void emit() { + for (final Integer i: values) { + getNamedValueReceiver().receive(getName(), i.toString(), this, getRecordCount(), getEntityCount()); + } + } + + @Override + protected boolean isComplete() { + return false; + } + + @Override + protected void receive(final String name, final String value, final NamedValueSource source) { + if (first == null) { + first = Integer.valueOf(value); + } else { + final int last = Integer.valueOf(value).intValue(); + for (int i = first.intValue(); i <= last; ++i) { + values.add(Integer.valueOf(i)); + } + first = null; + } + } + + @Override + protected void clear() { + values.clear(); + first = null; + } + +} diff --git a/src/main/resources/morph-collectors.properties b/src/main/resources/morph-collectors.properties index 1051685e0..754f16265 100644 --- a/src/main/resources/morph-collectors.properties +++ b/src/main/resources/morph-collectors.properties @@ -4,4 +4,5 @@ group org.culturegraph.mf.morph.collectors.Group entity org.culturegraph.mf.morph.collectors.Entity concat org.culturegraph.mf.morph.collectors.Concat tuples org.culturegraph.mf.morph.collectors.Tuples -square org.culturegraph.mf.morph.collectors.Square \ No newline at end of file +square org.culturegraph.mf.morph.collectors.Square +range org.culturegraph.mf.morph.collectors.Range \ No newline at end of file diff --git a/src/main/resources/schemata/metamorph.xsd b/src/main/resources/schemata/metamorph.xsd index 6505040d6..122195561 100644 --- a/src/main/resources/schemata/metamorph.xsd +++ b/src/main/resources/schemata/metamorph.xsd @@ -266,7 +266,7 @@ - Create an entity + Create an entity @@ -284,7 +284,19 @@ - + + Interprets pairs of consecutive literals as integer range start and end. For each number between the two an additional literal is generated. + + + + + + + + + + + Used to receive literals @@ -441,6 +453,7 @@ + diff --git a/src/test/java/org/culturegraph/mf/morph/collectors/CollectorTest.java b/src/test/java/org/culturegraph/mf/morph/collectors/CollectorTest.java index 8aa5fbfc1..823b2f296 100644 --- a/src/test/java/org/culturegraph/mf/morph/collectors/CollectorTest.java +++ b/src/test/java/org/culturegraph/mf/morph/collectors/CollectorTest.java @@ -25,6 +25,6 @@ */ @RunWith(TestSuite.class) @TestDefinitions({ "CombineTest.xml", "GroupTest.xml", "ChooseTest.xml", "EntityTest.xml", "ConcatTest.xml", - "Nested.xml", "NestedEntity.xml", "TuplesTest.xml", "Misc.xml", "SquareTest.xml" }) + "Nested.xml", "NestedEntity.xml", "TuplesTest.xml", "Misc.xml", "SquareTest.xml", "RangeTest.xml" }) public final class CollectorTest {/* bind to xml test */ } diff --git a/src/test/java/org/culturegraph/mf/morph/collectors/RangeTest.xml b/src/test/java/org/culturegraph/mf/morph/collectors/RangeTest.xml new file mode 100644 index 000000000..ba7ecca84 --- /dev/null +++ b/src/test/java/org/culturegraph/mf/morph/collectors/RangeTest.xml @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +