You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tiles.apache.org by ap...@apache.org on 2008/06/05 20:53:08 UTC
svn commit: r663697 - in /tiles/framework/trunk/tiles-core/src:
main/java/org/apache/tiles/definition/ test/java/org/apache/tiles/definition/
Author: apetrelli
Date: Thu Jun 5 11:53:08 2008
New Revision: 663697
URL: http://svn.apache.org/viewvc?rev=663697&view=rev
Log:
TILES-89
Moved DefinitionsImpl code to UrlDefinitionsFactory.
Removed:
tiles/framework/trunk/tiles-core/src/test/java/org/apache/tiles/definition/MockDefinitions.java
tiles/framework/trunk/tiles-core/src/test/java/org/apache/tiles/definition/MockPublicUrlDefinitionsFactory.java
tiles/framework/trunk/tiles-core/src/test/java/org/apache/tiles/definition/TestDefinitions.java
Modified:
tiles/framework/trunk/tiles-core/src/main/java/org/apache/tiles/definition/Definitions.java
tiles/framework/trunk/tiles-core/src/main/java/org/apache/tiles/definition/DefinitionsImpl.java
tiles/framework/trunk/tiles-core/src/main/java/org/apache/tiles/definition/UrlDefinitionsFactory.java
tiles/framework/trunk/tiles-core/src/test/java/org/apache/tiles/definition/TestUrlDefinitionsFactory.java
Modified: tiles/framework/trunk/tiles-core/src/main/java/org/apache/tiles/definition/Definitions.java
URL: http://svn.apache.org/viewvc/tiles/framework/trunk/tiles-core/src/main/java/org/apache/tiles/definition/Definitions.java?rev=663697&r1=663696&r2=663697&view=diff
==============================================================================
--- tiles/framework/trunk/tiles-core/src/main/java/org/apache/tiles/definition/Definitions.java (original)
+++ tiles/framework/trunk/tiles-core/src/main/java/org/apache/tiles/definition/Definitions.java Thu Jun 5 11:53:08 2008
@@ -27,15 +27,19 @@
import org.apache.tiles.Definition;
/**
- * Interface for managing collections of {@link Definition} objects.
- * <p/>
- * <p>The Definitions interface provides a pattern for managing
- * Definition objects. Implementations will provide a means to append
- * new Definitions to the collection, add and retrieve lcale-specific
- * Definitions objects, and reset the collections.</p>
+ * Interface for managing collections of {@link Definition} objects. <p/>
+ * <p>
+ * The Definitions interface provides a pattern for managing Definition objects.
+ * Implementations will provide a means to append new Definitions to the
+ * collection, add and retrieve lcale-specific Definitions objects, and reset
+ * the collections.
+ * </p>
*
* @version $Rev$ $Date$
+ * @deprecated This interface is never used, except in the deprecated class
+ * {@link DefinitionsImpl}.
*/
+@Deprecated
public interface Definitions {
/**
Modified: tiles/framework/trunk/tiles-core/src/main/java/org/apache/tiles/definition/DefinitionsImpl.java
URL: http://svn.apache.org/viewvc/tiles/framework/trunk/tiles-core/src/main/java/org/apache/tiles/definition/DefinitionsImpl.java?rev=663697&r1=663696&r2=663697&view=diff
==============================================================================
--- tiles/framework/trunk/tiles-core/src/main/java/org/apache/tiles/definition/DefinitionsImpl.java (original)
+++ tiles/framework/trunk/tiles-core/src/main/java/org/apache/tiles/definition/DefinitionsImpl.java Thu Jun 5 11:53:08 2008
@@ -34,7 +34,11 @@
/**
* @version $Rev$ $Date$
+ *
+ * @deprecated This class is, in fact, part of the implementation of
+ * {@link UrlDefinitionsFactory}.
*/
+@Deprecated
public class DefinitionsImpl implements Definitions {
/**
@@ -61,6 +65,18 @@
}
/**
+ * Creates a new instance of DefinitionsImpl to be used as a wrapper.
+ *
+ * @param baseDefinitions The base definitions to use.
+ * @param localeSpecificDefinitions Maps a locale to a map of definitions.
+ */
+ public DefinitionsImpl(Map<String, Definition> baseDefinitions,
+ Map<Locale, Map<String, Definition>> localeSpecificDefinitions) {
+ this.baseDefinitions = baseDefinitions;
+ this.localeSpecificDefinitions = localeSpecificDefinitions;
+ }
+
+ /**
* Returns a Definition object that matches the given name.
*
* @param name The name of the Definition to return.
Modified: tiles/framework/trunk/tiles-core/src/main/java/org/apache/tiles/definition/UrlDefinitionsFactory.java
URL: http://svn.apache.org/viewvc/tiles/framework/trunk/tiles-core/src/main/java/org/apache/tiles/definition/UrlDefinitionsFactory.java?rev=663697&r1=663696&r2=663697&view=diff
==============================================================================
--- tiles/framework/trunk/tiles-core/src/main/java/org/apache/tiles/definition/UrlDefinitionsFactory.java (original)
+++ tiles/framework/trunk/tiles-core/src/main/java/org/apache/tiles/definition/UrlDefinitionsFactory.java Thu Jun 5 11:53:08 2008
@@ -38,6 +38,7 @@
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@@ -107,9 +108,14 @@
/**
- * The definitions holder object.
+ * The base set of Definition objects not discriminated by locale.
*/
- private Definitions definitions;
+ private Map<String, Definition> baseDefinitions;
+
+ /**
+ * The locale-specific set of definitions objects.
+ */
+ private Map<Locale, Map<String, Definition>> localeSpecificDefinitions;
/**
* The locale resolver object.
@@ -195,9 +201,11 @@
* Returns the definitions holder object.
*
* @return The definitions holder.
+ * @deprecated Do not use! Deprecated with no replacement.
*/
+ @Deprecated
protected Definitions getDefinitions() {
- return definitions;
+ return new DefinitionsImpl(baseDefinitions, localeSpecificDefinitions);
}
@@ -214,19 +222,16 @@
public Definition getDefinition(String name,
TilesRequestContext tilesContext) {
- Definitions definitions = getDefinitions();
Locale locale = null;
if (tilesContext != null) {
locale = localeResolver.resolveLocale(tilesContext);
if (!isContextProcessed(tilesContext)) {
- synchronized (definitions) {
- addDefinitions(definitions, tilesContext);
- }
+ addDefinitions(tilesContext);
}
}
- return definitions.getDefinition(name, locale);
+ return getDefinition(name, locale);
}
/**
@@ -267,9 +272,24 @@
* @param definitions The Definitions object to append to.
* @param tilesContext The requested locale.
* @throws DefinitionsFactoryException if an error occurs reading definitions.
+ * @deprecated Use {@link #addDefinitions(TilesRequestContext)}.
*/
protected void addDefinitions(Definitions definitions,
TilesRequestContext tilesContext) {
+ addDefinitions(tilesContext);
+ }
+
+ /**
+ * Appends locale-specific {@link Definition} objects to existing
+ * definitions set by reading locale-specific versions of the applied
+ * sources.
+ *
+ * @param tilesContext The requested locale.
+ * @throws DefinitionsFactoryException if an error occurs reading
+ * definitions.
+ * @since 2.1.0
+ */
+ protected synchronized void addDefinitions(TilesRequestContext tilesContext) {
Locale locale = localeResolver.resolveLocale(tilesContext);
@@ -318,8 +338,8 @@
// At the end of definitions loading, they can be assigned to
// Definitions implementation, to allow inheritance resolution.
- definitions.addDefinitions(localeDefsMap, localeResolver
- .resolveLocale(tilesContext));
+ localeSpecificDefinitions.put(locale, localeDefsMap);
+ resolveInheritances(locale);
}
/**
@@ -334,7 +354,7 @@
@Deprecated
public Definitions readDefinitions() {
loadDefinitions();
- return definitions;
+ return new DefinitionsImpl(baseDefinitions, localeSpecificDefinitions);
}
/**
@@ -358,7 +378,9 @@
* to provide your custom instance of Definitions.
*
* @return A new instance of <code>Definitions</code>.
+ * @deprecated Do not use! Deprecated with no replacement.
*/
+ @Deprecated
protected Definitions createDefinitions() {
return new DefinitionsImpl();
}
@@ -391,19 +413,15 @@
}
/**
- * Creates a {@link Definitions} set by reading
- * configuration data from the applied sources.
+ * Creates a base set by reading configuration data from the applied
+ * sources.
*
* @throws DefinitionsFactoryException if an error occurs reading the
* sources.
* @since 2.1.0
*/
protected synchronized void loadDefinitions() {
- if (definitions == null) {
- definitions = createDefinitions();
- } else {
- definitions.reset();
- }
+ reset();
try {
for (URL source : sourceURLs) {
@@ -413,7 +431,8 @@
connection.getLastModified());
Map<String, Definition> defsMap = reader
.read(connection.getInputStream());
- definitions.addDefinitions(defsMap);
+ baseDefinitions.putAll(defsMap);
+ resolveInheritances();
}
} catch (IOException e) {
throw new DefinitionsFactoryException("I/O error accessing source.", e);
@@ -586,4 +605,124 @@
}
return filenames;
}
+
+ /**
+ * Clears definitions.
+ *
+ * @since 2.1.0
+ */
+ protected void reset() {
+ this.baseDefinitions = new HashMap<String, Definition>();
+ this.localeSpecificDefinitions =
+ new HashMap<Locale, Map<String, Definition>>();
+ }
+
+ /**
+ * Resolve extended instances.
+ *
+ * @throws NoSuchDefinitionException If a parent definition is not found.
+ * @since 2.1.0
+ */
+ protected void resolveInheritances() {
+ Set<String> alreadyResolvedDefinitions = new HashSet<String>();
+
+ for (Definition definition : baseDefinitions.values()) {
+ resolveInheritance(definition, null, alreadyResolvedDefinitions);
+ } // end loop
+ }
+
+ /**
+ * Resolve locale-specific extended instances.
+ *
+ * @param locale The locale to use.
+ * @throws NoSuchDefinitionException If a parent definition is not found.
+ * @since 2.1.0
+ */
+ protected void resolveInheritances(Locale locale) {
+ resolveInheritances();
+
+ Map<String, Definition> map = localeSpecificDefinitions.get(locale);
+ if (map != null) {
+ Set<String> alreadyResolvedDefinitions = new HashSet<String>();
+ for (Definition definition : map.values()) {
+ resolveInheritance(definition, locale,
+ alreadyResolvedDefinitions);
+ } // end loop
+ }
+ }
+
+ /**
+ * Resolve locale-specific inheritance.
+ * First, resolve parent's inheritance, then set template to the parent's
+ * template.
+ * Also copy attributes setted in parent, and not set in child
+ * If instance doesn't extend anything, do nothing.
+ *
+ * @param definition The definition to resolve
+ * @param locale The locale to use.
+ * @param alreadyResolvedDefinitions The set of the definitions that have
+ * been already resolved.
+ * @throws NoSuchDefinitionException If an inheritance can not be solved.
+ * @since 2.1.0
+ */
+ protected void resolveInheritance(Definition definition, Locale locale,
+ Set<String> alreadyResolvedDefinitions) {
+ // Already done, or not needed ?
+ if (!definition.isExtending()
+ || alreadyResolvedDefinitions.contains(definition.getName())) {
+ return;
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Resolve definition for child name='"
+ + definition.getName()
+ + "' extends='" + definition.getExtends() + "'.");
+ }
+
+ // Set as visited to avoid endless recurisvity.
+ alreadyResolvedDefinitions.add(definition.getName());
+
+ // Resolve parent before itself.
+ Definition parent = getDefinition(definition.getExtends(),
+ locale);
+ if (parent == null) { // error
+ String msg = "Error while resolving definition inheritance: child '"
+ + definition.getName()
+ + "' can't find its ancestor '"
+ + definition.getExtends()
+ + "'. Please check your description file.";
+ // to do : find better exception
+ throw new NoSuchDefinitionException(msg);
+ }
+
+ resolveInheritance(parent, locale, alreadyResolvedDefinitions);
+
+ definition.inherit(parent);
+ }
+
+ /**
+ * Returns a Definition object that matches the given name and locale.
+ *
+ * @param name The name of the Definition to return.
+ * @param locale The locale to use to resolve the definition.
+ * @return the Definition matching the given name or null if none is found.
+ * @since 2.1.0
+ */
+ protected Definition getDefinition(String name, Locale locale) {
+ Definition definition = null;
+
+ if (locale != null) {
+ Map<String, Definition> localeSpecificMap =
+ localeSpecificDefinitions.get(locale);
+ if (localeSpecificMap != null) {
+ definition = localeSpecificMap.get(name);
+ }
+ }
+
+ if (definition == null) {
+ definition = baseDefinitions.get(name);
+ }
+
+ return definition;
+ }
}
Modified: tiles/framework/trunk/tiles-core/src/test/java/org/apache/tiles/definition/TestUrlDefinitionsFactory.java
URL: http://svn.apache.org/viewvc/tiles/framework/trunk/tiles-core/src/test/java/org/apache/tiles/definition/TestUrlDefinitionsFactory.java?rev=663697&r1=663696&r2=663697&view=diff
==============================================================================
--- tiles/framework/trunk/tiles-core/src/test/java/org/apache/tiles/definition/TestUrlDefinitionsFactory.java (original)
+++ tiles/framework/trunk/tiles-core/src/test/java/org/apache/tiles/definition/TestUrlDefinitionsFactory.java Thu Jun 5 11:53:08 2008
@@ -50,13 +50,13 @@
/**
* The definitions factory.
*/
- private MockPublicUrlDefinitionsFactory factory;
+ private UrlDefinitionsFactory factory;
/** {@inheritDoc} */
@Override
protected void setUp() throws Exception {
super.setUp();
- factory = new MockPublicUrlDefinitionsFactory();
+ factory = new UrlDefinitionsFactory();
}
/**
@@ -124,12 +124,12 @@
+ "org/apache/tiles/config/defs3.xml");
factory.init(params);
- // Parse files.
- Definitions definitions = factory.getDefinitions();
-
- assertNotNull("test.def1 definition not found.", definitions.getDefinition("test.def1"));
- assertNotNull("test.def2 definition not found.", definitions.getDefinition("test.def2"));
- assertNotNull("test.def3 definition not found.", definitions.getDefinition("test.def3"));
+ assertNotNull("test.def1 definition not found.", factory.getDefinition(
+ "test.def1", (TilesRequestContext) null));
+ assertNotNull("test.def2 definition not found.", factory.getDefinition(
+ "test.def2", (TilesRequestContext) null));
+ assertNotNull("test.def3 definition not found.", factory.getDefinition(
+ "test.def3", (TilesRequestContext) null));
}
/**
@@ -269,27 +269,28 @@
factory.init(params);
// Parse files.
- Definitions definitions = factory.getDefinitions();
- factory.addDefinitions(definitions,
- new MockOnlyLocaleTilesContext(Locale.US));
- factory.addDefinitions(definitions,
- new MockOnlyLocaleTilesContext(Locale.FRENCH));
-
- assertNotNull("test.def1 definition not found.", definitions.getDefinition("test.def1"));
- assertNotNull("test.def1 US definition not found.", definitions.getDefinition("test.def1", Locale.US));
- assertNotNull("test.def1 France definition not found.", definitions.getDefinition("test.def1", Locale.FRENCH));
- assertNotNull("test.def1 China should return default.", definitions.getDefinition("test.def1", Locale.CHINA));
-
- assertEquals("Incorrect default country value", "default", definitions
- .getDefinition("test.def1").getAttribute("country").getValue());
- assertEquals("Incorrect US country value", "US", definitions
- .getDefinition("test.def1", Locale.US).getAttribute("country")
- .getValue());
- assertEquals("Incorrect France country value", "France", definitions
+ factory.addDefinitions(new MockOnlyLocaleTilesContext(Locale.US));
+ factory.addDefinitions(new MockOnlyLocaleTilesContext(Locale.FRENCH));
+
+ assertNotNull("test.def1 definition not found.", factory.getDefinition(
+ "test.def1", (Locale) null));
+ assertNotNull("test.def1 US definition not found.", factory
+ .getDefinition("test.def1", Locale.US));
+ assertNotNull("test.def1 France definition not found.", factory
+ .getDefinition("test.def1", Locale.FRENCH));
+ assertNotNull("test.def1 China should return default.", factory
+ .getDefinition("test.def1", Locale.CHINA));
+
+ assertEquals("Incorrect default country value", "default", factory
+ .getDefinition("test.def1", (Locale) null).getAttribute(
+ "country").getValue());
+ assertEquals("Incorrect US country value", "US", factory.getDefinition(
+ "test.def1", Locale.US).getAttribute("country").getValue());
+ assertEquals("Incorrect France country value", "France", factory
.getDefinition("test.def1", Locale.FRENCH).getAttribute(
"country").getValue());
assertEquals("Incorrect Chinese country value (should default)",
- "default", definitions.getDefinition("test.def1", Locale.CHINA)
+ "default", factory.getDefinition("test.def1", Locale.CHINA)
.getAttribute("country").getValue());
}
@@ -320,13 +321,12 @@
factory.init(params);
// Parse files.
- Definitions definitions = factory.getDefinitions();
TilesRequestContext tilesContext =
new MockOnlyLocaleTilesContext(Locale.US);
assertFalse("Locale should not be processed.",
factory.isContextProcessed(tilesContext));
- factory.addDefinitions(definitions, tilesContext);
+ factory.addDefinitions(tilesContext);
assertTrue("Locale should be processed.",
factory.isContextProcessed(tilesContext));
}