* @param context the package element related
* @return the source path
* @throws IllegalArgumentException if the package cannot be resolved
*/
public DiskFileSystem getSourcePath(ElementHandle.Package context) throws IllegalArgumentException {
PackageElement element = context.get(env);
if (element == null) {
throw new IllegalArgumentException("Package element cannot be resolved " + context);
}
if (sourcePath != null) {
log.info("Found eclipse source path " + sourcePath + " for package " + context.getPackageName());
return sourcePath;
}
else {
DiskFileSystem sourcePath = sourcePathMap.get(context);
if (sourcePath == null) {
try {
log.info("Trying to find a native file system for package " + context.getPackageName());
List<? extends AnnotationMirror> annotations = element.getAnnotationMirrors();
if (annotations.size() > 0) {
log.info("Found package " + context.getPackageName() + " annotations " + annotations + " will use first one");
AnnotationMirror annotation = annotations.get(0);
ClassLoader cl = env.getClass().getClassLoader();
if (cl == null) {
cl = ClassLoader.getSystemClassLoader();
}
Class<?> treesClass = cl.loadClass("com.sun.source.util.Trees");
Method instanceMethod = treesClass.getMethod("instance", ProcessingEnvironment.class);
Method getPathMethod = treesClass.getMethod("getPath", Element.class, AnnotationMirror.class);
Object trees = instanceMethod.invoke(null, env);
Object path = getPathMethod.invoke(trees, element, annotation);
if (path != null) {
Method getCompilationUnitMethod = path.getClass().getMethod("getCompilationUnit");
Object cu = getCompilationUnitMethod.invoke(path);
Method getSourceFileMethod = cu.getClass().getMethod("getSourceFile");
JavaFileObject file = (JavaFileObject)getSourceFileMethod.invoke(cu);
URI uri = file.toUri();
log.info("Resolved uri " + uri + " for package " + context.getPackageName());
File f = new File(uri.getPath());
if (f.exists() && f.isFile()) {
File dir = f.getParentFile().getParentFile();
javax.lang.model.element.Name name = element.getQualifiedName();
for (int i = 0;i < name.length();i++) {
if (name.charAt(i) == '.') {
dir = dir.getParentFile();
}
}