View Javadoc

1   /*
2    * $Id: FactorySet.java 421151 2006-07-12 06:07:14Z wsmoak $
3    *
4    * Copyright 1999-2004 The Apache Software Foundation.
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *      http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  
20  package org.apache.struts.tiles.xmlDefinition;
21  
22  import java.util.HashMap;
23  import java.util.Iterator;
24  import java.util.Map;
25  
26  import javax.servlet.ServletContext;
27  import javax.servlet.ServletRequest;
28  
29  import org.apache.struts.tiles.ComponentDefinition;
30  import org.apache.struts.tiles.ComponentDefinitionsFactory;
31  import org.apache.struts.tiles.DefinitionsFactoryException;
32  import org.apache.struts.tiles.FactoryNotFoundException;
33  import org.apache.struts.tiles.NoSuchDefinitionException;
34  
35  /***
36   * Component Definitions factory.
37   * This factory contains several factories identified by a key. The
38   * getDefinition() method first looks for the factory key, retrieves or creates this
39   * factory and then calls its getDefinition().
40   */
41  public abstract class FactorySet implements ComponentDefinitionsFactory
42  {
43  
44      /*** Loaded factories */
45    protected Map factories=null;
46  
47    /***
48     * Extract key that will be used to get the sub factory.
49     * @param name Name of requested definition.
50     * @param request Current servlet request.
51     * @param servletContext Current servlet context.
52     * @return Object.
53     */
54    abstract protected Object getDefinitionsFactoryKey(String name, ServletRequest request, ServletContext servletContext);
55  
56    /***
57     * Get default factory.
58     * @return Default factory.
59     */
60    abstract protected DefinitionsFactory getDefaultFactory();
61  
62    /***
63     * Get a factory by its key.
64     * If key is <code>null</code>, return defaultFactory.
65     * Search in loaded factories. If not found, create factory and store return value in
66     * loaded factories.
67     * @param key Key of requested definition.
68     * @param request Current servlet request.
69     * @param servletContext Current servlet context.
70     * @throws DefinitionsFactoryException If an error occur while creating factory.
71     */
72    protected DefinitionsFactory getFactory(Object key, ServletRequest request, ServletContext servletContext)
73      throws DefinitionsFactoryException
74    {
75    if(key == null )
76      return getDefaultFactory();
77  
78    Object factory = factories.get( key );
79    if( factory == null )
80      {
81        // synchronize creation to avoid double creation by separate threads.
82        // Also, check if factory hasn't been created while waiting for synchronized
83        // section.
84      synchronized(factories)
85        {
86        factory = factories.get( key );
87        if( factory == null )
88          {
89          factory = createFactory( key, request, servletContext);
90          factories.put( key, factory );
91          } // end if
92        } // end synchronized
93      } // end if
94    return (DefinitionsFactory)factory;
95    }
96  
97    /***
98     * Get a definition by its name.
99     *
100    * @param name Name of requested definition.
101    * @param request Current servlet request.
102    * @param servletContext Current servlet context.
103    * @throws NoSuchDefinitionException No definition found for specified name
104    * @throws DefinitionsFactoryException General exception
105    */
106   public ComponentDefinition getDefinition(String name, ServletRequest request, ServletContext servletContext)
107     throws NoSuchDefinitionException, DefinitionsFactoryException
108   {
109   if( factories == null )
110     throw new FactoryNotFoundException( "No definitions factory defined" );
111 
112   Object key = getDefinitionsFactoryKey( name, request, servletContext);
113   DefinitionsFactory factory = getFactory( key, request, servletContext);
114   return factory.getDefinition( name, request, servletContext );
115   }
116 
117   /***
118    * Create a factory for specified key.
119    * This method is called by getFactory() when the requested factory doesn't already exist.
120    * Must return a factory, or a default one.
121    * Real implementation needs to provide this method.
122    * @param key Key of requested definition.
123    * @param request Current servlet request.
124    * @param servletContext Current servlet context
125    * @throws DefinitionsFactoryException If an error occur while creating factory.
126    */
127   abstract protected DefinitionsFactory createFactory(Object key, ServletRequest request, ServletContext servletContext)
128           throws DefinitionsFactoryException;
129 
130   /***
131    * Init factory set.
132    * @param servletContext Current servlet context
133    * @param properties properties used to initialized factory set;
134    */
135   abstract public void initFactory(ServletContext servletContext, Map properties)
136     throws DefinitionsFactoryException;
137 
138   /***
139    * Constructor.
140    */
141   public FactorySet()
142   {
143   factories = new HashMap();
144   }
145 
146     /***
147      * Return String representation.
148      * @return String representation.
149      */
150   public String toString()
151     {
152     Iterator i = factories.values().iterator();
153     StringBuffer buff = new StringBuffer( "all FactorySet's factory : \n" );
154     while( i.hasNext() )
155       {
156       buff.append( i.next().toString() ).append("\n");
157       }
158     return buff.toString();
159     }
160 
161 }