001: /*
002: * ====================================================================
003: * JAFFA - Java Application Framework For All
004: *
005: * Copyright (C) 2002 JAFFA Development Group
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2.1 of the License, or (at your option) any later version.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this library; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020: *
021: * Redistribution and use of this software and associated documentation ("Software"),
022: * with or without modification, are permitted provided that the following conditions are met:
023: * 1. Redistributions of source code must retain copyright statements and notices.
024: * Redistributions must also contain a copy of this document.
025: * 2. Redistributions in binary form must reproduce the above copyright notice,
026: * this list of conditions and the following disclaimer in the documentation
027: * and/or other materials provided with the distribution.
028: * 3. The name "JAFFA" must not be used to endorse or promote products derived from
029: * this Software without prior written permission. For written permission,
030: * please contact mail to: jaffagroup@yahoo.com.
031: * 4. Products derived from this Software may not be called "JAFFA" nor may "JAFFA"
032: * appear in their names without prior written permission.
033: * 5. Due credit should be given to the JAFFA Project (http://jaffa.sourceforge.net).
034: *
035: * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
036: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
037: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
038: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
039: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
040: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
041: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
042: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
043: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
044: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
045: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
046: * SUCH DAMAGE.
047: * ====================================================================
048: */
049:
050: package org.jaffa.presentation.portlet.component;
051:
052: import org.apache.log4j.Logger;
053: import org.jaffa.presentation.portlet.session.UserSession;
054: import org.jaffa.presentation.portlet.component.componentdomain.Loader;
055: import java.util.Map;
056: import java.util.HashMap;
057: import java.util.Iterator;
058: import org.jaffa.security.SecurityManager;
059: import java.security.AccessControlException;
060:
061: /** This is a Factory for creating Component instances
062: */
063: public class ComponentManager {
064: private static Logger log = Logger
065: .getLogger(ComponentManager.class);
066:
067: // This field will hold a cache of ComponentDefinitions
068: private static Map c_componentPool = null;
069:
070: /** Creates an instance of the named component. This component is then added to the UserSession. This may throw the runtime ComponentCreationRuntimeException
071: * @param comp The name of the component to create. There should be a valid definition for this name in the 'components.xml' file
072: * @param us The UserSession to which this component will be added
073: * @return An instance of the Component
074: */
075: public static Component run(String comp, UserSession us) {
076: try {
077:
078: // see if this user has access to this component
079: if (!SecurityManager.checkComponentAccess(comp))
080: throw new AccessControlException(
081: "No Access To Component " + comp);
082:
083: //Find the Definition
084: ComponentDefinition cd = find(comp);
085:
086: // Get the ClassObject of the component
087: Class clazz = Class.forName(cd.getComponentClass());
088:
089: // Create an instance of the component
090: Component compInst = (Component) clazz.newInstance();
091: compInst.setComponentId(us.getNextComponentId());
092: compInst.setComponentDefinition(cd);
093: compInst.setUserSession(us);
094:
095: // Add the component to the UserSession
096: us.addComponent(compInst);
097: return compInst;
098: } catch (ClassNotFoundException e) {
099: String str = "Error in running the Component " + comp;
100: log.error(str, e);
101: throw new ComponentCreationRuntimeException(str, e);
102: } catch (InstantiationException e) {
103: String str = "Error in running the Component " + comp;
104: log.error(str, e);
105: throw new ComponentCreationRuntimeException(str, e);
106: } catch (IllegalAccessException e) {
107: String str = "Error in running the Component " + comp;
108: log.error(str, e);
109: throw new ComponentCreationRuntimeException(str, e);
110: }
111: }
112:
113: /** Locate the named component. This routine uses a cache of ComponentDefinitions.
114: * If the cache has not been initialized, this will initialize it by reading in
115: * and XML file into the component domain objects (via JAXB), and then create a
116: * pool of component definition objects.
117: *
118: * If the specified component id not found this throws a ComponentCreationRuntimeException
119: */
120: public static ComponentDefinition find(String comp) {
121:
122: // Make sure the pool is loaded
123: if (c_componentPool == null) {
124: c_componentPool = Loader.buildComponentPool();
125:
126: // Bail if the pool did not get loaded
127: if (c_componentPool == null) {
128: log
129: .error("Failed to build the ComponentDefinition cache");
130: } else {
131: if (log.isDebugEnabled()) {
132: log.debug("Loaded Component Definitions - Total="
133: + c_componentPool.size());
134: }
135: }
136: }
137:
138: if (c_componentPool.containsKey(comp))
139: return (ComponentDefinition) c_componentPool.get(comp);
140: else {
141: // Not Found
142: String str = "No ComponentDefinition found for " + comp;
143: log.error(str);
144: throw new ComponentCreationRuntimeException(str);
145: }
146: }
147:
148: /** Get the component requirements, this is Map of mandatory business functions
149: * that a user must have access to, to run this component. Each entry in the map is a
150: * component and its 'required' functions is stored as the 'value'. The 'value' is stored
151: * as and Array([]) of Strings .
152: * If there is no entry in the map for a given a component, it has no required business functions
153: * and is there for not constrained by the security system.
154: * @return a Map containing component requirements.
155: */
156: public static Map getComponentRequirements() {
157: HashMap m = new HashMap();
158:
159: // Make sure the pool is loaded
160: if (c_componentPool == null) {
161: c_componentPool = Loader.buildComponentPool();
162: // Bail if the pool did not get loaded
163: if (c_componentPool == null) {
164: log
165: .error("Failed to build the ComponentDefinition cache");
166: return m;
167: }
168:
169: if (log.isDebugEnabled()) {
170: log.debug("Loaded Component Definitions - Total="
171: + c_componentPool.size());
172: }
173: }
174:
175: // Loop through all the definitions, add only ones with required functions
176: for (Iterator it = c_componentPool.keySet().iterator(); it
177: .hasNext();) {
178: String comp = (String) it.next();
179: String[] funcs = ((ComponentDefinition) c_componentPool
180: .get(comp)).getMandatoryFunctions();
181: // Add this component to the list.
182: if (funcs != null && funcs.length != 0)
183: m.put(comp, funcs);
184: }
185:
186: return m;
187: }
188: }
|