You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2005/09/12 01:59:09 UTC
svn commit: r280219 - in /jakarta/tapestry/trunk: ./
framework/src/descriptor/META-INF/ framework/src/java/org/apache/tapestry/
framework/src/java/org/apache/tapestry/asset/
framework/src/java/org/apache/tapestry/binding/
framework/src/java/org/apache/...
Author: hlship
Date: Sun Sep 11 16:58:43 2005
New Revision: 280219
URL: http://svn.apache.org/viewcvs?rev=280219&view=rev
Log:
TAPESTRY-595: Resource prefixes not honored inside <page>'s specification-path attribute
TAPESTRY-578: Using component types with slashes in the HTML template fails
Added:
jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/services/NamespaceResources.java
jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/services/impl/NamespaceResourcesImpl.java
jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/junit/parse/SlashInComponentType.html
jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/junit/parse/SlashInComponentType.jwc
jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/junit/parse/SlashInComponentType.library
jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/services/impl/TestNamespaceResources.java
Modified:
jakarta/tapestry/trunk/framework/src/descriptor/META-INF/tapestry.asset.xml
jakarta/tapestry/trunk/framework/src/descriptor/META-INF/tapestry.parse.xml
jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/INamespace.java
jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/asset/AssetFactory.java
jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/asset/AssetSource.java
jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/asset/AssetSourceImpl.java
jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/asset/ContextAssetFactory.java
jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/binding/AbstractBinding.java
jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/binding/BindingMessages.java
jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/binding/BindingStrings.properties
jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/binding/ListenerMethodBinding.java
jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/engine/ISpecificationSource.java
jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/engine/Namespace.java
jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/parse/SpecificationParser.java
jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/parse/TemplateParser.java
jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/services/impl/SpecificationSourceImpl.java
jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/binding/BindingTestCase.java
jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/binding/TestListenerMethodBinding.java
jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/junit/TestComponentMessages.java
jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/junit/parse/TestSpecificationParser.java
jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/junit/parse/TestTemplateParser.java
jakarta/tapestry/trunk/status.xml
Modified: jakarta/tapestry/trunk/framework/src/descriptor/META-INF/tapestry.asset.xml
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/descriptor/META-INF/tapestry.asset.xml?rev=280219&r1=280218&r2=280219&view=diff
==============================================================================
--- jakarta/tapestry/trunk/framework/src/descriptor/META-INF/tapestry.asset.xml (original)
+++ jakarta/tapestry/trunk/framework/src/descriptor/META-INF/tapestry.asset.xml Sun Sep 11 16:58:43 2005
@@ -63,6 +63,7 @@
<construct class="ContextAssetFactory">
<set-service property="context" service-id="tapestry.globals.WebContext"/>
<set-object property="contextPath" value="infrastructure:contextPath"/>
+ <set-object property="assetService" value="engine-service:asset"/>
</construct>
</invoke-factory>
Modified: jakarta/tapestry/trunk/framework/src/descriptor/META-INF/tapestry.parse.xml
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/descriptor/META-INF/tapestry.parse.xml?rev=280219&r1=280218&r2=280219&view=diff
==============================================================================
--- jakarta/tapestry/trunk/framework/src/descriptor/META-INF/tapestry.parse.xml (original)
+++ jakarta/tapestry/trunk/framework/src/descriptor/META-INF/tapestry.parse.xml Sun Sep 11 16:58:43 2005
@@ -51,6 +51,7 @@
<construct class="org.apache.tapestry.services.impl.SpecificationSourceImpl">
<set-service property="parser" service-id="SpecificationParser"/>
<set-object property="specification" value="infrastructure:applicationSpecification"/>
+ <set-object property="assetSource" value="service:tapestry.asset.AssetSource"/>
<event-listener service-id="tapestry.ResetEventCoordinator"/>
</construct>
</invoke-factory>
Modified: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/INamespace.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/INamespace.java?rev=280219&r1=280218&r2=280219&view=diff
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/INamespace.java (original)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/INamespace.java Sun Sep 11 16:58:43 2005
@@ -148,8 +148,8 @@
* Returns the path for the named component (within the namespace).
*
* @param type
- * the component alias
- * @return the specification path of the component
+ * the component type
+ * @return the specification for the component
* @throws ApplicationRuntimeException
* if the specification doesn't exist or can't be loaded
*/
Modified: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/asset/AssetFactory.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/asset/AssetFactory.java?rev=280219&r1=280218&r2=280219&view=diff
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/asset/AssetFactory.java (original)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/asset/AssetFactory.java Sun Sep 11 16:58:43 2005
@@ -43,7 +43,8 @@
* @param locale
* the desired locale of the asset; the closest match will be used.
* @param location
- * the location to be associated with the returned asset.
+ * the location to be associated with the returned asset, or null to not attempt to
+ * localize the asset
* @throws org.apache.hivemind.ApplicationRuntimeException
* if no matching asset may be found.
*/
Modified: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/asset/AssetSource.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/asset/AssetSource.java?rev=280219&r1=280218&r2=280219&view=diff
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/asset/AssetSource.java (original)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/asset/AssetSource.java Sun Sep 11 16:58:43 2005
@@ -21,7 +21,7 @@
import org.apache.tapestry.IAsset;
/**
- * Used to create an {@link org.apache.tapestry.IAsset}instance for a particular asset path. The
+ * Used to create an {@link org.apache.tapestry.IAsset} instance for a particular asset path. The
* path may have a prefix that indicates its type, or it may be relative to some existing resource.
*
* @author Howard M. Lewis Ship
@@ -29,5 +29,24 @@
*/
public interface AssetSource
{
+ /**
+ * Finds an asset relative to some existing resource (typically, a page, component or library
+ * specification).
+ *
+ * @param base
+ * the base resource used for resolving the asset
+ * @param path
+ * the path relative to the base resource; alternately, the path may include a prefix
+ * that defines a domain (such as "classpath:" or "context:") in which case the base
+ * resource is ignored and the resource resolved within that domain
+ * @param locale
+ * used to find a localized version of the asset, may be null to indicate no
+ * localization
+ * @param location
+ * used to report errors (such as missing resources)
+ * @return the asset, possibly localized
+ * @throws org.apache.hivemind.ApplicationRuntimeException
+ * if the asset does not exist
+ */
public IAsset findAsset(Resource base, String path, Locale locale, Location location);
}
Modified: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/asset/AssetSourceImpl.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/asset/AssetSourceImpl.java?rev=280219&r1=280218&r2=280219&view=diff
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/asset/AssetSourceImpl.java (original)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/asset/AssetSourceImpl.java Sun Sep 11 16:58:43 2005
@@ -56,7 +56,6 @@
{
Defense.notNull(base, "base");
Defense.notNull(path, "path");
- Defense.notNull(locale, "locale");
Defense.notNull(location, "location");
int colonx = path.indexOf(':');
Modified: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/asset/ContextAssetFactory.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/asset/ContextAssetFactory.java?rev=280219&r1=280218&r2=280219&view=diff
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/asset/ContextAssetFactory.java (original)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/asset/ContextAssetFactory.java Sun Sep 11 16:58:43 2005
@@ -17,9 +17,12 @@
import java.util.Locale;
import org.apache.hivemind.ApplicationRuntimeException;
+import org.apache.hivemind.ClassResolver;
import org.apache.hivemind.Location;
import org.apache.hivemind.Resource;
+import org.apache.hivemind.util.ClasspathResource;
import org.apache.tapestry.IAsset;
+import org.apache.tapestry.engine.IEngineService;
import org.apache.tapestry.web.WebContext;
import org.apache.tapestry.web.WebContextResource;
@@ -38,6 +41,10 @@
private Resource _servletRoot;
+ private ClassResolver _classResolver;
+
+ private IEngineService _assetService;
+
public void initializeService()
{
_servletRoot = new WebContextResource(_context, "/");
@@ -46,6 +53,18 @@
public IAsset createAsset(Resource baseResource, String path, Locale locale, Location location)
{
Resource assetResource = _servletRoot.getRelativeResource(path);
+
+ // Here's the thing; In Tapestry 3.0 and earlier, you could specify
+ // library path like /org/apache/tapestry/contrib/Contrib.library. In the new scheme
+ // of things, that should be "classpath:/org/apache/tapestry/contrib/Contrib.library".
+ // But to keep a lot of things from breaking, we'll kludgely allow that here.
+
+ if (assetResource.getResourceURL() == null && path.startsWith("/"))
+ {
+ ClasspathResource resource = new ClasspathResource(_classResolver, path);
+ return new PrivateAsset(resource, _assetService, location);
+ }
+
Resource localized = assetResource.getLocalization(locale);
if (localized == null)
@@ -68,5 +87,15 @@
public void setContextPath(String contextPath)
{
_contextPath = contextPath;
+ }
+
+ public void setAssetService(IEngineService assetService)
+ {
+ _assetService = assetService;
+ }
+
+ public void setClassResolver(ClassResolver classResolver)
+ {
+ _classResolver = classResolver;
}
}
Modified: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/binding/AbstractBinding.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/binding/AbstractBinding.java?rev=280219&r1=280218&r2=280219&view=diff
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/binding/AbstractBinding.java (original)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/binding/AbstractBinding.java Sun Sep 11 16:58:43 2005
@@ -129,4 +129,30 @@
{
return _valueConverter;
}
+
+ public String toString()
+ {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append(getClass().getName());
+ buffer.append("@");
+ buffer.append(Integer.toHexString(hashCode()));
+ buffer.append("[");
+ buffer.append(_description);
+
+ extendDescription(buffer);
+
+ buffer.append(", location=");
+ buffer.append(_location);
+ buffer.append("]");
+
+ return buffer.toString();
+ }
+
+ /**
+ * Does nothing, subclasses may override to add additional information.
+ */
+ protected void extendDescription(StringBuffer buffer)
+ {
+
+ }
}
Modified: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/binding/BindingMessages.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/binding/BindingMessages.java?rev=280219&r1=280218&r2=280219&view=diff
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/binding/BindingMessages.java (original)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/binding/BindingMessages.java Sun Sep 11 16:58:43 2005
@@ -40,4 +40,13 @@
{
return _formatter.format("missing-asset", component.getExtendedId(), assetName);
}
+
+ static String listenerMethodFailure(IComponent component, String methodName, Throwable cause)
+ {
+ return _formatter.format(
+ "listener-method-failure",
+ methodName,
+ component.getExtendedId(),
+ cause);
+ }
}
Modified: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/binding/BindingStrings.properties
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/binding/BindingStrings.properties?rev=280219&r1=280218&r2=280219&view=diff
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/binding/BindingStrings.properties (original)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/binding/BindingStrings.properties Sun Sep 11 16:58:43 2005
@@ -14,4 +14,5 @@
convert-object-error=Error converting value for {0}: {1}
read-only-binding=Binding for {0} ({1}) may not be updated.
-missing-asset=Component {0} does not contain an asset named ''{1}''.
\ No newline at end of file
+missing-asset=Component {0} does not contain an asset named ''{1}''.
+listener-method-failure=Exception invoking listener method {0} of component {1}: {2}
\ No newline at end of file
Modified: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/binding/ListenerMethodBinding.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/binding/ListenerMethodBinding.java?rev=280219&r1=280218&r2=280219&view=diff
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/binding/ListenerMethodBinding.java (original)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/binding/ListenerMethodBinding.java Sun Sep 11 16:58:43 2005
@@ -16,19 +16,30 @@
import org.apache.hivemind.Location;
import org.apache.hivemind.util.Defense;
+import org.apache.tapestry.BindingException;
+import org.apache.tapestry.IActionListener;
import org.apache.tapestry.IComponent;
+import org.apache.tapestry.IRequestCycle;
+import org.apache.tapestry.PageRedirectException;
import org.apache.tapestry.coerce.ValueConverter;
/**
* @author Howard M. Lewis Ship
* @since 4.0
*/
-public class ListenerMethodBinding extends AbstractBinding
+public class ListenerMethodBinding extends AbstractBinding implements IActionListener
{
private final IComponent _component;
private final String _methodName;
+ // We have to defer obtaining the listener until after the page is loaded, because it is
+ // (currently) reliant on the page's engine property to gain access to the
+ // ListenerMapSource. I'd prefer it if this was a final field, resolved by the constructor,
+ // but that will involve injecting the ListenerMapSource into AbstractComponent.
+
+ private IActionListener _listener;
+
public ListenerMethodBinding(IComponent component, String methodName, String description,
ValueConverter valueConverter, Location location)
{
@@ -46,9 +57,43 @@
return _component;
}
+ /**
+ * Returns this binding object; the binding object delegates to the actual listener. This allows
+ * us to intercept errors and report the location of the binding.
+ */
public Object getObject()
{
- return _component.getListeners().getListener(_methodName);
+ return this;
+ }
+
+ public void actionTriggered(IComponent component, IRequestCycle cycle)
+ {
+ try
+ {
+ if (_listener == null)
+ _listener = _component.getListeners().getListener(_methodName);
+
+ _listener.actionTriggered(component, cycle);
+ }
+ catch (PageRedirectException ex)
+ {
+ throw ex;
+ }
+ catch (RuntimeException ex)
+ {
+ throw new BindingException(BindingMessages.listenerMethodFailure(
+ _component,
+ _methodName,
+ ex), _component, getLocation(), this, ex);
+ }
+ }
+
+ protected void extendDescription(StringBuffer buffer)
+ {
+ buffer.append(", component=");
+ buffer.append(_component.getExtendedId());
+ buffer.append(", methodName=");
+ buffer.append(_methodName);
}
}
Modified: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/engine/ISpecificationSource.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/engine/ISpecificationSource.java?rev=280219&r1=280218&r2=280219&view=diff
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/engine/ISpecificationSource.java (original)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/engine/ISpecificationSource.java Sun Sep 11 16:58:43 2005
@@ -20,75 +20,63 @@
import org.apache.tapestry.spec.ILibrarySpecification;
/**
- * Defines access to component specifications.
- *
- * @see IComponentSpecification
- *
- * @author Howard Lewis Ship
+ * Defines access to component specifications.
*
- **/
+ * @see IComponentSpecification
+ * @author Howard Lewis Ship
+ */
public interface ISpecificationSource
{
/**
- * Retrieves a component specification, parsing it as necessary.
- *
- * @param specificationLocation the location where the specification
- * may be read from.
+ * Retrieves a component specification, parsing it as necessary.
*
- * @throws org.apache.tapestry.ApplicationRuntimeException if the specification doesn't
- * exist, is unreadable or invalid.
- *
- * @since 2.2
- *
- **/
+ * @param specificationLocation
+ * the location where the specification may be read from.
+ * @throws org.apache.hivemind.ApplicationRuntimeException
+ * if the specification doesn't exist, is unreadable or invalid.
+ * @since 2.2
+ */
public IComponentSpecification getComponentSpecification(Resource specificationLocation);
/**
- * Retrieves a component specification, parsing it as necessary.
- *
- * @param specificationLocation the location where the specification
- * may be read from.
- *
- * @throws org.apache.tapestry.ApplicationRuntimeException if the specification doesn't
- * exist, is unreadable or invalid.
- *
- * @since 2.2
+ * Retrieves a page specification, parsing it as necessary.
*
- **/
+ * @param specificationLocation
+ * the location where the specification may be read from.
+ * @throws org.apache.hivemind.ApplicationRuntimeException
+ * if the specification doesn't exist, is unreadable or invalid.
+ * @since 2.2
+ */
public IComponentSpecification getPageSpecification(Resource specificationLocation);
/**
- * Returns a {@link org.apache.tapestry.spec.LibrarySpecification} with the given path.
+ * Returns a {@link org.apache.tapestry.spec.LibrarySpecification} with the given path.
*
- * @param specificationLocation the resource path of the specification
- * to return
- * @throws org.apache.tapestry.ApplicationRuntimeException if the specification
- * cannot be read
- *
- * @since 2.2
- *
- **/
+ * @param specificationLocation
+ * the resource path of the specification to return
+ * @throws org.apache.hivemind.ApplicationRuntimeException
+ * if the specification cannot be read
+ * @since 2.2
+ */
public ILibrarySpecification getLibrarySpecification(Resource specificationLocation);
/**
- * Returns the {@link INamespace} for the application.
+ * Returns the {@link INamespace} for the application.
*
- * @since 2.2
- *
- **/
+ * @since 2.2
+ */
public INamespace getApplicationNamespace();
/**
- * Returns the {@link INamespace} for the framework itself.
- *
- * @since 2.2
+ * Returns the {@link INamespace} for the framework itself.
*
- **/
+ * @since 2.2
+ */
public INamespace getFrameworkNamespace();
}
Modified: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/engine/Namespace.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/engine/Namespace.java?rev=280219&r1=280218&r2=280219&view=diff
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/engine/Namespace.java (original)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/engine/Namespace.java Sun Sep 11 16:58:43 2005
@@ -23,18 +23,18 @@
import java.util.Set;
import org.apache.hivemind.ApplicationRuntimeException;
-import org.apache.hivemind.ClassResolver;
import org.apache.hivemind.Location;
import org.apache.hivemind.Resource;
-import org.apache.hivemind.util.ClasspathResource;
import org.apache.tapestry.INamespace;
import org.apache.tapestry.Tapestry;
+import org.apache.tapestry.services.NamespaceResources;
import org.apache.tapestry.spec.IComponentSpecification;
import org.apache.tapestry.spec.ILibrarySpecification;
/**
- * Implementation of {@link org.apache.tapestry.INamespace}that works with a
- * {@link ISpecificationSource}to obtain page and component specifications as needed.
+ * Implementation of {@link org.apache.tapestry.INamespace} that works with a
+ * {@link org.apache.tapestry.services.NamespaceResources} to obtain page and component
+ * specifications as needed.
*
* @author Howard Lewis Ship
* @since 2.2
@@ -42,23 +42,21 @@
public class Namespace implements INamespace
{
- private ILibrarySpecification _specification;
+ private final ILibrarySpecification _specification;
- private ISpecificationSource _specificationSource;
-
- private String _id;
+ private final String _id;
private String _extendedId;
- private INamespace _parent;
+ private final INamespace _parent;
- private boolean _frameworkNamespace;
+ private final boolean _frameworkNamespace;
- private boolean _applicationNamespace;
+ private final boolean _applicationNamespace;
/** @since 4.0 */
- private ClassResolver _resolver;
+ private final NamespaceResources _resources;
/**
* Map of {@link org.apache.tapestry.spec.ComponentSpecification}keyed on page name. The map is
@@ -66,28 +64,27 @@
* page discovery in the application namespace).
*/
- private Map _pages = Collections.synchronizedMap(new HashMap());
+ private final Map _pages = Collections.synchronizedMap(new HashMap());
/**
* Map of {@link org.apache.tapestry.spec.ComponentSpecification}keyed on component alias.
*/
- private Map _components = Collections.synchronizedMap(new HashMap());
+ private final Map _components = Collections.synchronizedMap(new HashMap());
/**
* Map, keyed on id, of {@link INamespace}.
*/
- private Map _children = Collections.synchronizedMap(new HashMap());
+ private final Map _children = Collections.synchronizedMap(new HashMap());
public Namespace(String id, INamespace parent, ILibrarySpecification specification,
- ISpecificationSource specificationSource, ClassResolver resolver)
+ NamespaceResources resources)
{
_id = id;
_parent = parent;
_specification = specification;
- _specificationSource = specificationSource;
- _resolver = resolver;
+ _resources = resources;
_applicationNamespace = (_id == null);
_frameworkNamespace = FRAMEWORK_NAMESPACE.equals(_id);
@@ -260,9 +257,11 @@
name,
getNamespaceId()));
- Resource location = getSpecificationLocation().getRelativeResource(path);
+ // We don't record line-precise data about <page> elements
+ // so use the location for the specification as a whole (at least identifying
+ // the right file)
- return _specificationSource.getPageSpecification(location);
+ return _resources.getPageSpecification(getSpecificationLocation(), path, getLocation());
}
private IComponentSpecification locateComponentSpecification(String type)
@@ -275,9 +274,12 @@
type,
getNamespaceId()));
- Resource location = getSpecificationLocation().getRelativeResource(path);
+ // We don't record line-precise data about <component-type> elements
+ // so use the location for the specification as a whole (at least identifying
+ // the right file)
- return _specificationSource.getComponentSpecification(location);
+ return _resources
+ .getComponentSpecification(getSpecificationLocation(), path, getLocation());
}
private INamespace createNamespace(String id)
@@ -290,19 +292,16 @@
id,
getNamespaceId()));
- Resource location = getSpecificationLocation().getRelativeResource(path);
-
- // Ok, an absolute path to a library for an application whose specification
- // is in the context root is problematic, cause getRelativeLocation()
- // will still be looking in the context. Handle this case with the
- // following little kludge:
-
- if (location.getResourceURL() == null && path.startsWith("/"))
- location = new ClasspathResource(_resolver, path);
-
- ILibrarySpecification ls = _specificationSource.getLibrarySpecification(location);
+ // We don't record line-precise data about <library> elements
+ // so use the location for the specification as a whole (at least identifying
+ // the right file)
+
+ ILibrarySpecification ls = _resources.findChildLibrarySpecification(
+ getSpecificationLocation(),
+ path,
+ getLocation());
- return new Namespace(id, this, ls, _specificationSource, _resolver);
+ return new Namespace(id, this, ls, _resources);
}
public synchronized boolean containsPage(String name)
Modified: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/parse/SpecificationParser.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/parse/SpecificationParser.java?rev=280219&r1=280218&r2=280219&view=diff
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/parse/SpecificationParser.java (original)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/parse/SpecificationParser.java Sun Sep 11 16:58:43 2005
@@ -97,13 +97,16 @@
public static final String BEAN_NAME_PATTERN = Tapestry.SIMPLE_PROPERTY_NAME_PATTERN;
/**
- * Perl5 pattern for component alias. Letter, followed by letter, number, or underscore. This is
- * used to validate component types registered in the application or library specifications.
+ * Perl5 pattern for component type (which was known as an "alias" in earlier versions of
+ * Tapestry). This is either a simple property name, or a series of property names seperated by
+ * slashes (the latter being new in Tapestry 4.0). This defines a literal that can appear in a
+ * library or application specification.
*
* @since 2.2
*/
- public static final String COMPONENT_ALIAS_PATTERN = Tapestry.SIMPLE_PROPERTY_NAME_PATTERN;
+ public static final String COMPONENT_ALIAS_PATTERN = "^(" + IDENTIFIER_PATTERN + "/)*"
+ + IDENTIFIER_PATTERN + "$";
/**
* Perl5 pattern for component ids. Letter, followed by letter, number or underscore.
@@ -114,14 +117,16 @@
public static final String COMPONENT_ID_PATTERN = Tapestry.SIMPLE_PROPERTY_NAME_PATTERN;
/**
- * Perl5 pattern for component types. Component types are an optional namespace prefix followed
- * by a normal identifier.
+ * Perl5 pattern for component types (i.e., the type attribute of the <component>
+ * element). Component types are an optional namespace prefix followed by a component type
+ * (within the library defined by the namespace). Starting in 4.0, the type portion is actually
+ * a series of identifiers seperated by slashes.
*
* @since 2.2
*/
- public static final String COMPONENT_TYPE_PATTERN = "^(" + IDENTIFIER_PATTERN + ":)?"
- + IDENTIFIER_PATTERN + "$";
+ public static final String COMPONENT_TYPE_PATTERN = "^(" + IDENTIFIER_PATTERN + ":)?" + "("
+ + IDENTIFIER_PATTERN + "/)*" + IDENTIFIER_PATTERN + "$";
/**
* We can share a single map for all the XML attribute to object conversions, since the keys are
Modified: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/parse/TemplateParser.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/parse/TemplateParser.java?rev=280219&r1=280218&r2=280219&view=diff
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/parse/TemplateParser.java (original)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/parse/TemplateParser.java Sun Sep 11 16:58:43 2005
@@ -146,13 +146,14 @@
* Pattern used to recognize implicit components (whose type is defined in the template).
* Subgroup 1 is the id (which may be null) and subgroup 2 is the type (which may be qualified
* with a library prefix). Subgroup 4 is the library id, Subgroup 5 is the simple component
- * type.
+ * type, which may (as of 4.0) have slashes to delinate folders containing the component.
*
* @since 3.0
*/
public static final String IMPLICIT_ID_PATTERN = "^(" + PROPERTY_NAME_PATTERN + ")?@((("
- + PROPERTY_NAME_PATTERN + "):)?(" + PROPERTY_NAME_PATTERN + "))$";
+ + PROPERTY_NAME_PATTERN + "):)?((" + PROPERTY_NAME_PATTERN + "/)*"
+ + PROPERTY_NAME_PATTERN + "))$";
private static final int IMPLICIT_ID_PATTERN_ID_GROUP = 1;
@@ -756,9 +757,8 @@
_cursor - attributeValueStart);
attributeEndEvent(_cursor);
-
+
addAttributeIfUnique(tagName, attributeName, attributeValue);
-
// Advance over the quote.
advance();
@@ -778,9 +778,9 @@
{
String attributeValue = new String(_templateData, attributeValueStart,
_cursor - attributeValueStart);
-
+
attributeEndEvent(_cursor);
- addAttributeIfUnique(tagName, attributeName, attributeValue);
+ addAttributeIfUnique(tagName, attributeName, attributeValue);
state = WAIT_FOR_ATTRIBUTE_NAME;
break;
@@ -975,9 +975,11 @@
// with a leading dollar sign to ensure no conflicts
// with user defined component ids (which don't allow dollar signs
// in the id).
+ // New for 4.0: the component type may included slashes ('/'), but these
+ // are not valid identifiers, so we convert them to '$'.
if (jwcId == null)
- jwcId = _idAllocator.allocateId("$" + simpleType);
+ jwcId = _idAllocator.allocateId("$" + simpleType.replace('/', '$'));
try
{
Added: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/services/NamespaceResources.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/services/NamespaceResources.java?rev=280219&view=auto
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/services/NamespaceResources.java (added)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/services/NamespaceResources.java Sun Sep 11 16:58:43 2005
@@ -0,0 +1,82 @@
+// Copyright 2005 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import org.apache.hivemind.Location;
+import org.apache.hivemind.Resource;
+import org.apache.tapestry.spec.IComponentSpecification;
+import org.apache.tapestry.spec.ILibrarySpecification;
+
+/**
+ * Companion to the standard {@link org.apache.tapestry.engine.Namespace implementation} of
+ * {@link org.apache.tapestry.INamespace}. Defines resources needed by the Namespace instance to
+ * operate (these have grown numerous!)
+ *
+ * @author Howard M. Lewis Ship
+ * @since 4.0
+ */
+public interface NamespaceResources
+{
+ /**
+ * Finds a child library specification for some parent library specification.
+ *
+ * @param libraryResource
+ * the {@link Resource} from which the parent library (or application) specification
+ * was loaded
+ * @param path
+ * the relative path from the parent specification resource to the library
+ * specification. As a special case, a path starting with a leading slash is assumed
+ * to be on the classpath.
+ * @param location TODO
+ * @return the library specification.
+ */
+ ILibrarySpecification findChildLibrarySpecification(Resource libraryResource, String path, Location location);
+
+ /**
+ * Retrieves a page specification, parsing it as necessary.
+ *
+ * @param libraryResource
+ * the base resource for resolving the path to the page specification; this will be
+ * the resource for the library (or application) specification
+ * @param specificationPath
+ * the path to the specification to be parsed
+ * @param location
+ * used to report errors
+ * @throws org.apache.hivemind.ApplicationRuntimeException
+ * if the specification doesn't exist, is unreadable or invalid.
+ * @see org.apache.tapestry.engine.ISpecificationSource#getPageSpecification(Resource)
+ */
+
+ IComponentSpecification getPageSpecification(Resource libraryResource,
+ String specificationPath, Location location);
+
+ /**
+ * Retrieves a component specification, parsing it as necessary.
+ *
+ * @param libraryResource
+ * the base resource for resolving the path to the page specification; this will be
+ * the resource for the library (or application) specification
+ * @param specificationPath
+ * the path to the specification to be parsed
+ * @param location
+ * used to report errors
+ * @throws org.apache.hivemind.ApplicationRuntimeException
+ * if the specification doesn't exist, is unreadable or invalid.
+ */
+
+ public IComponentSpecification getComponentSpecification(Resource libraryResource,
+ String specificationPath, Location location);
+
+}
Added: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/services/impl/NamespaceResourcesImpl.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/services/impl/NamespaceResourcesImpl.java?rev=280219&view=auto
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/services/impl/NamespaceResourcesImpl.java (added)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/services/impl/NamespaceResourcesImpl.java Sun Sep 11 16:58:43 2005
@@ -0,0 +1,90 @@
+// Copyright 2005 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services.impl;
+
+import org.apache.hivemind.Location;
+import org.apache.hivemind.Resource;
+import org.apache.hivemind.util.Defense;
+import org.apache.tapestry.IAsset;
+import org.apache.tapestry.asset.AssetSource;
+import org.apache.tapestry.engine.ISpecificationSource;
+import org.apache.tapestry.services.NamespaceResources;
+import org.apache.tapestry.spec.IComponentSpecification;
+import org.apache.tapestry.spec.ILibrarySpecification;
+
+/**
+ * Implementation of {@link org.apache.tapestry.services.NamespaceResources}.
+ *
+ * @author Howard M. Lewis Ship
+ */
+public class NamespaceResourcesImpl implements NamespaceResources
+{
+ private final ISpecificationSource _specificationSource;
+
+ private final AssetSource _assetSource;
+
+ public NamespaceResourcesImpl(ISpecificationSource source, AssetSource assetSource)
+ {
+ Defense.notNull(source, "source");
+ Defense.notNull(assetSource, "assetSource");
+
+ _specificationSource = source;
+ _assetSource = assetSource;
+ }
+
+ public ILibrarySpecification findChildLibrarySpecification(Resource parentResource,
+ String path, Location location)
+ {
+ Resource childResource = findSpecificationResource(parentResource, path, location);
+
+ return _specificationSource.getLibrarySpecification(childResource);
+
+ }
+
+ private Resource findSpecificationResource(Resource libraryResource, String path,
+ Location location)
+ {
+ // TODO: This is where we'll play with assets and asset prefixes
+
+ IAsset childAsset = _assetSource.findAsset(libraryResource, path, null, location);
+
+ Resource childResource = childAsset.getResourceLocation();
+
+ return childResource;
+ }
+
+ public IComponentSpecification getPageSpecification(Resource resource,
+ String specificationPath, Location location)
+ {
+ Resource pageSpecificationResource = findSpecificationResource(
+ resource,
+ specificationPath,
+ location);
+
+ return _specificationSource.getPageSpecification(pageSpecificationResource);
+ }
+
+ public IComponentSpecification getComponentSpecification(Resource resource,
+ String specificationPath, Location location)
+ {
+ Resource componentSpecificationResource = findSpecificationResource(
+ resource,
+ specificationPath,
+ location);
+
+ return _specificationSource.getComponentSpecification(componentSpecificationResource);
+ }
+
+}
Modified: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/services/impl/SpecificationSourceImpl.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/services/impl/SpecificationSourceImpl.java?rev=280219&r1=280218&r2=280219&view=diff
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/services/impl/SpecificationSourceImpl.java (original)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/services/impl/SpecificationSourceImpl.java Sun Sep 11 16:58:43 2005
@@ -22,10 +22,12 @@
import org.apache.hivemind.Resource;
import org.apache.hivemind.util.ClasspathResource;
import org.apache.tapestry.INamespace;
+import org.apache.tapestry.asset.AssetSource;
import org.apache.tapestry.engine.ISpecificationSource;
import org.apache.tapestry.engine.Namespace;
import org.apache.tapestry.event.ResetEventListener;
import org.apache.tapestry.parse.ISpecificationParser;
+import org.apache.tapestry.services.NamespaceResources;
import org.apache.tapestry.spec.IApplicationSpecification;
import org.apache.tapestry.spec.IComponentSpecification;
import org.apache.tapestry.spec.ILibrarySpecification;
@@ -33,15 +35,12 @@
import org.apache.tapestry.util.xml.DocumentParseException;
/**
- * Default implementation of {@link ISpecificationSource} that
- * expects to use the normal class loader to locate component
- * specifications from within the classpath.
- *
- * <p>Caches specifications in memory forever, or until {@link #resetDidOccur()()} is invoked.
- *
- *
- * @author Howard Lewis Ship
+ * Default implementation of {@link ISpecificationSource} that expects to use the normal class
+ * loader to locate component specifications from within the classpath.
+ * <p>
+ * Caches specifications in memory forever, or until {@link #resetDidOccur()()} is invoked.
*
+ * @author Howard Lewis Ship
*/
public class SpecificationSourceImpl implements ISpecificationSource, ResetEventListener
@@ -49,48 +48,53 @@
private ClassResolver _classResolver;
private IApplicationSpecification _specification;
+
private ISpecificationParser _parser;
+ private NamespaceResources _namespaceResources;
+
private INamespace _applicationNamespace;
+
private INamespace _frameworkNamespace;
+ private AssetSource _assetSource;
+
/**
- * Contains previously parsed component specifications.
- *
+ * Contains previously parsed component specifications.
*/
private Map _componentCache = new HashMap();
/**
- * Contains previously parsed page specifications.
- *
- * @since 2.2
+ * Contains previously parsed page specifications.
*
+ * @since 2.2
*/
private Map _pageCache = new HashMap();
/**
- * Contains previously parsed library specifications, keyed
- * on specification resource path.
- *
- * @since 2.2
+ * Contains previously parsed library specifications, keyed on specification resource path.
*
+ * @since 2.2
*/
private Map _libraryCache = new HashMap();
/**
- * Contains {@link INamespace} instances, keyed on id (which will
- * be null for the application specification).
- *
+ * Contains {@link INamespace} instances, keyed on id (which will be null for the application
+ * specification).
*/
private Map _namespaceCache = new HashMap();
+ public void initializeService()
+ {
+ _namespaceResources = new NamespaceResourcesImpl(this, _assetSource);
+ }
+
/**
- * Clears the specification cache. This is used during debugging.
- *
+ * Clears the specification cache. This is used during debugging.
*/
public synchronized void resetEventDidOccur()
@@ -118,8 +122,7 @@
catch (DocumentParseException ex)
{
throw new ApplicationRuntimeException(
- ImplMessages.unableToParseSpecification(resource),
- ex);
+ ImplMessages.unableToParseSpecification(resource), ex);
}
return result;
@@ -134,24 +137,24 @@
catch (DocumentParseException ex)
{
throw new ApplicationRuntimeException(
- ImplMessages.unableToParseSpecification(resource),
- ex);
+ ImplMessages.unableToParseSpecification(resource), ex);
}
}
/**
- * Gets a component specification.
- *
- * @param resourcePath the complete resource path to the specification.
- * @throws ApplicationRuntimeException if the specification cannot be obtained.
+ * Gets a component specification.
*
+ * @param resourcePath
+ * the complete resource path to the specification.
+ * @throws ApplicationRuntimeException
+ * if the specification cannot be obtained.
*/
public synchronized IComponentSpecification getComponentSpecification(Resource resourceLocation)
{
- IComponentSpecification result =
- (IComponentSpecification) _componentCache.get(resourceLocation);
+ IComponentSpecification result = (IComponentSpecification) _componentCache
+ .get(resourceLocation);
if (result == null)
{
@@ -193,7 +196,7 @@
public synchronized INamespace getApplicationNamespace()
{
if (_applicationNamespace == null)
- _applicationNamespace = new Namespace(null, null, _specification, this, _classResolver);
+ _applicationNamespace = new Namespace(null, null, _specification, _namespaceResources);
return _applicationNamespace;
}
@@ -202,12 +205,13 @@
{
if (_frameworkNamespace == null)
{
- Resource frameworkLocation =
- new ClasspathResource(_classResolver, "/org/apache/tapestry/Framework.library");
+ Resource resource = new ClasspathResource(_classResolver,
+ "/org/apache/tapestry/Framework.library");
- ILibrarySpecification ls = getLibrarySpecification(frameworkLocation);
+ ILibrarySpecification ls = getLibrarySpecification(resource);
- _frameworkNamespace = new Namespace(INamespace.FRAMEWORK_NAMESPACE, null, ls, this, _classResolver);
+ _frameworkNamespace = new Namespace(INamespace.FRAMEWORK_NAMESPACE, null, ls,
+ _namespaceResources);
}
return _frameworkNamespace;
@@ -226,5 +230,10 @@
public void setSpecification(IApplicationSpecification specification)
{
_specification = specification;
+ }
+
+ public void setAssetSource(AssetSource assetSource)
+ {
+ _assetSource = assetSource;
}
}
Modified: jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/binding/BindingTestCase.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/binding/BindingTestCase.java?rev=280219&r1=280218&r2=280219&view=diff
==============================================================================
--- jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/binding/BindingTestCase.java (original)
+++ jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/binding/BindingTestCase.java Sun Sep 11 16:58:43 2005
@@ -14,9 +14,9 @@
package org.apache.tapestry.binding;
+import org.apache.tapestry.BaseComponentTestCase;
import org.apache.tapestry.IComponent;
import org.apache.tapestry.coerce.ValueConverter;
-import org.apache.tapestry.junit.TapestryTestCase;
import org.easymock.MockControl;
/**
@@ -25,7 +25,7 @@
* @author Howard M. Lewis Ship
* @since 4.0
*/
-public abstract class BindingTestCase extends TapestryTestCase
+public abstract class BindingTestCase extends BaseComponentTestCase
{
protected IComponent newComponent(String extendedId)
{
Modified: jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/binding/TestListenerMethodBinding.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/binding/TestListenerMethodBinding.java?rev=280219&r1=280218&r2=280219&view=diff
==============================================================================
--- jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/binding/TestListenerMethodBinding.java (original)
+++ jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/binding/TestListenerMethodBinding.java Sun Sep 11 16:58:43 2005
@@ -15,11 +15,13 @@
package org.apache.tapestry.binding;
import org.apache.hivemind.Location;
+import org.apache.tapestry.BindingException;
import org.apache.tapestry.IActionListener;
import org.apache.tapestry.IComponent;
+import org.apache.tapestry.IRequestCycle;
+import org.apache.tapestry.PageRedirectException;
import org.apache.tapestry.coerce.ValueConverter;
import org.apache.tapestry.listener.ListenerMap;
-import org.easymock.MockControl;
/**
* Test for {@link org.apache.tapestry.binding.ListenerMethodBinding}.
@@ -29,33 +31,160 @@
*/
public class TestListenerMethodBinding extends BindingTestCase
{
- public void testGetObject()
+ public void testInvokeListener()
{
- MockControl cc = newControl(IComponent.class);
- IComponent component = (IComponent) cc.getMock();
+ IComponent component = newComponent();
+ ListenerMap map = newListenerMap();
+ IActionListener listener = newListener();
+ Location l = newLocation();
+ IComponent sourceComponent = newComponent();
+ IRequestCycle cycle = newCycle();
+ ValueConverter vc = newValueConverter();
- MockControl lmc = newControl(ListenerMap.class);
- ListenerMap lm = (ListenerMap) lmc.getMock();
+ trainGetListener(component, map, listener);
- IActionListener listener = (IActionListener) newMock(IActionListener.class);
+ listener.actionTriggered(sourceComponent, cycle);
- component.getListeners();
- cc.setReturnValue(lm);
+ replayControls();
+
+ ListenerMethodBinding b = new ListenerMethodBinding(component, "foo", "param", vc, l);
+
+ assertSame(b, b.getObject());
+ assertSame(component, b.getComponent());
+
+ b.actionTriggered(sourceComponent, cycle);
- lm.getListener("foo");
- lmc.setReturnValue(listener);
+ verifyControls();
+ }
+ public void testToString()
+ {
+ IComponent component = newComponent();
+ Location l = newLocation();
ValueConverter vc = newValueConverter();
+ trainGetExtendedId(component, "Fred/barney");
+
+ replayControls();
+
+ ListenerMethodBinding b = new ListenerMethodBinding(component, "foo", "param", vc, l);
+
+ String toString = b.toString();
+ String description = toString.substring(toString.indexOf('[') + 1, toString.length() - 1);
+
+ assertEquals(
+ "param, component=Fred/barney, methodName=foo, location=classpath:/org/apache/tapestry/binding/TestListenerMethodBinding, line 1",
+ description);
+
+ verifyControls();
+ }
+
+ public void testInvokeAndRedirect()
+ {
+ IComponent component = newComponent();
+ ListenerMap map = newListenerMap();
+ IActionListener listener = newListener();
Location l = newLocation();
+ ValueConverter vc = newValueConverter();
+ IComponent sourceComponent = newComponent();
+ IRequestCycle cycle = newCycle();
+
+ trainGetListener(component, map, listener);
+
+ listener.actionTriggered(sourceComponent, cycle);
+
+ Throwable t = new PageRedirectException("TargetPage");
+ getControl(listener).setThrowable(t);
replayControls();
ListenerMethodBinding b = new ListenerMethodBinding(component, "foo", "param", vc, l);
- assertSame(listener, b.getObject());
- assertSame(component, b.getComponent());
+ try
+ {
+ b.actionTriggered(sourceComponent, cycle);
+ unreachable();
+ }
+ catch (PageRedirectException ex)
+ {
+ assertSame(t, ex);
+ }
+
+ verifyControls();
+
+ }
+
+ public void testInvokeListenerFailure()
+ {
+ IComponent component = newComponent();
+ ListenerMap map = newListenerMap();
+ IActionListener listener = newListener();
+ Location l = newLocation();
+ ValueConverter vc = newValueConverter();
+ IComponent sourceComponent = newComponent();
+ IRequestCycle cycle = newCycle();
+
+ trainGetListener(component, map, listener);
+
+ listener.actionTriggered(sourceComponent, cycle);
+
+ Throwable t = new RuntimeException("Failure.");
+ getControl(listener).setThrowable(t);
+
+ trainGetExtendedId(component, "Fred/barney");
+
+ replayControls();
+
+ ListenerMethodBinding b = new ListenerMethodBinding(component, "foo", "param", vc, l);
+
+ try
+ {
+ b.actionTriggered(sourceComponent, cycle);
+ unreachable();
+ }
+ catch (BindingException ex)
+ {
+ assertEquals(
+ "Exception invoking listener method foo of component Fred/barney: Failure.",
+ ex.getMessage());
+ assertSame(component, ex.getComponent());
+ assertSame(l, ex.getLocation());
+ assertSame(b, ex.getBinding());
+ }
verifyControls();
+ }
+
+ private void trainGetListener(IComponent component, ListenerMap lm, IActionListener listener)
+ {
+ trainGetListeners(component, lm);
+ trainGetListener(lm, "foo", listener);
+ }
+
+ protected IRequestCycle newCycle()
+ {
+ return (IRequestCycle) newMock(IRequestCycle.class);
+ }
+
+ private void trainGetListener(ListenerMap map, String methodName, IActionListener listener)
+ {
+ map.getListener(methodName);
+ getControl(map).setReturnValue(listener);
+ }
+
+ private void trainGetListeners(IComponent component, ListenerMap lm)
+ {
+ component.getListeners();
+ getControl(component).setReturnValue(lm);
+ }
+
+ private ListenerMap newListenerMap()
+ {
+ return (ListenerMap) newMock(ListenerMap.class);
+ }
+
+ private IActionListener newListener()
+ {
+ return (IActionListener) newMock(IActionListener.class);
}
}
Modified: jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/junit/TestComponentMessages.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/junit/TestComponentMessages.java?rev=280219&r1=280218&r2=280219&view=diff
==============================================================================
--- jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/junit/TestComponentMessages.java (original)
+++ jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/junit/TestComponentMessages.java Sun Sep 11 16:58:43 2005
@@ -150,7 +150,7 @@
IPage page = newPage(spec, source, locale);
- INamespace namespace = new Namespace(null, null, newLibrarySpec(), null, null);
+ INamespace namespace = new Namespace(null, null, newLibrarySpec(), null);
page.setNamespace(namespace);
@@ -301,7 +301,7 @@
IComponentSpecification spec = newSpec(MOCK1);
spec.setLocation(new CreatorLocation());
- INamespace namespace = new Namespace(null, null, newLibrarySpec(), null, null);
+ INamespace namespace = new Namespace(null, null, newLibrarySpec(), null);
IPage page = newPage(spec, source, new Locale("fr"));
page.setNamespace(namespace);
Added: jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/junit/parse/SlashInComponentType.html
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/junit/parse/SlashInComponentType.html?rev=280219&view=auto
==============================================================================
--- jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/junit/parse/SlashInComponentType.html (added)
+++ jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/junit/parse/SlashInComponentType.html Sun Sep 11 16:58:43 2005
@@ -0,0 +1,4 @@
+Tests for implicit components that have slashes in the component type.
+
+<span jwcid="@foo/Bar"/>
+<span jwcid="baz@biff/bop/Boop"/>
\ No newline at end of file
Added: jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/junit/parse/SlashInComponentType.jwc
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/junit/parse/SlashInComponentType.jwc?rev=280219&view=auto
==============================================================================
--- jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/junit/parse/SlashInComponentType.jwc (added)
+++ jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/junit/parse/SlashInComponentType.jwc Sun Sep 11 16:58:43 2005
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<!--
+ Copyright 2005 The Apache Software Foundation
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!DOCTYPE component-specification PUBLIC
+ "-//Apache Software Foundation//Tapestry Specification 4.0//EN"
+ "http://jakarta.apache.org/tapestry/dtd/Tapestry_4_0.dtd">
+<component-specification>
+ <component id="fred" type="rubble/Barney"/>
+</component-specification>
\ No newline at end of file
Added: jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/junit/parse/SlashInComponentType.library
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/junit/parse/SlashInComponentType.library?rev=280219&view=auto
==============================================================================
--- jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/junit/parse/SlashInComponentType.library (added)
+++ jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/junit/parse/SlashInComponentType.library Sun Sep 11 16:58:43 2005
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+<!--
+ Copyright 2005 The Apache Software Foundation
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!DOCTYPE library-specification PUBLIC
+ "-//Apache Software Foundation//Tapestry Specification 4.0//EN"
+ "http://jakarta.apache.org/tapestry/dtd/Tapestry_4_0.dtd">
+
+<library-specification>
+
+ <component-type
+ type="foo/Bar"
+ specification-path="foocomponents/BarComponent.jwc"/>
+
+</library-specification>
Modified: jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/junit/parse/TestSpecificationParser.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/junit/parse/TestSpecificationParser.java?rev=280219&r1=280218&r2=280219&view=diff
==============================================================================
--- jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/junit/parse/TestSpecificationParser.java (original)
+++ jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/junit/parse/TestSpecificationParser.java Sun Sep 11 16:58:43 2005
@@ -1098,4 +1098,30 @@
assertEquals(true, cs.isDeprecated());
}
+
+ /** @since 4.0 */
+
+ public void testLibrarySlashInComponentType() throws Exception
+ {
+ ILibrarySpecification ls = parseLib("SlashInComponentType.library");
+
+ List types = ls.getComponentTypes();
+
+ assertEquals(1, types.size());
+
+ assertEquals("foo/Bar", types.get(0));
+
+ assertEquals("foocomponents/BarComponent.jwc", ls.getComponentSpecificationPath("foo/Bar"));
+ }
+
+ /** @since 4.0 */
+
+ public void testComponentSlashInComponentType() throws Exception
+ {
+ IComponentSpecification cs = parseComponent("SlashInComponentType.jwc");
+
+ IContainedComponent cc = cs.getComponent("fred");
+
+ assertEquals("rubble/Barney", cc.getType());
+ }
}
Modified: jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/junit/parse/TestTemplateParser.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/junit/parse/TestTemplateParser.java?rev=280219&r1=280218&r2=280219&view=diff
==============================================================================
--- jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/junit/parse/TestTemplateParser.java (original)
+++ jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/junit/parse/TestTemplateParser.java Sun Sep 11 16:58:43 2005
@@ -667,4 +667,22 @@
"DuplicateTagAttributeSingleQuotes.html",
"Tag <input> on line 3 contains more than one 'value' attribute.");
}
+
+ /** @since 4.0 */
+ public void testSlashInComponentType() throws Exception
+ {
+ TemplateToken[] tokens = run("SlashInComponentType.html", new ParserDelegate());
+
+ assertEquals(6, tokens.length);
+
+ OpenToken token1 = (OpenToken) tokens[1];
+
+ assertEquals("$foo$Bar", token1.getId());
+ assertEquals("foo/Bar", token1.getComponentType());
+
+ OpenToken token2 = (OpenToken) tokens[4];
+
+ assertEquals("baz", token2.getId());
+ assertEquals("biff/bop/Boop", token2.getComponentType());
+ }
}
Added: jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/services/impl/TestNamespaceResources.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/services/impl/TestNamespaceResources.java?rev=280219&view=auto
==============================================================================
--- jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/services/impl/TestNamespaceResources.java (added)
+++ jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/services/impl/TestNamespaceResources.java Sun Sep 11 16:58:43 2005
@@ -0,0 +1,171 @@
+// Copyright 2005 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services.impl;
+
+import java.net.URL;
+
+import org.apache.hivemind.Location;
+import org.apache.hivemind.Resource;
+import org.apache.hivemind.test.HiveMindTestCase;
+import org.apache.tapestry.IAsset;
+import org.apache.tapestry.asset.AssetSource;
+import org.apache.tapestry.engine.ISpecificationSource;
+import org.apache.tapestry.services.NamespaceResources;
+import org.apache.tapestry.spec.IComponentSpecification;
+import org.apache.tapestry.spec.ILibrarySpecification;
+
+/**
+ * Tests for {@link org.apache.tapestry.services.impl.NamespaceResourcesImpl}.
+ *
+ * @author Howard M. Lewis Ship
+ * @since 4.0
+ */
+public class TestNamespaceResources extends HiveMindTestCase
+{
+ protected Resource newResource()
+ {
+ return (Resource) newMock(Resource.class);
+ }
+
+ protected void trainGetRelativeResource(Resource parent, String path, Resource child)
+ {
+ parent.getRelativeResource(path);
+ getControl(parent).setReturnValue(child);
+ }
+
+ protected void trainGetResourceURL(Resource resource, URL url)
+ {
+ resource.getResourceURL();
+ getControl(resource).setReturnValue(url);
+ }
+
+ protected ISpecificationSource newSource()
+ {
+ return (ISpecificationSource) newMock(ISpecificationSource.class);
+ }
+
+ protected ILibrarySpecification newSpec()
+ {
+ return (ILibrarySpecification) newMock(ILibrarySpecification.class);
+ }
+
+ protected AssetSource newAssetSource()
+ {
+ return (AssetSource) newMock(AssetSource.class);
+ }
+
+ public void testFindChildLibrarySpecification()
+ {
+ Resource parent = newResource();
+ Resource child = newResource();
+ ISpecificationSource source = newSource();
+ ILibrarySpecification spec = newSpec();
+ AssetSource assetSource = newAssetSource();
+ Location l = newLocation();
+
+ trainResolveChildResource(assetSource, parent, "foo/bar.library", l, child);
+
+ trainGetLibrarySpecification(source, child, spec);
+
+ replayControls();
+
+ NamespaceResources nr = new NamespaceResourcesImpl(source, assetSource);
+
+ assertSame(spec, nr.findChildLibrarySpecification(parent, "foo/bar.library", l));
+
+ verifyControls();
+
+ }
+
+ protected void trainResolveChildResource(AssetSource assetSource, Resource parent,
+ String childPath, Location location, Resource child)
+ {
+ IAsset asset = newAsset();
+
+ assetSource.findAsset(parent, childPath, null, location);
+ getControl(assetSource).setReturnValue(asset);
+
+ asset.getResourceLocation();
+ getControl(asset).setReturnValue(child);
+ }
+
+ protected IAsset newAsset()
+ {
+ return (IAsset) newMock(IAsset.class);
+ }
+
+ protected URL newURL()
+ {
+ return getClass().getResource("TestNamespaceResources.class");
+ }
+
+ protected void trainGetLibrarySpecification(ISpecificationSource source, Resource resource,
+ ILibrarySpecification spec)
+ {
+ source.getLibrarySpecification(resource);
+ getControl(source).setReturnValue(spec);
+ }
+
+ protected IComponentSpecification newComponentSpec()
+ {
+ return (IComponentSpecification) newMock(IComponentSpecification.class);
+ }
+
+ public void testGetPageSpecification()
+ {
+ Resource libraryResource = newResource();
+ Resource specResource = newResource();
+ IComponentSpecification spec = newComponentSpec();
+ ISpecificationSource source = newSource();
+ AssetSource assetSource = newAssetSource();
+ Location l = newLocation();
+
+ trainResolveChildResource(assetSource, libraryResource, "Foo.page", l, specResource);
+
+ source.getPageSpecification(specResource);
+ getControl(source).setReturnValue(spec);
+
+ replayControls();
+
+ NamespaceResources nr = new NamespaceResourcesImpl(source, assetSource);
+
+ assertSame(spec, nr.getPageSpecification(libraryResource, "Foo.page", l));
+
+ verifyControls();
+ }
+
+ public void testGetComponentSpecification()
+ {
+ Resource libraryResource = newResource();
+ Resource specResource = newResource();
+ IComponentSpecification spec = newComponentSpec();
+ ISpecificationSource source = newSource();
+ AssetSource assetSource = newAssetSource();
+ Location l = newLocation();
+
+ trainResolveChildResource(assetSource, libraryResource, "Foo.jwc", l, specResource);
+
+ source.getComponentSpecification(specResource);
+ getControl(source).setReturnValue(spec);
+
+ replayControls();
+
+ NamespaceResources nr = new NamespaceResourcesImpl(source, assetSource);
+
+ assertSame(spec, nr.getComponentSpecification(libraryResource, "Foo.jwc", l));
+
+ verifyControls();
+ }
+}
Modified: jakarta/tapestry/trunk/status.xml
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/status.xml?rev=280219&r1=280218&r2=280219&view=diff
==============================================================================
--- jakarta/tapestry/trunk/status.xml (original)
+++ jakarta/tapestry/trunk/status.xml Sun Sep 11 16:58:43 2005
@@ -66,6 +66,8 @@
<action type="fix" dev="MB" fixes-bug="TAPESTRY-467">Document GenericLink component</action>
<action type="fix" dev="MB" fixes-bug="TAPESTRY-480">Document Rollover component</action>
<action type="fix" dev="MB" fixes-bug="TAPESTRY-484">Document ServiceLink component</action>
+ <action type="fix" dev="HLS" fixes-bug="TAPESTRY-579">Using component types with slashes in the HTML template fails</action>
+ <action type="fix" dev="HLS" fixes-bug="TAPESTRY-595">Resource prefixes not honored inside <page>'s specification-path attribute</action>
</release>
<release version="4.0-beta-6" date="Sep 7 2005">
<action type="update" dev="HLS" due-to="Henri Yandell">Convert Tapestry repository from CVS to SVN</action>
---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-dev-help@jakarta.apache.org