001: /*
002: * $Id: FactorySet.java 471754 2006-11-06 14:55:09Z husted $
003: *
004: * Licensed to the Apache Software Foundation (ASF) under one
005: * or more contributor license agreements. See the NOTICE file
006: * distributed with this work for additional information
007: * regarding copyright ownership. The ASF licenses this file
008: * to you under the Apache License, Version 2.0 (the
009: * "License"); you may not use this file except in compliance
010: * with the License. You may obtain a copy of the License at
011: *
012: * http://www.apache.org/licenses/LICENSE-2.0
013: *
014: * Unless required by applicable law or agreed to in writing,
015: * software distributed under the License is distributed on an
016: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017: * KIND, either express or implied. See the License for the
018: * specific language governing permissions and limitations
019: * under the License.
020: */
021:
022: package org.apache.struts.tiles.xmlDefinition;
023:
024: import java.util.HashMap;
025: import java.util.Iterator;
026: import java.util.Map;
027:
028: import javax.servlet.ServletContext;
029: import javax.servlet.ServletRequest;
030:
031: import org.apache.struts.tiles.ComponentDefinition;
032: import org.apache.struts.tiles.ComponentDefinitionsFactory;
033: import org.apache.struts.tiles.DefinitionsFactoryException;
034: import org.apache.struts.tiles.FactoryNotFoundException;
035: import org.apache.struts.tiles.NoSuchDefinitionException;
036:
037: /**
038: * Component Definitions factory.
039: * This factory contains several factories identified by a key. The
040: * getDefinition() method first looks for the factory key, retrieves or creates this
041: * factory and then calls its getDefinition().
042: */
043: public abstract class FactorySet implements ComponentDefinitionsFactory {
044:
045: /** Loaded factories */
046: protected Map factories = null;
047:
048: /**
049: * Extract key that will be used to get the sub factory.
050: * @param name Name of requested definition.
051: * @param request Current servlet request.
052: * @param servletContext Current servlet context.
053: * @return Object.
054: */
055: abstract protected Object getDefinitionsFactoryKey(String name,
056: ServletRequest request, ServletContext servletContext);
057:
058: /**
059: * Get default factory.
060: * @return Default factory.
061: */
062: abstract protected DefinitionsFactory getDefaultFactory();
063:
064: /**
065: * Get a factory by its key.
066: * If key is <code>null</code>, return defaultFactory.
067: * Search in loaded factories. If not found, create factory and store return value in
068: * loaded factories.
069: * @param key Key of requested definition.
070: * @param request Current servlet request.
071: * @param servletContext Current servlet context.
072: * @throws DefinitionsFactoryException If an error occur while creating factory.
073: */
074: protected DefinitionsFactory getFactory(Object key,
075: ServletRequest request, ServletContext servletContext)
076: throws DefinitionsFactoryException {
077: if (key == null)
078: return getDefaultFactory();
079:
080: Object factory = factories.get(key);
081: if (factory == null) {
082: // synchronize creation to avoid double creation by separate threads.
083: // Also, check if factory hasn't been created while waiting for synchronized
084: // section.
085: synchronized (factories) {
086: factory = factories.get(key);
087: if (factory == null) {
088: factory = createFactory(key, request,
089: servletContext);
090: factories.put(key, factory);
091: } // end if
092: } // end synchronized
093: } // end if
094: return (DefinitionsFactory) factory;
095: }
096:
097: /**
098: * Get a definition by its name.
099: *
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,
107: ServletRequest request, ServletContext servletContext)
108: throws NoSuchDefinitionException,
109: DefinitionsFactoryException {
110: if (factories == null)
111: throw new FactoryNotFoundException(
112: "No definitions factory defined");
113:
114: Object key = getDefinitionsFactoryKey(name, request,
115: servletContext);
116: DefinitionsFactory factory = getFactory(key, request,
117: servletContext);
118: return factory.getDefinition(name, request, servletContext);
119: }
120:
121: /**
122: * Create a factory for specified key.
123: * This method is called by getFactory() when the requested factory doesn't already exist.
124: * Must return a factory, or a default one.
125: * Real implementation needs to provide this method.
126: * @param key Key of requested definition.
127: * @param request Current servlet request.
128: * @param servletContext Current servlet context
129: * @throws DefinitionsFactoryException If an error occur while creating factory.
130: */
131: abstract protected DefinitionsFactory createFactory(Object key,
132: ServletRequest request, ServletContext servletContext)
133: throws DefinitionsFactoryException;
134:
135: /**
136: * Init factory set.
137: * @param servletContext Current servlet context
138: * @param properties properties used to initialized factory set;
139: */
140: abstract public void initFactory(ServletContext servletContext,
141: Map properties) throws DefinitionsFactoryException;
142:
143: /**
144: * Constructor.
145: */
146: public FactorySet() {
147: factories = new HashMap();
148: }
149:
150: /**
151: * Return String representation.
152: * @return String representation.
153: */
154: public String toString() {
155: Iterator i = factories.values().iterator();
156: StringBuffer buff = new StringBuffer(
157: "all FactorySet's factory : \n");
158: while (i.hasNext()) {
159: buff.append(i.next().toString()).append("\n");
160: }
161: return buff.toString();
162: }
163:
164: }
|