CVS: Tapestry/framework/src/net/sf/tapestry/resolver AbstractSpecificationResolver.java,NONE,1.1.2.1 PageSpecificationResolver.java,NONE,1.1.2.1 ComponentSpecificationResolver.java,NONE,1.1.2.1
Howard Lewis Ship <[email protected]>
| Newsgroups | gmane.comp.java.tapestry.cvs |
|---|---|
| Message-ID | <[email protected]> |
Update of /cvsroot/tapestry/Tapestry/framework/src/net/sf/tapestry/resolver
In directory sc8-pr-cvs1:/tmp/cvs-serv23659/framework/src/net/sf/tapestry/resolver
Added Files:
Tag: hship-2-3
AbstractSpecificationResolver.java
PageSpecificationResolver.java
ComponentSpecificationResolver.java
Log Message:
Allow searches for component specifications.
Allow application specification to be in WEB-INF instead of on classpath.
Allow application to run without an application specification.
--- NEW FILE: AbstractSpecificationResolver.java ---
package net.sf.tapestry.resolver;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import net.sf.tapestry.IEngine;
import net.sf.tapestry.INamespace;
import net.sf.tapestry.IRequestCycle;
import net.sf.tapestry.IResourceLocation;
import net.sf.tapestry.ISpecificationSource;
import net.sf.tapestry.Tapestry;
import net.sf.tapestry.spec.ComponentSpecification;
/**
* Base class for resolving a {@link net.sf.tapestry.spec.ComponentSpecification}
* for a particular page or component, within a specified
* {@link net.sf.tapestry.INamespace}. In some cases, a search is necessary.
*
* @author Howard Lewis Ship
* @version $Id: AbstractSpecificationResolver.java,v 1.1.2.1 2002/12/15 16:26:12 hship Exp $
* @since 2.4
*
**/
public class AbstractSpecificationResolver
{
private static final Log LOG = LogFactory.getLog(AbstractSpecificationResolver.class);
private ISpecificationSource _specificationSource;
private INamespace _namespace;
private ComponentSpecification _specification;
private IResourceLocation _applicationRootLocation;
private IResourceLocation _webInfLocation;
private IResourceLocation _webInfAppLocation;
public AbstractSpecificationResolver(IRequestCycle cycle)
{
IEngine engine = cycle.getEngine();
_specificationSource = engine.getSpecificationSource();
_applicationRootLocation = Tapestry.getApplicationRootLocation(cycle);
String servletName = cycle.getRequestContext().getServlet().getServletConfig().getServletName();
_webInfLocation = _applicationRootLocation.getRelativeLocation("/WEB-INF/");
_webInfAppLocation = _webInfLocation.getRelativeLocation(servletName + "/");
}
/**
* Returns the location of the servlet, within the
* servlet context.
*
**/
protected IResourceLocation getApplicationRootLocation()
{
return _applicationRootLocation;
}
/**
* Invoked in subclasses to identify the resolved namespace.
*
**/
protected void setNamespace(INamespace namespace)
{
_namespace = namespace;
}
/**
* Returns the resolve namespace.
*
**/
public INamespace getNamespace()
{
return _namespace;
}
/**
* Returns the specification source for the running application.
*
**/
protected ISpecificationSource getSpecificationSource()
{
return _specificationSource;
}
/**
* Returns the location of /WEB-INF/, in the servlet context.
*
**/
protected IResourceLocation getWebInfLocation()
{
return _webInfLocation;
}
/**
* Returns the location of the application-specific subdirectory, under
* /WEB-INF/, in the servlet context.
*
**/
protected IResourceLocation getWebInfAppLocation()
{
return _webInfAppLocation;
}
/**
* Returns the resolved specification.
*
**/
public ComponentSpecification getSpecification()
{
return _specification;
}
/**
* Invoked in subclass to set the final specification the initial
* inputs are resolved to.
*
**/
protected void setSpecification(ComponentSpecification specification)
{
_specification = specification;
}
/**
* Clears the namespace, specification and simpleName properties.
*
**/
protected void reset()
{
_namespace = null;
_specification = null;
}
}
--- NEW FILE: PageSpecificationResolver.java ---
package net.sf.tapestry.resolver;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import net.sf.tapestry.ApplicationRuntimeException;
import net.sf.tapestry.INamespace;
import net.sf.tapestry.IRequestCycle;
import net.sf.tapestry.IResourceLocation;
import net.sf.tapestry.Tapestry;
import net.sf.tapestry.html.BasePage;
import net.sf.tapestry.spec.ComponentSpecification;
/**
* Performs the tricky work of resolving a page name to a page specification.
* The search for pages in the application namespace is the most complicated,
* since Tapestry searches for pages that aren't explicitly defined in the
* application specification. The search, based on the <i>simple-name</i>
* of the page, goes as follows:
*
* <ul>
* <li><i>simple-name</i>.page in the same folder as the application specification
* <li><i>simple-name</i> page in the WEB-INF/<i>servlet-name</i> directory of the context root
* <li><i>simple-name</i>.page in WEB-INF
* <li><i>simple-name</i>.page in the application root (within the context root)
* <li><i>simple-name</i>.html as a template in the application root,
* for which an implicit specification is generated
* </ul>
*
* <p>If none of these work out, then the page is searched for in the framework namespace.
* This is used to find default implementations of pages such as Exception and StaleLink.
*
* @see net.sf.tapestry.IPageSource
* @author Howard Lewis Ship
* @version $Id: PageSpecificationResolver.java,v 1.1.2.1 2002/12/15 16:26:12 hship Exp $
* @since 2.4
*
**/
public class PageSpecificationResolver extends AbstractSpecificationResolver
{
private static final Log LOG = LogFactory.getLog(PageSpecificationResolver.class);
private String _simpleName;
public PageSpecificationResolver(IRequestCycle cycle)
{
super(cycle);
}
/**
* Resolve the name (which may have a library id prefix) to a namespace
* (see {@link #getNamespace()}) and a specification (see {@link #getSpecification()}).
*
* @throws ApplicationRuntimeException if the name cannot be resolved
*
**/
public void resolve(String prefixedName)
{
reset();
INamespace namespace = null;
int colonx = prefixedName.indexOf(':');
if (colonx > 0)
{
_simpleName = prefixedName.substring(colonx + 1);
String namespaceId = prefixedName.substring(0, colonx);
if (namespaceId.equals(INamespace.FRAMEWORK_NAMESPACE))
namespace = getSpecificationSource().getFrameworkNamespace();
else
namespace = getSpecificationSource().getApplicationNamespace().getChildNamespace(namespaceId);
}
else
{
_simpleName = prefixedName;
namespace = getSpecificationSource().getApplicationNamespace();
}
setNamespace(namespace);
if (namespace.containsPage(_simpleName))
{
setSpecification(namespace.getPageSpecification(_simpleName));
return;
}
// Not defined in the specification, so it's time to hunt it down.
searchForPage();
if (getSpecification() == null)
throw new ApplicationRuntimeException(
Tapestry.getString("Namespace.no-such-page", _simpleName, namespace.getNamespaceId()));
}
private void searchForPage()
{
INamespace namespace = getNamespace();
if (LOG.isDebugEnabled())
LOG.debug("Resolving unknown page '" + _simpleName + "' in " + namespace);
String expectedName = _simpleName + ".page";
IResourceLocation namespaceLocation = namespace.getSpecificationLocation();
// See if there's a specification file in the same folder
// as the library or application specification that's
// supposed to contain the page.
if (found(namespaceLocation.getRelativeLocation(expectedName)))
return;
// If not for the (unnamed) application specification, then return ... which will
// cause an exception.
if (!namespace.isApplicationNamespace())
return;
// The application namespace gets some extra searching.
if (found(getWebInfAppLocation().getRelativeLocation(expectedName)))
return;
if (found(getWebInfLocation().getRelativeLocation(expectedName)))
return;
if (found(getApplicationRootLocation().getRelativeLocation(expectedName)))
return;
// The wierd one ... where we see if there's an HTML file in the application root location.
String templateName = _simpleName + ".html";
IResourceLocation templateLocation = getApplicationRootLocation().getRelativeLocation(templateName);
if (templateLocation.getResourceURL() != null)
{
setupImplicitPage(templateLocation);
return;
}
// Not found in application namespace, so maybe its a framework page.
INamespace framework = getSpecificationSource().getFrameworkNamespace();
if (framework.containsPage(_simpleName))
{
if (LOG.isDebugEnabled())
LOG.debug("Found " + _simpleName + " in framework namespace.");
setNamespace(framework);
// Note: This implies that normal lookup rules don't work
// for the framework! Framework pages must be
// defined in the framework library specification.
setSpecification(framework.getPageSpecification(_simpleName));
}
}
private void setupImplicitPage(IResourceLocation location)
{
if (LOG.isDebugEnabled())
LOG.debug("Found HTML template at " + location);
ComponentSpecification specification = new ComponentSpecification();
specification.setComponentClassName(BasePage.class.getName());
specification.setPageSpecification(true);
specification.setSpecificationLocation(location);
setSpecification(specification);
install();
}
private boolean found(IResourceLocation location)
{
if (LOG.isDebugEnabled())
LOG.debug("Checking: " + location);
if (location.getResourceURL() == null)
return false;
setSpecification(getSpecificationSource().getPageSpecification(location));
install();
return true;
}
private void install()
{
INamespace namespace = getNamespace();
ComponentSpecification specification = getSpecification();
if (LOG.isDebugEnabled())
LOG.debug("Installing page " + _simpleName + " into " + namespace + " as " + specification);
namespace.installPageSpecification(_simpleName, specification);
}
}
--- NEW FILE: ComponentSpecificationResolver.java ---
package net.sf.tapestry.resolver;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import net.sf.tapestry.ApplicationRuntimeException;
import net.sf.tapestry.INamespace;
import net.sf.tapestry.IRequestCycle;
import net.sf.tapestry.IResourceLocation;
import net.sf.tapestry.PageLoaderException;
import net.sf.tapestry.Tapestry;
import net.sf.tapestry.spec.ComponentSpecification;
/**
* Utility class that understands the rules of component types (which
* may optionally have a library prefix) and can resolve
* the type to a {@link net.sf.tapestry.INamespace} and a
* {@link net.sf.tapestry.spec.ComponentSpecification}.
*
* <p>Like {@link net.sf.tapestry.resolver.PageSpecificationResolver},
* if the component is not defined explicitly in the namespace, a search
* may occur:
*
* Performs the tricky work of resolving a page name to a page specification.
* The search for pages in the application namespace is the most complicated,
* since Tapestry searches for pages that aren't explicitly defined in the
* application specification. The search, based on the <i>simple-name</i>
* of the page, goes as follows:
*
* <ul>
* <li><i>type</i>.jwc in the same folder as the application specification
* <li><i>type</i> jwc in the WEB-INF/<i>servlet-name</i> directory of the context root
* <li><i>type</i>.jwc in WEB-INF
* <li><i>type</i>.jwc in the application root (within the context root)
* </ul>
*
* @author Howard Lewis Ship
* @version $Id: ComponentSpecificationResolver.java,v 1.1.2.1 2002/12/15 16:26:13 hship Exp $
* @since 2.4
*
**/
public class ComponentSpecificationResolver extends AbstractSpecificationResolver
{
private static final Log LOG = LogFactory.getLog(ComponentSpecificationResolver.class);
private String _type;
public ComponentSpecificationResolver(IRequestCycle cycle)
{
super(cycle);
}
/**
* Passed the namespace of a container (to resolve the type in)
* and the type to resolve, performs the processing. A "bare type"
* (without a library prefix) may be in the containerNamespace,
* or the framework namespace
* (a search occurs in that order).
*
* @param containerNamespace namespace that may contain
* a library referenced in the type
* @param type the component specification
* to find, either a simple name, or prefixed with a library id
* (defined for the container namespace)
*
* @see #getNamespace()
* @see #getSpecification()
* @throws PageLoaderException if the type cannot be resolved
*
**/
public void resolve(INamespace containerNamespace, String type) throws PageLoaderException
{
int colonx = type.indexOf(':');
if (colonx > 0)
{
String libraryId = type.substring(0, colonx);
String simpleType = type.substring(colonx + 1);
resolve(containerNamespace, libraryId, simpleType);
}
else
resolve(containerNamespace, null, type);
}
/**
* Like {@link #resolve(INamespace, String)}, but used when the type has already
* been parsed into a library id and a simple type.
*
* @param containerNamespace namespace that may contain
* a library referenced in the type
* @param libraryId the library id within the container namespace, or null
* @param type the component specification
* to find as a simple name
* @throws ApplicationRuntimeException if the type cannot be resolved
*
**/
public void resolve(INamespace containerNamespace, String libraryId, String type)
{
reset();
_type = type;
INamespace namespace = null;
if (libraryId != null)
namespace = containerNamespace.getChildNamespace(libraryId);
else
namespace = containerNamespace;
setNamespace(namespace);
if (namespace.containsComponentType(type))
{
setSpecification(namespace.getComponentSpecification(type));
return;
}
searchForComponent();
// If not found after search, check to see if it's in
// the framework instead.
if (getSpecification() == null)
{
throw new ApplicationRuntimeException(
Tapestry.getString("Namespace.no-such-component-type", type, namespace.getNamespaceId()));
}
}
private void searchForComponent()
{
INamespace namespace = getNamespace();
if (LOG.isDebugEnabled())
LOG.debug("Resolving unknown component '" + _type + "' in " + namespace);
String expectedName = _type + ".jwc";
IResourceLocation namespaceLocation = namespace.getSpecificationLocation();
// Look for appropriate file in same folder as the library (or application)
// specificaiton.
if (found(namespaceLocation.getRelativeLocation(expectedName)))
return;
if (namespace.isApplicationNamespace())
{
// The application namespace gets some extra searching.
if (found(getWebInfAppLocation().getRelativeLocation(expectedName)))
return;
if (found(getWebInfLocation().getRelativeLocation(expectedName)))
return;
if (found(getApplicationRootLocation().getRelativeLocation(expectedName)))
return;
}
// Not in the library or app spec; does it match a component
// provided by the Framework?
INamespace framework = getSpecificationSource().getFrameworkNamespace();
if (framework.containsComponentType(_type))
setSpecification(framework.getComponentSpecification(_type));
// If not found by here, an exception will be thrown.
}
private boolean found(IResourceLocation location)
{
if (LOG.isDebugEnabled())
LOG.debug("Checking: " + location);
if (location.getResourceURL() == null)
return false;
setSpecification(getSpecificationSource().getComponentSpecification(location));
install();
return true;
}
private void install()
{
INamespace namespace = getNamespace();
ComponentSpecification specification = getSpecification();
if (LOG.isDebugEnabled())
LOG.debug("Installing component type " + _type + " into " + namespace + " as " + specification);
namespace.installComponentSpecification(_type, specification);
}
}
-------------------------------------------------------
This sf.net email is sponsored by:
With Great Power, Comes Great Responsibility
Learn to use your power at OSDN's High Performance Computing Channel
http://hpc.devchannel.org/