/* vim: set ts=2 et sw=2 cindent fo=qroca: */
package com.globant.katari.trails;
import org.apache.commons.lang.Validate;
import org.apache.hivemind.Resource;
import org.apache.hivemind.impl.DefaultClassResolver;
import org.apache.hivemind.util.ClasspathResource;
import org.apache.tapestry.INamespace;
import org.apache.tapestry.IRequestCycle;
import org.apache.tapestry.TapestryUtils;
import org.apache.tapestry.resolver.ISpecificationResolverDelegate;
import org.apache.tapestry.spec.IComponentSpecification;
/** Delegate interface used when a page or component specification can not be
* found by the normal means.
*
* This allows hooks to support specifications from
* unusual locations, or generated on the fly.<br>
* The components and page specifications will be found in this locations:
* <ol>
* <li>The WEB-INF directory.</li>
* <li>Any of the locations defined in the property
* org.apache.tapestry.page-class-packages</li>
* <li>Resources in the support packages:
* com.globant.katari.trails.pages and
* com.globant.katari.trails.components.
* </ol>
* @author pruggia
*/
public class ModuleTemplateSourceDelegate implements
ISpecificationResolverDelegate {
/** The comma-separated list of classpath locations of tapestry pages.
*/
private String customPagesLocation = null;
/** The comma-separated list of classpath locations of tapestry components.
*/
private String customComponentsLocation = null;
/**
* {@inheritDoc}
*/
public IComponentSpecification findPageSpecification(final IRequestCycle
cycle, final INamespace namespace, final String simplePageName) {
Resource specResource = findSpecificationResource(cycle, namespace,
simplePageName, ".page", customPagesLocation,
"org.apache.tapestry.page-class-packages");
if (specResource.getResourceURL() != null) {
return cycle.getInfrastructure().getSpecificationSource()
.getPageSpecification(specResource);
} else {
return null;
}
}
/**
* {@inheritDoc}
*/
public IComponentSpecification findComponentSpecification(
final IRequestCycle cycle, final INamespace namespace,
final String type) {
Resource specResource = findSpecificationResource(cycle, namespace, type,
".jwc", customComponentsLocation,
"org.apache.tapestry.component-class-packages");
if (specResource.getResourceURL() != null) {
return cycle.getInfrastructure().getSpecificationSource()
.getComponentSpecification(specResource);
} else {
return null;
}
}
/** Searches for resources that describes the component or page.
*
* @param cycle Controller object that manages a single request cycle. A
* request cycle is one 'hit' on the web server.
*
* @param namespace Organizes different libraries of Tapestry pages,
* components and services into "frameworks", used to disambiguate names.
*
* @param name Name of the component or page.
*
* @param specExtension .jwc for components, .page for pages.
*
* @param additionalLocation Additional classpath location to look for pages
* and components. Ignored if null.
*
* @param packagePropertyValue Name of tapestry configuration of the packages
* to look at to find component and page classes.
*
* @return Always a valid or invalid Resource. Check if that resource exist
* by doing resource.getResourceURL() and comparing it to null.
*/
protected Resource findSpecificationResource(final IRequestCycle cycle,
final INamespace namespace, final String name,
final String specExtension, final String additionalLocation,
final String packagePropertyValue) {
DefaultClassResolver classResolver = new DefaultClassResolver();
String packages = namespace.getPropertyValue(packagePropertyValue);
if (additionalLocation != null) {
packages = additionalLocation + ", " + packages;
}
String className = name.replace('/', '.');
String[] packagesArray = TapestryUtils.split(packages, ',');
Resource specResource = null;
for (int i = 0; i < packagesArray.length; i++) {
String fullName = packagesArray[i].trim() + "." + className;
String fullPath = fullName.replace('.', '/') + specExtension;
specResource = new ClasspathResource(classResolver, fullPath);
if (specResource.getResourceURL() != null) {
break;
}
}
return specResource;
}
/** Sets the classpath location of the aplication specific trails pages.
*
* @param location The classpath location. It cannot be null.
*/
public void setCustomPagesLocation(final String location) {
Validate.notNull(location, "The pages location cannot be null.");
if (!location.equals("NONE")) {
customPagesLocation = location;
} else {
customPagesLocation = null;
}
}
/** Sets the classpath location of the aplication specific trails components.
*
* @param location The classpath location. It cannot be null.
*/
public void setCustomComponentsLocation(final String location) {
Validate.notNull(location, "The components location cannot be null.");
if (!location.equals("NONE")) {
customComponentsLocation = location;
} else {
customComponentsLocation = null;
}
}
}