Source code: org/apache/struts/tiles/xmlDefinition/FactorySet.java
1 /*
2 * $Id: FactorySet.java 54929 2004-10-16 16:38:42Z germuska $
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 }