Skip to content

Commit 205a527

Browse files
author
mgeipel
committed
Merge branch 'master' of ssh://[email protected]/culturegraph/metafacture-core.git
2 parents 1ea56c4 + a62d463 commit 205a527

File tree

6 files changed

+318
-25
lines changed

6 files changed

+318
-25
lines changed

src/main/java/org/culturegraph/mf/Flux.java

Lines changed: 65 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
import java.io.File;
1919
import java.io.FilenameFilter;
2020
import java.io.IOException;
21+
import java.net.MalformedURLException;
22+
import java.net.URISyntaxException;
2123
import java.net.URL;
2224
import java.net.URLClassLoader;
2325
import java.util.HashMap;
@@ -34,13 +36,19 @@
3436

3537
/**
3638
* @author Markus Michael Geipel
37-
*
39+
*
3840
*/
3941
public final class Flux {
4042
public static final String MODULES_DIR = "modules";
43+
44+
private static final String JAR_FILE_EXTENSION = ".jar";
45+
private static final String CLASS_FILE_EXTENSION = ".class";
46+
4147
private static final Pattern VAR_PATTERN = Pattern.compile("([^=]*)=(.*)");
4248
private static final String SCRIPT_HOME = "FLUX_DIR";
4349

50+
private static final String MODULES_DIR_ARG = "-modules=";
51+
4452
private Flux() {
4553
// no instances
4654
}
@@ -49,34 +57,27 @@ private Flux() {
4957
* @param args
5058
* @throws IOException
5159
* @throws RecognitionException
60+
* @throws URISyntaxException
5261
*/
5362
public static void main(final String[] args) throws IOException, RecognitionException {
5463

55-
final File modulesDir = new File(MODULES_DIR);
56-
if (modulesDir.exists()) {
57-
final FilenameFilter filter = new FilenameFilter() {
58-
@Override
59-
public boolean accept(final File dir, final String name) {
60-
return name.endsWith(".jar") || name.endsWith(".class");
61-
}
62-
};
63-
final List<URL> moduleURLs = new LinkedList<URL>();
64-
for (File file : modulesDir.listFiles(filter)) {
65-
moduleURLs.add(file.getAbsoluteFile().toURI().toURL());
66-
}
67-
final URLClassLoader moduleLoader = new URLClassLoader(moduleURLs.toArray(new URL[0]), Thread
68-
.currentThread().getContextClassLoader());
69-
Thread.currentThread().setContextClassLoader(moduleLoader);
64+
loadModules(getModulesDir(args));
65+
66+
final int fileArg;
67+
if (args.length > 0 && args[0].startsWith(MODULES_DIR_ARG)) {
68+
fileArg = 1;
69+
} else {
70+
fileArg = 0;
7071
}
7172

72-
if (args.length < 1) {
73+
if (args.length < (fileArg + 1)) {
7374
Flow.printHelp(System.out);
7475
System.exit(2);
7576
} else {
7677

77-
final File fluxFile = new File(args[0]);
78+
final File fluxFile = new File(args[fileArg]);
7879
if (!fluxFile.exists()) {
79-
System.err.println("File not found: " + args[0]);
80+
System.err.println("File not found: " + args[fileArg]);
8081
System.exit(1);
8182
return;
8283
}
@@ -85,7 +86,10 @@ public boolean accept(final File dir, final String name) {
8586
final Map<String, String> vars = new HashMap<String, String>();
8687
vars.put(SCRIPT_HOME, fluxFile.getAbsoluteFile().getParent() + System.getProperty("file.separator"));
8788

88-
for (int i = 1; i < args.length; ++i) {
89+
for (int i = fileArg + 1; i < args.length; ++i) {
90+
if (args[i].startsWith(MODULES_DIR_ARG)) {
91+
continue;
92+
}
8993
final Matcher matcher = VAR_PATTERN.matcher(args[i]);
9094
if (!matcher.find()) {
9195
Flow.printHelp(System.err);
@@ -96,11 +100,51 @@ public boolean accept(final File dir, final String name) {
96100

97101
// run parser and builder
98102
final List<Flow> flows = FluxCompiler.compile(ResourceUtil.getStream(fluxFile), vars);
99-
for (Flow flow : flows) {
103+
for (final Flow flow : flows) {
100104
flow.start();
101105
}
102106
}
103107
}
104108

109+
private static File getModulesDir(final String[] args) {
110+
File modulesDir = new File(MODULES_DIR);
111+
112+
File programDir = null;
113+
try {
114+
programDir = new File(Flux.class.getProtectionDomain().getCodeSource().getLocation().toURI());
115+
} catch (final URISyntaxException e) {
116+
// Ignore the programDir, if it is not available
117+
}
118+
if (programDir != null) {
119+
if (programDir.getName().endsWith(JAR_FILE_EXTENSION)) {
120+
programDir = programDir.getParentFile();
121+
}
122+
modulesDir = new File(programDir, MODULES_DIR);
123+
}
124+
125+
if (args.length > 0 && args[0].startsWith(MODULES_DIR_ARG)) {
126+
modulesDir = new File(args[0].substring(MODULES_DIR_ARG.length()));
127+
}
128+
129+
return modulesDir;
130+
}
131+
132+
private static void loadModules(final File modulesDir) throws MalformedURLException {
133+
if (modulesDir.exists()) {
134+
final FilenameFilter filter = new FilenameFilter() {
135+
@Override
136+
public boolean accept(final File dir, final String name) {
137+
return name.endsWith(JAR_FILE_EXTENSION) || name.endsWith(CLASS_FILE_EXTENSION);
138+
}
139+
};
140+
final List<URL> moduleURLs = new LinkedList<URL>();
141+
for (final File file : modulesDir.listFiles(filter)) {
142+
moduleURLs.add(file.getAbsoluteFile().toURI().toURL());
143+
}
144+
final URLClassLoader moduleLoader = new URLClassLoader(moduleURLs.toArray(new URL[0]), Thread
145+
.currentThread().getContextClassLoader());
146+
Thread.currentThread().setContextClassLoader(moduleLoader);
147+
}
148+
}
105149

106150
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright 2013 Deutsche Nationalbibliothek
3+
*
4+
* Licensed under the Apache License, Version 2.0 the "License";
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.culturegraph.mf.morph.collectors;
17+
18+
import java.util.SortedSet;
19+
import java.util.TreeSet;
20+
21+
import org.culturegraph.mf.morph.Metamorph;
22+
import org.culturegraph.mf.morph.NamedValueSource;
23+
24+
25+
/**
26+
* Corresponds to the <code>&lt;range&gt;</code> tag.
27+
*
28+
* @author Christoph Böhme
29+
*/
30+
public final class Range extends AbstractCollect {
31+
private final SortedSet<Integer> values = new TreeSet<Integer>();
32+
33+
private Integer first;
34+
35+
public Range(final Metamorph metamorph) {
36+
super(metamorph);
37+
setNamedValueReceiver(metamorph);
38+
}
39+
40+
@Override
41+
protected void emit() {
42+
for (final Integer i: values) {
43+
getNamedValueReceiver().receive(getName(), i.toString(), this, getRecordCount(), getEntityCount());
44+
}
45+
}
46+
47+
@Override
48+
protected boolean isComplete() {
49+
return false;
50+
}
51+
52+
@Override
53+
protected void receive(final String name, final String value, final NamedValueSource source) {
54+
if (first == null) {
55+
first = Integer.valueOf(value);
56+
} else {
57+
final int last = Integer.valueOf(value).intValue();
58+
for (int i = first.intValue(); i <= last; ++i) {
59+
values.add(Integer.valueOf(i));
60+
}
61+
first = null;
62+
}
63+
}
64+
65+
@Override
66+
protected void clear() {
67+
values.clear();
68+
first = null;
69+
}
70+
71+
}

src/main/resources/morph-collectors.properties

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ group org.culturegraph.mf.morph.collectors.Group
44
entity org.culturegraph.mf.morph.collectors.Entity
55
concat org.culturegraph.mf.morph.collectors.Concat
66
tuples org.culturegraph.mf.morph.collectors.Tuples
7-
square org.culturegraph.mf.morph.collectors.Square
7+
square org.culturegraph.mf.morph.collectors.Square
8+
range org.culturegraph.mf.morph.collectors.Range

src/main/resources/schemata/metamorph.xsd

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@
266266
</element>
267267

268268
<element name="entity">
269-
<annotation><documentation>Create an entity</documentation></annotation>
269+
<annotation><documentation>Create an entity</documentation></annotation>
270270
<complexType>
271271
<choice minOccurs="1" maxOccurs="unbounded">
272272
<element ref="tns:entity-name" minOccurs="0" maxOccurs="1" />
@@ -284,7 +284,19 @@
284284
</complexType>
285285
</element>
286286

287-
287+
<element name="range">
288+
<annotation><documentation>Interprets pairs of consecutive literals as integer range start and end. For each number between the two an additional literal is generated.</documentation></annotation>
289+
<complexType>
290+
<sequence>
291+
<group ref="tns:literal-rule" minOccurs="1" maxOccurs="unbounded" />
292+
<element ref="tns:postprocess" minOccurs="0" maxOccurs="1" />
293+
</sequence>
294+
<attribute name="name" type="string" use="required" />
295+
<attribute name="reset" type="boolean" use="optional" default="false" />
296+
<attribute name="sameEntity" type="boolean" use="optional" default="false" />
297+
<attribute name="flushWith" type="string" use="optional" default="record"/>
298+
</complexType>
299+
</element>
288300

289301
<element name="data">
290302
<annotation><documentation>Used to receive literals</documentation></annotation>
@@ -441,6 +453,7 @@
441453
<element ref="tns:concat" />
442454
<element ref="tns:square" />
443455
<element ref="tns:tuples" />
456+
<element ref="tns:range" />
444457
</choice>
445458
</group>
446459

src/test/java/org/culturegraph/mf/morph/collectors/CollectorTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,6 @@
2525
*/
2626
@RunWith(TestSuite.class)
2727
@TestDefinitions({ "CombineTest.xml", "GroupTest.xml", "ChooseTest.xml", "EntityTest.xml", "ConcatTest.xml",
28-
"Nested.xml", "NestedEntity.xml", "TuplesTest.xml", "Misc.xml", "SquareTest.xml" })
28+
"Nested.xml", "NestedEntity.xml", "TuplesTest.xml", "Misc.xml", "SquareTest.xml", "RangeTest.xml" })
2929
public final class CollectorTest {/* bind to xml test */
3030
}

0 commit comments

Comments
 (0)