/*
 * 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.ComponentDefinitionsFactory;
import org.apache.tiles.ComponentDefinition;
import org.apache.tiles.NoSuchDefinitionException;
import org.apache.tiles.DefinitionsFactoryException;
import org.apache.tiles.FactoryNotFoundException;

import javax.servlet.ServletContext;
import javax.servlet.ServletRequest;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * Component Definitions factory.
 * This factory contains several factories identified by a key. The
 * getDefinition() method first looks for the factory key, retrieves or creates this
 * factory and then calls its getDefinition().
 */
public abstract class FactorySet implements ComponentDefinitionsFactory
{

    /** Loaded factories */
  protected Map factories=null;

  /**
   * 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 Object.
   */
  abstract protected Object getDefinitionsFactoryKey(String name, ServletRequest request, ServletContext servletContext);

  /**
   * Get default factory.
   * @return Default factory.
   */
  abstract protected DefinitionsFactory getDefaultFactory();

  /**
   * Get a factory by its key.
   * If key is <code>null</code>, return defaultFactory.
   * Search in loaded factories. If not found, create factory and store return value in
   * loaded factories.
   * @param key Key of requested definition.
   * @param request Current servlet request.
   * @param servletContext Current servlet context.
   * @throws DefinitionsFactoryException If an error occur while creating factory.
   */
  protected DefinitionsFactory getFactory(Object key, ServletRequest request, ServletContext servletContext)
    throws DefinitionsFactoryException
  {
  if(key == null )
    return getDefaultFactory();

  Object factory = factories.get( key );
  if( factory == null )
    {
      // synchronize creation to avoid double creation by separate threads.
      // Also, check if factory hasn't been created while waiting for synchronized
      // section.
    synchronized(factories)
      {
      factory = factories.get( key );
      if( factory == null )
        {
        factory = createFactory( key, request, servletContext);
        factories.put( key, factory );
        } // end if
      } // end synchronized
    } // end if
  return (DefinitionsFactory)factory;
  }

  /**
   * Get a definition by its name.
   *
   * @param name Name of requested definition.
   * @param request Current servlet request.
   * @param servletContext Current servlet context.
   * @throws NoSuchDefinitionException No definition found for specified name
   * @throws DefinitionsFactoryException General exception
   */
  public ComponentDefinition getDefinition(String name, ServletRequest request, ServletContext servletContext)
    throws NoSuchDefinitionException, DefinitionsFactoryException
  {
  if( factories == null )
    throw new FactoryNotFoundException( "No definitions factory defined" );

  Object key = getDefinitionsFactoryKey( name, request, servletContext);
  DefinitionsFactory factory = getFactory( key, request, servletContext);
  return factory.getDefinition( name, request, servletContext );
  }

  /**
   * Create a factory for specified key.
   * This method is called by getFactory() when the requested factory doesn't already exist.
   * Must return a factory, or a default one.
   * Real implementation needs to provide this method.
   * @param key Key of requested definition.
   * @param request Current servlet request.
   * @param servletContext Current servlet context
   * @throws DefinitionsFactoryException If an error occur while creating factory.
   */
  abstract protected DefinitionsFactory createFactory(Object key, ServletRequest request, ServletContext servletContext)
          throws DefinitionsFactoryException;

  /**
   * Init factory set.
   * @param servletContext Current servlet context
   * @param properties properties used to initialized factory set;
   */
  abstract public void initFactory(ServletContext servletContext, Map properties)
    throws DefinitionsFactoryException;

  /**
   * Constructor.
   */
  public FactorySet()
  {
  factories = new HashMap();
  }

    /**
     * Return String representation.
     * @return String representation.
     */
  public String toString()
    {
    Iterator i = factories.values().iterator();
    StringBuffer buff = new StringBuffer( "all FactorySet's factory : \n" );
    while( i.hasNext() )
      {
      buff.append( i.next().toString() ).append("\n");
      }
    return buff.toString();
    }

}
