diff --git a/src/main/java/org/scijava/annotations/AnnotationProcessor.java b/src/main/java/org/scijava/annotations/AnnotationProcessor.java index 778d909fa..fe0a5c26b 100644 --- a/src/main/java/org/scijava/annotations/AnnotationProcessor.java +++ b/src/main/java/org/scijava/annotations/AnnotationProcessor.java @@ -32,7 +32,9 @@ package org.scijava.annotations; import java.io.ByteArrayOutputStream; +import java.io.File; import java.io.FileNotFoundException; +import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -62,6 +64,7 @@ import javax.lang.model.util.Elements; import javax.lang.model.util.Types; import javax.tools.Diagnostic.Kind; +import javax.tools.FileObject; import javax.tools.StandardLocation; import org.scijava.annotations.AbstractIndexWriter.StreamFactory; @@ -90,14 +93,14 @@ public boolean process(final Set elements, try { writer.write(writer); } - catch (IOException e) { + catch (final IOException e) { final ByteArrayOutputStream out = new ByteArrayOutputStream(); e.printStackTrace(new PrintStream(out)); try { out.close(); processingEnv.getMessager().printMessage(Kind.ERROR, out.toString()); } - catch (IOException e2) { + catch (final IOException e2) { processingEnv.getMessager().printMessage(Kind.ERROR, e2.getMessage() + " while printing " + e.getMessage()); } @@ -152,8 +155,9 @@ public void add(final TypeElement element) { } @SuppressWarnings("unchecked") - private Map adapt(List mirrors, - TypeMirror annotationType) + private Map adapt( + final List mirrors, + final TypeMirror annotationType) { final Map result = new TreeMap(); for (final AnnotationMirror mirror : mirrors) { @@ -208,7 +212,8 @@ else if (o instanceof VariableElement) { } private AnnotationMirror getMirror(final TypeElement element) { - for (AnnotationMirror candidate : utils.getAllAnnotationMirrors(element)) + for (final AnnotationMirror candidate : utils + .getAllAnnotationMirrors(element)) { final Name binaryName = utils.getBinaryName((TypeElement) candidate.getAnnotationType() @@ -221,7 +226,9 @@ private AnnotationMirror getMirror(final TypeElement element) { } @Override - public InputStream openInput(String annotationName) throws IOException { + public InputStream openInput(final String annotationName) + throws IOException + { try { return filer.getResource(StandardLocation.CLASS_OUTPUT, "", Index.INDEX_PREFIX + annotationName).openInputStream(); @@ -232,16 +239,37 @@ public InputStream openInput(String annotationName) throws IOException { } @Override - public OutputStream openOutput(String annotationName) throws IOException { + public OutputStream openOutput(final String annotationName) + throws IOException + { final List originating = originatingElements.get(annotationName); - return filer.createResource(StandardLocation.CLASS_OUTPUT, "", - Index.INDEX_PREFIX + annotationName, - originating.toArray(new Element[originating.size()])) - .openOutputStream(); + final String path = Index.INDEX_PREFIX + annotationName; + final FileObject fileObject = + filer.createResource(StandardLocation.CLASS_OUTPUT, "", path, + originating.toArray(new Element[originating.size()])); + + /* + * Verify that the generated file is in the META-INF/json/ subdirectory; + * Despite our asking for it explicitly, the DefaultFileManager will + * strip out the directory if javac was called without an explicit + * output directory (i.e. without -d option). + */ + final String uri = fileObject.toUri().toString(); + if (uri != null && uri.endsWith("/" + path)) { + return fileObject.openOutputStream(); + } + final String prefix = + uri.substring(0, uri.length() - annotationName.length()); + final File file = new File(prefix + path); + final File parent = file.getParentFile(); + if (parent != null && !parent.isDirectory() && !parent.mkdirs()) { + throw new IOException("Could not create directory: " + parent); + } + return new FileOutputStream(file); } @Override - public boolean isClassObsolete(String className) { + public boolean isClassObsolete(final String className) { return false; }