You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by dg...@apache.org on 2005/06/14 23:59:17 UTC
svn commit: r190662 [5/6] - in /struts/sandbox/trunk/tiles: ./ core-library/
core-library/src/ core-library/src/conf/ core-library/src/java/
core-library/src/java/org/ core-library/src/java/org/apache/
core-library/src/java/org/apache/taglib/
core-library/src/java/org/apache/taglib/tiles/
core-library/src/java/org/apache/taglib/tiles/doc-files/
core-library/src/java/org/apache/taglib/tiles/util/
core-library/src/java/org/apache/tiles/
core-library/src/java/org/apache/tiles/beans/
core-library/src/java/org/apache/tiles/definition/
core-library/src/java/org/apache/tiles/doc-files/
core-library/src/java/org/apache/tiles/servlets/
core-library/src/java/org/apache/tiles/xmlDefinition/
core-library/src/java/org/apache/util/ core-library/src/test/ examples/
examples/simple/ examples/simple/WEB-INF/ examples/simple/WEB-INF/lib/
examples/simple/graphics/ examples/simple/graphics/flags/
Added: struts/sandbox/trunk/tiles/core-library/src/java/org/apache/tiles/xmlDefinition/I18nFactorySet.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/tiles/core-library/src/java/org/apache/tiles/xmlDefinition/I18nFactorySet.java?rev=190662&view=auto
==============================================================================
--- struts/sandbox/trunk/tiles/core-library/src/java/org/apache/tiles/xmlDefinition/I18nFactorySet.java (added)
+++ struts/sandbox/trunk/tiles/core-library/src/java/org/apache/tiles/xmlDefinition/I18nFactorySet.java Tue Jun 14 14:59:13 2005
@@ -0,0 +1,587 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tiles.xmlDefinition;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletRequest;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.tiles.DefinitionsFactoryException;
+import org.apache.tiles.DefinitionsUtil;
+import org.apache.tiles.FactoryNotFoundException;
+import org.apache.taglib.tiles.ComponentConstants;
+import org.xml.sax.SAXException;
+
+/**
+ * Definitions factory.
+ * This implementation allows to have a set of definition factories.
+ * There is a main factory and one factory for each file associated to a Locale.
+ *
+ * To retrieve a definition, we first search for the appropriate factory using
+ * the Locale found in session context. If no factory is found, use the
+ * default one. Then we ask the factory for the definition.
+ *
+ * A definition factory file is loaded using main filename extended with locale code
+ * (ex : <code>templateDefinitions_fr.xml</code>). If no file is found under this name, use default file.
+ */
+public class I18nFactorySet extends FactorySet {
+
+ /**
+ * Commons Logging instance.
+ */
+ protected static Log log = LogFactory.getLog(I18nFactorySet.class);
+
+ /**
+ * Config file parameter name.
+ */
+ public static final String DEFINITIONS_CONFIG_PARAMETER_NAME =
+ "definitions-config";
+
+ /**
+ * Config file parameter name.
+ */
+ public static final String PARSER_DETAILS_PARAMETER_NAME =
+ "definitions-parser-details";
+
+ /**
+ * Config file parameter name.
+ */
+ public static final String PARSER_VALIDATE_PARAMETER_NAME =
+ "definitions-parser-validate";
+
+ /**
+ * Possible definition filenames.
+ */
+ public static final String DEFAULT_DEFINITION_FILENAMES[] =
+ {
+ "/WEB-INF/tileDefinitions.xml",
+ "/WEB-INF/componentDefinitions.xml",
+ "/WEB-INF/instanceDefinitions.xml" };
+
+ /**
+ * Maximum length of one branch of the resource search path tree.
+ * Used in getBundle().
+ */
+ private static final int MAX_BUNDLES_SEARCHED = 2;
+
+ /**
+ * Default filenames extension.
+ */
+ public static final String FILENAME_EXTENSION = ".xml";
+
+ /**
+ * Default factory.
+ */
+ protected DefinitionsFactory defaultFactory = null;
+
+ /**
+ * XML parser used.
+ * Attribute is transient to allow serialization. In this implementaiton,
+ * xmlParser is created each time we need it ;-(.
+ */
+ protected transient XmlParser xmlParser;
+
+ /**
+ * Do we want validating parser. Default is <code>false</code>.
+ * Can be set from servlet config file.
+ */
+ protected boolean isValidatingParser = false;
+
+ /**
+ * Parser detail level. Default is 0.
+ * Can be set from servlet config file.
+ */
+ protected int parserDetailLevel = 0;
+
+ /**
+ * Names of files containing instances descriptions.
+ */
+ private List filenames = null;
+
+ /**
+ * Collection of already loaded definitions set, referenced by their suffix.
+ */
+ private Map loaded = null;
+
+ /**
+ * Parameterless Constructor.
+ * Method {@link #initFactory} must be called prior to any use of created factory.
+ */
+ public I18nFactorySet() {
+ super();
+ log.info("CONSTRUCTING I18NFactorySet");
+ }
+
+ /**
+ * Constructor.
+ * Init the factory by reading appropriate configuration file.
+ * @param servletContext Servlet context.
+ * @param properties Map containing all properties.
+ * @throws FactoryNotFoundException Can't find factory configuration file.
+ */
+ public I18nFactorySet(ServletContext servletContext, Map properties)
+ throws DefinitionsFactoryException {
+
+ initFactory(servletContext, properties);
+ }
+
+ /**
+ * Initialization method.
+ * Init the factory by reading appropriate configuration file.
+ * This method is called exactly once immediately after factory creation in
+ * case of internal creation (by DefinitionUtil).
+ * @param servletContext Servlet Context passed to newly created factory.
+ * @param properties Map of name/property passed to newly created factory. Map can contains
+ * more properties than requested.
+ * @throws DefinitionsFactoryException An error occur during initialization.
+ */
+ public void initFactory(ServletContext servletContext, Map properties)
+ throws DefinitionsFactoryException {
+
+ // Set some property values
+ String value = (String) properties.get(PARSER_VALIDATE_PARAMETER_NAME);
+ if (value != null) {
+ isValidatingParser = Boolean.valueOf(value).booleanValue();
+ }
+
+ value = (String) properties.get(PARSER_DETAILS_PARAMETER_NAME);
+ if (value != null) {
+ try {
+ parserDetailLevel = Integer.valueOf(value).intValue();
+
+ } catch (NumberFormatException ex) {
+ log.error(
+ "Bad format for parameter '"
+ + PARSER_DETAILS_PARAMETER_NAME
+ + "'. Integer expected.");
+ }
+ }
+
+ // init factory withappropriate configuration file
+ // Try to use provided filename, if any.
+ // If no filename are provided, try to use default ones.
+ String filename = (String) properties.get(DEFINITIONS_CONFIG_PARAMETER_NAME);
+ if (filename != null) { // Use provided filename
+ try {
+ initFactory(servletContext, filename);
+ if (log.isDebugEnabled()) {
+ log.debug("Factory initialized from file '" + filename + "'.");
+ }
+
+ } catch (FileNotFoundException ex) { // A filename is specified, throw appropriate error.
+ log.error(ex.getMessage() + " : Can't find file '" + filename + "'");
+ throw new FactoryNotFoundException(
+ ex.getMessage() + " : Can't find file '" + filename + "'");
+ }
+
+ } else { // try each default file names
+ for (int i = 0; i < DEFAULT_DEFINITION_FILENAMES.length; i++) {
+ filename = DEFAULT_DEFINITION_FILENAMES[i];
+ try {
+ initFactory(servletContext, filename);
+ if (log.isInfoEnabled()) {
+ log.info(
+ "Factory initialized from file '" + filename + "'.");
+ }
+ } catch (FileNotFoundException ex) {
+ // Do nothing
+ }
+ }
+ }
+
+ }
+
+ /**
+ * Initialization method.
+ * Init the factory by reading appropriate configuration file.
+ * This method is called exactly once immediately after factory creation in
+ * case of internal creation (by DefinitionUtil).
+ * @param servletContext Servlet Context passed to newly created factory.
+ * @param proposedFilename File names, comma separated, to use as base file names.
+ * @throws DefinitionsFactoryException An error occur during initialization.
+ */
+ protected void initFactory(
+ ServletContext servletContext,
+ String proposedFilename)
+ throws DefinitionsFactoryException, FileNotFoundException {
+
+ // Init list of filenames
+ StringTokenizer tokenizer = new StringTokenizer(proposedFilename, ",");
+ this.filenames = new ArrayList(tokenizer.countTokens());
+ while (tokenizer.hasMoreTokens()) {
+ this.filenames.add(tokenizer.nextToken().trim());
+ }
+
+ loaded = new HashMap();
+ defaultFactory = createDefaultFactory(servletContext);
+ if (log.isDebugEnabled())
+ log.debug("default factory:" + defaultFactory);
+ }
+
+ /**
+ * Get default factory.
+ * @return Default factory
+ */
+ protected DefinitionsFactory getDefaultFactory() {
+ return defaultFactory;
+ }
+
+ /**
+ * Create default factory .
+ * Create InstancesMapper for specified Locale.
+ * If creation failes, use default mapper and log error message.
+ * @param servletContext Current servlet context. Used to open file.
+ * @return Created default definition factory.
+ * @throws DefinitionsFactoryException If an error occur while creating factory.
+ * @throws FileNotFoundException if factory can't be loaded from filenames.
+ */
+ protected DefinitionsFactory createDefaultFactory(ServletContext servletContext)
+ throws DefinitionsFactoryException, FileNotFoundException {
+
+ XmlDefinitionsSet rootXmlConfig = parseXmlFiles(servletContext, "", null);
+ if (rootXmlConfig == null) {
+ log.info("COULDN'T FIND THE FILE");
+ throw new FileNotFoundException();
+ }
+
+ rootXmlConfig.resolveInheritances();
+
+ if (log.isDebugEnabled()) {
+ log.debug(rootXmlConfig);
+ }
+
+ DefinitionsFactory factory = new DefinitionsFactory(rootXmlConfig);
+ if (log.isDebugEnabled()) {
+ log.debug("factory loaded : " + factory);
+ }
+
+ return factory;
+ }
+
+ /**
+ * Extract key that will be used to get the sub factory.
+ * @param name Name of requested definition
+ * @param request Current servlet request.
+ * @param servletContext Current servlet context.
+ * @return the key or <code>null</code> if not found.
+ */
+ protected Object getDefinitionsFactoryKey(
+ String name,
+ ServletRequest request,
+ ServletContext servletContext) {
+
+ Locale locale = null;
+ try {
+ HttpSession session = ((HttpServletRequest) request).getSession(false);
+ if (session != null) {
+ locale = (Locale) session.getAttribute(ComponentConstants.LOCALE_KEY);
+ }
+
+ } catch (ClassCastException ex) {
+ log.error("I18nFactorySet.getDefinitionsFactoryKey");
+ ex.printStackTrace();
+ }
+
+ return locale;
+ }
+
+ /**
+ * Create a factory for specified key.
+ * If creation failes, return default factory and log an error message.
+ * @param key The key.
+ * @param request Servlet request.
+ * @param servletContext Servlet context.
+ * @return Definition factory for specified key.
+ * @throws DefinitionsFactoryException If an error occur while creating factory.
+ */
+ protected DefinitionsFactory createFactory(
+ Object key,
+ ServletRequest request,
+ ServletContext servletContext)
+ throws DefinitionsFactoryException {
+
+ if (key == null) {
+ return getDefaultFactory();
+ }
+
+ // Build possible postfixes
+ List possiblePostfixes = calculatePostixes("", (Locale) key);
+
+ // Search last postix corresponding to a config file to load.
+ // First check if something is loaded for this postfix.
+ // If not, try to load its config.
+ XmlDefinitionsSet lastXmlFile = null;
+ DefinitionsFactory factory = null;
+ String curPostfix = null;
+ int i = 0;
+
+ for (i = possiblePostfixes.size() - 1; i >= 0; i--) {
+ curPostfix = (String) possiblePostfixes.get(i);
+
+ // Already loaded ?
+ factory = (DefinitionsFactory) loaded.get(curPostfix);
+ if (factory != null) { // yes, stop search
+ return factory;
+ }
+
+ // Try to load it. If success, stop search
+ lastXmlFile = parseXmlFiles(servletContext, curPostfix, null);
+ if (lastXmlFile != null) {
+ break;
+ }
+ }
+
+ // Have we found a description file ?
+ // If no, return default one
+ if (lastXmlFile == null) {
+ return getDefaultFactory();
+ }
+
+ // We found something. Need to load base and intermediate files
+ String lastPostfix = curPostfix;
+ XmlDefinitionsSet rootXmlConfig = parseXmlFiles(servletContext, "", null);
+ for (int j = 0; j < i; j++) {
+ curPostfix = (String) possiblePostfixes.get(j);
+ parseXmlFiles(servletContext, curPostfix, rootXmlConfig);
+ }
+
+ rootXmlConfig.extend(lastXmlFile);
+ rootXmlConfig.resolveInheritances();
+
+ factory = new DefinitionsFactory(rootXmlConfig);
+ loaded.put(lastPostfix, factory);
+
+ if (log.isDebugEnabled()) {
+ log.debug("factory loaded : " + factory);
+ }
+
+ // return last available found !
+ return factory;
+ }
+
+ /**
+ * Calculate the postixes along the search path from the base bundle to the
+ * bundle specified by baseName and locale.
+ * Method copied from java.util.ResourceBundle
+ * @param baseName the base bundle name
+ * @param locale the locale
+ */
+ private static List calculatePostixes(String baseName, Locale locale) {
+ final List result = new ArrayList(MAX_BUNDLES_SEARCHED);
+ final String language = locale.getLanguage();
+ final int languageLength = language.length();
+ final String country = locale.getCountry();
+ final int countryLength = country.length();
+ final String variant = locale.getVariant();
+ final int variantLength = variant.length();
+
+ if (languageLength + countryLength + variantLength == 0) {
+ //The locale is "", "", "".
+ return result;
+ }
+
+ final StringBuffer temp = new StringBuffer(baseName);
+ temp.append('_');
+ temp.append(language);
+
+ if (languageLength > 0)
+ result.add(temp.toString());
+
+ if (countryLength + variantLength == 0)
+ return result;
+
+ temp.append('_');
+ temp.append(country);
+
+ if (countryLength > 0)
+ result.add(temp.toString());
+
+ if (variantLength == 0) {
+ return result;
+ } else {
+ temp.append('_');
+ temp.append(variant);
+ result.add(temp.toString());
+ return result;
+ }
+ }
+
+ /**
+ * Parse files associated to postix if they exist.
+ * For each name in filenames, append postfix before file extension,
+ * then try to load the corresponding file.
+ * If file doesn't exist, try next one. Each file description is added to
+ * the XmlDefinitionsSet description.
+ * The XmlDefinitionsSet description is created only if there is a definition file.
+ * Inheritance is not resolved in the returned XmlDefinitionsSet.
+ * If no description file can be opened and no definiion set is provided, return <code>null</code>.
+ * @param postfix Postfix to add to each description file.
+ * @param xmlDefinitions Definitions set to which definitions will be added. If <code>null</code>, a definitions
+ * set is created on request.
+ * @return XmlDefinitionsSet The definitions set created or passed as parameter.
+ * @throws DefinitionsFactoryException On errors parsing file.
+ */
+ private XmlDefinitionsSet parseXmlFiles(
+ ServletContext servletContext,
+ String postfix,
+ XmlDefinitionsSet xmlDefinitions)
+ throws DefinitionsFactoryException {
+
+ if (postfix != null && postfix.length() == 0) {
+ postfix = null;
+ }
+
+ // Iterate throw each file name in list
+ Iterator i = filenames.iterator();
+ while (i.hasNext()) {
+ String filename = concatPostfix((String) i.next(), postfix);
+ xmlDefinitions = parseXmlFile(servletContext, filename, xmlDefinitions);
+ }
+
+ return xmlDefinitions;
+ }
+
+ /**
+ * Parse specified xml file and add definition to specified definitions set.
+ * This method is used to load several description files in one instances list.
+ * If filename exists and definition set is <code>null</code>, create a new set. Otherwise, return
+ * passed definition set (can be <code>null</code>).
+ * @param servletContext Current servlet context. Used to open file.
+ * @param filename Name of file to parse.
+ * @param xmlDefinitions Definitions set to which definitions will be added. If null, a definitions
+ * set is created on request.
+ * @return XmlDefinitionsSet The definitions set created or passed as parameter.
+ * @throws DefinitionsFactoryException On errors parsing file.
+ */
+ private XmlDefinitionsSet parseXmlFile(
+ ServletContext servletContext,
+ String filename,
+ XmlDefinitionsSet xmlDefinitions)
+ throws DefinitionsFactoryException {
+
+ try {
+ InputStream input = servletContext.getResourceAsStream(filename);
+ // Try to load using real path.
+ // This allow to load config file under websphere 3.5.x
+ // Patch proposed Houston, Stephen (LIT) on 5 Apr 2002
+ if (null == input) {
+ try {
+ input =
+ new java.io.FileInputStream(
+ servletContext.getRealPath(filename));
+ } catch (Exception e) {
+ }
+ }
+
+ // If still nothing found, this mean no config file is associated
+ if (input == null) {
+ if (log.isDebugEnabled()) {
+ log.debug("Can't open file '" + filename + "'");
+ }
+ return xmlDefinitions;
+ }
+
+ // Check if parser already exist.
+ // Doesn't seem to work yet.
+ //if( xmlParser == null )
+ if (true) {
+ xmlParser = new XmlParser();
+ xmlParser.setValidating(isValidatingParser);
+ }
+
+ // Check if definition set already exist.
+ if (xmlDefinitions == null) {
+ xmlDefinitions = new XmlDefinitionsSet();
+ }
+
+ xmlParser.parse(input, xmlDefinitions);
+
+ } catch (SAXException ex) {
+ if (log.isDebugEnabled()) {
+ log.debug("Error while parsing file '" + filename + "'.");
+ ex.printStackTrace();
+ }
+ throw new DefinitionsFactoryException(
+ "Error while parsing file '" + filename + "'. " + ex.getMessage(),
+ ex);
+
+ } catch (IOException ex) {
+ throw new DefinitionsFactoryException(
+ "IO Error while parsing file '" + filename + "'. " + ex.getMessage(),
+ ex);
+ }
+
+ return xmlDefinitions;
+ }
+
+ /**
+ * Concat postfix to the name. Take care of existing filename extension.
+ * Transform the given name "name.ext" to have "name" + "postfix" + "ext".
+ * If there is no ext, return "name" + "postfix".
+ * @param name Filename.
+ * @param postfix Postfix to add.
+ * @return Concatenated filename.
+ */
+ private String concatPostfix(String name, String postfix) {
+ if (postfix == null) {
+ return name;
+ }
+
+ // Search file name extension.
+ // take care of Unix files starting with .
+ int dotIndex = name.lastIndexOf(".");
+ int lastNameStart = name.lastIndexOf(java.io.File.pathSeparator);
+ if (dotIndex < 1 || dotIndex < lastNameStart) {
+ return name + postfix;
+ }
+
+ String ext = name.substring(dotIndex);
+ name = name.substring(0, dotIndex);
+ return name + postfix + ext;
+ }
+
+ /**
+ * Return String representation.
+ * @return String representation.
+ */
+ public String toString() {
+ StringBuffer buff = new StringBuffer("I18nFactorySet : \n");
+ buff.append("--- default factory ---\n");
+ buff.append(defaultFactory.toString());
+ buff.append("\n--- other factories ---\n");
+ Iterator i = factories.values().iterator();
+ while (i.hasNext()) {
+ buff.append(i.next().toString()).append("---------- \n");
+ }
+ return buff.toString();
+ }
+
+}
Added: struts/sandbox/trunk/tiles/core-library/src/java/org/apache/tiles/xmlDefinition/XmlAttribute.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/tiles/core-library/src/java/org/apache/tiles/xmlDefinition/XmlAttribute.java?rev=190662&view=auto
==============================================================================
--- struts/sandbox/trunk/tiles/core-library/src/java/org/apache/tiles/xmlDefinition/XmlAttribute.java (added)
+++ struts/sandbox/trunk/tiles/core-library/src/java/org/apache/tiles/xmlDefinition/XmlAttribute.java Tue Jun 14 14:59:13 2005
@@ -0,0 +1,238 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tiles.xmlDefinition;
+
+import org.apache.tiles.DefinitionNameAttribute;
+import org.apache.tiles.DirectStringAttribute;
+import org.apache.tiles.PathAttribute;
+import org.apache.tiles.UntypedAttribute;
+
+/**
+ * A property key-value pair. This class is used to read configuration files.
+ */
+public class XmlAttribute {
+
+ /**
+ * Attribute name or key.
+ */
+ private String name = null;
+
+ /**
+ * Attribute value.
+ * Value read from description file.
+ */
+ private Object value = null;
+
+ /**
+ * Attribute value.
+ */
+ private String direct = null;
+
+ /**
+ * Attribute value.
+ */
+ private String valueType = null;
+
+ /**
+ * Attribute value.
+ */
+ private String role = null;
+
+ /**
+ * Real attribute value.
+ * Real value is the value after processing of valueType.
+ * I.e. if a type is defined, realValue contains wrapper for this type.
+ */
+ private Object realValue = null;
+
+ /**
+ * Constructor.
+ */
+ public XmlAttribute() {
+ super();
+ }
+
+ /**
+ * Constructor.
+ */
+ public XmlAttribute(String name, Object value) {
+ this.name = name;
+ this.value = value;
+ }
+
+ /**
+ * Access method for the name property.
+ *
+ * @return The current value of the name property.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Sets the value of the name property.
+ *
+ * @param aName the new value of the name property
+ */
+ public void setRole(String role) {
+ this.role = role;
+ }
+
+ /**
+ * Access method for the name property.
+ *
+ * @return The current value of the name property.
+ */
+ public String getRole() {
+ return role;
+ }
+
+ /**
+ * Sets the value of the name property.
+ *
+ * @param aName the new value of the name property.
+ */
+ public void setName(String aName) {
+ name = aName;
+ }
+
+ /**
+ * Another access method for the name property.
+ *
+ * @return the current value of the name property
+ */
+ public String getAttribute() {
+ return name;
+ }
+
+ /**
+ * Sets the value of the name property.
+ *
+ * @param aName the new value of the name property
+ */
+ public void setAttribute(String aName) {
+ name = aName;
+ }
+
+ /**
+ * Access method for the value property. Return the value or a
+ * QualifiedAttribute containing the value if 'direct' is set.
+ *
+ * @return The current value of the value property.
+ */
+ public Object getValue() {
+ // Compatibility with JSP Template
+ if (this.realValue == null) {
+ this.realValue = this.computeRealValue();
+ }
+
+ return this.realValue;
+ }
+
+ /**
+ * Sets the value of the value property.
+ *
+ * @param aValue the new value of the value property
+ */
+ public void setValue(Object aValue) {
+ realValue = null;
+ value = aValue;
+ }
+
+ /**
+ * Sets the value of the value property.
+ *
+ * @param aValue the new value of the value property
+ */
+ public void setContent(Object aValue) {
+ setValue(aValue);
+ }
+
+ /**
+ * Sets the value of the value property.
+ *
+ * @param aValue the new value of the value property
+ */
+ public void setBody(String body) {
+ if (body.length() == 0) {
+ return;
+ }
+
+ setValue(body);
+ }
+
+ /**
+ * Sets the value of the value property.
+ *
+ * @param aValue the new value of the value property
+ */
+ public void setDirect(String value) {
+ this.direct = value;
+ }
+
+ /**
+ * Sets the value of the value property.
+ *
+ * @param aValue the new value of the value property
+ */
+ public void setType(String value) {
+ this.valueType = value;
+ }
+
+ /**
+ * Compute real value from attributes setting.
+ */
+ protected Object computeRealValue() {
+ Object realValue = value;
+ // Is there a type set ?
+ // First check direct attribute, and translate it to a valueType.
+ // Then, evaluate valueType, and create requested typed attribute.
+ if (direct != null) {
+ this.valueType =
+ Boolean.valueOf(direct).booleanValue() ? "string" : "path";
+ }
+
+ if (value != null && valueType != null) {
+ String strValue = value.toString();
+
+ if (valueType.equalsIgnoreCase("string")) {
+ realValue = new DirectStringAttribute(strValue);
+
+ } else if (valueType.equalsIgnoreCase("page")) {
+ realValue = new PathAttribute(strValue);
+
+ } else if (valueType.equalsIgnoreCase("template")) {
+ realValue = new PathAttribute(strValue);
+
+ } else if (valueType.equalsIgnoreCase("instance")) {
+ realValue = new DefinitionNameAttribute(strValue);
+ }
+
+ // Set realValue's role value if needed
+ if (role != null) {
+ ((UntypedAttribute) realValue).setRole(role);
+ }
+ }
+
+ // Create attribute wrapper to hold role if role is set and no type specified
+ if (role != null && value != null && valueType == null) {
+ realValue = new UntypedAttribute(value.toString(), role);
+ }
+
+ return realValue;
+ }
+}
Added: struts/sandbox/trunk/tiles/core-library/src/java/org/apache/tiles/xmlDefinition/XmlDefinition.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/tiles/core-library/src/java/org/apache/tiles/xmlDefinition/XmlDefinition.java?rev=190662&view=auto
==============================================================================
--- struts/sandbox/trunk/tiles/core-library/src/java/org/apache/tiles/xmlDefinition/XmlDefinition.java (added)
+++ struts/sandbox/trunk/tiles/core-library/src/java/org/apache/tiles/xmlDefinition/XmlDefinition.java Tue Jun 14 14:59:13 2005
@@ -0,0 +1,187 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tiles.xmlDefinition;
+
+import org.apache.tiles.ComponentDefinition;
+import org.apache.tiles.NoSuchDefinitionException;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.util.Iterator;
+
+/**
+ *A definition read from an XML definitions file.
+ */
+public class XmlDefinition extends ComponentDefinition
+{
+ /**
+ * Extends attribute value.
+ */
+ private String inherit;
+
+ /** Commons Logging instance. */
+ protected static Log log = LogFactory.getLog(XmlDefinition.class);
+
+ /**
+ * Used for resolving inheritance.
+ */
+ private boolean isVisited=false;
+
+
+ /**
+ * Constructor.
+ */
+ public XmlDefinition()
+ {
+ super();
+ //if(debug)
+ //System.out.println( "create definition" );
+ }
+
+ /**
+ * Add an attribute to this component.
+ *
+ * @param attribute Attribute to add.
+ */
+ public void addAttribute( XmlAttribute attribute)
+ {
+ putAttribute( attribute.getName(), attribute.getValue() );
+ }
+
+ /**
+ * Set extends.
+ *
+ * @param name Name of the extended definition.
+ */
+ public void setExtends(String name)
+ {
+ inherit = name;
+ }
+
+ /**
+ * Get extends.
+ *
+ * @return Name of the extended definition.
+ */
+ public String getExtends()
+ {
+ return inherit;
+ }
+
+ /**
+ * Get extends flag.
+ *
+ */
+ public boolean isExtending( )
+ {
+ return inherit!=null;
+ }
+
+ /**
+ * Set isVisited.
+ *
+ */
+ public void setIsVisited( boolean isVisited )
+ {
+ this.isVisited = isVisited;
+ }
+
+ /**
+ * Resolve inheritance.
+ * First, resolve parent's inheritance, then set path to the parent's path.
+ * Also copy attributes setted in parent, and not set in child
+ * If instance doesn't extend anything, do nothing.
+ * @throws NoSuchDefinitionException If an inheritance can not be solved.
+ */
+ public void resolveInheritance( XmlDefinitionsSet definitionsSet )
+ throws NoSuchDefinitionException
+ {
+ // Already done, or not needed ?
+ if( isVisited || !isExtending() )
+ return;
+
+ if(log.isDebugEnabled())
+ log.debug( "Resolve definition for child name='" + getName()
+ + "' extends='" + getExtends() + "'.");
+
+ // Set as visited to avoid endless recurisvity.
+ setIsVisited( true );
+
+ // Resolve parent before itself.
+ XmlDefinition parent = definitionsSet.getDefinition( getExtends() );
+ if( parent == null )
+ { // error
+ String msg = "Error while resolving definition inheritance: child '"
+ + getName() + "' can't find its ancestor '"
+ + getExtends() + "'. Please check your description file.";
+ log.error( msg );
+ // to do : find better exception
+ throw new NoSuchDefinitionException( msg );
+ }
+
+ parent.resolveInheritance( definitionsSet );
+
+ // Iterate on each parent's attribute and add it if not defined in child.
+ Iterator parentAttributes = parent.getAttributes().keySet().iterator();
+ while( parentAttributes.hasNext() )
+ {
+ String name = (String)parentAttributes.next();
+ if( !getAttributes().containsKey(name) )
+ putAttribute( name, parent.getAttribute(name) );
+ }
+ // Set path and role if not setted
+ if( path == null )
+ setPath( parent.getPath() );
+ if( role == null )
+ setRole( parent.getRole() );
+ if( controller==null )
+ {
+ setController( parent.getController());
+ setControllerType( parent.getControllerType());
+ }
+ }
+
+ /**
+ * Overload this definition with passed child.
+ * All attributes from child are copied to this definition. Previous attributes with
+ * same name are disguarded.
+ * Special attribute 'path','role' and 'extends' are overloaded if defined in child.
+ * @param child Child used to overload this definition.
+ */
+ public void overload( XmlDefinition child )
+ {
+ if( child.getPath() != null )
+ {
+ path = child.getPath();
+ }
+ if( child.getExtends() != null )
+ {
+ inherit = child.getExtends();
+ }
+ if( child.getRole() != null )
+ {
+ role = child.getRole();
+ }
+ if( child.getController()!=null )
+ {
+ controller = child.getController();
+ controllerType = child.getControllerType();
+ }
+ // put all child attributes in parent.
+ attributes.putAll( child.getAttributes());
+ }
+}
Added: struts/sandbox/trunk/tiles/core-library/src/java/org/apache/tiles/xmlDefinition/XmlDefinitionsSet.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/tiles/core-library/src/java/org/apache/tiles/xmlDefinition/XmlDefinitionsSet.java?rev=190662&view=auto
==============================================================================
--- struts/sandbox/trunk/tiles/core-library/src/java/org/apache/tiles/xmlDefinition/XmlDefinitionsSet.java (added)
+++ struts/sandbox/trunk/tiles/core-library/src/java/org/apache/tiles/xmlDefinition/XmlDefinitionsSet.java Tue Jun 14 14:59:13 2005
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tiles.xmlDefinition;
+
+import org.apache.tiles.NoSuchDefinitionException;
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Iterator;
+
+/**
+ * A set of definitions read from XML definitions file.
+*/
+public class XmlDefinitionsSet
+{
+ /** Defined definitions. */
+ protected Map definitions;
+
+ /**
+ * Constructor.
+ */
+ public XmlDefinitionsSet()
+ {
+ definitions = new HashMap();
+ }
+
+ /**
+ * Put definition in set.
+ * @param definition Definition to add.
+ */
+ public void putDefinition(XmlDefinition definition)
+ {
+ definitions.put( definition.getName(), definition );
+ }
+
+ /**
+ * Get requested definition.
+ * @param name Definition name.
+ */
+ public XmlDefinition getDefinition(String name)
+ {
+ return (XmlDefinition)definitions.get( name );
+ }
+
+ /**
+ * Get definitions map.
+ */
+ public Map getDefinitions()
+ {
+ return definitions;
+ }
+
+ /**
+ * Resolve extended instances.
+ */
+ public void resolveInheritances() throws NoSuchDefinitionException
+ {
+ // Walk through all definitions and resolve individual inheritance
+ Iterator i = definitions.values().iterator();
+ while( i.hasNext() )
+ {
+ XmlDefinition definition = (XmlDefinition)i.next();
+ definition.resolveInheritance( this );
+ } // end loop
+ }
+
+ /**
+ * Add definitions from specified child definitions set.
+ * For each definition in child, look if it already exists in this set.
+ * If not, add it, if yes, overload parent's definition with child definition.
+ * @param child Definition used to overload this object.
+ */
+ public void extend( XmlDefinitionsSet child )
+ {
+ if(child==null)
+ return;
+ Iterator i = child.getDefinitions().values().iterator();
+ while( i.hasNext() )
+ {
+ XmlDefinition childInstance = (XmlDefinition)i.next();
+ XmlDefinition parentInstance = getDefinition(childInstance.getName() );
+ if( parentInstance != null )
+ {
+ parentInstance.overload( childInstance );
+ }
+ else
+ putDefinition( childInstance );
+ } // end loop
+ }
+ /**
+ * Get String representation.
+ */
+ public String toString()
+ {
+ return "definitions=" + definitions.toString() ;
+ }
+
+}
Added: struts/sandbox/trunk/tiles/core-library/src/java/org/apache/tiles/xmlDefinition/XmlListAttribute.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/tiles/core-library/src/java/org/apache/tiles/xmlDefinition/XmlListAttribute.java?rev=190662&view=auto
==============================================================================
--- struts/sandbox/trunk/tiles/core-library/src/java/org/apache/tiles/xmlDefinition/XmlListAttribute.java (added)
+++ struts/sandbox/trunk/tiles/core-library/src/java/org/apache/tiles/xmlDefinition/XmlListAttribute.java Tue Jun 14 14:59:13 2005
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tiles.xmlDefinition;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.servlet.RequestDispatcher;
+
+public class XmlListAttribute extends XmlAttribute {
+ /** List.
+ * We declare a List to avoid cast.
+ * Parent "value" property points to the same list.
+ */
+ private List list;
+
+ /**
+ * Constructor.
+ */
+ public XmlListAttribute()
+ {
+ list = new ArrayList();
+ setValue(list);
+ }
+
+ /**
+ * Constructor.
+ * @param name Name.
+ * @param value List.
+ */
+ public XmlListAttribute( String name, List value)
+ {
+ super( name, value );
+ list = value;
+ }
+
+ /**
+ * Add an element in list.
+ * We use a property to avoid rewriting a new class.
+ * @param element XmlAttribute to add.
+ */
+ public void add( XmlAttribute element )
+ {
+ list.add( element.getValue() );
+ }
+
+ /**
+ * Add an element in list.
+ * @param value Object to add.
+ */
+ public void add( Object value )
+ {
+ //list.add( value );
+ // To correct a bug in digester, we need to check the object type
+ // Digester doesn't call correct method according to object type ;-(
+ if(value instanceof XmlAttribute)
+ {
+ add((XmlAttribute)value);
+ return;
+ }
+ else
+ list.add( value );
+ }
+
+ /**
+ * Add an element in list.
+ * @param value Object to add.
+ */
+ public void addObject( Object value )
+ {
+ list.add( value );
+ }
+
+
+
+}
Added: struts/sandbox/trunk/tiles/core-library/src/java/org/apache/tiles/xmlDefinition/XmlParser.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/tiles/core-library/src/java/org/apache/tiles/xmlDefinition/XmlParser.java?rev=190662&view=auto
==============================================================================
--- struts/sandbox/trunk/tiles/core-library/src/java/org/apache/tiles/xmlDefinition/XmlParser.java (added)
+++ struts/sandbox/trunk/tiles/core-library/src/java/org/apache/tiles/xmlDefinition/XmlParser.java Tue Jun 14 14:59:13 2005
@@ -0,0 +1,345 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tiles.xmlDefinition;
+
+import java.io.BufferedInputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+import org.apache.commons.digester.Digester;
+import org.xml.sax.SAXException;
+
+/**
+ * Parse an XML definitions file.
+ *
+ * @author Cedric Dumoulin
+ * @author David Geary
+ */
+public class XmlParser {
+ /** Associated digester. */
+ protected Digester digester;
+ /**
+ * Should we use a validating XML parser to read the configuration file.
+ * Default is <code>false</code>.
+ */
+ protected boolean validating = false;
+ /**
+ * The set of public identifiers, and corresponding resource names for
+ * the versions of the configuration file DTDs we know about. There
+ * <strong>MUST</strong> be an even number of Strings in this list!
+ */
+ protected String registrations[] = {
+ // pre 1.1
+ "-//Apache Software Foundation//DTD Tiles Configuration//EN",
+ "/org/apache/struts/resources/tiles-config_1_1.dtd",
+ "-//Apache Software Foundation//DTD Components Configuration//EN",
+ "/org/apache/struts/resources/tiles-config.dtd",
+ // version 1.1
+ "-//Apache Software Foundation//DTD Tiles Configuration 1.1//EN",
+ "/org/apache/struts/resources/tiles-config_1_1.dtd",
+ };
+
+ /**
+ * Constructor.
+ * Creates a digester parser and initializes syntax rules.
+ */
+ public XmlParser()
+ {
+ digester = new Digester();
+ digester.setValidating(validating);
+ digester.setNamespaceAware(true);
+ digester.setUseContextClassLoader(true);
+ // Register our local copy of the DTDs that we can find
+ for (int i = 0; i < registrations.length; i += 2) {
+ URL url = this.getClass().getResource(registrations[i+1]);
+ if (url != null)
+ {
+ digester.register(registrations[i], url.toString());
+ }
+ }
+ // Init syntax rules
+ initDigester( digester );
+ }
+
+ /**
+ * Set digester validating flag.
+ */
+ public void setValidating( boolean validating )
+ {
+ digester.setValidating( validating);
+ }
+
+
+ /**
+ * Init digester for components syntax.
+ * This is an old set of rules, left for backward compatibility.
+ * @param digester Digester instance to use.
+ */
+ private void initDigesterForComponentsDefinitionsSyntax( Digester digester )
+ {
+ // Common constants
+ String PACKAGE_NAME = "org.apache.tiles.xmlDefinition";
+ String DEFINITION_TAG = "component-definitions/definition";
+ String definitionHandlerClass = PACKAGE_NAME + ".XmlDefinition";
+
+ String PUT_TAG = DEFINITION_TAG + "/put";
+ String putAttributeHandlerClass = PACKAGE_NAME + ".XmlAttribute";
+
+ String LIST_TAG = DEFINITION_TAG + "/putList";
+ String listHandlerClass = PACKAGE_NAME + ".XmlListAttribute";
+
+ String ADD_LIST_ELE_TAG = LIST_TAG + "/add";
+
+ // syntax rules
+ digester.addObjectCreate( DEFINITION_TAG, definitionHandlerClass );
+ digester.addSetProperties( DEFINITION_TAG);
+ digester.addSetNext( DEFINITION_TAG, "putDefinition", definitionHandlerClass);
+ // put / putAttribute rules
+ digester.addObjectCreate( PUT_TAG, putAttributeHandlerClass);
+ digester.addSetNext( PUT_TAG, "addAttribute", putAttributeHandlerClass);
+ digester.addSetProperties( PUT_TAG);
+ digester.addCallMethod( PUT_TAG, "setBody", 0);
+ // list rules
+ digester.addObjectCreate( LIST_TAG, listHandlerClass);
+ digester.addSetProperties( LIST_TAG);
+ digester.addSetNext( LIST_TAG, "addAttribute", putAttributeHandlerClass);
+ // list elements rules
+ // We use Attribute class to avoid rewriting a new class.
+ // Name part can't be used in listElement attribute.
+ digester.addObjectCreate( ADD_LIST_ELE_TAG, putAttributeHandlerClass);
+ digester.addSetNext( ADD_LIST_ELE_TAG, "add", putAttributeHandlerClass);
+ digester.addSetProperties( ADD_LIST_ELE_TAG);
+ digester.addCallMethod( ADD_LIST_ELE_TAG, "setBody", 0);
+ }
+
+ /**
+ * Init digester for Tiles syntax.
+ * Same as components, but with first element = tiles-definitions
+ * @param digester Digester instance to use.
+ */
+ private void initDigesterForTilesDefinitionsSyntax( Digester digester )
+ {
+ // Common constants
+ String PACKAGE_NAME = "org.apache.tiles.xmlDefinition";
+ String DEFINITION_TAG = "tiles-definitions/definition";
+ String definitionHandlerClass = PACKAGE_NAME + ".XmlDefinition";
+
+ String PUT_TAG = DEFINITION_TAG + "/put";
+ String putAttributeHandlerClass = PACKAGE_NAME + ".XmlAttribute";
+
+ //String LIST_TAG = DEFINITION_TAG + "/putList";
+ // List tag value
+ String LIST_TAG = "putList";
+ String DEF_LIST_TAG = DEFINITION_TAG + "/" + LIST_TAG;
+ String listHandlerClass = PACKAGE_NAME + ".XmlListAttribute";
+ // Tag value for adding an element in a list
+ String ADD_LIST_ELE_TAG = "*/" + LIST_TAG + "/add";
+
+ // syntax rules
+ digester.addObjectCreate( DEFINITION_TAG, definitionHandlerClass );
+ digester.addSetProperties( DEFINITION_TAG);
+ digester.addSetNext( DEFINITION_TAG, "putDefinition", definitionHandlerClass);
+ // put / putAttribute rules
+ // Rules for a same pattern are called in order, but rule.end() are called
+ // in reverse order.
+ // SetNext and CallMethod use rule.end() method. So, placing SetNext in
+ // first position ensure it will be called last (sic).
+ digester.addObjectCreate( PUT_TAG, putAttributeHandlerClass);
+ digester.addSetNext( PUT_TAG, "addAttribute", putAttributeHandlerClass);
+ digester.addSetProperties( PUT_TAG);
+ digester.addCallMethod( PUT_TAG, "setBody", 0);
+ // Definition level list rules
+ // This is rules for lists nested in a definition
+ digester.addObjectCreate( DEF_LIST_TAG, listHandlerClass);
+ digester.addSetProperties( DEF_LIST_TAG);
+ digester.addSetNext( DEF_LIST_TAG, "addAttribute", putAttributeHandlerClass);
+ // list elements rules
+ // We use Attribute class to avoid rewriting a new class.
+ // Name part can't be used in listElement attribute.
+ digester.addObjectCreate( ADD_LIST_ELE_TAG, putAttributeHandlerClass);
+ digester.addSetNext( ADD_LIST_ELE_TAG, "add", putAttributeHandlerClass);
+ digester.addSetProperties( ADD_LIST_ELE_TAG);
+ digester.addCallMethod( ADD_LIST_ELE_TAG, "setBody", 0);
+
+ // nested list elements rules
+ // Create a list handler, and add it to parent list
+ String NESTED_LIST = "*/" + LIST_TAG + "/" + LIST_TAG;
+ digester.addObjectCreate( NESTED_LIST, listHandlerClass);
+ digester.addSetProperties( NESTED_LIST);
+ digester.addSetNext( NESTED_LIST, "add", putAttributeHandlerClass);
+
+ // item elements rules
+ // We use Attribute class to avoid rewriting a new class.
+ // Name part can't be used in listElement attribute.
+ //String ADD_WILDCARD = LIST_TAG + "/addItem";
+ // non String ADD_WILDCARD = LIST_TAG + "/addx*";
+ String ADD_WILDCARD = "*/item";
+ String menuItemDefaultClass = "org.apache.tiles.beans.SimpleMenuItem";
+ digester.addObjectCreate( ADD_WILDCARD, menuItemDefaultClass, "classtype");
+ digester.addSetNext( ADD_WILDCARD, "add", "java.lang.Object");
+ digester.addSetProperties( ADD_WILDCARD);
+
+ // bean elements rules
+ String BEAN_TAG = "*/bean";
+ String beanDefaultClass = "org.apache.tiles.beans.SimpleMenuItem";
+ digester.addObjectCreate( BEAN_TAG, beanDefaultClass, "classtype");
+ digester.addSetNext( BEAN_TAG, "add", "java.lang.Object");
+ digester.addSetProperties( BEAN_TAG);
+
+ // Set properties to surrounding element
+ digester.addSetProperty(BEAN_TAG+ "/set-property", "property", "value");
+ }
+
+ /**
+ * Init digester in order to parse instances definition file syntax.
+ * Instances is an old name for "definition". This method is left for
+ * backwards compatibility.
+ * @param digester Digester instance to use.
+ */
+ private void initDigesterForInstancesSyntax( Digester digester )
+ {
+ // Build a digester to process our configuration resource
+ String PACKAGE_NAME = "org.apache.tiles.xmlDefinition";
+ String INSTANCE_TAG = "component-instances/instance";
+ String instanceHandlerClass = PACKAGE_NAME + ".XmlDefinition";
+
+ String PUT_TAG = INSTANCE_TAG + "/put";
+ String PUTATTRIBUTE_TAG = INSTANCE_TAG + "/putAttribute";
+ String putAttributeHandlerClass = PACKAGE_NAME + ".XmlAttribute";
+
+ String LIST_TAG = INSTANCE_TAG + "/putList";
+ String listHandlerClass = PACKAGE_NAME + ".XmlListAttribute";
+
+ String ADD_LIST_ELE_TAG = LIST_TAG + "/add";
+
+ // component instance rules
+ digester.addObjectCreate( INSTANCE_TAG, instanceHandlerClass );
+ digester.addSetProperties( INSTANCE_TAG);
+ digester.addSetNext( INSTANCE_TAG, "putDefinition", instanceHandlerClass);
+ // put / putAttribute rules
+ digester.addObjectCreate( PUTATTRIBUTE_TAG, putAttributeHandlerClass);
+ digester.addSetProperties( PUTATTRIBUTE_TAG);
+ digester.addSetNext( PUTATTRIBUTE_TAG, "addAttribute", putAttributeHandlerClass);
+ // put / putAttribute rules
+ digester.addObjectCreate( PUT_TAG, putAttributeHandlerClass);
+ digester.addSetProperties( PUT_TAG);
+ digester.addSetNext( PUT_TAG, "addAttribute", putAttributeHandlerClass);
+ // list rules
+ digester.addObjectCreate( LIST_TAG, listHandlerClass);
+ digester.addSetProperties( LIST_TAG);
+ digester.addSetNext( LIST_TAG, "addAttribute", putAttributeHandlerClass);
+ // list elements rules
+ // We use Attribute class to avoid rewriting a new class.
+ // Name part can't be used in listElement attribute.
+ digester.addObjectCreate( ADD_LIST_ELE_TAG, putAttributeHandlerClass);
+ digester.addSetProperties( ADD_LIST_ELE_TAG);
+ digester.addSetNext( ADD_LIST_ELE_TAG, "add", putAttributeHandlerClass);
+ }
+
+ /**
+ * Init digester.
+ * @param digester Digester instance to use.
+ */
+ protected void initDigester( Digester digester )
+ {
+ initDigesterForTilesDefinitionsSyntax( digester );
+ initDigesterForComponentsDefinitionsSyntax( digester );
+ initDigesterForInstancesSyntax( digester );
+ }
+
+ /**
+ * Parse input reader and add encountered definitions to definitions set.
+ * @param in Input stream.
+ * @param definitions Xml Definitions set to which encountered definition are added.
+ * @throws IOException On errors during file parsing.
+ * @throws SAXException On errors parsing XML.
+ */
+ public void parse( InputStream in, XmlDefinitionsSet definitions ) throws IOException, SAXException
+ {
+ try
+ {
+ // set first object in stack
+ //digester.clear();
+ digester.push(definitions);
+ // parse
+ digester.parse(in);
+ in.close();
+ }
+ catch (SAXException e)
+ {
+ //throw new ServletException( "Error while parsing " + mappingConfig, e);
+ throw e;
+ }
+
+ }
+
+ /**
+ * Main method to check file syntax.
+ */
+ public static void main(String[] args)
+ {
+ //String filename = "E:/programs/jakarta-tomcat/webapps/wtiles-struts/WEB-INF/tiles-examples-defs.xml";
+ String filename = "E:/programs/jakarta-tomcat-4.0.3/webapps/wtiles-struts/WEB-INF/tiles-examples-defs.xml";
+ //String filename = "E:/programs/jakarta-tomcat/webapps/wtiles-struts/WEB-INF/tilesDefinitions.xml";
+ //String filename = "E:/programs/jakarta-tomcat/webapps/wtiles-channel/WEB-INF/componentDefinitions.xml";
+ //String filename2 = "E:/programs/jakarta-tomcat/webapps/wtiles-tutorial/WEB-INF/componentDefinitions.xml";
+
+
+ if( args.length > 1 )
+ {
+ filename = args[1];
+ } // end if
+
+ System.out.println( "Read file '" + filename +"'" );
+
+ InputStream input = null;
+ // InputStream input2 = null;
+ // Open file
+ try
+ {
+ input = new BufferedInputStream(
+ new FileInputStream( filename) );
+ // input2 = new BufferedInputStream(
+ // new FileInputStream( filename2) );
+ }
+ catch( IOException ex )
+ {
+ System.out.println( "can't open file '" + filename + "' : " + ex.getMessage() );
+ }
+ // Check file syntax
+ try
+ {
+ XmlParser parser = new XmlParser();
+ parser.setValidating(true);
+ XmlDefinitionsSet definitions = new XmlDefinitionsSet();
+ System.out.println( " Parse file" );
+ parser.parse( input, definitions);
+ // System.out.println( " Check file 2" );
+ //parser.parse( input2, definitions);
+ System.out.println( " done." );
+ System.out.println( " Result : " + definitions.toString() );
+ }
+ catch( Exception ex )
+ {
+ System.out.println( "Error during parsing '" + filename + "' : " + ex.getMessage() );
+ ex.printStackTrace();
+ }
+ }
+
+}
Added: struts/sandbox/trunk/tiles/core-library/src/java/org/apache/tiles/xmlDefinition/sub
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/tiles/core-library/src/java/org/apache/tiles/xmlDefinition/sub?rev=190662&view=auto
==============================================================================
--- struts/sandbox/trunk/tiles/core-library/src/java/org/apache/tiles/xmlDefinition/sub (added)
+++ struts/sandbox/trunk/tiles/core-library/src/java/org/apache/tiles/xmlDefinition/sub Tue Jun 14 14:59:13 2005
@@ -0,0 +1,3 @@
+2,/^END/{
+ /org.apache.struts.tiles/s//org.apache.tiles/g
+}
Added: struts/sandbox/trunk/tiles/core-library/src/java/org/apache/util/MessageResources.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/tiles/core-library/src/java/org/apache/util/MessageResources.java?rev=190662&view=auto
==============================================================================
--- struts/sandbox/trunk/tiles/core-library/src/java/org/apache/util/MessageResources.java (added)
+++ struts/sandbox/trunk/tiles/core-library/src/java/org/apache/util/MessageResources.java Tue Jun 14 14:59:13 2005
@@ -0,0 +1,517 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.util;
+
+import java.io.Serializable;
+import java.text.MessageFormat;
+import java.util.HashMap;
+import java.util.Locale;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * General purpose abstract class that describes an API for retrieving
+ * Locale-sensitive messages from underlying resource locations of an
+ * unspecified design, and optionally utilizing the <code>MessageFormat</code>
+ * class to produce internationalized messages with parametric replacement.
+ * <p>
+ * Calls to <code>getMessage()</code> variants without a <code>Locale</code>
+ * argument are presumed to be requesting a message string in the default
+ * <code>Locale</code> for this JVM.
+ * <p>
+ * Calls to <code>getMessage()</code> with an unknown key, or an unknown
+ * <code>Locale</code> will return <code>null</code> if the
+ * <code>returnNull</code> property is set to <code>true</code>. Otherwise,
+ * a suitable error message will be returned instead.
+ * <p>
+ * <strong>IMPLEMENTATION NOTE</strong> - Classes that extend this class
+ * must be Serializable so that instances may be used in distributable
+ * application server environments.
+ *
+ * @author Craig R. McClanahan
+ * @version $Revision: 1.18 $ $Date: 2003/07/02 03:42:09 $
+ */
+public abstract class MessageResources implements Serializable {
+
+ // ------------------------------------------------------------- Properties
+
+ /**
+ * Commons Logging instance.
+ */
+ protected static Log log = LogFactory.getLog(MessageResources.class);
+
+ /**
+ * The configuration parameter used to initialize this MessageResources.
+ */
+ protected String config = null;
+
+ /**
+ * The configuration parameter used to initialize this MessageResources.
+ * @return parameter used to initialize this MessageResources
+ */
+ public String getConfig() {
+ return (this.config);
+ }
+
+ /**
+ * The default Locale for our environment.
+ */
+ protected Locale defaultLocale = Locale.getDefault();
+
+ /**
+ * The <code>MessageResourcesFactory</code> that created this instance.
+ */
+ protected MessageResourcesFactory factory = null;
+
+ /**
+ * The <code>MessageResourcesFactory</code> that created this instance.
+ * @return <code>MessageResourcesFactory</code> that created instance
+ */
+ public MessageResourcesFactory getFactory() {
+ return (this.factory);
+ }
+
+ /**
+ * The set of previously created MessageFormat objects, keyed by the
+ * key computed in <code>messageKey()</code>.
+ */
+ protected HashMap formats = new HashMap();
+
+ /**
+ * Indicate is a <code>null</code> is returned instead of an error message string
+ * when an unknown Locale or key is requested.
+ */
+ protected boolean returnNull = false;
+
+ /**
+ * Indicates that a <code>null</code> is returned instead of an error message string
+ * if an unknown Locale or key is requested.
+ * @return true if null is returned if unknown key or locale is requested
+ */
+ public boolean getReturnNull() {
+ return (this.returnNull);
+ }
+
+ /**
+ * Indicates that a <code>null</code> is returned instead of an error message string
+ * if an unknown Locale or key is requested.
+ * @param returnNull true Indicates that a <code>null</code> is returned
+ * if an unknown Locale or key is requested.
+ */
+ public void setReturnNull(boolean returnNull) {
+ this.returnNull = returnNull;
+ }
+
+ // ----------------------------------------------------------- Constructors
+
+ /**
+ * Construct a new MessageResources according to the specified parameters.
+ *
+ * @param factory The MessageResourcesFactory that created us
+ * @param config The configuration parameter for this MessageResources
+ */
+ public MessageResources(MessageResourcesFactory factory, String config) {
+
+ this(factory, config, false);
+
+ }
+
+ /**
+ * Construct a new MessageResources according to the specified parameters.
+ *
+ * @param factory The MessageResourcesFactory that created us
+ * @param config The configuration parameter for this MessageResources
+ * @param returnNull The returnNull property we should initialize with
+ */
+ public MessageResources(
+ MessageResourcesFactory factory,
+ String config,
+ boolean returnNull) {
+
+ super();
+ this.factory = factory;
+ this.config = config;
+ this.returnNull = returnNull;
+
+ }
+
+ // --------------------------------------------------------- Public Methods
+
+ /**
+ * Returns a text message for the specified key, for the default Locale.
+ *
+ * @param key The message key to look up
+ */
+ public String getMessage(String key) {
+
+ return this.getMessage((Locale) null, key);
+
+ }
+
+ /**
+ * Returns a text message after parametric replacement of the specified
+ * parameter placeholders.
+ *
+ * @param key The message key to look up
+ * @param args An array of replacement parameters for placeholders
+ */
+ public String getMessage(String key, Object args[]) {
+
+ return this.getMessage((Locale) null, key, args);
+
+ }
+
+ /**
+ * Returns a text message after parametric replacement of the specified
+ * parameter placeholders.
+ *
+ * @param key The message key to look up
+ * @param arg0 The replacement for placeholder {0} in the message
+ */
+ public String getMessage(String key, Object arg0) {
+
+ return this.getMessage((Locale) null, key, arg0);
+
+ }
+
+ /**
+ * Returns a text message after parametric replacement of the specified
+ * parameter placeholders.
+ *
+ * @param key The message key to look up
+ * @param arg0 The replacement for placeholder {0} in the message
+ * @param arg1 The replacement for placeholder {1} in the message
+ */
+ public String getMessage(String key, Object arg0, Object arg1) {
+
+ return this.getMessage((Locale) null, key, arg0, arg1);
+
+ }
+
+ /**
+ * Returns a text message after parametric replacement of the specified
+ * parameter placeholders.
+ *
+ * @param key The message key to look up
+ * @param arg0 The replacement for placeholder {0} in the message
+ * @param arg1 The replacement for placeholder {1} in the message
+ * @param arg2 The replacement for placeholder {2} in the message
+ */
+ public String getMessage(String key, Object arg0, Object arg1, Object arg2) {
+
+ return this.getMessage((Locale) null, key, arg0, arg1, arg2);
+
+ }
+
+ /**
+ * Returns a text message after parametric replacement of the specified
+ * parameter placeholders.
+ *
+ * @param key The message key to look up
+ * @param arg0 The replacement for placeholder {0} in the message
+ * @param arg1 The replacement for placeholder {1} in the message
+ * @param arg2 The replacement for placeholder {2} in the message
+ * @param arg3 The replacement for placeholder {3} in the message
+ */
+ public String getMessage(
+ String key,
+ Object arg0,
+ Object arg1,
+ Object arg2,
+ Object arg3) {
+
+ return this.getMessage((Locale) null, key, arg0, arg1, arg2, arg3);
+
+ }
+
+ /**
+ * Returns a text message for the specified key, for the default Locale.
+ * A null string result will be returned by this method if no relevant
+ * message resource is found for this key or Locale, if the
+ * <code>returnNull</code> property is set. Otherwise, an appropriate
+ * error message will be returned.
+ * <p>
+ * This method must be implemented by a concrete subclass.
+ *
+ * @param locale The requested message Locale, or <code>null</code>
+ * for the system default Locale
+ * @param key The message key to look up
+ */
+ public abstract String getMessage(Locale locale, String key);
+
+ /**
+ * Returns a text message after parametric replacement of the specified
+ * parameter placeholders. A null string result will be returned by
+ * this method if no resource bundle has been configured.
+ *
+ * @param locale The requested message Locale, or <code>null</code>
+ * for the system default Locale
+ * @param key The message key to look up
+ * @param args An array of replacement parameters for placeholders
+ */
+ public String getMessage(Locale locale, String key, Object args[]) {
+
+ // Cache MessageFormat instances as they are accessed
+ if (locale == null) {
+ locale = defaultLocale;
+ }
+
+ MessageFormat format = null;
+ String formatKey = messageKey(locale, key);
+
+ synchronized (formats) {
+ format = (MessageFormat) formats.get(formatKey);
+ if (format == null) {
+ String formatString = getMessage(locale, key);
+
+ if (formatString == null) {
+ return returnNull ? null : ("???" + formatKey + "???");
+ }
+
+ format = new MessageFormat(escape(formatString));
+ formats.put(formatKey, format);
+ }
+
+ }
+
+ return format.format(args);
+ }
+
+ /**
+ * Returns a text message after parametric replacement of the specified
+ * parameter placeholders. A null string result will never be returned
+ * by this method.
+ *
+ * @param locale The requested message Locale, or <code>null</code>
+ * for the system default Locale
+ * @param key The message key to look up
+ * @param arg0 The replacement for placeholder {0} in the message
+ */
+ public String getMessage(Locale locale, String key, Object arg0) {
+ return this.getMessage(locale, key, new Object[] { arg0 });
+ }
+
+ /**
+ * Returns a text message after parametric replacement of the specified
+ * parameter placeholders. A null string result will never be returned
+ * by this method.
+ *
+ * @param locale The requested message Locale, or <code>null</code>
+ * for the system default Locale
+ * @param key The message key to look up
+ * @param arg0 The replacement for placeholder {0} in the message
+ * @param arg1 The replacement for placeholder {1} in the message
+ */
+ public String getMessage(Locale locale, String key, Object arg0, Object arg1) {
+ return this.getMessage(locale, key, new Object[] { arg0, arg1 });
+ }
+
+ /**
+ * Returns a text message after parametric replacement of the specified
+ * parameter placeholders. A null string result will never be returned
+ * by this method.
+ *
+ * @param locale The requested message Locale, or <code>null</code>
+ * for the system default Locale
+ * @param key The message key to look up
+ * @param arg0 The replacement for placeholder {0} in the message
+ * @param arg1 The replacement for placeholder {1} in the message
+ * @param arg2 The replacement for placeholder {2} in the message
+ */
+ public String getMessage(
+ Locale locale,
+ String key,
+ Object arg0,
+ Object arg1,
+ Object arg2) {
+
+ return this.getMessage(locale, key, new Object[] { arg0, arg1, arg2 });
+ }
+
+ /**
+ * Returns a text message after parametric replacement of the specified
+ * parameter placeholders. A null string result will never be returned
+ * by this method.
+ *
+ * @param locale The requested message Locale, or <code>null</code>
+ * for the system default Locale
+ * @param key The message key to look up
+ * @param arg0 The replacement for placeholder {0} in the message
+ * @param arg1 The replacement for placeholder {1} in the message
+ * @param arg2 The replacement for placeholder {2} in the message
+ * @param arg3 The replacement for placeholder {3} in the message
+ */
+ public String getMessage(
+ Locale locale,
+ String key,
+ Object arg0,
+ Object arg1,
+ Object arg2,
+ Object arg3) {
+
+ return this.getMessage(locale, key, new Object[] { arg0, arg1, arg2, arg3 });
+ }
+
+ /**
+ * Return <code>true</code> if there is a defined message for the specified
+ * key in the system default locale.
+ *
+ * @param key The message key to look up
+ */
+ public boolean isPresent(String key) {
+
+ return this.isPresent(null, key);
+
+ }
+
+ /**
+ * Return <code>true</code> if there is a defined message for the specified
+ * key in the specified Locale.
+ *
+ * @param locale The requested message Locale, or <code>null</code>
+ * for the system default Locale
+ * @param key The message key to look up
+ */
+ public boolean isPresent(Locale locale, String key) {
+
+ String message = getMessage(locale, key);
+
+ if (message == null) {
+ return false;
+
+ } else if (message.startsWith("???") && message.endsWith("???")) {
+ return false; // FIXME - Only valid for default implementation
+
+ } else {
+ return true;
+ }
+
+ }
+
+ // ------------------------------------------------------ Protected Methods
+
+ /**
+ * Escape any single quote characters that are included in the specified
+ * message string.
+ *
+ * @param string The string to be escaped
+ */
+ protected String escape(String string) {
+
+ if ((string == null) || (string.indexOf('\'') < 0)) {
+ return string;
+ }
+
+ int n = string.length();
+ StringBuffer sb = new StringBuffer(n);
+
+ for (int i = 0; i < n; i++) {
+ char ch = string.charAt(i);
+
+ if (ch == '\'') {
+ sb.append('\'');
+ }
+
+ sb.append(ch);
+ }
+
+ return sb.toString();
+
+ }
+
+ /**
+ * Compute and return a key to be used in caching information by a Locale.
+ * <strong>NOTE</strong> - The locale key for the default Locale in our
+ * environment is a zero length String.
+ *
+ * @param locale The locale for which a key is desired
+ */
+ protected String localeKey(Locale locale) {
+ return (locale == null) ? "" : locale.toString();
+ }
+
+ /**
+ * Compute and return a key to be used in caching information
+ * by Locale and message key.
+ *
+ * @param locale The Locale for which this format key is calculated
+ * @param key The message key for which this format key is calculated
+ */
+ protected String messageKey(Locale locale, String key) {
+
+ return (localeKey(locale) + "." + key);
+
+ }
+
+ /**
+ * Compute and return a key to be used in caching information
+ * by locale key and message key.
+ *
+ * @param localeKey The locale key for which this cache key is calculated
+ * @param key The message key for which this cache key is calculated
+ */
+ protected String messageKey(String localeKey, String key) {
+
+ return (localeKey + "." + key);
+
+ }
+
+ // --------------------------------------------------------- Static Methods
+
+ /**
+ * The default MessageResourcesFactory used to create MessageResources
+ * instances.
+ */
+ protected static MessageResourcesFactory defaultFactory = null;
+
+ /**
+ * Create and return an instance of <code>MessageResources</code> for the
+ * created by the default <code>MessageResourcesFactory</code>.
+ *
+ * @param config Configuration parameter for this message bundle.
+ */
+ public synchronized static MessageResources getMessageResources(String config) {
+
+ if (defaultFactory == null) {
+ defaultFactory = MessageResourcesFactory.createFactory();
+ }
+
+ return defaultFactory.createResources(config);
+ }
+
+ /**
+ * Log a message to the Writer that has been configured for our use.
+ *
+ * @param message The message to be logged
+ */
+ public void log(String message) {
+ log.debug(message);
+ }
+
+ /**
+ * Log a message and exception to the Writer that has been configured
+ * for our use.
+ *
+ * @param message The message to be logged
+ * @param throwable The exception to be logged
+ */
+ public void log(String message, Throwable throwable) {
+ log.debug(message, throwable);
+ }
+
+}
Propchange: struts/sandbox/trunk/tiles/core-library/src/java/org/apache/util/MessageResources.java
------------------------------------------------------------------------------
svn:executable = *
Added: struts/sandbox/trunk/tiles/core-library/src/java/org/apache/util/MessageResourcesFactory.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/tiles/core-library/src/java/org/apache/util/MessageResourcesFactory.java?rev=190662&view=auto
==============================================================================
--- struts/sandbox/trunk/tiles/core-library/src/java/org/apache/util/MessageResourcesFactory.java (added)
+++ struts/sandbox/trunk/tiles/core-library/src/java/org/apache/util/MessageResourcesFactory.java Tue Jun 14 14:59:13 2005
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.util;
+
+import java.io.Serializable;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.tiles.TilesUtil;
+
+
+/**
+ * Factory for <code>MessageResources</code> instances. The general usage
+ * pattern for this class is:
+ * <ul>
+ * <li>Call <code>MessageResourcesFactory().createFactory()</code> to retrieve
+ * a <code>MessageResourcesFactory</code> instance.</li>
+ * <li>Set properties as required to configure this factory instance to create
+ * <code>MessageResources</code> instances with desired
+ * characteristics.</li>
+ * <li>Call the <code>createResources()</code> method of the factory to
+ * retrieve a newly instantiated <code>MessageResources</code>
+ * instance.</li>
+ * </ul>
+ *
+ * @author Craig R. McClanahan
+ * @author David Geary
+ * @version $Revision: 1.8 $ $Date: 2002/10/17 03:20:31 $
+ */
+
+public abstract class MessageResourcesFactory implements Serializable {
+
+
+ // ---------------------------------------------------- Instance Properties
+
+
+ /**
+ * The "return null" property value to which newly created
+ * MessageResourcess should be initialized.
+ */
+ protected boolean returnNull = true;
+
+ /**
+ * Get default value of the "returnNull" property used to initialize newly created
+ * MessageResourcess.
+ * @return default value of the "returnNull" property newly created
+ * MessageResourcess are initialized to.
+ */
+ public boolean getReturnNull() {
+ return (this.returnNull);
+ }
+
+ /**
+ * Set the default value of the "returnNull" property newly created
+ * MessageResourcess are initialized to.
+ * @param returnNull default value of the "returnNull" MessageResourcess are initialized to.
+ */
+ public void setReturnNull(boolean returnNull) {
+ this.returnNull = returnNull;
+ }
+
+
+ // --------------------------------------------------------- Public Methods
+
+
+ /**
+ * Create and return a newly instansiated <code>MessageResources</code>.
+ * This method must be implemented by concrete subclasses.
+ *
+ * @param config Configuration parameter(s) for the requested bundle
+ */
+ public abstract MessageResources createResources(String config);
+
+
+ // ------------------------------------------------------ Static Properties
+
+
+ /**
+ * The Java class to be used for
+ * <code>MessageResourcesFactory</code> instances.
+ */
+ protected static transient Class clazz = null;
+
+
+ /**
+ * Commons Logging instance.
+ */
+ private static Log LOG = LogFactory.getLog(MessageResourcesFactory.class);
+
+
+ /**
+ * The fully qualified class name to be used for
+ * <code>MessageResourcesFactory</code> instances.
+ */
+ protected static String factoryClass =
+ "org.apache.util.PropertyMessageResourcesFactory";
+
+ /**
+ * The fully qualified class name that is used for
+ * <code>MessageResourcesFactory</code> instances.
+ * @return class name that is used for
+ * <code>MessageResourcesFactory</code> instances
+ */
+ public static String getFactoryClass() {
+ return (MessageResourcesFactory.factoryClass);
+ }
+
+ /**
+ * Set the fully qualified class name that is used for
+ * <code>MessageResourcesFactory</code> instances.
+ * @param factoryClass name that is used for
+ * <code>MessageResourcesFactory</code> instances
+ */
+ public static void setFactoryClass(String factoryClass) {
+ MessageResourcesFactory.factoryClass = factoryClass;
+ MessageResourcesFactory.clazz = null;
+ }
+
+
+ // --------------------------------------------------------- Static Methods
+
+
+ /**
+ * Create and return a <code>MessageResourcesFactory</code> instance of the
+ * appropriate class, which can be used to create customized
+ * <code>MessageResources</code> instances. If no such factory can be
+ * created, return <code>null</code> instead.
+ */
+ public static MessageResourcesFactory createFactory() {
+
+ // Construct a new instance of the specified factory class
+ try {
+ if (clazz == null)
+ clazz = TilesUtil.applicationClass(factoryClass);
+ MessageResourcesFactory factory =
+ (MessageResourcesFactory) clazz.newInstance();
+ return (factory);
+ } catch (Throwable t) {
+ LOG.error("MessageResourcesFactory.createFactory", t);
+ return (null);
+ }
+
+ }
+
+
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org