001: /*
002: * This file is part of PFIXCORE.
003: *
004: * PFIXCORE is free software; you can redistribute it and/or modify
005: * it under the terms of the GNU Lesser General Public License as published by
006: * the Free Software Foundation; either version 2 of the License, or
007: * (at your option) any later version.
008: *
009: * PFIXCORE is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: * GNU Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public License
015: * along with PFIXCORE; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: *
018: */
019:
020: package de.schlund.pfixcore.workflow.app;
021:
022: import java.util.HashSet;
023: import java.util.Iterator;
024: import java.util.Properties;
025:
026: import de.schlund.pfixcore.generator.IHandler;
027: import de.schlund.pfixcore.generator.IHandlerFactory;
028: import de.schlund.pfixcore.workflow.Context;
029: import de.schlund.pfixxml.config.IWrapperConfig;
030: import de.schlund.pfixxml.config.PageRequestConfig;
031: import de.schlund.pfixxml.perflogging.PerfEvent;
032: import de.schlund.pfixxml.perflogging.PerfEventType;
033:
034: /**
035: * This class is a default implementation of the <code>IHandlerContainer</code> interface.
036: * <br/>
037: *
038: * Created: Thu Apr 18 13:49:36 2002
039: *
040: * @author <a href="mailto:jtl@schlund.de">Jens Lautenbacher</a>
041: *
042: *
043: */
044:
045: public class IHandlerSimpleContainer implements IHandlerContainer {
046: /** Store all created handlers here*/
047: private HashSet<IHandler> handlers;
048: /** Store all handlers here which do not have a 'ihandlercontainer.ignore' property*/
049: private HashSet<IHandler> activeset;
050:
051: private String policy;
052:
053: public static final String PROP_CONTAINER = "ihandlercontainer";
054: private static final String PROP_POLICY = PROP_CONTAINER
055: + ".policy";
056:
057: // private static Logger LOG = Logger.getLogger(IHandlerSimpleContainer.class);
058:
059: // implementation of de.schlund.pfixcore.workflow.app.IHandlerContainer interface
060:
061: /**
062: * Initialize the IHandlers. Get the handlers from {@link IHandlerFactory}
063: * and store them.
064: * @param props the properties containing the interface names
065: * @see de.schlund.pfixcore.workflow.app.IHandlerContainer#initIHandlers(Properties)
066: */
067: public void initIHandlers(PageRequestConfig config) {
068: handlers = new HashSet<IHandler>();
069: activeset = new HashSet<IHandler>();
070:
071: if (config.getIWrapperPolicy() == PageRequestConfig.Policy.ALL) {
072: this .policy = "ALL";
073: } else if (config.getIWrapperPolicy() == PageRequestConfig.Policy.ANY) {
074: this .policy = "ANY";
075: } else {
076: this .policy = "NONE";
077: }
078:
079: for (IWrapperConfig iConfig : config.getIWrappers().values()) {
080: String wrapperclass = iConfig.getWrapperClass().getName();
081: IHandler handler = IHandlerFactory.getInstance()
082: .getIHandlerForWrapperClass(wrapperclass);
083: handlers.add(handler);
084: if (!iConfig.isActiveIgnore()) {
085: activeset.add(handler);
086: }
087: }
088:
089: }
090:
091: /**
092: * The principal accessibility of a page is deduced as follows:
093: * If ANY of all the associated IHandlers returns false on a call to
094: * prerequisitesMet(context), the page is NOT accessible.
095: * @param context the current context
096: * @return true if page is accesible, else false
097: * @exception Exception if an error occurs
098: * @see de.schlund.pfixcore.workflow.app.IHandlerContainer#isPageAccessible(Context)
099: */
100: public boolean isPageAccessible(Context context) throws Exception {
101: if (handlers.isEmpty())
102: return true; // border case
103:
104: for (Iterator<IHandler> iter = handlers.iterator(); iter
105: .hasNext();) {
106: IHandler handler = iter.next();
107: PerfEvent pe = new PerfEvent(
108: PerfEventType.IHANDLER_PREREQUISITESMET, handler
109: .getClass().getName());
110: pe.start();
111: boolean test = handler.prerequisitesMet(context);
112: pe.save();
113:
114: if (!test) {
115: return false;
116: }
117: }
118: return true;
119: }
120:
121: /**
122: * <code>areHandlerActive</code> asks all IHandlers that are contained on
123: * the page and which are not listed in the property <code>ihandlercontainer.ignore</code>
124: * (as a space separated list) in turn if they are active (<code>IHandler.isActive(Context context)</code>).
125: * Depending on the policy (set by the (sub-) property <code>ihandlercontainer.policy</code>) which can be
126: * <code>ALL</code>, <code>ANY</code> (default) or <code>NONE</code>,
127: * this method requires either all (ALL), at least one (ANY) or none (NONE) of the
128: * handlers to be active to return a value of <code>true</code>
129: * If no wrapper/handler is defined, it returns true, too.
130: * @param context the current context
131: * @return true if handlers are active, else false
132: * @exception Exception if an error occurs
133: * @see de.schlund.pfixcore.workflow.app.IHandlerContainer#areHandlerActive(Context)
134: */
135: public boolean areHandlerActive(Context context) throws Exception {
136: if (activeset.isEmpty() || policy.equals("NONE")) {
137: return true; // border case
138: }
139:
140: boolean retval = true;
141:
142: if (policy.equals("ALL")) {
143: retval = true;
144: for (Iterator<IHandler> iter = activeset.iterator(); iter
145: .hasNext();) {
146: IHandler handler = iter.next();
147:
148: boolean test = doIsActive(handler, context);
149: if (!test) {
150: retval = false;
151: break;
152: }
153: }
154: } else if (policy.equals("ANY")) {
155: retval = false;
156: for (Iterator<IHandler> iter = activeset.iterator(); iter
157: .hasNext();) {
158: IHandler handler = iter.next();
159:
160: boolean test = doIsActive(handler, context);
161: if (test) {
162: retval = true;
163: break;
164: }
165: }
166: } else {
167: throw new RuntimeException("ERROR: property '"
168: + PROP_POLICY
169: + "' must be 'ALL', 'ANY'(default) or 'NONE'");
170: }
171:
172: return (retval);
173: }
174:
175: /**
176: * Call the <see>isActive</see>-Method of the passed <see>IHandler</see>
177: * with the given context.
178: *
179: * @param handler
180: * @param ctx
181: * @return
182: * @throws Exception
183: */
184: private boolean doIsActive(IHandler handler, Context ctx)
185: throws Exception {
186: PerfEvent pe = new PerfEvent(PerfEventType.IHANDLER_ISACTIVE,
187: handler.getClass().getName());
188: pe.start();
189: boolean test = handler.isActive(ctx);
190: pe.save();
191: return test;
192: }
193:
194: /**
195: * Call the <see>needsData/see>-Method of the passed <see>IHandler</see>
196: * with the given context.
197: *
198: * @param handler
199: * @param ctx
200: * @return
201: * @throws Exception
202: */
203: private boolean doNeedsData(IHandler handler, Context ctx)
204: throws Exception {
205: PerfEvent pe = new PerfEvent(PerfEventType.IHANDLER_NEEDSDATA,
206: handler.getClass().getName());
207: pe.start();
208: boolean test = handler.needsData(ctx);
209: pe.save();
210: return test;
211: }
212:
213: /**
214: * The method <code>needsData</code> tells if any of the IHandlers this instance
215: * aggregates still needs data.
216: * @param context the current context
217: * @return true if data is needed, else false
218: * @exception Exception if an error occurs
219: * @see de.schlund.pfixcore.workflow.app.IHandlerContainer#needsData(Context)
220: */
221: public boolean needsData(Context context) throws Exception {
222: if (handlers.isEmpty())
223: return true; // border case
224:
225: for (Iterator<IHandler> iter = handlers.iterator(); iter
226: .hasNext();) {
227: IHandler handler = iter.next();
228: if (handler.isActive(context)) {
229:
230: boolean test = doNeedsData(handler, context);
231: if (test) {
232: return true;
233: }
234: }
235: }
236: return false;
237: }
238:
239: }// IHandlerSimpleContainer
|