package com.anjlab.eclipse.tapestry5.templates;
import java.io.InputStream;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import com.anjlab.eclipse.tapestry5.TapestryContext.FileNameBuilder;
import com.anjlab.eclipse.tapestry5.Activator;
import com.anjlab.eclipse.tapestry5.TapestryProject;
import com.anjlab.eclipse.tapestry5.TapestryUtils;
public class TapestryTemplates
{
private static final FileNameBuilder defaultTemplates = new FileNameBuilder()
{
@Override
public String getFileName(String fileName, String fileExtension)
{
return fileName + "." + fileExtension;
}
};
private final TapestryProject tapestryProject;
private final FileNameBuilder versionedTemplates;
private TapestryTemplates(TapestryProject tapestryProject, FileNameBuilder versionedTemplates)
{
this.tapestryProject = tapestryProject;
this.versionedTemplates = versionedTemplates;
}
public static TapestryTemplates get(final TapestryProject tapestryProject)
{
if (tapestryProject == null)
{
return new TapestryTemplates(tapestryProject, defaultTemplates);
}
return new TapestryTemplates(tapestryProject, new FileNameBuilder()
{
@Override
public String getFileName(String fileName, String fileExtension)
{
return fileName + "-" + tapestryProject.getTapestryVersionMajorMinor() + "." + fileExtension;
}
});
}
public InputStream openTemplate(IPath containerFullPath, String fileName, String fileExtension)
{
if (tapestryProject == null)
{
return getFromPlugin(fileName, fileExtension);
}
IContainer configDir =
(IContainer) tapestryProject.getProject()
.findMember(TapestryUtils.SRC_MAIN_ECLIPSE_TAPESTRY5);
if (configDir == null)
{
return getFromPlugin(fileName, fileExtension);
}
if (containerFullPath != null)
{
IPath tapestryRelativePath = getTapestryRelativePath(containerFullPath);
if (tapestryRelativePath != null)
{
// Find closest template
for (int i = 0; i < tapestryRelativePath.segmentCount(); i++)
{
IContainer subfolder = (IContainer) configDir.findMember(
tapestryRelativePath.removeLastSegments(i));
if (subfolder != null)
{
InputStream stream = getFromContainer(subfolder, fileName, fileExtension);
if (stream != null)
{
return stream;
}
}
}
}
}
InputStream stream = getFromContainer(configDir, fileName, fileExtension);
return stream != null
? stream
: getFromPlugin(fileName, fileExtension);
}
private IPath getTapestryRelativePath(IPath containerFullPath)
{
if (isFromThisProject(containerFullPath))
{
// containerFullPath may not exist yet in file system
IContainer container = null;
IPath projectRelativePath = containerFullPath.removeFirstSegments(
tapestryProject.getProject().getFullPath().segmentCount());
// Find at closest parent that do exists
for (int i = 0; container == null && i < projectRelativePath.segmentCount(); i++)
{
container = (IContainer) tapestryProject.getProject()
.findMember(projectRelativePath.removeLastSegments(i));
}
if (container != null)
{
IContainer root = TapestryUtils.getRoot(container);
if (root != null)
{
// Get path relative to source folder or to WebApp
IPath rootRelativePath = projectRelativePath
.removeFirstSegments(
root.getProjectRelativePath().segmentCount());
if (TapestryUtils.isWebApp(root))
{
return rootRelativePath;
}
else
{
// Remove leading package name from path,
// make path relative to the tapestry-root packages
IPath tapestryRelativePath = getPathOfSubpackage(
rootRelativePath,
TapestryUtils.getPagesPackage(tapestryProject.getProject()));
if (tapestryRelativePath == null)
{
tapestryRelativePath = getPathOfSubpackage(
rootRelativePath,
TapestryUtils.getComponentsPackage(tapestryProject.getProject()));
}
if (tapestryRelativePath == null)
{
tapestryRelativePath = getPathOfSubpackage(
rootRelativePath,
TapestryUtils.getMixinsPackage(tapestryProject.getProject()));
}
return tapestryRelativePath;
}
}
}
}
return null;
}
private boolean isFromThisProject(IPath containerFullPath)
{
return tapestryProject.getProject().getFullPath().isPrefixOf(containerFullPath);
}
private IPath getPathOfSubpackage(IPath relativePath, String parentPackage)
{
IPath packagePath = Path.fromPortableString(parentPackage.replaceAll("\\.", "/"));
if (packagePath.isPrefixOf(relativePath))
{
return relativePath.removeFirstSegments(packagePath.segmentCount());
}
return null;
}
private InputStream getFromContainer(
IContainer container, String fileName, String fileExtension)
{
IResource resource = container.findMember(
versionedTemplates.getFileName(fileName, fileExtension));
if (resource == null && versionedTemplates != defaultTemplates)
{
resource = container.findMember(
defaultTemplates.getFileName(fileName, fileExtension));
}
try
{
return (resource instanceof IFile)
? ((IFile) resource).getContents()
: null;
}
catch (CoreException e)
{
Activator.getDefault().logError("Error getting content from '" + resource + "'", e);
return null;
}
}
private InputStream getFromPlugin(String fileName, String fileExtension)
{
InputStream stream = getClass().getResourceAsStream(
versionedTemplates.getFileName(fileName, fileExtension));
if (stream == null && versionedTemplates != defaultTemplates)
{
stream = getClass().getResourceAsStream(
defaultTemplates.getFileName(fileName, fileExtension));
}
return stream;
}
}