org.apache.tiles.definition.UrlDefinitionsFactory.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.tiles.definition.UrlDefinitionsFactory.java

Source

/*
 * $Id: UrlDefinitionsFactory.java 734996 2009-01-16 13:27:28Z apetrelli $
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.definition;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.tiles.Definition;
import org.apache.tiles.context.TilesRequestContext;
import org.apache.tiles.definition.dao.DefinitionDAO;
import org.apache.tiles.definition.dao.ResolvingLocaleUrlDefinitionDAO;
import org.apache.tiles.definition.dao.URLReader;
import org.apache.tiles.impl.BasicTilesContainer;
import org.apache.tiles.util.LocaleUtil;

import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.StringTokenizer;

/**
 * {@link DefinitionsFactory DefinitionsFactory} implementation that manages
 * Definitions configuration data from URLs, resolving inheritance when the URL
 * is loaded. <p/>
 * <p>
 * The Definition objects are read from the
 * {@link org.apache.tiles.definition.digester.DigesterDefinitionsReader DigesterDefinitionsReader}
 * class unless another implementation is specified.
 * </p>
 *
 * @version $Rev: 734996 $ $Date: 2009-01-16 14:27:28 +0100 (Fri, 16 Jan 2009) $
 */
public class UrlDefinitionsFactory extends LocaleDefinitionsFactory implements Refreshable {

    /**
     * Compatibility constant.
     *
     * @deprecated use {@link DEFINITIONS_CONFIG} to avoid namespace collisions.
     */
    private static final String LEGACY_DEFINITIONS_CONFIG = "definitions-config";

    /**
     * LOG instance for all UrlDefinitionsFactory instances.
     */
    private final Log log = LogFactory.getLog(UrlDefinitionsFactory.class);

    /**
     * Contains the URL objects identifying where configuration data is found.
     *
     * @deprecated Use {@link #sourceURLs}.
     */
    protected List<Object> sources;

    /**
     * Reader used to get definitions from the sources.
     *
     * @deprecated No more used.
     */
    protected DefinitionsReader reader;

    /**
     * Contains the dates that the URL sources were last modified.
     *
     * @deprecated No more used.
     */
    protected Map<String, Long> lastModifiedDates;

    /**
     * Returns a Definition object that matches the given name and
     * Tiles context.
     *
     * @param name         The name of the Definition to return.
     * @param tilesContext The Tiles context to use to resolve the definition.
     * @return the Definition matching the given name or null if none
     *         is found.
     * @throws DefinitionsFactoryException if an error occurs reading definitions.
     */
    @Override
    public Definition getDefinition(String name, TilesRequestContext tilesContext) {

        Locale locale = localeResolver.resolveLocale(tilesContext);

        return definitionDao.getDefinition(name, locale);
    }

    /** {@inheritDoc} */
    public synchronized void refresh() {
        log.debug("Updating Tiles definitions. . .");
        if (definitionDao instanceof Refreshable) {
            ((Refreshable) definitionDao).refresh();
        }
    }

    /**
     * Indicates whether the DefinitionsFactory is out of date and needs to be
     * reloaded.
     *
     * @return If the factory needs refresh.
     */
    public boolean refreshRequired() {
        return (definitionDao instanceof RefreshMonitor) && ((RefreshMonitor) definitionDao).refreshRequired();
    }

    /**
     * Indicates whether a given context has been processed or not.
     * <p/>
     * This method can be used to avoid unnecessary synchronization of the
     * DefinitionsFactory in multi-threaded situations.  Check the return of
     * isContextProcessed before synchronizing the object and reading
     * locale-specific definitions.
     *
     * @param tilesContext The Tiles context to check.
     * @return true if the given context has been processed and false otherwise.
     * @deprecated It always return <code>true</code>.
     */
    @Deprecated
    protected boolean isContextProcessed(TilesRequestContext tilesContext) {
        return true;
    }

    /**
     * Adds a source where Definition objects are stored.
     * <p/>
     * Implementations should publish what type of source object they expect.
     * The source should contain enough information to resolve a configuration
     * source containing definitions.  The source should be a "base" source for
     * configurations.  Internationalization and Localization properties will be
     * applied by implementations to discriminate the correct data sources based
     * on locale.
     *
     * @param source The configuration source for definitions.
     * @throws DefinitionsFactoryException if an invalid source is passed in or
     *                                     an error occurs resolving the source to an actual data store.
     * @deprecated Use {@link URLReader#addSourceURL(URL)}.
     */
    public void addSource(Object source) {
        if (source == null) {
            throw new DefinitionsFactoryException("Source object must not be null");
        }

        if (!(source instanceof URL)) {
            throw new DefinitionsFactoryException("Source object must be an URL");
        }

        if (definitionDao instanceof URLReader) {
            ((URLReader) definitionDao).addSourceURL((URL) source);
        }
    }

    /** {@inheritDoc} */
    @Override
    protected DefinitionDAO<Locale> createDefaultDefinitionDAO() {
        return new ResolvingLocaleUrlDefinitionDAO();
    }

    /**
     * Creates and returns a {@link Definitions} set by reading
     * configuration data from the applied sources.
     *
     * @return The definitions holder object, filled with base definitions.
     * @throws DefinitionsFactoryException if an error occurs reading the
     * sources.
     * @deprecated Let the Definitions Factory use it.
     */
    @Deprecated
    public Definitions readDefinitions() {
        return new CompatibilityDefinitionsImpl(definitionDao);
    }

    /**
     * Returns the definitions holder object.
     *
     * @return The definitions holder.
     * @deprecated Do not use! Deprecated with no replacement.
     */
    @Deprecated
    protected Definitions getDefinitions() {
        return new CompatibilityDefinitionsImpl(definitionDao);
    }

