Skip to content

Commit 73b5938

Browse files
gselzerctrueden
authored andcommitted
Separate out API module to contain annotations
1 parent e5114b8 commit 73b5938

12 files changed

Lines changed: 513 additions & 0 deletions

File tree

pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
<module>scijava/scijava-function</module>
5252
<module>scijava/scijava-ops</module>
5353
<module>scijava/scijava-struct</module>
54+
<module>scijava/scijava-ops-api</module>
5455
<module>scijava/scijava-taglets</module>
5556
<module>scijava/scijava-testutil</module>
5657
<module>scijava/scijava-types</module>

scijava/scijava-ops-api/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/.apt_generated/
2+
/.apt_generated_tests/
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
Copyright (c) 2016 - 2019, SciJava Ops developers.
2+
All rights reserved.
3+
4+
Redistribution and use in source and binary forms, with or without modification,
5+
are permitted provided that the following conditions are met:
6+
7+
1. Redistributions of source code must retain the above copyright notice, this
8+
list of conditions and the following disclaimer.
9+
10+
2. Redistributions in binary form must reproduce the above copyright notice,
11+
this list of conditions and the following disclaimer in the documentation
12+
and/or other materials provided with the distribution.
13+
14+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17+
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
18+
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19+
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20+
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21+
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22+
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23+
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24+
POSSIBILITY OF SUCH DAMAGE.

