blob: 8fd5039e7377c2bbeff751916075eba7749d3e20 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.netbeans.modules.groovy.grailsproject.classpath;
import java.util.HashMap;
import java.util.Map;
import org.netbeans.api.java.classpath.ClassPath;
import org.netbeans.modules.groovy.grailsproject.GrailsProject;
import org.netbeans.spi.java.classpath.ClassPathFactory;
import org.netbeans.spi.java.classpath.ClassPathProvider;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
/**
* @todo runtime classpath
*
* Defines the various class paths for a EJB project.
*/
public final class ClassPathProviderImpl implements ClassPathProvider {
private final GrailsProject project;
private final SourceRoots sourceRoots;
private final SourceRoots testSourceRoots;
/**
* Cache for classpaths:
* <dl>
* <dt>0</dt> <dd>sources classpath</dd>
* <dt>1</dt> <dd>test sources classpath</dd>
* <dt>2</dt> <dd>sources compile classpath</dd>
* <dt>3</dt> <dd>test sources compile classpath</dd>
* <dt>4</dt> <dd>sources and built sources run classpath</dd>
* <dt>5</dt> <dd>test sources and built test sources run classpath</dd>
* <dt>6</dt> <dd>XXX: todo</dd>
* <dt>7</dt> <dd>boot classpath</dd>
* <dt>8</dt> <dd>J2EE platform classpath</dd>
* </dl>
*/
private final ClassPath[] cache = new ClassPath[9];
private final Map<String, FileObject> dirCache = new HashMap<String, FileObject>();
public ClassPathProviderImpl(SourceRoots sourceRoots, SourceRoots testSourceRoots, GrailsProject project) {
this.project = project;
this.sourceRoots = sourceRoots;
this.testSourceRoots = testSourceRoots;
}
private synchronized FileObject getDir(String propname) {
FileObject fo = this.dirCache.get(propname);
return fo;
}
private FileObject[] getPrimarySrcPath() {
return this.sourceRoots.getRoots();
}
private FileObject[] getTestSrcDir() {
return this.testSourceRoots.getRoots();
}
private FileObject getBuildClassesDir() {
return getDir("build.classes.dir"); //NOI18N
}
private FileObject getBuildJar() {
return getDir("dist.jar"); //NOI18N
}
private FileObject getBuildTestClassesDir() {
return getDir("build.test.classes.dir"); // NOI18N
}
/**
* Find what a given file represents.
* @param file a file in the project
* @return one of: <dl>
* <dt>0</dt> <dd>normal source</dd>
* <dt>1</dt> <dd>test source</dd>
* <dt>2</dt> <dd>built class (unpacked)</dd>
* <dt>3</dt> <dd>built test class</dd>
* <dt>4</dt> <dd>built class (in dist JAR)</dd>
* <dt>-1</dt> <dd>something else</dd>
* </dl>
*/
private int getType(FileObject file) {
FileObject[] srcPath = getPrimarySrcPath();
for (int i=0; i < srcPath.length; i++) {
FileObject root = srcPath[i];
if (root.equals(file) || FileUtil.isParentOf(root, file)) {
return 0;
}
}
srcPath = getTestSrcDir();
for (int i=0; i< srcPath.length; i++) {
FileObject root = srcPath[i];
if (root.equals(file) || FileUtil.isParentOf(root, file)) {
return 1;
}
}
FileObject dir = getBuildClassesDir();
if (dir != null && (dir.equals(file) || FileUtil.isParentOf(dir, file))) {
return 2;
}
dir = getBuildJar();
if (dir != null && (dir.equals(file))) { //TODO: When MasterFs check also isParentOf
return 4;
}
dir = getBuildTestClassesDir();
if (dir != null && (dir.equals(file) || FileUtil.isParentOf(dir,file))) {
return 3;
}
return -1;
}
private ClassPath getCompileTimeClasspath(FileObject file) {
int type = getType(file);
return this.getCompileTimeClasspath(type);
}
private synchronized ClassPath getCompileTimeClasspath(int type) {
if (type < 0 || type > 1) {
// Not a source file.
return null;
}
ClassPath cp = cache[2+type];
if ( cp == null) {
cp = ClassPathFactory.createClassPath(ProjectClassPathImplementation.forProject(project));
cache[2 + type] = cp;
}
return cp;
}
private synchronized ClassPath getRunTimeClasspath(FileObject file) {
int type = getType(file);
if (type < 0 || type > 4) {
return null;
} else if (type > 1) {
type -= 2;
}
ClassPath cp = cache[4+type];
return cp;
}
private ClassPath getSourcepath(FileObject file) {
int type = getType(file);
return this.getSourcepath(type);
}
private synchronized ClassPath getSourcepath(int type) {
if (type < 0 || type > 1) {
return null;
}
ClassPath cp = cache[type];
if (cp == null) {
switch (type) {
case 0:
cp = ClassPathFactory.createClassPath(
SourcePathImplementation.forProject(project, this.sourceRoots));
break;
case 1:
cp = ClassPathFactory.createClassPath(
SourcePathImplementation.forProject(project, this.testSourceRoots));
break;
}
}
cache[type] = cp;
return cp;
}
private synchronized ClassPath getBootClassPath() {
ClassPath cp = cache[7];
if (cp == null) {
cp = ClassPathFactory.createClassPath(BootClassPathImplementation.forProject(project));
cache[7] = cp;
}
return cp;
}
@Override
public ClassPath findClassPath(FileObject file, String type) {
if (type.equals(ClassPath.COMPILE)) {
return getCompileTimeClasspath(file);
} else if (type.equals(ClassPath.EXECUTE)) {
return getRunTimeClasspath(file);
} else if (type.equals(ClassPath.SOURCE)) {
return getSourcepath(file);
} else if (type.equals(ClassPath.BOOT)) {
return getBootClassPath();
} else {
return null;
}
}
/**
* Returns array of all classpaths of the given type in the project.
* The result is used for example for GlobalPathRegistry registrations.
*/
public ClassPath[] getProjectClassPaths(String type) {
if (ClassPath.BOOT.equals(type)) {
return new ClassPath[]{getBootClassPath()};
}
if (ClassPath.COMPILE.equals(type)) {
ClassPath[] l = new ClassPath[2];
l[0] = getCompileTimeClasspath(0);
l[1] = getCompileTimeClasspath(1);
return l;
}
if (ClassPath.SOURCE.equals(type)) {
ClassPath[] l = new ClassPath[2];
l[0] = getSourcepath(0);
l[1] = getSourcepath(1);
return l;
}
assert false;
return null;
}
/**
* Returns the given type of the classpath for the project sources
* (i.e., excluding tests roots).
*/
public ClassPath getProjectSourcesClassPath(String type) {
if (ClassPath.BOOT.equals(type)) {
return getBootClassPath();
}
if (ClassPath.COMPILE.equals(type)) {
return getCompileTimeClasspath(0);
}
if (ClassPath.SOURCE.equals(type)) {
return getSourcepath(0);
}
assert false;
return null;
}
}