You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2007/02/12 02:14:50 UTC
svn commit: r506201 - in /tapestry/tapestry5/tapestry-core/trunk/src:
main/java/org/apache/tapestry/internal/services/
main/java/org/apache/tapestry/services/ main/java/org/apache/tapestry/test/
test/java/org/apache/tapestry/internal/services/
Author: hlship
Date: Sun Feb 11 17:14:49 2007
New Revision: 506201
URL: http://svn.apache.org/viewvc?view=rev&rev=506201
Log:
Move the logic for resolving component meta data up the containment tree to its own service, and introduce a system of defaults in that service's configuration.
Added:
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/MetaDataLocatorImpl.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/MetaDataLocator.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/MetaDataLocatorImplTest.java
Modified:
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PersistentFieldManagerImpl.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ServicesMessages.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/TapestryTestCase.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/PersistentFieldManagerImplTest.java
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/MetaDataLocatorImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/MetaDataLocatorImpl.java?view=auto&rev=506201
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/MetaDataLocatorImpl.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/MetaDataLocatorImpl.java Sun Feb 11 17:14:49 2007
@@ -0,0 +1,143 @@
+// Copyright 2007 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.internal.services;
+
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newCaseInsensitiveMap;
+
+import java.util.Map;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.events.InvalidationListener;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.services.ComponentClassResolver;
+import org.apache.tapestry.services.MetaDataLocator;
+
+public class MetaDataLocatorImpl implements MetaDataLocator, InvalidationListener
+{
+ private final Map<String, Map<String, String>> _defaultsByFolder = newCaseInsensitiveMap();
+
+ private final Map<String, String> _cache = CollectionFactory.newThreadSafeMap();
+
+ private final ComponentClassResolver _componentClassResolver;
+
+ public MetaDataLocatorImpl(ComponentClassResolver componentClassResolver,
+ Map<String, String> configuration)
+ {
+ _componentClassResolver = componentClassResolver;
+
+ loadDefaults(configuration);
+ }
+
+ public void objectWasInvalidated()
+ {
+ _cache.clear();
+ }
+
+ private void loadDefaults(Map<String, String> configuration)
+ {
+ for (Map.Entry<String, String> e : configuration.entrySet())
+ {
+ String key = e.getKey();
+
+ int colonx = key.indexOf(':');
+
+ String folderKey = colonx < 0 ? "" : key.substring(0, colonx);
+
+ Map<String, String> forFolder = _defaultsByFolder.get(folderKey);
+
+ if (forFolder == null)
+ {
+ forFolder = CollectionFactory.newCaseInsensitiveMap();
+ _defaultsByFolder.put(folderKey, forFolder);
+ }
+
+ String defaultKey = colonx < 0 ? key : key.substring(colonx + 1);
+
+ forFolder.put(defaultKey, e.getValue());
+ }
+ }
+
+ public String findMeta(String key, ComponentResources resources)
+ {
+ // The component's complete id should be sufficient as locale-specific
+ // values don't enter into this.
+
+ String cacheKey = resources.getCompleteId() + "/" + key;
+
+ if (_cache.containsKey(cacheKey))
+ return _cache.get(cacheKey);
+
+ String result = locate(key, resources);
+
+ _cache.put(cacheKey, result);
+
+ return result;
+ }
+
+ private String locate(String key, ComponentResources resources)
+ {
+ ComponentResources cursor = resources;
+
+ while (true)
+ {
+ String value = cursor.getComponentModel().getMeta(key);
+
+ if (value != null)
+ return value;
+
+ ComponentResources next = cursor.getContainerResources();
+
+ if (next == null)
+ return locateInDefaults(key, cursor);
+
+ cursor = next;
+ }
+ }
+
+ private String locateInDefaults(String key, ComponentResources pageResources)
+ {
+ String pageClassName = pageResources.getCompleteId();
+
+ String logicalName = _componentClassResolver.resolvePageClassNameToPageName(pageClassName);
+
+ // We're going to peel this apart, slash by slash. Thus for
+ // "mylib/myfolder/mysubfolder/MyPage" we'll be checking: "mylib/myfolder/mysubfolder",
+ // then "mylib/myfolder", then "mylib", then "".
+
+ String path = logicalName;
+
+ while (true)
+ {
+ int lastSlashx = path.lastIndexOf('/');
+
+ String folderKey = lastSlashx < 0 ? "" : path.substring(0, lastSlashx);
+
+ Map<String, String> forFolder = _defaultsByFolder.get(folderKey);
+
+ if (forFolder != null && forFolder.containsKey(key))
+ return forFolder.get(key);
+
+ if (lastSlashx < 0)
+ break;
+
+ path = path.substring(0, lastSlashx);
+ }
+
+ // Perhaps from here into the symbol sources? That may come later.
+
+ return null;
+ }
+
+}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PersistentFieldManagerImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PersistentFieldManagerImpl.java?view=diff&rev=506201&r1=506200&r2=506201
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PersistentFieldManagerImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PersistentFieldManagerImpl.java Sun Feb 11 17:14:49 2007
@@ -1,4 +1,4 @@
-// Copyright 2006 The Apache Software Foundation
+// Copyright 2006, 2007 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.
@@ -14,6 +14,8 @@
package org.apache.tapestry.internal.services;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newCaseInsensitiveMap;
+
import java.util.Collection;
import java.util.Map;
@@ -21,6 +23,7 @@
import org.apache.tapestry.ioc.internal.util.CollectionFactory;
import org.apache.tapestry.ioc.internal.util.InternalUtils;
import org.apache.tapestry.model.ComponentModel;
+import org.apache.tapestry.services.MetaDataLocator;
import org.apache.tapestry.services.PersistentFieldBundle;
import org.apache.tapestry.services.PersistentFieldChange;
import org.apache.tapestry.services.PersistentFieldManager;
@@ -28,15 +31,20 @@
public class PersistentFieldManagerImpl implements PersistentFieldManager
{
- static final String META_KEY = "tapestry.persistence-strategy";
+ public static final String META_KEY = "tapestry.persistence-strategy";
+
+ public static final String DEFAULT_STRATEGY = "session";
- static final String DEFAULT_STRATEGY = "session";
+ private final MetaDataLocator _metaDataLocator;
private final Map<String, PersistentFieldStrategy> _strategies;
- public PersistentFieldManagerImpl(final Map<String, PersistentFieldStrategy> strategies)
+ public PersistentFieldManagerImpl(MetaDataLocator locator,
+ Map<String, PersistentFieldStrategy> strategies)
{
- _strategies = strategies;
+ _metaDataLocator = locator;
+
+ _strategies = newCaseInsensitiveMap(strategies);
}
private PersistentFieldStrategy getStrategy(String strategyName)
@@ -44,13 +52,9 @@
PersistentFieldStrategy result = _strategies.get(strategyName);
if (result == null)
- {
- String catalog = InternalUtils.joinSorted(_strategies.keySet());
-
throw new RuntimeException(ServicesMessages.unknownPersistentFieldStrategy(
strategyName,
- catalog));
- }
+ _strategies.keySet()));
return result;
}
@@ -85,26 +89,6 @@
if (InternalUtils.isNonBlank(strategy))
return strategy;
- // OK, it isn't specified for the field itself, so work up the component hierarchy,
- // checking to see if any component set a default persistent strategy.
-
- ComponentResources search = resources;
- while (search != null)
- {
- model = search.getComponentModel();
-
- strategy = model.getMeta(META_KEY);
-
- if (strategy != null)
- return strategy;
-
- // Work up the containment hierarchy. For a persistent field inside a mixin, the
- // container is the component. From there we work up the normal page containment
- // hierarchy.
-
- search = search.getContainerResources();
- }
-
- return DEFAULT_STRATEGY;
+ return _metaDataLocator.findMeta(META_KEY, resources);
}
}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ServicesMessages.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ServicesMessages.java?view=diff&rev=506201&r1=506200&r2=506201
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ServicesMessages.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ServicesMessages.java Sun Feb 11 17:14:49 2007
@@ -1,4 +1,4 @@
-// Copyright 2006 The Apache Software Foundation
+// Copyright 2006, 2007 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.
@@ -210,9 +210,11 @@
return MESSAGES.format("component-event-is-aborted", methodDescription);
}
- static String unknownPersistentFieldStrategy(String stategyName, String catalog)
+ static String unknownPersistentFieldStrategy(String stategyName,
+ Collection<String> strategyNames)
{
- return MESSAGES.format("unknown-persistent-field-strategy", stategyName, catalog);
+ return MESSAGES.format("unknown-persistent-field-strategy", stategyName, InternalUtils
+ .joinSorted(strategyNames));
}
static String couldNotResolvePageName(String pageName)
@@ -377,7 +379,7 @@
propertyName,
propertyExpression);
}
-
+
static String writeOnlyProperty(String propertyName, Class clazz, String propertyExpression)
{
return MESSAGES.format(
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/MetaDataLocator.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/MetaDataLocator.java?view=auto&rev=506201
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/MetaDataLocator.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/MetaDataLocator.java Sun Feb 11 17:14:49 2007
@@ -0,0 +1,41 @@
+// Copyright 2007 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.tapestry.ComponentResources;
+import org.apache.tapestry.model.ComponentModel;
+
+/**
+ * Used to lookup meta data concerning a particular component. The primary source of meta data is
+ * the meta data defined for the component, accessed via {@link ComponentModel#getMeta(String)}.
+ * This includes meta data defined by base classes. When meta-data for a particular component can
+ * not be found, a search works up the containment hierarchy (to the component's container, and the
+ * container's containter, and so on). If <em>that</em> proves unfruitful, a system of defaults is
+ * provided by configuration and matched against the containing page's logical name.
+ */
+public interface MetaDataLocator
+{
+ /**
+ * Searches for the value for the corresponding key.
+ *
+ * @param key
+ * the key used to locate the meta data (case insensitive)
+ * @param resources
+ * the resources of the initial component used in the search
+ * @return the value if found (in the component, the component's container, etc. or via a folder
+ * default) or null if not found anywhere
+ */
+ String findMeta(String key, ComponentResources resources);
+}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java?view=diff&rev=506201&r1=506200&r2=506201
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java Sun Feb 11 17:14:49 2007
@@ -109,6 +109,7 @@
import org.apache.tapestry.internal.services.LinkActionResponseGenerator;
import org.apache.tapestry.internal.services.LinkFactory;
import org.apache.tapestry.internal.services.MarkupWriterImpl;
+import org.apache.tapestry.internal.services.MetaDataLocatorImpl;
import org.apache.tapestry.internal.services.MetaWorker;
import org.apache.tapestry.internal.services.MixinAfterWorker;
import org.apache.tapestry.internal.services.MixinWorker;
@@ -209,6 +210,10 @@
private final StrategyBuilder _strategyBuilder;
+ // Primarily used as a InvalidationEventHub for service implementations
+ // that should clear their cache when the underlying component class loader
+ // is discarded.
+
private final ComponentInstantiatorSource _componentInstantiatorSource;
private final LinkFactory _linkFactory;
@@ -557,6 +562,7 @@
FieldValidatorSource.class,
GridDataModelSource.class,
MarkupWriterFactory.class,
+ MetaDataLocator.class,
PersistentFieldManager.class,
PropertyConduitSource.class,
Request.class,
@@ -972,9 +978,12 @@
/** A public service since extensions may provide new persistent strategies. */
public static PersistentFieldManager buildPersistentFieldManager(
+ @Inject("infrastructure:MetaDataLocator")
+ MetaDataLocator locator,
+
Map<String, PersistentFieldStrategy> configuration)
{
- return new PersistentFieldManagerImpl(configuration);
+ return new PersistentFieldManagerImpl(locator, configuration);
}
/**
@@ -1393,5 +1402,24 @@
{
return new GridDataModelSourceImpl(_propertyAccess, _componentClassFactory,
_propertyConduitSource);
+ }
+
+ public MetaDataLocator buildMetaDataLocator(@Inject("infrastructure:ComponentClassResolver")
+ ComponentClassResolver componentClassResolver,
+
+ Map<String, String> configuration)
+ {
+ MetaDataLocatorImpl service = new MetaDataLocatorImpl(componentClassResolver, configuration);
+
+ _componentInstantiatorSource.addInvalidationListener(service);
+
+ return service;
+ }
+
+ public void contributeMetaDataLocator(MappedConfiguration<String, String> configuration)
+ {
+ configuration.add(
+ PersistentFieldManagerImpl.META_KEY,
+ PersistentFieldManagerImpl.DEFAULT_STRATEGY);
}
}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/TapestryTestCase.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/TapestryTestCase.java?view=diff&rev=506201&r1=506200&r2=506201
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/TapestryTestCase.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/TapestryTestCase.java Sun Feb 11 17:14:49 2007
@@ -822,4 +822,9 @@
{
return newMock(ValidationConstraintGenerator.class);
}
+
+ protected final void train_getMeta(ComponentModel model, String key, String value)
+ {
+ expect(model.getMeta(key)).andReturn(value).atLeastOnce();
+ }
}
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/MetaDataLocatorImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/MetaDataLocatorImplTest.java?view=auto&rev=506201
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/MetaDataLocatorImplTest.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/MetaDataLocatorImplTest.java Sun Feb 11 17:14:49 2007
@@ -0,0 +1,255 @@
+// Copyright 2007 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.internal.services;
+
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newMap;
+
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.model.ComponentModel;
+import org.apache.tapestry.services.ComponentClassResolver;
+import org.apache.tapestry.services.MetaDataLocator;
+import org.testng.annotations.Test;
+
+public class MetaDataLocatorImplTest extends InternalBaseTestCase
+{
+ @Test
+ public void found_in_component()
+ {
+ ComponentResources resources = newComponentResources();
+ ComponentModel model = newComponentModel();
+ ComponentClassResolver resolver = newComponentClassResolver();
+
+ String key = "foo.bar";
+ String value = "zaphod";
+ String completeId = "foo.Bar:baz";
+
+ train_getCompleteId(resources, completeId);
+ train_getComponentModel(resources, model);
+ train_getMeta(model, key, value);
+
+ replay();
+
+ Map<String, String> configuration = Collections.emptyMap();
+
+ MetaDataLocator locator = new MetaDataLocatorImpl(resolver, configuration);
+
+ assertSame(locator.findMeta(key, resources), value);
+
+ verify();
+
+ // And check that it's cached:
+
+ train_getCompleteId(resources, completeId);
+
+ replay();
+
+ assertSame(locator.findMeta(key, resources), value);
+
+ verify();
+ }
+
+ @Test
+ public void found_in_container()
+ {
+ ComponentResources resources = newComponentResources();
+ ComponentResources containerResources = newComponentResources();
+ ComponentModel model = newComponentModel();
+ ComponentModel containerModel = newComponentModel();
+ ComponentClassResolver resolver = newComponentClassResolver();
+
+ String key = "foo.bar";
+ String value = "zaphod";
+ String completeId = "foo.Bar:baz";
+
+ train_getCompleteId(resources, completeId);
+ train_getComponentModel(resources, model);
+ train_getMeta(model, key, null);
+ train_getContainerResources(resources, containerResources);
+ train_getComponentModel(containerResources, containerModel);
+ train_getMeta(containerModel, key, value);
+
+ replay();
+
+ Map<String, String> configuration = Collections.emptyMap();
+
+ MetaDataLocator locator = new MetaDataLocatorImpl(resolver, configuration);
+
+ assertSame(locator.findMeta(key, resources), value);
+
+ verify();
+ }
+
+ @Test
+ public void found_via_high_level_default()
+ {
+ ComponentResources resources = newComponentResources();
+ ComponentModel model = newComponentModel();
+ ComponentClassResolver resolver = newComponentClassResolver();
+
+ String key = "foo.bar";
+ String value = "zaphod";
+ String completeId = "foo.Bar";
+
+ train_getCompleteId(resources, completeId);
+ train_getComponentModel(resources, model);
+ train_getMeta(model, key, null);
+ train_getContainerResources(resources, null);
+ train_resolvePageClassNameToPageName(resolver, completeId, "foo/Bar");
+
+ replay();
+
+ Map<String, String> configuration = newMap();
+ configuration.put(key, value);
+
+ MetaDataLocator locator = new MetaDataLocatorImpl(resolver, configuration);
+
+ assertSame(locator.findMeta(key, resources), value);
+
+ verify();
+
+ // And check that it's cached:
+
+ train_getCompleteId(resources, completeId);
+
+ replay();
+
+ assertSame(locator.findMeta(key, resources), value);
+
+ verify();
+ }
+
+ @Test
+ public void default_matching_is_case_insensitive()
+ {
+ ComponentResources resources = newComponentResources();
+ ComponentModel model = newComponentModel();
+ ComponentClassResolver resolver = newComponentClassResolver();
+
+ String key = "foo.bar";
+ String value = "zaphod";
+ String completeId = "foo.Bar";
+
+ train_getCompleteId(resources, completeId);
+ train_getComponentModel(resources, model);
+ train_getMeta(model, key, null);
+ train_getContainerResources(resources, null);
+ train_resolvePageClassNameToPageName(resolver, completeId, "foo/Bar");
+
+ replay();
+
+ Map<String, String> configuration = newMap();
+ configuration.put(key.toUpperCase(), value);
+
+ MetaDataLocator locator = new MetaDataLocatorImpl(resolver, configuration);
+
+ assertSame(locator.findMeta(key, resources), value);
+
+ verify();
+
+ // And check that it's cached:
+
+ train_getCompleteId(resources, completeId);
+
+ replay();
+
+ assertSame(locator.findMeta(key, resources), value);
+
+ verify();
+ }
+
+ @Test
+ public void subfolder_default_overrides_high_level_default()
+ {
+ ComponentResources resources = newComponentResources();
+ ComponentModel model = newComponentModel();
+ ComponentClassResolver resolver = newComponentClassResolver();
+
+ String key = "foo.bar";
+ String value = "zaphod";
+ String completeId = "foo.Bar";
+
+ train_getCompleteId(resources, completeId);
+ train_getComponentModel(resources, model);
+ train_getMeta(model, key, null);
+ train_getContainerResources(resources, null);
+ train_resolvePageClassNameToPageName(resolver, completeId, "foo/Bar");
+
+ replay();
+
+ Map<String, String> configuration = newMap();
+ configuration.put(key, "xxx");
+ configuration.put("foo:" + key, value);
+
+ MetaDataLocator locator = new MetaDataLocatorImpl(resolver, configuration);
+
+ assertSame(locator.findMeta(key, resources), value);
+
+ verify();
+
+ // And check that it's cached:
+
+ train_getCompleteId(resources, completeId);
+
+ replay();
+
+ assertSame(locator.findMeta(key, resources), value);
+
+ verify();
+ }
+
+ @Test
+ public void test_cache_cleared()
+ {
+ ComponentResources resources = newComponentResources();
+ ComponentModel model = newComponentModel();
+ ComponentClassResolver resolver = newComponentClassResolver();
+
+ String key = "foo.bar";
+ String value = "zaphod";
+ String completeId = "foo.Bar:baz";
+
+ train_getCompleteId(resources, completeId);
+ train_getComponentModel(resources, model);
+ train_getMeta(model, key, value);
+
+ replay();
+
+ Map<String, String> configuration = Collections.emptyMap();
+
+ MetaDataLocatorImpl locator = new MetaDataLocatorImpl(resolver, configuration);
+
+ assertSame(locator.findMeta(key, resources), value);
+
+ verify();
+
+ // And check that it's cached:
+
+ train_getCompleteId(resources, completeId);
+ train_getComponentModel(resources, model);
+ train_getMeta(model, key, value);
+
+ replay();
+
+ locator.objectWasInvalidated();
+
+ assertSame(locator.findMeta(key, resources), value);
+
+ verify();
+ }
+}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/PersistentFieldManagerImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/PersistentFieldManagerImplTest.java?view=diff&rev=506201&r1=506200&r2=506201
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/PersistentFieldManagerImplTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/PersistentFieldManagerImplTest.java Sun Feb 11 17:14:49 2007
@@ -1,4 +1,4 @@
-// Copyright 2006 The Apache Software Foundation
+// Copyright 2006, 2007 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.
@@ -23,6 +23,7 @@
import org.apache.tapestry.ComponentResources;
import org.apache.tapestry.internal.test.InternalBaseTestCase;
import org.apache.tapestry.model.ComponentModel;
+import org.apache.tapestry.services.MetaDataLocator;
import org.apache.tapestry.services.PersistentFieldBundle;
import org.apache.tapestry.services.PersistentFieldChange;
import org.apache.tapestry.services.PersistentFieldManager;
@@ -51,7 +52,7 @@
replay();
- PersistentFieldManager manager = new PersistentFieldManagerImpl(strategies);
+ PersistentFieldManager manager = new PersistentFieldManagerImpl(null, strategies);
try
{
@@ -94,20 +95,19 @@
replay();
- PersistentFieldManager manager = new PersistentFieldManagerImpl(strategies);
+ PersistentFieldManager manager = new PersistentFieldManagerImpl(null, strategies);
manager.postChange(pageName, resources, fieldName, value);
verify();
}
-
- @Test
- public void post_change_strategy_by_meta_data()
+
+ public void strategy_name_is_case_insensitive()
{
String pageName = "foo.Bar";
String nestedId = "nested";
String fieldName = "field";
- String strategyName = "foo";
+ String strategyName = "FOO";
ComponentResources resources = newComponentResources();
ComponentModel model = newComponentModel();
@@ -115,13 +115,11 @@
Object value = new Object();
Map<String, PersistentFieldStrategy> strategies = newMap();
- strategies.put(strategyName, strat);
+ strategies.put("foo", strat);
train_getComponentModel(resources, model);
- train_getFieldPersistenceStrategy(model, fieldName, "");
-
- train_getMeta(model, PersistentFieldManagerImpl.META_KEY, strategyName);
+ train_getFieldPersistenceStrategy(model, fieldName, strategyName);
train_getNestedId(resources, nestedId);
@@ -129,15 +127,15 @@
replay();
- PersistentFieldManager manager = new PersistentFieldManagerImpl(strategies);
+ PersistentFieldManager manager = new PersistentFieldManagerImpl(null, strategies);
manager.postChange(pageName, resources, fieldName, value);
- verify();
+ verify();
}
@Test
- public void post_change_strategy_by_container_meta_data()
+ public void post_change_strategy_by_meta_data()
{
String pageName = "foo.Bar";
String nestedId = "nested";
@@ -146,9 +144,9 @@
ComponentResources resources = newComponentResources();
ComponentModel model = newComponentModel();
- ComponentResources containerResources = newComponentResources();
- ComponentModel containerModel = newComponentModel();
PersistentFieldStrategy strat = newPersistentFieldStrategy();
+ MetaDataLocator locator = newMetaDataLocator();
+
Object value = new Object();
Map<String, PersistentFieldStrategy> strategies = newMap();
@@ -158,12 +156,7 @@
train_getFieldPersistenceStrategy(model, fieldName, "");
- train_getMeta(model, PersistentFieldManagerImpl.META_KEY, null);
-
- train_getContainerResources(resources, containerResources);
- train_getComponentModel(containerResources, containerModel);
-
- train_getMeta(containerModel, PersistentFieldManagerImpl.META_KEY, strategyName);
+ train_findMeta(locator, PersistentFieldManagerImpl.META_KEY, resources, strategyName);
train_getNestedId(resources, nestedId);
@@ -171,7 +164,7 @@
replay();
- PersistentFieldManager manager = new PersistentFieldManagerImpl(strategies);
+ PersistentFieldManager manager = new PersistentFieldManagerImpl(locator, strategies);
manager.postChange(pageName, resources, fieldName, value);
@@ -187,6 +180,8 @@
ComponentResources resources = newComponentResources();
ComponentModel model = newComponentModel();
+ MetaDataLocator locator = newMetaDataLocator();
+
PersistentFieldStrategy strat = newPersistentFieldStrategy();
Object value = new Object();
@@ -197,9 +192,11 @@
train_getFieldPersistenceStrategy(model, fieldName, "");
- train_getMeta(model, PersistentFieldManagerImpl.META_KEY, null);
-
- train_getContainerResources(resources, null);
+ train_findMeta(
+ locator,
+ PersistentFieldManagerImpl.META_KEY,
+ resources,
+ PersistentFieldManagerImpl.DEFAULT_STRATEGY);
train_getNestedId(resources, nestedId);
@@ -207,16 +204,22 @@
replay();
- PersistentFieldManager manager = new PersistentFieldManagerImpl(strategies);
+ PersistentFieldManager manager = new PersistentFieldManagerImpl(locator, strategies);
manager.postChange(pageName, resources, fieldName, value);
verify();
}
- protected final void train_getMeta(ComponentModel model, String key, String value)
+ protected void train_findMeta(MetaDataLocator locator, String key,
+ ComponentResources resources, String value)
+ {
+ expect(locator.findMeta(key, resources)).andReturn(value).atLeastOnce();
+ }
+
+ protected MetaDataLocator newMetaDataLocator()
{
- expect(model.getMeta(key)).andReturn(value).atLeastOnce();
+ return newMock(MetaDataLocator.class);
}
private PersistentFieldStrategy newPersistentFieldStrategy()
@@ -256,7 +259,7 @@
strategies.put("alpha", strat1);
strategies.put("beta", strat2);
- PersistentFieldManager manager = new PersistentFieldManagerImpl(strategies);
+ PersistentFieldManager manager = new PersistentFieldManagerImpl(null, strategies);
PersistentFieldBundle bundle = manager.gatherChanges("foo.Bar");