scijava/scijava-ops-api/README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
The SciJava Ops projects offers a framework for typed operations, or Ops.
2+
3+
Each op implements a particular functional interface, possessing typed inputs
4+
or outputs. The system provides the ability to request ops matching particular
5+
constraints, including implementing interface, input types and output types.
6+
7+
It is like Java's method overloading, but more powerful, and more extensible.
8+
9+
More documentation coming later.
10+
11+
See also [ImageJ Ops](https://github.com/imagej/imagej-ops), a collection of
12+
ops focused on scientific image processing and analysis.
Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
#!/usr/bin/env groovy
2+
3+
/*
4+
* #%L
5+
* SciJava Operations: a framework for reusable algorithms.
6+
* %%
7+
* Copyright (C) 2018 SciJava developers.
8+
* %%
9+
* Redistribution and use in source and binary forms, with or without
10+
* modification, are permitted provided that the following conditions are met:
11+
*
12+
* 1. Redistributions of source code must retain the above copyright notice,
13+
* this list of conditions and the following disclaimer.
14+
* 2. Redistributions in binary form must reproduce the above copyright notice,
15+
* this list of conditions and the following disclaimer in the documentation
16+
* and/or other materials provided with the distribution.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
22+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28+
* POSSIBILITY OF SUCH DAMAGE.
29+
* #L%
30+
*/
31+
32+
debug = System.getenv('DEBUG')
33+
def debug(msg) {
34+
if (debug) System.err.println("[DEBUG] $msg")
35+
}
36+
37+
@Grab('org.apache.velocity:velocity:1.7')
38+
import org.apache.velocity.app.VelocityEngine
39+
40+
// TODO: Get path to Groovy script and make these dirs relative to that.
41+
templateDirectory = 'templates'
42+
outputDirectory = 'src'
43+
44+
knownFiles = new java.util.HashSet();
45+
46+
/* Gets the last modified timestamp for the given file. */
47+
def timestamp(dir, file) {
48+
if (file == null) return Long.MAX_VALUE;
49+
file = new java.io.File(dir, file);
50+
knownFiles.add(file);
51+
return file.lastModified();
52+
}
53+
54+
/* Processes a template using Apache Velocity. */
55+
def processTemplate(engine, context, templateFile, outFilename) {
56+
debug("processTemplate('$engine', '$context', '$templateFile', '$outFilename')")
57+
58+
if (outFilename == null) return; // nothing to do
59+
60+
// create output directory if it does not already exist
61+
outFile = new java.io.File(outputDirectory, outFilename);
62+
knownFiles.add(outFile);
63+
if (outFile.getParentFile() != null) outFile.getParentFile().mkdirs();
64+
65+
// apply the template and write out the result
66+
t = engine.getTemplate(templateFile);
67+
writer = new StringWriter();
68+
t.merge(context, writer);
69+
out = new PrintWriter(outFile, "UTF-8");
70+
out.print(writer.toString());
71+
out.close();
72+
}
73+
74+
/* Evaluates a string using Groovy. */
75+
def parseValue(sh, translationsFile, key, expression) {
76+
try {
77+
result = sh.evaluate(expression)
78+
sh.setVariable(key, result)
79+
return result
80+
}
81+
catch (groovy.lang.GroovyRuntimeException e) {
82+
print("[WARNING] $translationsFile: " +
83+
"key '$key' has unparseable value: " + e.getMessage());
84+
}
85+
}
86+
87+
/* Reads a translations File */
88+
def readTranslation(engine, globalContext, reader, templateSubdirectory, templateFile, translationsFile, isInclude){
89+
sh = new groovy.lang.GroovyShell();
90+
for (;;) {
91+
// read the line
92+
line = reader.readLine();
93+
94+
if (line == null) break;
95+
// check if the line starts a new section
96+
if (line.startsWith("[") && line.endsWith("]")) {
97+
// if we are parsing a .include file, return when we hit any sections
98+
if(isInclude){
99+
println("[WARNING] $translationsFile: Section definition in .include file. Ending processing of $translationsFile");
100+
return context;
101+
}
102+
// write out the previous file
103+
processTemplate(engine, context, templateFile, outputFilename);
104+
105+
// start a new file
106+
outputFilename = line.substring(1, line.length() - 1);
107+
if (!templateDirectory.equals(templateSubdirectory)) {
108+
subPath = templateSubdirectory.substring(templateDirectory.length() + 1);
109+
outputFilename = "$subPath/$outputFilename";
110+
}
111+
context = new org.apache.velocity.VelocityContext(globalContext);
112+
continue;
113+
}
114+
115+
// ignore blank lines
116+
trimmedLine = line.trim();
117+
if (trimmedLine.isEmpty()) continue;
118+
119+
// ignore comments
120+
if (trimmedLine.startsWith("#")) continue;
121+
122+
// include any global files
123+
if (trimmedLine.startsWith(".include")){
124+
includeFile = line.substring(9);
125+
if(includeFile.startsWith("templates")){
126+
includeSubdirectory = includeFile.substring(0, includeFile.lastIndexOf("/"))
127+
includeFile = includeFile.substring(includeFile.lastIndexOf("/"))
128+
}
129+
else{
130+
includeSubdirectory = templateSubdirectory
131+
}
132+
globalReader = new java.io.BufferedReader(new java.io.FileReader("$includeSubdirectory/$includeFile"));
133+
encapsulatedContext = new org.apache.velocity.VelocityContext(context)
134+
context = readTranslation(engine, encapsulatedContext, globalReader, templateSubdirectory, templateFile, includeFile, true)
135+
continue;
136+
}
137+
138+
if (!line.contains('=')) {
139+
print("[WARNING] $translationsFile: Ignoring spurious line: $line");
140+
continue;
141+
}
142+
143+
int idx = line.indexOf('=');
144+
key = line.substring(0, idx).trim();
145+
value = line.substring(idx + 1);
146+
147+
if (value.trim().equals('```')) {
148+
// multi-line value
149+
builder = new StringBuilder();
150+
for (;;) {
151+
line = reader.readLine();
152+
if (line == null) {
153+
throw new RuntimeException("Unfinished value: " + builder.toString());
154+
}
155+
if (line.equals('```')) {
156+
break;
157+
}
158+
if (builder.length() > 0) {
159+
builder.append("\n");
160+
}
161+
builder.append(line);
162+
}
163+
value = builder.toString();
164+
}
165+
166+
context.put(key, parseValue(sh, translationsFile, key, value));
167+
}
168+
169+
return context;
170+
}
171+
172+
/*
173+
* Translates a template into many files in the outputDirectory,
174+
* given a translations file in INI style; e.g.:
175+
*
176+
* [filename1]
177+
* variable1 = value1
178+
* variable2 = value2
179+
* ...
180+
* [filename2]
181+
* variable1 = value3
182+
* variable2 = value4
183+
* ...
184+
*/
185+
def translate(templateSubdirectory, templateFile, translationsFile) {
186+
debug("translate('$templateSubdirectory', '$templateFile', '$translationsFile')")
187+
188+
// initialize the Velocity engine
189+
engine = new org.apache.velocity.app.VelocityEngine();
190+
p = new java.util.Properties();
191+
// fail if template uses an invalid expression; e.g., an undefined variable
192+
p.setProperty("runtime.references.strict", "true");
193+
// tell Velocity where the templates are located
194+
p.setProperty("file.resource.loader.path", "$templateSubdirectory");
195+
// tell Velocity to log to stderr rather than to a velocity.log file
196+
p.setProperty(org.apache.velocity.runtime.RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS,
197+
"org.apache.velocity.runtime.log.SystemLogChute");
198+
engine.init(p);
199+
200+
// read translation lines
201+
outputFilename = null;
202+
context = globalContext = new org.apache.velocity.VelocityContext();
203+
reader = new java.io.BufferedReader(new java.io.FileReader("$templateSubdirectory/$translationsFile"));
204+
205+
readTranslation(engine, context, reader, templateSubdirectory, templateFile, translationsFile, false);
206+
207+
reader.close();
208+
209+
// process the template
210+
processTemplate(engine, context, templateFile, outputFilename);
211+
}
212+
213+
/* Recursively translates all templates in the given directory. */
214+
def translateDirectory(templateSubdirectory) {
215+
debug("translateDirectory('$templateSubdirectory')")
216+
217+
for (file in new java.io.File(templateSubdirectory).listFiles()) {
218+
if (file.isDirectory()) {
219+
// process subdirectories recursively
220+
translateDirectory(file.getPath());
221+
}
222+
else {
223+
// process Velocity template files only
224+
name = file.getName();
225+
if (!name.endsWith('.vm')) continue;
226+
prefix = name.substring(0, name.lastIndexOf('.'));
227+
translate(templateSubdirectory, name, prefix + '.list');
228+
}
229+
}
230+
}
231+
232+
try {
233+
translateDirectory(templateDirectory);
234+
}
235+
catch (Throwable t) {
236+
t.printStackTrace(System.err);
237+
throw t;
238+
}

0 commit comments

Comments
 (0)