diff --git a/java/compiler/javac2/src/com/intellij/ant/Javac2.java b/java/compiler/javac2/src/com/intellij/ant/Javac2.java index aea6261e8f2f..507e5a78ca58 100644 --- a/java/compiler/javac2/src/com/intellij/ant/Javac2.java +++ b/java/compiler/javac2/src/com/intellij/ant/Javac2.java @@ -32,14 +32,11 @@ import java.io.*; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.StringTokenizer; +import java.util.*; public class Javac2 extends Javac { private ArrayList myFormFiles; - private Path myNestedFormDirs; + private List myNestedFormPathList; public Javac2() { } @@ -170,34 +167,32 @@ public class Javac2 extends Javac { /** * Sets the nested form directories that will be used during the * compilation. - * @param nestedformdirs a path + * @param nestedformdirs a list of {@link PrefixedPath} */ - public void setNestedformdirs(Path nestedformdirs) { - if (myNestedFormDirs == null) { - myNestedFormDirs = nestedformdirs; - } else { - myNestedFormDirs.append(nestedformdirs); - } + public void setNestedformdirs(List nestedformdirs) { + myNestedFormPathList = nestedformdirs; } /** * Gets the nested form directories that will be used during the * compilation. - * @return the extension directories as a path + * @return the extension directories as a list of {@link PrefixedPath} */ - public Path getNestedformdirs() { - return myNestedFormDirs; + public List getNestedformdirs() { + return myNestedFormPathList; } /** * Adds a path to nested form directories. * @return a path to be configured */ - public Path createNestedformdirs() { - if (myNestedFormDirs == null) { - myNestedFormDirs = new Path(getProject()); + public PrefixedPath createNestedformdirs() { + PrefixedPath p = new PrefixedPath(getProject()); + if (myNestedFormPathList == null) { + myNestedFormPathList = new ArrayList(); } - return myNestedFormDirs.createPath(); + myNestedFormPathList.add(p); + return p; } /** @@ -287,8 +282,9 @@ public class Javac2 extends Javac { finally { stream.close(); } - final AsmCodeGenerator codeGenerator = new AsmCodeGenerator(rootContainer, loader, new AntNestedFormLoader(loader, myNestedFormDirs), false, - new AntClassWriter(getAsmClassWriterFlags(version), loader)); + AntNestedFormLoader formLoader = new AntNestedFormLoader(loader, myNestedFormPathList); + AntClassWriter classWriter = new AntClassWriter(getAsmClassWriterFlags(version), loader); + final AsmCodeGenerator codeGenerator = new AsmCodeGenerator(rootContainer, loader, formLoader, false, classWriter); codeGenerator.patchFile(classFile); final FormErrorInfo[] warnings = codeGenerator.getWarnings(); @@ -493,52 +489,44 @@ public class Javac2 extends Javac { private class AntNestedFormLoader implements NestedFormLoader { private final ClassLoader myLoader; - private final Path myNestedFormDirs; + private final List myNestedFormPathList; private final HashMap myFormCache = new HashMap(); - public AntNestedFormLoader(final ClassLoader loader, Path nestedFormDirs) { + public AntNestedFormLoader(final ClassLoader loader, List nestedFormPathList) { myLoader = loader; - myNestedFormDirs = nestedFormDirs; + myNestedFormPathList = nestedFormPathList; } - public LwRootContainer loadForm(String formFileName) throws Exception { - if (myFormCache.containsKey(formFileName)) { - return (LwRootContainer)myFormCache.get(formFileName); + public LwRootContainer loadForm(String formFilePath) throws Exception { + if (myFormCache.containsKey(formFilePath)) { + return (LwRootContainer)myFormCache.get(formFilePath); } - String formFileFullName = formFileName.toLowerCase(); - log("Searching for form " + formFileFullName, Project.MSG_VERBOSE); + + String lowerFormFilePath = formFilePath.toLowerCase(); + log("Searching for form " + lowerFormFilePath, Project.MSG_VERBOSE); for (Iterator iterator = myFormFiles.iterator(); iterator.hasNext();) { File file = (File)iterator.next(); String name = file.getAbsolutePath().replace(File.separatorChar, '/').toLowerCase(); log("Comparing with " + name, Project.MSG_VERBOSE); - if (name.endsWith(formFileFullName)) { - return loadForm(formFileName, new FileInputStream(file)); + if (name.endsWith(lowerFormFilePath)) { + return loadForm(formFilePath, new FileInputStream(file)); } } - if (myNestedFormDirs != null) { - String[] list = myNestedFormDirs.list(); - for (int i = 0, listLength = list.length; i < listLength; i++) { - String formPath = list[i]; - if (!formPath.endsWith("/")) { - formPath += "/"; + + if (myNestedFormPathList != null) { + for (int i = 0; i < myNestedFormPathList.size(); i++) { + PrefixedPath path = (PrefixedPath)myNestedFormPathList.get(i); + File formFile = path.findFile(formFilePath); + if (formFile != null) { + return loadForm(formFilePath, new FileInputStream(formFile)); + } } - if (formFileFullName.startsWith("/")) { - formPath += formFileName.substring(1); - } - else { - formPath += formFileName; - } - File formFile = new File(formPath.replace('/', File.separatorChar)); - if (formFile.isFile()) { - return loadForm(formFileName, new FileInputStream(formFile)); - } - } } - InputStream resourceStream = myLoader.getResourceAsStream(formFileName); + InputStream resourceStream = myLoader.getResourceAsStream(formFilePath); if (resourceStream != null) { - return loadForm(formFileName, resourceStream); + return loadForm(formFilePath, resourceStream); } - throw new Exception("Cannot find nested form file " + formFileName); + throw new Exception("Cannot find nested form file " + formFilePath); } private LwRootContainer loadForm(String formFileName, InputStream resourceStream) throws Exception { diff --git a/java/compiler/javac2/src/com/intellij/ant/PrefixedPath.java b/java/compiler/javac2/src/com/intellij/ant/PrefixedPath.java new file mode 100644 index 000000000000..c7af4eb63613 --- /dev/null +++ b/java/compiler/javac2/src/com/intellij/ant/PrefixedPath.java @@ -0,0 +1,79 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * 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 com.intellij.ant; + +import org.apache.tools.ant.Project; +import org.apache.tools.ant.types.Path; + +import java.io.File; + +/** + * Allows to specify relative output prefix for Path. + * Used to support searching for nested form files under source roots with package prefixes. + * + * @author nik + */ +public class PrefixedPath extends Path { + private String myPrefix; + + public PrefixedPath(Project project) { + super(project); + } + + public PrefixedPath(Project p, String path) { + super(p, path); + } + + public String getPrefix() { + return myPrefix; + } + + public void setPrefix(String prefix) { + myPrefix = prefix; + } + + public File findFile(String relativePath) { + relativePath = trimStartSlash(relativePath); + String prefix = myPrefix; + if (prefix != null) { + prefix = trimStartSlash(ensureEndsWithSlash(prefix)); + if (!relativePath.toLowerCase().startsWith(prefix.toLowerCase())) { + return null; + } + relativePath = relativePath.substring(prefix.length()); + } + + String[] dirsList = list(); + for (int j = 0, listLength = dirsList.length; j < listLength; j++) { + String fullPath = ensureEndsWithSlash(dirsList[j]) + relativePath; + File file = new File(fullPath.replace('/', File.separatorChar)); + if (file.isFile()) { + return file; + } + } + return null; + } + + private static String trimStartSlash(String path) { + if (path.startsWith("/")) return path.substring(1); + return path; + } + + private static String ensureEndsWithSlash(String path) { + if (!path.endsWith("/")) return path + "/"; + return path; + } +}