    /**
     * Appends locale-specific {@link Definition} objects to an existing
     * {@link Definitions} set by reading locale-specific versions of
     * the applied sources.
     *
     * @param definitions  The Definitions object to append to.
     * @param tilesContext The requested locale.
     * @throws DefinitionsFactoryException if an error occurs reading definitions.
     * @deprecated Let the definitions be loaded by a {@link DefinitionDAO}.
     */
    @Deprecated
    protected void addDefinitions(Definitions definitions, TilesRequestContext tilesContext) {
        Locale locale = localeResolver.resolveLocale(tilesContext);
        Map<String, Definition> defsMap = definitionDao.getDefinitions(locale);
        if (defsMap == null) {
            throw new NullPointerException("There are no definitions mapped to locale '" + locale.toString() + "'");
        }
    }

    /**
     * Creates a new instance of <code>Definitions</code>. Override this method
     * 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 CompatibilityDefinitionsImpl(definitionDao);
    }

    /**
     * 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.
     * @deprecated Use {@link LocaleUtil#concatPostfix(String,String)} instead
     */
    protected static String concatPostfix(String name, String postfix) {
        return LocaleUtil.concatPostfix(name, postfix);
    }

    /**
     * Calculate the postfixes along the search path from the base bundle to the
     * bundle specified by baseName and locale.
     * Method copied from java.util.ResourceBundle
     *
     * @param locale the locale
     * @return a list of
     * @deprecated Use {@link LocaleUtil#calculatePostfixes(Locale)} instead.
     */
    protected static List<String> calculatePostfixes(Locale locale) {
        return LocaleUtil.calculatePostfixes(locale);
    }

    /**
     * Derive the resource string from the initialization parameters. If no
     * parameter {@link DefinitionsFactory#DEFINITIONS_CONFIG} is available,
     * attempts to retrieve {@link BasicTilesContainer#DEFINITIONS_CONFIG} and
     * {@link UrlDefinitionsFactory#LEGACY_DEFINITIONS_CONFIG}. If neither are
     * available, returns "/WEB-INF/tiles.xml".
     *
     * @param parms The initialization parameters.
     * @return resource string to be parsed.
     * @deprecated Deprecated without replacement.
     */
    @Deprecated
    protected String getResourceString(Map<String, String> parms) {
        String resourceStr = parms.get(DefinitionsFactory.DEFINITIONS_CONFIG);
        if (resourceStr == null) {
            resourceStr = parms.get(BasicTilesContainer.DEFINITIONS_CONFIG);
        }
        if (resourceStr == null) {
            resourceStr = parms.get(UrlDefinitionsFactory.LEGACY_DEFINITIONS_CONFIG);
        }
        if (resourceStr == null) {
            resourceStr = "/WEB-INF/tiles.xml";
        }
        return resourceStr;
    }

    /**
     * Parse the resourceString into a list of resource paths
     * which can be loaded by the application context.
     *
     * @param resourceString comma seperated resources
     * @return parsed resources
     * @deprecated Deprecated without replacement.
     */
    @Deprecated
    protected List<String> getResourceNames(String resourceString) {
        StringTokenizer tokenizer = new StringTokenizer(resourceString, ",");
        List<String> filenames = new ArrayList<String>(tokenizer.countTokens());
        while (tokenizer.hasMoreTokens()) {
            filenames.add(tokenizer.nextToken().trim());
        }
        return filenames;
    }

    /**
     * {@link Definitions} implementation that uses a {@link DefinitionDAO}.
     *
     * @since 2.1.0
     * @deprecated Here only for compatibility reasons.
     */
    @Deprecated
    private static final class CompatibilityDefinitionsImpl implements Definitions {

        /**
         * The definition DAO to use.
         *
         * @since 2.1.0
         */
        private DefinitionDAO<Locale> definitionDao;

        /**
         * Constructor.
         *
         * @param definitionDao The definition DAO to use.
         * @since 2.1.0
         */
        public CompatibilityDefinitionsImpl(DefinitionDAO<Locale> definitionDao) {
            this.definitionDao = definitionDao;
        }

        /** {@inheritDoc} */
        public void addDefinitions(Map<String, Definition> defsMap) {
            Map<String, Definition> definitions = definitionDao.getDefinitions(null);
            if (definitions == null) {
                throw new NullPointerException("No definitions loaded for default locale");
            }
            definitions.putAll(defsMap);
        }

        /** {@inheritDoc} */
        public void addDefinitions(Map<String, Definition> defsMap, Locale locale) {
            Map<String, Definition> definitions = definitionDao.getDefinitions(locale);
            if (definitions == null) {
                throw new NullPointerException("No definitions loaded for locale '" + locale.toString() + "'");
            }
            definitions.putAll(defsMap);
        }

        /** {@inheritDoc} */
        public Map<String, Definition> getBaseDefinitions() {
            return definitionDao.getDefinitions(null);
        }

        /** {@inheritDoc} */
        public Definition getDefinition(String name) {
            return definitionDao.getDefinition(name, null);
        }

        /** {@inheritDoc} */
        public Definition getDefinition(String name, Locale locale) {
            return definitionDao.getDefinition(name, locale);
        }

        /** {@inheritDoc} */
        public void reset() {
            if (definitionDao instanceof Refreshable) {
                ((Refreshable) definitionDao).refresh();
            }
        }

        /** {@inheritDoc} */
        public void resolveInheritances() {
            // Does nothing.
        }

        /** {@inheritDoc} */
        public void resolveInheritances(Locale locale) {
            // Does nothing.
        }
    }
}