package com.anjlab.eclipse.tapestry5;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.jdt.core.IClassFile;
import org.eclipse.jdt.core.IJarEntryResource;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IParent;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
public class JarFileLookup implements FileLookup
{
private IType relativeTo;
public JarFileLookup(IType relativeTo)
{
this.relativeTo = relativeTo;
}
@Override
public String findClasspathRelativePath(TapestryFile file)
{
return file.getPath().toPortableString();
}
@Override
public TapestryFile findClasspathFileCaseInsensitive(String path)
{
if (relativeTo == null)
{
return null;
}
IParent root = (IParent) relativeTo.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
TapestryFile file = null;
try
{
file = searchChildren(root, path);
if (file == null)
{
file = searchNonJavaResources(root, path);
}
}
catch (JavaModelException e)
{
Activator.getDefault().logError("Error performing search", e);
}
return file;
}
private TapestryFile searchNonJavaResources(IParent root, String path) throws JavaModelException
{
String[] segments = path.split("/");
if (root instanceof IPackageFragmentRoot)
{
for (Object nonJava : ((IPackageFragmentRoot) root).getNonJavaResources())
{
if (nonJava instanceof IJarEntryResource)
{
IJarEntryResource resource = (IJarEntryResource) nonJava;
if (StringUtils.equals(segments[0], resource.getName()))
{
return searchRecursively(resource, path, segments, 1);
}
}
}
}
return null;
}
private TapestryFile searchRecursively(IJarEntryResource parent, String path, String[] segments, int segmentIndex)
{
if (pathEquals(parent, path))
{
return Activator.getDefault()
.getTapestryContextFactory()
.createTapestryContext(parent)
.getInitialFile();
}
if (segmentIndex >= segments.length)
{
return null;
}
if (parent.isFile())
{
return null;
}
for (IJarEntryResource child : parent.getChildren())
{
if (StringUtils.equals(segments[segmentIndex], child.getName()))
{
return searchRecursively(child, path, segments, segmentIndex + 1);
}
}
return null;
}
private TapestryFile searchChildren(IParent root, String path) throws JavaModelException
{
int index = path.lastIndexOf('/');
String[] segments = index < 0
? new String[] { path }
: new String[] { path.substring(0, index).replace("/", "."), path.substring(index + 1) };
for (IJavaElement child : root.getChildren())
{
if (child.getElementName().equalsIgnoreCase(segments[0]))
{
if (segments.length == 0)
{
if (child instanceof IClassFile)
{
IClassFile classFile = (IClassFile) child;
return Activator.getDefault()
.getTapestryContextFactory()
.createTapestryContext(classFile)
.getInitialFile();
}
if (child instanceof IJarEntryResource)
{
IJarEntryResource jarEntry = (IJarEntryResource) child;
return Activator.getDefault()
.getTapestryContextFactory()
.createTapestryContext(jarEntry)
.getInitialFile();
}
}
else
{
IPackageFragment pkg = (IPackageFragment) child;
for (IClassFile classFile : pkg.getClassFiles())
{
if (classFile.getElementName().equalsIgnoreCase(segments[1]))
{
return Activator.getDefault()
.getTapestryContextFactory()
.createTapestryContext(classFile)
.getInitialFile();
}
}
for (Object nonJava : pkg.getNonJavaResources())
{
if (nonJava instanceof IJarEntryResource)
{
IJarEntryResource jarEntry = ((IJarEntryResource) nonJava);
if (pathEquals(jarEntry, path))
{
return Activator.getDefault()
.getTapestryContextFactory()
.createTapestryContext(jarEntry)
.getInitialFile();
}
}
}
break;
}
}
}
return null;
}
private boolean pathEquals(IJarEntryResource resource, String path)
{
// Full path has leading slash
return resource.getFullPath().toPortableString().equalsIgnoreCase(path.startsWith("/") ? path : "/" + path);
}
}