You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by jk...@apache.org on 2007/05/08 05:13:06 UTC
svn commit: r536045 - in /tapestry/tapestry4/trunk:
tapestry-examples/Workbench/src/context/WEB-INF/form/
tapestry-framework/src/descriptor/META-INF/
tapestry-framework/src/java/org/apache/tapestry/l10n/
tapestry-framework/src/java/org/apache/tapestry/...
Author: jkuhnert
Date: Mon May 7 20:13:04 2007
New Revision: 536045
URL: http://svn.apache.org/viewvc?view=rev&rev=536045
Log:
Because Ben won't let me sleep unless this happens correctly. =p
Changed Component template / properties resolution to use new single service to handle the logic of finding things in the context/classpath/whatever so that logic isn't duplicated anymore and context resources always take precidence over classpath resources in the resolving chain.
Added:
tapestry/tapestry4/trunk/tapestry-examples/Workbench/src/context/WEB-INF/form/ShowError.properties
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/resolver/ComponentResourceResolverImpl.java (with props)
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/resolver/IComponentResourceResolver.java (with props)
tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/resolver/TestComponentResourceResolver.java (with props)
Modified:
tapestry/tapestry4/trunk/tapestry-framework/src/descriptor/META-INF/hivemodule.xml
tapestry/tapestry4/trunk/tapestry-framework/src/descriptor/META-INF/tapestry.page.xml
tapestry/tapestry4/trunk/tapestry-framework/src/descriptor/META-INF/tapestry.parse.xml
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/l10n/DefaultResourceLocalizer.java
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/ClasspathResourceFactory.java
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/ComponentMessagesSourceImpl.java
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/ComponentPropertySourceImpl.java
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/ComponentTemplateLoaderImpl.java
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/ComponentTemplateLoaderLogic.java
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/TemplateSourceImpl.java
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/web/LocalizedWebContextResourceFinder.java
tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/junit/TestComponentMessages.java
Added: tapestry/tapestry4/trunk/tapestry-examples/Workbench/src/context/WEB-INF/form/ShowError.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-examples/Workbench/src/context/WEB-INF/form/ShowError.properties?view=auto&rev=536045
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-examples/Workbench/src/context/WEB-INF/form/ShowError.properties (added)
+++ tapestry/tapestry4/trunk/tapestry-examples/Workbench/src/context/WEB-INF/form/ShowError.properties Mon May 7 20:13:04 2007
@@ -0,0 +1 @@
+test.error=Test error property found.
\ No newline at end of file
Modified: tapestry/tapestry4/trunk/tapestry-framework/src/descriptor/META-INF/hivemodule.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/descriptor/META-INF/hivemodule.xml?view=diff&rev=536045&r1=536044&r2=536045
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/descriptor/META-INF/hivemodule.xml (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/descriptor/META-INF/hivemodule.xml Mon May 7 20:13:04 2007
@@ -207,6 +207,7 @@
<construct class="impl.ComponentMessagesSourceImpl">
<event-listener service-id="ResetEventHub"/>
<set-object property="componentPropertySource" value="infrastructure:componentPropertySource"/>
+ <set-service property="componentResourceResolver" service-id="tapestry.page.ComponentResourceResolver" />
</construct>
</invoke-factory>
Modified: tapestry/tapestry4/trunk/tapestry-framework/src/descriptor/META-INF/tapestry.page.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/descriptor/META-INF/tapestry.page.xml?view=diff&rev=536045&r1=536044&r2=536045
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/descriptor/META-INF/tapestry.page.xml (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/descriptor/META-INF/tapestry.page.xml Mon May 7 20:13:04 2007
@@ -135,6 +135,21 @@
</service-point>
+ <service-point id="ComponentResourceResolver" interface="org.apache.tapestry.resolver.IComponentResourceResolver">
+
+ Locates and loads resource relative to a component / page.
+
+ <invoke-factory>
+ <construct class="org.apache.tapestry.resolver.ComponentResourceResolverImpl">
+ <set-object property="contextRoot" value="infrastructure:contextRoot"/>
+ <set-object property="applicationId" value="infrastructure:applicationId"/>
+ <set-service property="contextAssetFactory" service-id="tapestry.asset.ContextAssetFactory" />
+ <set-service property="classpathAssetFactory" service-id="tapestry.asset.ClasspathAssetFactory" />
+ </construct>
+ </invoke-factory>
+
+ </service-point>
+
<configuration-point id="PageClassProviderChain" schema-id="hivemind.lib.ChainContribution">
Chain of objects implementing ComponentClassProvider that are used to locate the page class
Modified: tapestry/tapestry4/trunk/tapestry-framework/src/descriptor/META-INF/tapestry.parse.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/descriptor/META-INF/tapestry.parse.xml?view=diff&rev=536045&r1=536044&r2=536045
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/descriptor/META-INF/tapestry.parse.xml (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/descriptor/META-INF/tapestry.parse.xml Mon May 7 20:13:04 2007
@@ -16,98 +16,95 @@
-->
<module id="tapestry.parse" version="4.0.0" package="org.apache.tapestry.parse">
-
- Template and specification parsers.
-
- <service-point id="SpecificationParser" interface="ISpecificationParser">
-
- The parser for all types of specifications (page, component, library and application).
-
- <!-- This one is constructed a little wierdly, to help maintain compatibility with Spindle. -->
-
- <invoke-factory model="pooled">
- <construct class="SpecificationParser" autowire-services="false">
- <error-handler/>
- <log/>
- <class-resolver/>
- <object> instance:org.apache.tapestry.spec.SpecFactory </object>
-
- <!-- Can't use infrastructure:valueConverter, because SpecificationParser will be created earlier than
- tapestry.Infrastructure -->
-
- <set-service property="valueConverter" service-id="tapestry.coerce.ValueConverter"/>
- <set-service property="bindingSource" service-id="tapestry.bindings.BindingSource"/>
- </construct>
- </invoke-factory>
-
- <interceptor service-id="hivemind.LoggingInterceptor"/>
- </service-point>
-
- <service-point id="SpecificationSource" interface="org.apache.tapestry.engine.ISpecificationSource">
-
- Used to obtain specifications for pages, components and libraries.
-
- <invoke-factory>
- <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.ResetEventHub"/>
- <event-listener service-id="tapestry.describe.ReportStatusHub"/>
- </construct>
- </invoke-factory>
-
- </service-point>
-
- <service-point id="TemplateParser" interface="ITemplateParser">
-
- Parses a template into a series of tokens that are used to construct a component's body.
-
- <invoke-factory model="threaded">
- <construct class="TemplateParser">
- <set-object property="factory" value="instance:TemplateTokenFactory"/>
- </construct>
- </invoke-factory>
-
- </service-point>
-
- <service-point id="TemplateSource" interface="org.apache.tapestry.services.TemplateSource">
-
- A smart cache for localized templates for pages and components. Retrieves a template on
- first reference, and returns it on subsequent references.
-
-
- <invoke-factory>
- <construct class="org.apache.tapestry.services.impl.TemplateSourceImpl">
- <set-service property="parser" service-id="TemplateParser"/>
- <set-service property="delegate" service-id="TemplateSourceDelegate"/>
- <set-object property="contextRoot" value="infrastructure:contextRoot"/>
- <set-object property="applicationId" value="infrastructure:applicationId"/>
- <set-service property="componentSpecificationResolver" service-id="tapestry.page.ComponentSpecificationResolver"/>
- <set-object property="componentPropertySource" value="infrastructure:componentPropertySource"/>
- <set-object property="localizer" value="infrastructure:resourceLocalizer"/>
- <set-service property="contextAssetFactory" service-id="tapestry.asset.ContextAssetFactory" />
- <set-service property="classpathAssetFactory" service-id="tapestry.asset.ClasspathAssetFactory" />
- <event-listener service-id="tapestry.ResetEventHub"/>
- <event-listener service-id="tapestry.describe.ReportStatusHub"/>
- </construct>
- </invoke-factory>
-
- </service-point>
-
- <service-point id="TemplateSourceDelegate" interface="org.apache.tapestry.engine.ITemplateSourceDelegate">
-
- Delegate for TemplateSource that knows how to find templates in unusual places.
-
- <invoke-factory service-id="tapestry.ExtensionLookupFactory">
- <lookup extension-name="org.apache.tapestry.template-source-delegate"/>
- </invoke-factory>
-
- </service-point>
-
- <contribution configuration-id="tapestry.Infrastructure">
- <property name="templateSource" object="service:TemplateSource"/>
- <property name="specificationSource" object="service:SpecificationSource"/>
- </contribution>
-
+
+ Template and specification parsers.
+
+ <service-point id="SpecificationParser" interface="ISpecificationParser">
+
+ The parser for all types of specifications (page, component, library and application).
+
+ <!-- This one is constructed a little wierdly, to help maintain compatibility with Spindle. -->
+
+ <invoke-factory model="pooled">
+ <construct class="SpecificationParser" autowire-services="false">
+ <error-handler/>
+ <log/>
+ <class-resolver/>
+ <object> instance:org.apache.tapestry.spec.SpecFactory </object>
+
+ <!-- Can't use infrastructure:valueConverter, because SpecificationParser will be created earlier than
+ tapestry.Infrastructure -->
+
+ <set-service property="valueConverter" service-id="tapestry.coerce.ValueConverter"/>
+ <set-service property="bindingSource" service-id="tapestry.bindings.BindingSource"/>
+ </construct>
+ </invoke-factory>
+
+ <interceptor service-id="hivemind.LoggingInterceptor"/>
+ </service-point>
+
+ <service-point id="SpecificationSource" interface="org.apache.tapestry.engine.ISpecificationSource">
+
+ Used to obtain specifications for pages, components and libraries.
+
+ <invoke-factory>
+ <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.ResetEventHub"/>
+ <event-listener service-id="tapestry.describe.ReportStatusHub"/>
+ </construct>
+ </invoke-factory>
+
+ </service-point>
+
+ <service-point id="TemplateParser" interface="ITemplateParser">
+
+ Parses a template into a series of tokens that are used to construct a component's body.
+
+ <invoke-factory model="threaded">
+ <construct class="TemplateParser">
+ <set-object property="factory" value="instance:TemplateTokenFactory"/>
+ </construct>
+ </invoke-factory>
+
+ </service-point>
+
+ <service-point id="TemplateSource" interface="org.apache.tapestry.services.TemplateSource">
+
+ A smart cache for localized templates for pages and components. Retrieves a template on
+ first reference, and returns it on subsequent references.
+
+ <invoke-factory>
+ <construct class="org.apache.tapestry.services.impl.TemplateSourceImpl">
+ <set-service property="parser" service-id="TemplateParser"/>
+ <set-service property="delegate" service-id="TemplateSourceDelegate"/>
+ <set-object property="contextRoot" value="infrastructure:contextRoot"/>
+ <set-service property="componentSpecificationResolver" service-id="tapestry.page.ComponentSpecificationResolver"/>
+ <set-object property="componentPropertySource" value="infrastructure:componentPropertySource"/>
+ <set-object property="localizer" value="infrastructure:resourceLocalizer"/>
+ <set-service property="componentResourceResolver" service-id="tapestry.page.ComponentResourceResolver" />
+ <event-listener service-id="tapestry.ResetEventHub"/>
+ <event-listener service-id="tapestry.describe.ReportStatusHub"/>
+ </construct>
+ </invoke-factory>
+
+ </service-point>
+
+ <service-point id="TemplateSourceDelegate" interface="org.apache.tapestry.engine.ITemplateSourceDelegate">
+
+ Delegate for TemplateSource that knows how to find templates in unusual places.
+
+ <invoke-factory service-id="tapestry.ExtensionLookupFactory">
+ <lookup extension-name="org.apache.tapestry.template-source-delegate"/>
+ </invoke-factory>
+
+ </service-point>
+
+ <contribution configuration-id="tapestry.Infrastructure">
+ <property name="templateSource" object="service:TemplateSource"/>
+ <property name="specificationSource" object="service:SpecificationSource"/>
+ </contribution>
+
</module>
Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/l10n/DefaultResourceLocalizer.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/l10n/DefaultResourceLocalizer.java?view=diff&rev=536045&r1=536044&r2=536045
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/l10n/DefaultResourceLocalizer.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/l10n/DefaultResourceLocalizer.java Mon May 7 20:13:04 2007
@@ -14,17 +14,15 @@
package org.apache.tapestry.l10n;
-import java.util.Locale;
-
import org.apache.hivemind.Resource;
+import java.util.Locale;
+
/**
* Default implementation of {@link org.apache.tapestry.l10n.ResourceLocalizer} that leverages the
* localization rules built into
* {@link org.apache.hivemind.Resource#getLocalization(java.util.Locale)}.
*
- * @author Howard M. Lewis Ship
- * @since 4.0
*/
public class DefaultResourceLocalizer implements ResourceLocalizer
{
Added: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/resolver/ComponentResourceResolverImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/resolver/ComponentResourceResolverImpl.java?view=auto&rev=536045
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/resolver/ComponentResourceResolverImpl.java (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/resolver/ComponentResourceResolverImpl.java Mon May 7 20:13:04 2007
@@ -0,0 +1,165 @@
+package org.apache.tapestry.resolver;
+
+import org.apache.hivemind.Resource;
+import org.apache.hivemind.util.ContextResource;
+import org.apache.tapestry.IComponent;
+import org.apache.tapestry.IRequestCycle;
+import org.apache.tapestry.TapestryUtils;
+import org.apache.tapestry.asset.AssetFactory;
+import org.apache.tapestry.web.WebContextResource;
+
+import java.util.Locale;
+
+/**
+ * Implementation of {@link IComponentResourceResolver}.
+ */
+public class ComponentResourceResolverImpl implements IComponentResourceResolver {
+
+ /**
+ * Used to find resources under the context WEB-INF/ directory.
+ */
+ private static final String WEB_INF = "WEB-INF/";
+
+ private AssetFactory _classpathAssetFactory;
+ private AssetFactory _contextAssetFactory;
+
+ /** Application id of the current tapestry app - as in applicationId.application */
+ private String _applicationId;
+
+ /** Root web context directory */
+ private Resource _contextRoot;
+ /** The location of the WEB-INF context directory */
+ private Resource _webInfLocation;
+ /** The location of the application within the WEB-INF/ folder */
+ private Resource _webInfAppLocation;
+
+ /**
+ * Called by hivemind automatically.
+ */
+ public void initializeService()
+ {
+ _webInfLocation = _contextRoot.getRelativeResource(WEB_INF);
+
+ _webInfAppLocation = _webInfLocation.getRelativeResource(_applicationId + "/");
+ }
+
+ public Resource findComponentResource(IComponent component, IRequestCycle cycle, String path, String extension, Locale locale)
+ {
+ Resource base = component.getSpecification().getSpecificationLocation();
+ String baseName = path == null ? extractBaseName(base) : path;
+ Resource resource = null;
+
+ // have to do explicit check for context resource first
+ // as it might be a classpath based spec and then we need to manually figure out
+ // the best location to start from as context paths always get resolved first
+ // before classpath resources
+
+ if (WebContextResource.class.isInstance(base) || ContextResource.class.isInstance(base))
+ {
+ resource = base.getRelativeResource(baseName + extension);
+
+ if (resource != null)
+ return localizeResource(resource, locale);
+ }
+
+ resource = findComponentClassResource(component, cycle, baseName, extension, locale);
+
+ // In some cases the generic classpath resource path is fine - such as bundled component properties
+
+ if (resource == null) {
+
+ resource = base.getRelativeResource(baseName + extension);
+
+ if (resource != null)
+ resource = localizeResource(resource, locale);
+ }
+
+ return resource;
+ }
+
+ String extractBaseName(Resource baseResourceLocation)
+ {
+ String fileName = baseResourceLocation.getName();
+ int dotx = fileName.lastIndexOf('.');
+
+ return dotx > -1 ? fileName.substring(0, dotx) : fileName;
+ }
+
+ Resource localizeResource(Resource resource, Locale locale)
+ {
+ if (locale == null)
+ return resource;
+
+ Resource localized = resource.getLocalization(locale);
+ if (localized != null && localized.getResourceURL() != null)
+ return localized;
+
+ return resource;
+ }
+
+ Resource findComponentClassResource(IComponent component, IRequestCycle cycle, String baseName, String extension, Locale locale)
+ {
+ Resource base = component.getSpecification().getSpecificationLocation();
+ String componentPackages = component.getNamespace().getPropertyValue("org.apache.tapestry.component-class-packages");
+
+ // this relies on finding things from the component class name
+
+ if (componentPackages == null)
+ return null;
+
+ String className = component.getSpecification().getComponentClassName();
+ if (className == null)
+ return null;
+
+ String[] packages = TapestryUtils.split(componentPackages);
+ for (int i=0; i < packages.length; i++)
+ {
+ // find matching package in class
+ int index = className.lastIndexOf(packages[i]);
+ if (index < 0)
+ continue;
+
+ // First try context
+
+ String templateName = className.substring((index + packages[i].length()) + 1, className.length()).replaceAll("\\.", "/");
+ templateName = templateName + extension;
+
+ if (_contextAssetFactory.assetExists(component.getSpecification(), _webInfAppLocation, templateName, locale)) {
+
+ return _contextAssetFactory.createAsset(_webInfAppLocation, component.getSpecification(), templateName, locale, component.getLocation()).getResourceLocation();
+ } else if (_contextAssetFactory.assetExists(component.getSpecification(), _webInfLocation, templateName, locale)) {
+
+ return _contextAssetFactory.createAsset(_webInfLocation, component.getSpecification(), templateName, locale, component.getLocation()).getResourceLocation();
+ }
+
+ // else classpath
+
+ String resourceName = baseName + extension;
+
+ if (_classpathAssetFactory.assetExists(component.getSpecification(), base, resourceName, locale))
+ return _classpathAssetFactory.createAsset(base, component.getSpecification(), resourceName, locale, component.getLocation()).getResourceLocation();
+ }
+
+ return null;
+ }
+
+ public void setContextRoot(Resource contextRoot)
+ {
+ _contextRoot = contextRoot;
+ }
+
+ public void setClasspathAssetFactory(AssetFactory classpathAssetFactory)
+ {
+ _classpathAssetFactory = classpathAssetFactory;
+ }
+
+ public void setContextAssetFactory(AssetFactory contextAssetFactory)
+ {
+ _contextAssetFactory = contextAssetFactory;
+ }
+
+ public void setApplicationId(String applicationId)
+ {
+ _applicationId = applicationId;
+ }
+}
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/resolver/ComponentResourceResolverImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/resolver/IComponentResourceResolver.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/resolver/IComponentResourceResolver.java?view=auto&rev=536045
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/resolver/IComponentResourceResolver.java (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/resolver/IComponentResourceResolver.java Mon May 7 20:13:04 2007
@@ -0,0 +1,36 @@
+package org.apache.tapestry.resolver;
+
+import org.apache.hivemind.Resource;
+import org.apache.tapestry.IComponent;
+import org.apache.tapestry.IRequestCycle;
+
+import java.util.Locale;
+
+/**
+ * Service responsible for finding resources relative or specific to a {@link org.apache.tapestry.IComponent}.
+ *
+ */
+public interface IComponentResourceResolver {
+
+ /**
+ * Searches for a resource relative to the specified {@link IComponent}, optionally also attemping to
+ * find a localized version of the resource using the specified {@link Locale}.
+ *
+ * @param component
+ * The component to find the resource relative to.
+ * @param cycle
+ * The current request.
+ * @param name
+ * Optional resource name to search for, the default is to use the component name.
+ * @param extension
+ * Extension name of the resource, such as <ComponentName>.properties for properties
+ * / <ComponentName>.html for templates and so on.
+ * @param locale
+ * Optional localization specifier.
+ *
+ * @return The resolved resource, or null if none could be found. The returned {@link Resource} may
+ * also be not null but still not valid. To ensure validity check {@link org.apache.hivemind.Resource#getResourceURL()} for
+ * a not null value.
+ */
+ Resource findComponentResource(IComponent component, IRequestCycle cycle, String name, String extension, Locale locale);
+}
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/resolver/IComponentResourceResolver.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/ClasspathResourceFactory.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/ClasspathResourceFactory.java?view=diff&rev=536045&r1=536044&r2=536045
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/ClasspathResourceFactory.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/ClasspathResourceFactory.java Mon May 7 20:13:04 2007
@@ -18,9 +18,6 @@
/**
* Used to create new instances of {@link org.apache.hivemind.util.ClasspathResource}.
- *
- * @author Howard Lewis Ship
- * @since 4.0
*/
public interface ClasspathResourceFactory
{
Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/ComponentMessagesSourceImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/ComponentMessagesSourceImpl.java?view=diff&rev=536045&r1=536044&r2=536045
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/ComponentMessagesSourceImpl.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/ComponentMessagesSourceImpl.java Mon May 7 20:13:04 2007
@@ -23,6 +23,7 @@
import org.apache.tapestry.IComponent;
import org.apache.tapestry.INamespace;
import org.apache.tapestry.event.ResetEventListener;
+import org.apache.tapestry.resolver.IComponentResourceResolver;
import org.apache.tapestry.services.ClasspathResourceFactory;
import org.apache.tapestry.services.ComponentMessagesSource;
import org.apache.tapestry.services.ComponentPropertySource;
@@ -36,7 +37,7 @@
/**
* Service used to access localized properties for a component.
- *
+ *
* @author Howard Lewis Ship
* @since 2.0.4
*/
@@ -49,16 +50,16 @@
*/
public static final String MESSAGES_ENCODING_PROPERTY_NAME = "org.apache.tapestry.messages-encoding";
-
+
/**
* The alternate file name of a namespace properties file to lookup. Can be used to override the default
* behaviour which is to look for a <namespace name>.properties file to find localized/global properties.
*/
-
+
public static final String NAMESPACE_PROPERTIES_NAME = "org.apache.tapestry.namespace-properties-name";
-
+
private static final String SUFFIX = ".properties";
-
+
private Properties _emptyProperties = new Properties();
/**
@@ -75,7 +76,9 @@
* For locating resources on the classpath as well as context path.
*/
private ClasspathResourceFactory _classpathResourceFactory;
-
+
+ private IComponentResourceResolver _resourceResolver;
+
/**
* Returns an instance of {@link Properties}containing the properly
* localized messages for the component, in the {@link Locale}identified by
@@ -87,19 +90,19 @@
Defense.notNull(component, "component");
Resource specificationLocation = component.getSpecification().getSpecificationLocation();
-
+
Locale locale = component.getPage().getLocale();
-
+
Map propertiesMap = findPropertiesMapForResource(specificationLocation);
-
+
Properties result = (Properties) propertiesMap.get(locale);
if (result == null)
{
// Not found, create it now.
-
+
result = assembleComponentProperties(component, specificationLocation, propertiesMap, locale);
-
+
propertiesMap.put(locale, result);
}
@@ -122,13 +125,13 @@
private Properties getNamespaceProperties(IComponent component, Locale locale)
{
INamespace namespace = component.getNamespace();
-
+
Resource namespaceLocation = namespace.getSpecificationLocation();
-
+
Map propertiesMap = findPropertiesMapForResource(namespaceLocation);
-
+
Properties result = (Properties) propertiesMap.get(locale);
-
+
if (result == null)
{
result = assembleNamespaceProperties(namespace, propertiesMap, locale);
@@ -139,12 +142,12 @@
return result;
}
- private Properties assembleComponentProperties(IComponent component, Resource baseResourceLocation,
- Map propertiesMap, Locale locale)
+ private Properties assembleComponentProperties(IComponent component, Resource baseResourceLocation,
+ Map propertiesMap, Locale locale)
{
- List localizations = findLocalizationsForResource(baseResourceLocation, locale,
- component.getSpecification().getProperty(NAMESPACE_PROPERTIES_NAME));
-
+ List localizations = findLocalizationsForResource(component, baseResourceLocation, locale,
+ component.getSpecification().getProperty(NAMESPACE_PROPERTIES_NAME));
+
Properties parent = null;
Properties assembledProperties = null;
@@ -169,31 +172,34 @@
// Override parent properties with current locale
if (parent != null)
{
- if (properties != null)
+ if (properties != null)
parent.putAll(properties);
}
- else
+ else
parent = properties;
// Add to assembled properties
- if (parent != null)
+ if (parent != null)
assembledProperties.putAll(parent);
// Save result in cache
propertiesMap.put(l, assembledProperties);
}
+ if (assembledProperties == null)
+ assembledProperties = new Properties();
+
return assembledProperties;
}
private Properties assembleNamespaceProperties(INamespace namespace,
- Map propertiesMap, Locale locale)
+ Map propertiesMap, Locale locale)
{
- List localizations = findLocalizationsForResource(namespace.getSpecificationLocation(), locale,
- namespace.getPropertyValue(NAMESPACE_PROPERTIES_NAME));
-
+ List localizations = findLocalizationsForResource(namespace.getSpecificationLocation(), locale,
+ namespace.getPropertyValue(NAMESPACE_PROPERTIES_NAME));
+
// Build them back up in reverse order.
-
+
Properties parent = _emptyProperties;
Iterator i = localizations.iterator();
@@ -209,7 +215,7 @@
if (properties == null)
{
properties = readNamespaceProperties(namespace, l, rl.getResource(), parent);
-
+
propertiesMap.put(l, properties);
}
@@ -230,30 +236,62 @@
private List findLocalizationsForResource(Resource resource, Locale locale, String alternateName)
{
List result = new ArrayList();
-
+
String baseName = null;
if (alternateName != null) {
-
+
baseName = alternateName.replace('.', '/');
} else {
-
+
baseName = extractBaseName(resource);
}
-
+
LocalizedNameGenerator g = new LocalizedNameGenerator(baseName, locale, SUFFIX);
-
+
while(g.more())
{
String localizedName = g.next();
Locale l = g.getCurrentLocale();
-
+
Resource localizedResource = resource.getRelativeResource(localizedName);
-
+
if (localizedResource.getResourceURL() == null) {
-
+
localizedResource = _classpathResourceFactory.newResource(baseName + SUFFIX);
}
-
+
+ result.add(new ResourceLocalization(l, localizedResource));
+ }
+
+ Collections.reverse(result);
+
+ return result;
+ }
+
+ private List findLocalizationsForResource(IComponent component, Resource resource, Locale locale, String alternateName)
+ {
+ List result = new ArrayList();
+
+ String baseName = null;
+ if (alternateName != null) {
+
+ baseName = alternateName.replace('.', '/');
+ } else {
+
+ baseName = extractBaseName(resource);
+ }
+
+ LocalizedNameGenerator g = new LocalizedNameGenerator(baseName, locale, "");
+
+ while(g.more())
+ {
+ String localizedName = g.next();
+ Locale l = g.getCurrentLocale();
+
+ Resource localizedResource = _resourceResolver.findComponentResource(component, null, localizedName, SUFFIX, null);
+ if (localizedResource == null)
+ continue;
+
result.add(new ResourceLocalization(l, localizedResource));
}
@@ -271,18 +309,18 @@
}
private Properties readComponentProperties(IComponent component,
- Locale locale, Resource propertiesResource, Properties parent)
+ Locale locale, Resource propertiesResource, Properties parent)
{
String encoding = getComponentMessagesEncoding(component, locale);
-
+
return readPropertiesResource(propertiesResource.getResourceURL(), encoding, parent);
}
-
+
private Properties readNamespaceProperties(INamespace namespace,
- Locale locale, Resource propertiesResource, Properties parent)
+ Locale locale, Resource propertiesResource, Properties parent)
{
String encoding = getNamespaceMessagesEncoding(namespace, locale);
-
+
return readPropertiesResource(propertiesResource.getResourceURL(), encoding, parent);
}
@@ -290,11 +328,11 @@
{
if (resourceURL == null)
return parent;
-
+
Properties result = new Properties(parent);
-
+
LocalizedProperties wrapper = new LocalizedProperties(result);
-
+
InputStream input = null;
try
@@ -303,15 +341,14 @@
if (encoding == null)
wrapper.load(input);
- else
+ else
wrapper.load(input, encoding);
input.close();
}
catch (IOException ex)
{
- throw new ApplicationRuntimeException(ImplMessages
- .unableToLoadProperties(resourceURL, ex), ex);
+ throw new ApplicationRuntimeException(ImplMessages.unableToLoadProperties(resourceURL, ex), ex);
}
finally
{
@@ -345,14 +382,14 @@
public Messages getMessages(IComponent component)
{
return new ComponentMessages(component.getPage().getLocale(),
- getLocalizedProperties(component));
+ getLocalizedProperties(component));
}
private String getComponentMessagesEncoding(IComponent component,
- Locale locale)
+ Locale locale)
{
String encoding = _componentPropertySource.getLocalizedComponentProperty(component, locale,
- MESSAGES_ENCODING_PROPERTY_NAME);
+ MESSAGES_ENCODING_PROPERTY_NAME);
if (encoding == null)
encoding = _componentPropertySource.getLocalizedComponentProperty(
@@ -363,7 +400,7 @@
}
private String getNamespaceMessagesEncoding(INamespace namespace,
- Locale locale)
+ Locale locale)
{
return _componentPropertySource.getLocalizedNamespaceProperty(
namespace, locale, MESSAGES_ENCODING_PROPERTY_NAME);
@@ -373,9 +410,14 @@
{
_componentPropertySource = componentPropertySource;
}
-
+
public void setClasspathResourceFactory(ClasspathResourceFactory factory)
{
_classpathResourceFactory = factory;
+ }
+
+ public void setComponentResourceResolver(IComponentResourceResolver resourceResolver)
+ {
+ _resourceResolver = resourceResolver;
}
}
Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/ComponentPropertySourceImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/ComponentPropertySourceImpl.java?view=diff&rev=536045&r1=536044&r2=536045
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/ComponentPropertySourceImpl.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/ComponentPropertySourceImpl.java Mon May 7 20:13:04 2007
@@ -14,12 +14,6 @@
package org.apache.tapestry.services.impl;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-
import org.apache.hivemind.Resource;
import org.apache.hivemind.lib.chain.ChainBuilder;
import org.apache.tapestry.IComponent;
@@ -30,6 +24,8 @@
import org.apache.tapestry.spec.IComponentSpecification;
import org.apache.tapestry.util.PropertyHolderPropertySource;
+import java.util.*;
+
/**
* Implementation of tapestry.props.ComponentPropertySource.
* <p>
@@ -94,8 +90,7 @@
{
Resource key = component.getSpecification().getSpecificationLocation();
- LocalizedPropertySource result = (LocalizedPropertySource) _localizedComponentSources
- .get(key);
+ LocalizedPropertySource result = (LocalizedPropertySource) _localizedComponentSources.get(key);
if (result == null)
{
@@ -111,8 +106,7 @@
{
Resource key = namespace.getSpecificationLocation();
- LocalizedPropertySource result = (LocalizedPropertySource) _localizedNamespaceSources
- .get(key);
+ LocalizedPropertySource result = (LocalizedPropertySource) _localizedNamespaceSources.get(key);
if (result == null)
{
Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/ComponentTemplateLoaderImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/ComponentTemplateLoaderImpl.java?view=diff&rev=536045&r1=536044&r2=536045
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/ComponentTemplateLoaderImpl.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/ComponentTemplateLoaderImpl.java Mon May 7 20:13:04 2007
@@ -55,8 +55,7 @@
{
ComponentTemplate template = _templateSource.getTemplate(requestCycle, loadComponent);
- ComponentTemplateLoaderLogic logic =
- new ComponentTemplateLoaderLogic(_log, _pageLoader, _bindingSource);
+ ComponentTemplateLoaderLogic logic = new ComponentTemplateLoaderLogic(_log, _pageLoader, _bindingSource);
logic.loadTemplate(requestCycle, loadComponent, template);
}
Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/ComponentTemplateLoaderLogic.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/ComponentTemplateLoaderLogic.java?view=diff&rev=536045&r1=536044&r2=536045
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/ComponentTemplateLoaderLogic.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/ComponentTemplateLoaderLogic.java Mon May 7 20:13:04 2007
@@ -37,9 +37,7 @@
* Contains the logic from {@link org.apache.tapestry.services.impl.ComponentTemplateLoaderImpl},
* which creates one of these instances to process the request. This is necessary because the
* service must be re-entrant (because templates can contain components that have templates).
- *
- * @author Howard Lewis Ship
- * @since 4.0
+ *
*/
public class ComponentTemplateLoaderLogic
{
@@ -69,7 +67,7 @@
}
public void loadTemplate(IRequestCycle requestCycle, ITemplateComponent loadComponent,
- ComponentTemplate template)
+ ComponentTemplate template)
{
_requestCycle = requestCycle;
_loadComponent = loadComponent;
@@ -110,7 +108,6 @@
if (type == TokenType.LOCALIZATION)
{
process((LocalizationToken) token);
- continue;
}
}
@@ -118,8 +115,8 @@
// of date, too.
if (_stackx != 0)
- throw new ApplicationRuntimeException(Tapestry
- .getMessage("BaseComponent.unbalance-open-tags"), _loadComponent, null, null);
+ throw new ApplicationRuntimeException(Tapestry.getMessage("BaseComponent.unbalance-open-tags"),
+ _loadComponent, null, null);
checkAllComponentsReferenced();
}
@@ -142,7 +139,7 @@
if (!_activeComponent.getSpecification().getAllowBody())
throw createBodylessComponentException(_activeComponent);
-
+
_activeComponent.addBody(token);
}
@@ -164,9 +161,8 @@
// Make sure the template contains each component only once.
if (_seenIds.contains(id))
- throw new ApplicationRuntimeException(ImplMessages.multipleComponentReferences(
- _loadComponent,
- id), _loadComponent, token.getLocation(), null);
+ throw new ApplicationRuntimeException(ImplMessages.multipleComponentReferences(_loadComponent,id),
+ _loadComponent, token.getLocation(), null);
_seenIds.add(id);
@@ -179,7 +175,7 @@
if (!_activeComponent.getSpecification().getAllowBody())
throw createBodylessComponentException(_activeComponent);
-
+
_activeComponent.addBody(component);
}
@@ -199,19 +195,17 @@
if (cc != null)
throw new ApplicationRuntimeException(ImplMessages.dupeComponentId(id, cc),
- _loadComponent, location, null);
+ _loadComponent, location, null);
}
private IComponent createImplicitComponent(String id, String componentType, Location location)
{
- IComponent result = _pageLoader.createImplicitComponent(
+ return _pageLoader.createImplicitComponent(
_requestCycle,
_loadComponent,
id,
componentType,
location);
-
- return result;
}
private IComponent getEmbeddedComponent(String id)
@@ -226,7 +220,7 @@
if (_stackx <= 0)
throw new ApplicationRuntimeException(ImplMessages.unbalancedCloseTags(),
- _loadComponent, token.getLocation(), null);
+ _loadComponent, token.getLocation(), null);
// Null and forget the top element on the stack.
@@ -252,9 +246,9 @@
void addTemplateBindings(IComponent component, OpenToken token)
{
// sets the html tag name used to specify the component
-
+
component.setTemplateTagName(token.getTag());
-
+
IComponentSpecification spec = component.getSpecification();
Map attributes = token.getAttributesMap();
@@ -299,7 +293,7 @@
// add a static binding carrying the template tag
if (spec.getParameter(TemplateSource.TEMPLATE_TAG_PARAMETER_NAME) != null
- && component.getBinding(TemplateSource.TEMPLATE_TAG_PARAMETER_NAME) == null)
+ && component.getBinding(TemplateSource.TEMPLATE_TAG_PARAMETER_NAME) == null)
{
IBinding binding = _bindingSource.createBinding(
component,
@@ -318,8 +312,8 @@
* It is an error to specify expression bindings in both the specification and the template.
*/
- private void addBinding(IComponent component, IComponentSpecification spec, String name,
- IBinding binding)
+ private void addBinding(IComponent component, IComponentSpecification spec,
+ String name, IBinding binding)
{
// If matches a formal parameter name, allow it to be set
@@ -331,8 +325,8 @@
component.setBinding(name, binding);
}
- private boolean validate(IComponent component, IComponentSpecification spec, String name,
- IBinding binding)
+ private boolean validate(IComponent component, IComponentSpecification spec,
+ String name, IBinding binding)
{
// TODO: This is ugly! Need a better/smarter way, even if we have to extend BindingSource
// to tell us.
@@ -351,9 +345,8 @@
if (isLiteral)
return false;
- throw new ApplicationRuntimeException(ImplMessages
- .templateBindingForInformalParameter(_loadComponent, name, component),
- component, binding.getLocation(), null);
+ throw new ApplicationRuntimeException(ImplMessages.templateBindingForInformalParameter(_loadComponent, name, component),
+ component, binding.getLocation(), null);
}
// If the name is reserved (matches a formal parameter
@@ -367,9 +360,8 @@
if (isLiteral)
return false;
- throw new ApplicationRuntimeException(ImplMessages
- .templateBindingForReservedParameter(_loadComponent, name, component),
- component, binding.getLocation(), null);
+ throw new ApplicationRuntimeException(ImplMessages.templateBindingForReservedParameter(_loadComponent, name, component),
+ component, binding.getLocation(), null);
}
}
@@ -424,7 +416,6 @@
private ApplicationRuntimeException createBodylessComponentException(IComponent component)
{
- return new ApplicationRuntimeException(ImplMessages.bodylessComponent(), component, null,
- null);
+ return new ApplicationRuntimeException(ImplMessages.bodylessComponent(), component, null, null);
}
}
Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/TemplateSourceImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/TemplateSourceImpl.java?view=diff&rev=536045&r1=536044&r2=536045
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/TemplateSourceImpl.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/TemplateSourceImpl.java Mon May 7 20:13:04 2007
@@ -19,7 +19,6 @@
import org.apache.hivemind.ApplicationRuntimeException;
import org.apache.hivemind.Resource;
import org.apache.tapestry.*;
-import org.apache.tapestry.asset.AssetFactory;
import org.apache.tapestry.engine.ITemplateSourceDelegate;
import org.apache.tapestry.event.ReportStatusEvent;
import org.apache.tapestry.event.ReportStatusListener;
@@ -27,6 +26,7 @@
import org.apache.tapestry.l10n.ResourceLocalizer;
import org.apache.tapestry.parse.*;
import org.apache.tapestry.resolver.ComponentSpecificationResolver;
+import org.apache.tapestry.resolver.IComponentResourceResolver;
import org.apache.tapestry.services.ComponentPropertySource;
import org.apache.tapestry.services.TemplateSource;
import org.apache.tapestry.spec.IComponentSpecification;
@@ -56,8 +56,6 @@
public static final String TEMPLATE_ENCODING_PROPERTY_NAME = "org.apache.tapestry.template-encoding";
- private static final String WEB_INF = "WEB-INF/";
-
private static final int BUFFER_SIZE = 2000;
private String _serviceId;
@@ -98,23 +96,8 @@
private ResourceLocalizer _localizer;
/** @since 4.1.2 */
- private AssetFactory _classpathAssetFactory;
-
- /** @since 4.1.2 */
- private AssetFactory _contextAssetFactory;
-
- private String _applicationId;
-
- private Resource _webInfLocation;
-
- private Resource _webInfAppLocation;
-
- public void initializeService()
- {
- _webInfLocation = _contextRoot.getRelativeResource(WEB_INF);
-
- _webInfAppLocation = _webInfLocation.getRelativeResource(_applicationId + "/");
- }
+
+ private IComponentResourceResolver _resourceResolver;
/**
* Clears the template cache. This is used during debugging.
@@ -246,7 +229,7 @@
IAsset templateAsset = component.getAsset(TEMPLATE_ASSET_NAME);
if (templateAsset != null)
- return readTemplateFromAsset(cycle, component, templateAsset);
+ return readTemplateFromAsset(cycle, component, templateAsset.getResourceLocation());
String name = resource.getName();
int dotx = name.lastIndexOf('.');
@@ -269,57 +252,16 @@
locale);
if (result == null) {
+
+ Resource template = _resourceResolver.findComponentResource(component, cycle, null, "." + templateExtension, locale);
- templateAsset = findSpeclessTemplate(cycle, resource, component, locale, templateExtension);
-
- if (templateAsset != null)
- return readTemplateFromAsset(cycle, component, templateAsset);
+ if (template != null)
+ return readTemplateFromAsset(cycle, component, template);
}
return result;
}
- private IAsset findSpeclessTemplate(IRequestCycle cycle, Resource base,
- IComponent component, Locale locale, String templateExtension)
- {
- String componentPackages = component.getNamespace().getPropertyValue("org.apache.tapestry.component-class-packages");
- if (componentPackages == null)
- return null;
-
- String name = base.getName();
- String className = component.getSpecification().getComponentClassName();
-
- String[] packages = TapestryUtils.split(componentPackages);
- for (int i=0; i < packages.length; i++)
- {
- int index = className.lastIndexOf(packages[i]);
- if (index < 0)
- continue;
-
- // First try context
-
- String templateName = className.substring((index + packages[i].length()) + 1, className.length()).replaceAll("\\.", "/");
- templateName = templateName + "." + templateExtension;
-
- if (_contextAssetFactory.assetExists(component.getSpecification(), _webInfAppLocation, templateName, locale)) {
-
- return _contextAssetFactory.createAsset(_webInfAppLocation, component.getSpecification(), templateName, locale, component.getLocation());
- } else if (_contextAssetFactory.assetExists(component.getSpecification(), _webInfLocation, templateName, locale)) {
-
- return _contextAssetFactory.createAsset(_webInfLocation, component.getSpecification(), templateName, locale, component.getLocation());
- }
-
- // else classpath
-
- templateName = name + "." + templateExtension;
-
- if (_classpathAssetFactory.assetExists(component.getSpecification(), base, templateName, locale))
- return _classpathAssetFactory.createAsset(base, component.getSpecification(), templateName, locale, component.getLocation());
- }
-
- return null;
- }
-
private ComponentTemplate findPageTemplateInApplicationRoot(IRequestCycle cycle, IPage page,
String templateExtension, Locale locale)
{
@@ -345,19 +287,23 @@
return getOrParseTemplate(cycle, localizedLocation, page);
}
+
+
/**
* Reads an asset to get the template.
*/
private ComponentTemplate readTemplateFromAsset(IRequestCycle cycle, IComponent component,
- IAsset asset)
+ Resource asset)
{
- InputStream stream = asset.getResourceAsStream();
+ InputStream stream = null;
char[] templateData = null;
try
{
+ stream = asset.getResourceURL().openStream();
+
String encoding = getTemplateEncoding(component, null);
templateData = readTemplateStream(stream, encoding);
@@ -369,9 +315,7 @@
throw new ApplicationRuntimeException(ImplMessages.unableToReadTemplate(asset), ex);
}
- Resource resourceLocation = asset.getResourceLocation();
-
- return constructTemplateInstance(cycle, templateData, resourceLocation, component);
+ return constructTemplateInstance(cycle, templateData, asset, component);
}
/**
@@ -635,20 +579,8 @@
_localizer = localizer;
}
- /** @since 4.1.2 */
- public void setClasspathAssetFactory(AssetFactory classpathAssetFactory)
- {
- _classpathAssetFactory = classpathAssetFactory;
- }
-
- /** @since 4.1.2 */
- public void setContextAssetFactory(AssetFactory contextAssetFactory)
- {
- _contextAssetFactory = contextAssetFactory;
- }
-
- public void setApplicationId(String applicationId)
+ public void setComponentResourceResolver(IComponentResourceResolver resourceResolver)
{
- _applicationId = applicationId;
+ _resourceResolver = resourceResolver;
}
}
Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/web/LocalizedWebContextResourceFinder.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/web/LocalizedWebContextResourceFinder.java?view=diff&rev=536045&r1=536044&r2=536045
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/web/LocalizedWebContextResourceFinder.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/web/LocalizedWebContextResourceFinder.java Mon May 7 20:13:04 2007
@@ -73,8 +73,7 @@
String candidatePath = generator.next();
if (isExistingResource(candidatePath))
- return new LocalizedResource(candidatePath, generator
- .getCurrentLocale());
+ return new LocalizedResource(candidatePath, generator.getCurrentLocale());
}
return null;
Modified: tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/junit/TestComponentMessages.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/junit/TestComponentMessages.java?view=diff&rev=536045&r1=536044&r2=536045
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/junit/TestComponentMessages.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/junit/TestComponentMessages.java Mon May 7 20:13:04 2007
@@ -14,11 +14,6 @@
package org.apache.tapestry.junit;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.GregorianCalendar;
-import java.util.Locale;
-
import org.apache.hivemind.Location;
import org.apache.hivemind.Messages;
import org.apache.hivemind.Resource;
@@ -34,6 +29,7 @@
import org.apache.tapestry.enhance.InjectMessagesWorker;
import org.apache.tapestry.enhance.InjectSpecificationWorker;
import org.apache.tapestry.html.BasePage;
+import org.apache.tapestry.resolver.ComponentResourceResolverImpl;
import org.apache.tapestry.services.ComponentMessagesSource;
import org.apache.tapestry.services.ComponentPropertySource;
import org.apache.tapestry.services.impl.ClasspathResourceFactoryImpl;
@@ -44,6 +40,11 @@
import org.apache.tapestry.spec.LibrarySpecification;
import org.testng.annotations.Test;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.Locale;
+
/**
* Tests the class {@link org.apache.tapestry.services.impl.ComponentMessagesSourceImpl}.
* <p>
@@ -105,7 +106,6 @@
String actual = messages.getMessage(key);
assertEquals(expected, actual);
-
}
private static final String MOCK1 = "/org/apache/tapestry/junit/MockPage1.page";
@@ -164,6 +164,7 @@
ComponentMessagesSourceImpl source = new ComponentMessagesSourceImpl();
source.setClasspathResourceFactory(new ClasspathResourceFactoryImpl(new DefaultClassResolver()));
source.setComponentPropertySource(new NullComponentPropertySource());
+ source.setComponentResourceResolver(new ComponentResourceResolverImpl());
IComponentSpecification spec = newSpec(location);
spec.setLocation(_locationFixture);
@@ -182,6 +183,7 @@
ComponentMessagesSourceImpl source = new ComponentMessagesSourceImpl();
source.setClasspathResourceFactory(new ClasspathResourceFactoryImpl(new DefaultClassResolver()));
source.setComponentPropertySource(new NullComponentPropertySource());
+ source.setComponentResourceResolver(new ComponentResourceResolverImpl());
IComponentSpecification spec = newSpec(location);
spec.setLocation(_locationFixture);
@@ -353,6 +355,7 @@
ComponentMessagesSourceImpl source = new ComponentMessagesSourceImpl();
source.setClasspathResourceFactory(new ClasspathResourceFactoryImpl(new DefaultClassResolver()));
source.setComponentPropertySource(new NullComponentPropertySource());
+ source.setComponentResourceResolver(new ComponentResourceResolverImpl());
IComponentSpecification spec = newSpec(MOCK1);
spec.setLocation(_locationFixture);
Added: tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/resolver/TestComponentResourceResolver.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/resolver/TestComponentResourceResolver.java?view=auto&rev=536045
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/resolver/TestComponentResourceResolver.java (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/resolver/TestComponentResourceResolver.java Mon May 7 20:13:04 2007
@@ -0,0 +1,239 @@
+package org.apache.tapestry.resolver;
+
+import org.apache.hivemind.Location;
+import org.apache.hivemind.Resource;
+import org.apache.hivemind.impl.DefaultClassResolver;
+import org.apache.hivemind.util.ClasspathResource;
+import org.apache.tapestry.*;
+import org.apache.tapestry.asset.AssetFactory;
+import org.apache.tapestry.spec.ComponentSpecification;
+import org.apache.tapestry.spec.IComponentSpecification;
+import org.apache.tapestry.web.WebContext;
+import org.apache.tapestry.web.WebContextResource;
+import static org.easymock.EasyMock.checkOrder;
+import static org.easymock.EasyMock.expect;
+import org.testng.annotations.Test;
+
+import java.net.URL;
+import java.util.Locale;
+
+/**
+ * Tests functionality of {@link ComponentResourceResolverImpl}.
+ */
+@Test
+public class TestComponentResourceResolver extends TestBase {
+
+ public void test_Context_Spec_Resource()
+ {
+ IComponent comp = newMock(IComponent.class);
+ checkOrder(comp, false);
+ WebContext context = newMock(WebContext.class);
+ IRequestCycle cycle = newMock(IRequestCycle.class);
+
+ IComponentSpecification spec = new ComponentSpecification();
+ WebContextResource base = new WebContextResource(context, "/WEB-INF/MyComponent.jwc");
+ spec.setSpecificationLocation(base);
+
+ ComponentResourceResolverImpl resolver = new ComponentResourceResolverImpl();
+
+ expect(comp.getSpecification()).andReturn(spec).anyTimes();
+ expect(context.getResource("/WEB-INF/MyComponent.html")).andReturn(newURL());
+
+ replay();
+
+ Resource resolved = resolver.findComponentResource(comp, cycle, null, ".html", null);
+ assert resolved != null;
+ assert resolved.getResourceURL() != null;
+
+ verify();
+ }
+
+ public void test_Context_Spec_Localized_Resource()
+ {
+ IComponent comp = newMock(IComponent.class);
+ checkOrder(comp, false);
+ WebContext context = newMock(WebContext.class);
+ IRequestCycle cycle = newMock(IRequestCycle.class);
+
+ IComponentSpecification spec = new ComponentSpecification();
+ WebContextResource base = new WebContextResource(context, "/WEB-INF/MyComponent.jwc");
+ spec.setSpecificationLocation(base);
+
+ ComponentResourceResolverImpl resolver = new ComponentResourceResolverImpl();
+
+ expect(comp.getSpecification()).andReturn(spec).anyTimes();
+ expect(context.getResource("/WEB-INF/MyComponent_en.html")).andReturn(newURL()).anyTimes();
+ expect(context.getResource("/WEB-INF/MyComponent_en_US.html")).andReturn(null);
+
+ replay();
+
+ Resource resolved = resolver.findComponentResource(comp, cycle, null, ".html", Locale.US);
+ assert resolved != null;
+ assert resolved.getResourceURL() != null;
+
+ verify();
+ }
+
+ public void test_Classpath_Spec_Resource_App_Context_Resolved()
+ {
+ IComponent comp = newMock(IComponent.class);
+ checkOrder(comp, false);
+
+ INamespace namespace = newMock(INamespace.class);
+ IRequestCycle cycle = newMock(IRequestCycle.class);
+
+ IComponentSpecification spec = new ComponentSpecification();
+ ClasspathResource base = new ClasspathResource(new DefaultClassResolver(), "/org/apache/tapestry/resolver/MyComponent.jwc");
+ spec.setSpecificationLocation(base);
+ spec.setComponentClassName("org.apache.tapestry.resolver.MyComponent");
+
+ AssetFactory classpathFactory = newMock(AssetFactory.class);
+ AssetFactory contextFactory = newMock(AssetFactory.class);
+ Resource contextRoot = newMock(Resource.class);
+ Resource webinfLocation = newMock(Resource.class);
+ Resource webinfAppLocation = newMock(Resource.class);
+
+ ComponentResourceResolverImpl resolver = new ComponentResourceResolverImpl();
+ resolver.setApplicationId("foo");
+ resolver.setClasspathAssetFactory(classpathFactory);
+ resolver.setContextAssetFactory(contextFactory);
+ resolver.setContextRoot(contextRoot);
+
+ expect(contextRoot.getRelativeResource("WEB-INF/")).andReturn(webinfLocation);
+ expect(webinfLocation.getRelativeResource("foo/")).andReturn(webinfAppLocation);
+
+ expect(comp.getSpecification()).andReturn(spec).anyTimes();
+ expect(comp.getNamespace()).andReturn(namespace);
+ expect(namespace.getPropertyValue("org.apache.tapestry.component-class-packages")).andReturn("org.apache.tapestry.resolver");
+
+ Location l = newMock(Location.class);
+ IAsset asset = newMock(IAsset.class);
+ Resource resource = newMock(Resource.class);
+
+ expect(contextFactory.assetExists(spec, webinfAppLocation, "MyComponent.html", null)).andReturn(true);
+ expect(comp.getLocation()).andReturn(l);
+ expect(contextFactory.createAsset(webinfAppLocation, spec, "MyComponent.html", null, l)).andReturn(asset);
+ expect(asset.getResourceLocation()).andReturn(resource);
+
+ replay();
+
+ resolver.initializeService();
+
+ Resource resolved = resolver.findComponentResource(comp, cycle, null, ".html", null);
+ assertEquals(resolved, resource);
+
+ verify();
+ }
+
+ public void test_Classpath_Spec_Resource_WebInf_Context_Resolved()
+ {
+ IComponent comp = newMock(IComponent.class);
+ checkOrder(comp, false);
+
+ INamespace namespace = newMock(INamespace.class);
+ IRequestCycle cycle = newMock(IRequestCycle.class);
+
+ IComponentSpecification spec = new ComponentSpecification();
+ ClasspathResource base = new ClasspathResource(new DefaultClassResolver(), "/org/apache/tapestry/resolver/MyComponent.jwc");
+ spec.setSpecificationLocation(base);
+ spec.setComponentClassName("org.apache.tapestry.resolver.MyComponent");
+
+ AssetFactory classpathFactory = newMock(AssetFactory.class);
+ AssetFactory contextFactory = newMock(AssetFactory.class);
+ Resource contextRoot = newMock(Resource.class);
+ Resource webinfLocation = newMock(Resource.class);
+ Resource webinfAppLocation = newMock(Resource.class);
+
+ ComponentResourceResolverImpl resolver = new ComponentResourceResolverImpl();
+ resolver.setApplicationId("foo");
+ resolver.setClasspathAssetFactory(classpathFactory);
+ resolver.setContextAssetFactory(contextFactory);
+ resolver.setContextRoot(contextRoot);
+
+ expect(contextRoot.getRelativeResource("WEB-INF/")).andReturn(webinfLocation);
+ expect(webinfLocation.getRelativeResource("foo/")).andReturn(webinfAppLocation);
+
+ expect(comp.getSpecification()).andReturn(spec).anyTimes();
+ expect(comp.getNamespace()).andReturn(namespace);
+ expect(namespace.getPropertyValue("org.apache.tapestry.component-class-packages")).andReturn("org.apache.tapestry.resolver");
+
+ Location l = newMock(Location.class);
+ IAsset asset = newMock(IAsset.class);
+ Resource resource = newMock(Resource.class);
+
+ expect(contextFactory.assetExists(spec, webinfAppLocation, "MyComponent.html", null)).andReturn(false);
+ expect(contextFactory.assetExists(spec, webinfLocation, "MyComponent.html", null)).andReturn(true);
+ expect(comp.getLocation()).andReturn(l);
+ expect(contextFactory.createAsset(webinfLocation, spec, "MyComponent.html", null, l)).andReturn(asset);
+ expect(asset.getResourceLocation()).andReturn(resource);
+
+ replay();
+
+ resolver.initializeService();
+
+ Resource resolved = resolver.findComponentResource(comp, cycle, null, ".html", null);
+ assertEquals(resolved, resource);
+
+ verify();
+ }
+
+ public void test_Classpath_Spec_Resource_Classpath_Resolved()
+ {
+ IComponent comp = newMock(IComponent.class);
+ checkOrder(comp, false);
+
+ INamespace namespace = newMock(INamespace.class);
+ IRequestCycle cycle = newMock(IRequestCycle.class);
+
+ IComponentSpecification spec = new ComponentSpecification();
+ ClasspathResource base = new ClasspathResource(new DefaultClassResolver(), "/org/apache/tapestry/resolver/MyComponent.jwc");
+ spec.setSpecificationLocation(base);
+ spec.setComponentClassName("org.apache.tapestry.resolver.MyComponent");
+
+ AssetFactory classpathFactory = newMock(AssetFactory.class);
+ AssetFactory contextFactory = newMock(AssetFactory.class);
+ Resource contextRoot = newMock(Resource.class);
+ Resource webinfLocation = newMock(Resource.class);
+ Resource webinfAppLocation = newMock(Resource.class);
+
+ ComponentResourceResolverImpl resolver = new ComponentResourceResolverImpl();
+ resolver.setApplicationId("foo");
+ resolver.setClasspathAssetFactory(classpathFactory);
+ resolver.setContextAssetFactory(contextFactory);
+ resolver.setContextRoot(contextRoot);
+
+ expect(contextRoot.getRelativeResource("WEB-INF/")).andReturn(webinfLocation);
+ expect(webinfLocation.getRelativeResource("foo/")).andReturn(webinfAppLocation);
+
+ expect(comp.getSpecification()).andReturn(spec).anyTimes();
+ expect(comp.getNamespace()).andReturn(namespace);
+ expect(namespace.getPropertyValue("org.apache.tapestry.component-class-packages")).andReturn("org.apache.tapestry.resolver");
+
+ Location l = newMock(Location.class);
+ IAsset asset = newMock(IAsset.class);
+ Resource resource = newMock(Resource.class);
+
+ expect(contextFactory.assetExists(spec, webinfAppLocation, "MyComponent.html", null)).andReturn(false);
+ expect(contextFactory.assetExists(spec, webinfLocation, "MyComponent.html", null)).andReturn(false);
+ expect(classpathFactory.assetExists(spec, base, "MyComponent.html", null)).andReturn(true);
+
+ expect(comp.getLocation()).andReturn(l);
+ expect(classpathFactory.createAsset(base, spec, "MyComponent.html", null, l)).andReturn(asset);
+ expect(asset.getResourceLocation()).andReturn(resource);
+
+ replay();
+
+ resolver.initializeService();
+
+ Resource resolved = resolver.findComponentResource(comp, cycle, null, ".html", null);
+ assertEquals(resolved, resource);
+
+ verify();
+ }
+
+ // Returns the same URL object pointing to any arbitrary test classpath resource
+ public URL newURL()
+ {
+ return this.getClass().getResource("MyComponent.jwc");
+ }
+}
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/resolver/TestComponentResourceResolver.java
------------------------------------------------------------------------------
svn:eol-style = native