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.ArrayList;
023: import java.util.Arrays;
024: import java.util.Collection;
025: import java.util.HashMap;
026: import java.util.Iterator;
027: import java.util.Properties;
028: import java.util.StringTokenizer;
029: import java.util.TreeMap;
030: import java.util.TreeSet;
031:
032: import javax.servlet.http.HttpSession;
033:
034: import org.apache.log4j.Logger;
035: import org.w3c.dom.Element;
036:
037: import de.schlund.pfixcore.generator.IHandler;
038: import de.schlund.pfixcore.generator.IWrapper;
039: import de.schlund.pfixcore.generator.IWrapperParam;
040: import de.schlund.pfixcore.generator.RequestData;
041: import de.schlund.pfixcore.generator.StatusCodeInfo;
042: import de.schlund.pfixcore.util.PropertiesUtils;
043: import de.schlund.pfixcore.workflow.Context;
044: import de.schlund.pfixxml.PfixServletRequest;
045: import de.schlund.pfixxml.RequestParam;
046: import de.schlund.pfixxml.ResultDocument;
047: import de.schlund.pfixxml.XMLException;
048: import de.schlund.pfixxml.config.IWrapperConfig;
049: import de.schlund.pfixxml.config.PageRequestConfig;
050: import de.schlund.pfixxml.perflogging.PerfEvent;
051: import de.schlund.pfixxml.perflogging.PerfEventType;
052: import de.schlund.pfixxml.resources.FileResource;
053: import de.schlund.pfixxml.resources.ResourceUtil;
054:
055: /**
056: * Deprecated implementation of the <code>IWrapperContainer</code> interface.
057: * <br/>
058: *
059: * Created: Fri Aug 17 14:58:49 2001
060: *
061: * @author <a href="mailto:jtl@schlund.de">Jens Lautenbacher</a>
062: *
063: *
064: */
065:
066: @Deprecated
067: public class IWrapperSimpleContainer implements IWrapperContainer {
068: private TreeMap<String, IWrapper> wrappers = new TreeMap<String, IWrapper>();
069:
070: // depends on request
071: private ArrayList<IWrapperGroup> activegroups = new ArrayList<IWrapperGroup>();
072: private IWrapperGroup currentgroup = null;
073: private IWrapperGroup selectedwrappers = null;
074:
075: private IWrapperGroup contwrappers = null;
076: private IWrapperGroup always_retrieve = null;
077:
078: private Context context = null;
079: private ResultDocument resdoc = null;
080: private PfixServletRequest preq = null;
081: private RequestData reqdata = null;
082: private boolean is_splitted = false;
083: private boolean is_loaded = false;
084: protected Logger LOG = Logger.getLogger(this .getClass());
085:
086: //private static final String PROP_INTERFACE = "interface";
087: public static final String PROP_RESTRICED = "restrictedcontinue";
088: public static final String PROP_ALWAYS_RETRIEVE = "alwaysretrieve";
089: private static final String GROUP_STATUS_PARAM = "__groupdisplay";
090: private static final String GROUP_STATUS = "__GROUPDISPLAY__STATUS__";
091: private static final Boolean GROUP_ON = new Boolean(true);
092: private static final Boolean GROUP_OFF = new Boolean(false);
093: private static final String GROUP_ON_PARAM = "on";
094: private static final String GROUP_OFF_PARAM = "off";
095: private static final String GROUP_FORCE_PROP = "forcegroupdisplay";
096: private static final String GROUP_PROP = "group";
097: private static final String GROUP_ANONYMOUS = "__AnonymousGroup__";
098:
099: private String GROUP_CURR;
100: private static final String GROUP_NEXT = "NEXT";
101: private static final String GROUP_PREV = "PREV";
102: private static final String SELECT_GROUP = "SELGRP";
103: private static final String SELECT_WRAPPER = "SELWRP";
104: private static final String WRAPPER_LOGDIR = "interfacelogging";
105:
106: // private static final String WRAPPER_LOGLIST = "loginterfaces";
107:
108: /**
109: * This method must be called right after an instance of this class is created.
110: *
111: * @param context a <code>Context</code> value. Not null.
112: * @param preq a <code>PfixServletRequest</code> value. Not null.
113: * @param resdoc a <code>ResultDocument</code> value. Not null.
114: * @exception Exception if an error occurs
115: * @see de.schlund.pfixcore.workflow.app.IWrapperContainer#initIWrappers(Context, PfixServletRequest, ResultDocument)
116: */
117: public synchronized void initIWrappers(Context context,
118: PfixServletRequest preq, ResultDocument resdoc)
119: throws Exception {
120: if (context == null)
121: throw new IllegalArgumentException(
122: "A 'null' value for the Context argument is not acceptable here.");
123: if (preq == null)
124: throw new IllegalArgumentException(
125: "A 'null' value for the PfixServletRequest argument is not acceptable here.");
126: if (resdoc == null)
127: throw new IllegalArgumentException(
128: "A 'null' value for the ResultDocument argument is not acceptable here.");
129:
130: this .context = context;
131: this .preq = preq;
132: this .resdoc = resdoc;
133:
134: GROUP_CURR = "__currentindex["
135: + context.getCurrentPageRequest().getName() + "]";
136:
137: readIWrappersConfigFromProperties();
138: }
139:
140: /**
141: * Use this method at any time to check if any error has happened in
142: * any of the "currently active" IWrappers of this Container.
143: * Depending on the use of grouping, or restricting to certain
144: * IWrappers the term "currently active" means something between
145: * the two extremes of "all handled IWrappers" to
146: * "just the one I explicitely talk to".
147: *
148: * @return a <code>boolean</code> value
149: * @exception Exception if an error occurs
150: * @see de.schlund.pfixcore.workflow.app.IWrapperContainer#errorHappened()
151: */
152: public boolean errorHappened() throws Exception {
153: if (wrappers.isEmpty())
154: return false; // border case
155:
156: if (!is_loaded)
157: throw new XMLException(
158: "You must first call handleSubmittedData() here!");
159: if (!is_splitted)
160: splitIWrappers();
161: IWrapper[] cwrappers = selectedwrappers.getIWrappers();
162: for (int i = 0; i < cwrappers.length; i++) {
163: IWrapper wrapper = cwrappers[i];
164: if (wrapper.errorHappened()) {
165: return true;
166: }
167: }
168: return false;
169: }
170:
171: /**
172: * This method takes care of putting all error messages into the ResultDocument.
173: * This method needs the instance to be initialized with a non-null resdoc param (see
174: * {@link initIWrappers initIWrappers}).
175: * @exception Exception if an error occurs
176: * @see de.schlund.pfixcore.workflow.app.IWrapperContainer#addErrorCodes()
177: */
178: public void addErrorCodes() throws Exception {
179: // COMMENT: is it OK to NOT enforce loading here? Needed to be able to set errors in retrieveCurrentStatus, too.
180: // if (!is_loaded) throw new XMLException("You must first call handleSubmittedData() here!");
181: if (!is_splitted)
182: splitIWrappers();
183: IWrapper[] cwrappers = selectedwrappers.getIWrappers();
184: for (int i = 0; i < cwrappers.length; i++) {
185: IWrapper wrapper = cwrappers[i];
186: String prefix = wrapper.gimmePrefix();
187: IWrapperParam[] errors = wrapper.gimmeAllParamsWithErrors();
188: if (errors != null) {
189: wrapper.tryErrorLogging();
190: for (int j = 0; j < errors.length; j++) {
191: IWrapperParam param = errors[j];
192: StatusCodeInfo[] scodeinfos = param
193: .getStatusCodeInfos();
194: String name = prefix + "." + param.getName();
195: if (scodeinfos != null) {
196: for (int k = 0; k < scodeinfos.length; k++) {
197: StatusCodeInfo sci = scodeinfos[k];
198: resdoc.addStatusCode(context
199: .getProperties(), sci
200: .getStatusCode(), sci.getArgs(),
201: sci.getLevel(), name);
202: }
203: }
204: }
205: }
206: }
207: }
208:
209: /**
210: * This method puts all the string representation of all submitted
211: * form values back into the result tree.
212: * This method needs the instance to be initialized with a non-null resdoc param (see
213: * {@link initIWrappers initIWrappers}).
214: *
215: * @exception Exception if an error occurs
216: * @see de.schlund.pfixcore.workflow.app.IWrapperContainer#addStringValues()
217: */
218: public void addStringValues() throws Exception {
219: if (!is_splitted)
220: splitIWrappers();
221: IWrapper[] cwrappers = currentgroup.getIWrappers();
222: for (int i = 0; i < cwrappers.length; i++) {
223: IWrapper wrapper = cwrappers[i];
224: String prfx = wrapper.gimmePrefix();
225: IWrapperParam[] pinfoall = wrapper.gimmeAllParams();
226: for (int j = 0; j < pinfoall.length; j++) {
227: IWrapperParam pinfo = pinfoall[j];
228: String name = pinfo.getName();
229: String[] strval = pinfo.getStringValue();
230: if (strval != null) {
231: for (int k = 0; k < strval.length; k++) {
232: resdoc.addValue(prfx + "." + name, strval[k]);
233: }
234: }
235: }
236: }
237: }
238:
239: /**
240: * Use this method to query if the IWrapperContainer wants to continue with submitting data (thereby staying on the page),
241: * or if it assumes this whole page to be completed (and give control to the context to continue with the pageflow).
242: *
243: * @return a <code>boolean</code> value
244: * @exception Exception if an error occurs
245: * @see de.schlund.pfixcore.workflow.app.IWrapperContainer#continueSubmit()
246: */
247: public boolean stayAfterSubmit() throws Exception {
248: if (wrappers.isEmpty())
249: return false; // border case
250:
251: if (!is_splitted)
252: splitIWrappers();
253:
254: if (selectedwrappers != currentgroup) {
255: if (contwrappers != null
256: && contwrappers.containsAll(selectedwrappers)) {
257: LOG
258: .debug("*** Allow continue because all selected wrappers are members of the restriced_continue group!");
259: return false;
260: }
261: return true;
262: }
263:
264: Integer index = checkForNextIndexInRequest();
265: if (index == null) {
266: return false;
267: } else {
268: setCurrentIWrapperGroupByIndex(index.intValue());
269: selectedwrappers = currentgroup;
270: return true;
271: }
272: }
273:
274: /**
275: * Returns the {@link ResultDocument ResultDocument} that's associated with this IWrapperContainer.
276: * @return a <code>ResultDocument</code> value
277: * @see de.schlund.pfixcore.workflow.app.IWrapperContainer#getAssociatedResultDocument()
278: */
279: public ResultDocument getAssociatedResultDocument() {
280: return resdoc;
281: }
282:
283: /**
284: * Returns the {@link PfixServletRequest} that's associated with this IWrapperContainer.
285: *
286: * @return a <code>HttpServletRequest</code> value
287: * @see de.schlund.pfixcore.workflow.app.IWrapperContainer#getAssociatedPfixServletRequest()
288: */
289: public PfixServletRequest getAssociatedPfixServletRequest() {
290: return preq;
291: }
292:
293: /**
294: * Returns the {@link Context} that's associated with this IWrapperContainer.
295: *
296: * @return a <code>Context</code> value
297: * @see de.schlund.pfixcore.workflow.app.IWrapperContainer#getAssociatedContext()
298: */
299: public Context getAssociatedContext() {
300: return context;
301: }
302:
303: /**
304: * <code>addIWrapperStatus</code> inserts the status of all IWrappers into the result tree.
305: * You can only call this method if this instance was initialized with a non null ResultDocument.
306: * The IWrappers will be grouped according to the group they belong to. If there's no groups defined,
307: * one big anonymous group will be created that contains all the defined IWrappers
308: *
309: * @exception Exception if an error occurs
310: * @see de.schlund.pfixcore.workflow.app.IWrapperContainer#addIWrapperStatus()
311: */
312: public void addIWrapperStatus() throws Exception {
313: if (!is_splitted)
314: splitIWrappers();
315: Element grpstati = resdoc.createNode("iwrappergroups");
316: grpstati.setAttribute("currentindex", ""
317: + getCurrentIWrapperGroupIndex());
318: grpstati.setAttribute("lastindex", ""
319: + (activegroups.size() - 1));
320: grpstati.setAttribute("groupdisplay", ""
321: + checkGroupDisplayStatus());
322:
323: for (int i = 0; i < activegroups.size(); i++) {
324: IWrapperGroup group = (IWrapperGroup) activegroups.get(i);
325: String name = group.getName();
326: String curr = "false";
327: if (currentgroup == group) {
328: curr = "true";
329: }
330: Element status = resdoc.createSubNode(grpstati, "group");
331: status.setAttribute("index", "" + i);
332: status.setAttribute("name", name);
333: status.setAttribute("current", curr);
334:
335: IWrapper[] tmpwrappers = group.getIWrappers();
336: for (int j = 0; j < tmpwrappers.length; j++) {
337: IWrapper wrapper = tmpwrappers[j];
338: IHandler handler = wrapper.gimmeIHandler();
339: Element wrap = resdoc
340: .createSubNode(status, "interface");
341: wrap.setAttribute("active", ""
342: + handler.isActive(context));
343: wrap.setAttribute("name", wrapper.getClass().getName());
344: wrap.setAttribute("prefix", wrapper.gimmePrefix());
345: }
346: }
347: }
348:
349: // /**
350: // * The method <code>needsData</code> tells if any of the IWrappers this instance aggregates still needs Data.
351: // *
352: // * @return a <code>boolean</code> value
353: // * @exception Exception if an error occurs
354: // * @see de.schlund.pfixcore.workflow.app.IWrapperContainer#needsData()
355: // */
356: // public boolean needsData() throws Exception{
357: // if (wrappers.isEmpty()) return true; // border case
358: //
359: // // synchronized (wrappers) {
360: // for (Iterator<IWrapper> i = wrappers.values().iterator(); i.hasNext(); ) {
361: // IWrapper wrapper = i.next();
362: // IHandler handler = wrapper.gimmeIHandler();
363: // if (handler.isActive(context) && handler.needsData(context)) {
364: // return true;
365: // }
366: // }
367: // // }
368: // return false;
369: // }
370:
371: /**
372: * <code>handleSubmittedData</code> will call all or a part of the defined IWrappers
373: * (depending of grouping and/or restricting the IWrappers) to get
374: * the IHandler that these IWrappers are bound to. The IHandler are called in turn to handle the submitted data.
375: * This works by calling ihandler.handleSubmittedData(Context context, IWrapper wrapper).
376: * See {@link IHandler}.
377: * You can only call this method if you initialized the instance with a non null ResultDocument.
378: *
379: * @exception Exception if an error occurs
380: * @see de.schlund.pfixcore.workflow.app.IWrapperContainer#handleSubmittedData()
381: */
382: public void handleSubmittedData() throws Exception {
383: if (!is_splitted)
384: splitIWrappers();
385: IWrapper[] cwrappers = currentgroup.getIWrappers();
386:
387: for (int i = 0; i < cwrappers.length; i++) {
388: IWrapper wrapper = cwrappers[i];
389: IHandler handler = wrapper.gimmeIHandler();
390: if (handler.isActive(context)) {
391: wrapper.load(reqdata);
392: if (selectedwrappers.contains(wrapper)) {
393: wrapper.tryParamLogging();
394: if (!wrapper.errorHappened()) {
395: PerfEvent pe = new PerfEvent(
396: PerfEventType.IHANDLER_HANDLESUBMITTEDDATA,
397: handler.getClass().getName());
398: pe.start();
399: handler.handleSubmittedData(context, wrapper);
400: pe.save();
401: }
402: }
403: }
404: }
405: is_loaded = true;
406: }
407:
408: /**
409: * <code>retrieveCurrentStatus</code> will call all or a part of the defined IWrappers
410: * (depending of grouping and/or restricting the IWrappers) to get the "active" IHandlers, which
411: * are called in turn via ihandler.retrieveCurrentStatus(Context context, IWrapper wrapper).
412: *
413: * @exception Exception if an error occurs
414: * @see de.schlund.pfixcore.workflow.app.IWrapperContainer#retrieveCurrentStatus()
415: */
416: public void retrieveCurrentStatus() throws Exception {
417: if (!is_splitted)
418: splitIWrappers();
419: IWrapper[] selwrappers = selectedwrappers.getIWrappers();
420: retrieveCurrentStatusForWrappers(selwrappers);
421:
422: if (always_retrieve != null && !always_retrieve.isEmpty()) {
423: for (int i = 0; i < always_retrieve.getIWrappers().length; i++) {
424: IWrapper wrapper = always_retrieve.getIWrappers()[i];
425: if (!selectedwrappers.contains(wrapper)
426: && currentgroup.contains(wrapper)) {
427: IHandler handler = wrapper.gimmeIHandler();
428: if (handler.isActive(context)) {
429: handler.retrieveCurrentStatus(context, wrapper);
430: }
431: }
432: }
433: }
434: }
435:
436: //
437: // PRIVATE
438: //
439:
440: private void retrieveCurrentStatusForWrappers(IWrapper[] allwrappers)
441: throws Exception {
442: for (int i = 0; i < allwrappers.length; i++) {
443: IWrapper wrapper = allwrappers[i];
444: IHandler handler = wrapper.gimmeIHandler();
445: if (handler.isActive(context)) {
446: handler.retrieveCurrentStatus(context, wrapper);
447: }
448: }
449: }
450:
451: private void splitIWrappers() throws Exception {
452: reqdata = new RequestDataImpl(context, preq);
453: checkGroupDisplayStatus();
454: boolean group_wanted = ((Boolean) preq.getSession(false)
455: .getAttribute(GROUP_STATUS)).booleanValue();
456: boolean group_defined = hasGroupDefinition();
457: if (group_wanted && group_defined) {
458: readIWrapperGroupsConfigFromProperties();
459: currentgroup = getCurrentGroupFromRequest();
460: } else {
461: IWrapperGroup group = new IWrapperGroup();
462: group.setName(GROUP_ANONYMOUS);
463: for (Iterator<IWrapper> i = wrappers.values().iterator(); i
464: .hasNext();) {
465: group.addIWrapper(i.next());
466: }
467: activegroups.add(group);
468: currentgroup = group;
469: }
470: checkForRestrictedCalling();
471:
472: createRestrictedContinueGroup();
473: createAlwaysRetrieveGroup();
474:
475: is_splitted = true;
476: }
477:
478: private void checkForRestrictedCalling() throws Exception {
479: IWrapperGroup selected = new IWrapperGroup();
480: String[] selwrappers = reqdata.getCommands(SELECT_WRAPPER);
481: if (selwrappers != null) {
482: for (int i = 0; i < selwrappers.length; i++) {
483: String prefix = selwrappers[i];
484: LOG.debug(" >> Restricted to Wrapper: " + prefix);
485: IWrapper selwrap = (IWrapper) wrappers.get(prefix);
486: if (selwrap == null) {
487: LOG.warn(" *** No wrapper found for prefix "
488: + prefix + "! ignoring");
489: continue;
490: }
491: selected.addIWrapper(selwrap);
492: }
493: }
494:
495: if (selected.isEmpty()) {
496: selectedwrappers = currentgroup;
497: } else {
498: selectedwrappers = selected;
499: }
500: }
501:
502: private boolean checkGroupDisplayStatus() {
503: Properties props = context.getPropertiesForCurrentPageRequest();
504: String force = props.getProperty(GROUP_FORCE_PROP);
505:
506: if (force != null
507: && (force.equals("yes") || force.equals("true") || force
508: .equals("on"))) {
509: return true;
510: }
511:
512: HttpSession session = preq.getSession(false);
513: RequestParam status = preq.getRequestParam(GROUP_STATUS_PARAM);
514: if (status != null
515: && (status.getValue().equals(GROUP_ON_PARAM))) {
516: LOG.debug("*** Request says: Groupdisplay ON");
517: session.setAttribute(GROUP_STATUS, GROUP_ON);
518: return true;
519: } else if (status != null
520: && status.getValue().equals(GROUP_OFF_PARAM)) {
521: LOG.debug("*** Request says: Groupdisplay OFF");
522: session.setAttribute(GROUP_STATUS, GROUP_OFF);
523: return false;
524: } else if (session.getAttribute(GROUP_STATUS) == null) {
525: LOG
526: .debug("*** Nothing in Session: init by switching Groupdisplay ON");
527: session.setAttribute(GROUP_STATUS, GROUP_ON);
528: return true;
529: } else {
530: LOG.debug("*** Session says: Groupddisplay is "
531: + session.getAttribute(GROUP_STATUS));
532: return ((Boolean) session.getAttribute(GROUP_STATUS))
533: .booleanValue();
534: }
535: }
536:
537: private void readIWrappersConfigFromProperties() throws Exception {
538: //Properties props = context.getPropertiesForCurrentPageRequest();
539: //HashMap interfaces = PropertiesUtils.selectProperties(props, PROP_INTERFACE);
540: PageRequestConfig config = context
541: .getConfigForCurrentPageRequest();
542: Collection<? extends IWrapperConfig> interfaces = config
543: .getIWrappers().values();
544:
545: if (interfaces.size() == 0) {
546: LOG.debug("*** Found no interfaces for this page (page="
547: + context.getCurrentPageRequest().getName() + ")");
548: } else {
549: // Initialize all wrappers
550: int i = 0;
551: for (IWrapperConfig iConfig : interfaces) {
552: String prefix = iConfig.getPrefix();
553: int order = i++;
554:
555: if (wrappers.get(prefix) != null) {
556: throw new XMLException(
557: "FATAL: you have already defined a wrapper with prefix "
558: + prefix
559: + " on page "
560: + context.getCurrentPageRequest()
561: .getName());
562: }
563:
564: String iface = iConfig.getWrapperClass().getName();
565:
566: Class<?> thewrapper = null;
567: IWrapper wrapper = null;
568: try {
569: thewrapper = Class.forName(iface);
570: wrapper = (IWrapper) thewrapper.newInstance();
571: } catch (ClassNotFoundException e) {
572: throw new XMLException("unable to find class ["
573: + iface + "] :" + e.getMessage());
574: } catch (InstantiationException e) {
575: throw new XMLException(
576: "unable to instantiate class [" + iface
577: + "] :" + e.getMessage());
578: } catch (IllegalAccessException e) {
579: throw new XMLException("unable to acces class ["
580: + iface + "] :" + e.getMessage());
581: } catch (ClassCastException e) {
582: throw new XMLException(
583: "class ["
584: + iface
585: + "] does not implement the interface IWrapper :"
586: + e.getMessage());
587: }
588:
589: wrapper.defineOrder(order);
590:
591: wrappers.put(prefix, wrapper);
592: wrapper.init(prefix);
593:
594: String logdir = context.getProperties().getProperty(
595: WRAPPER_LOGDIR);
596: boolean dolog = iConfig.getLogging();
597: if (dolog && logdir != null && !logdir.equals("")) {
598: FileResource dir = ResourceUtil
599: .getFileResourceFromDocroot(logdir);
600: if (dir.isDirectory() && dir.canWrite()) {
601: wrapper.initLogging(dir, context
602: .getCurrentPageRequest().getName(),
603: context.getVisitId());
604: }
605: }
606: }
607:
608: }
609: }
610:
611: private void createAlwaysRetrieveGroup() {
612: always_retrieve = new IWrapperGroup();
613:
614: for (IWrapperConfig iConfig : context
615: .getConfigForCurrentPageRequest().getIWrappers()
616: .values()) {
617: if (iConfig.isAlwaysRetrieve()) {
618: IWrapper wrapper = (IWrapper) wrappers.get(iConfig
619: .getPrefix());
620: LOG.debug("*** Adding interface '"
621: + iConfig.getPrefix()
622: + "' to the always_retrieve group...");
623: always_retrieve.addIWrapper(wrapper);
624: }
625: }
626: }
627:
628: private void createRestrictedContinueGroup() {
629: contwrappers = new IWrapperGroup();
630:
631: for (IWrapperConfig iConfig : context
632: .getConfigForCurrentPageRequest().getIWrappers()
633: .values()) {
634: if (iConfig.isContinue()) {
635: IWrapper wrapper = (IWrapper) wrappers.get(iConfig
636: .getPrefix());
637: LOG.debug("*** Adding interface '"
638: + iConfig.getPrefix()
639: + "' to the restricted_continue group...");
640: contwrappers.addIWrapper(wrapper);
641: }
642: }
643: }
644:
645: private void readIWrapperGroupsConfigFromProperties()
646: throws Exception {
647: Properties props = context.getPropertiesForCurrentPageRequest();
648: TreeMap<String, String> pmap = PropertiesUtils
649: .selectPropertiesSorted(props, GROUP_PROP);
650:
651: for (Iterator<String> i = pmap.keySet().iterator(); i.hasNext();) {
652: String page = i.next();
653: String spec = pmap.get(page);
654: IWrapperGroup group = new IWrapperGroup();
655: group.setName(page);
656: if (spec == null || spec.equals("")) {
657: throw new XMLException("Specification for group '"
658: + page + "' must be given.");
659: }
660: StringTokenizer tok = new StringTokenizer(spec);
661: for (; tok.hasMoreTokens();) {
662: String prefix = tok.nextToken();
663: IWrapper wrapper = (IWrapper) wrappers.get(prefix);
664: if (wrapper == null) {
665: throw new XMLException(
666: "No matching interface for specification token '"
667: + prefix + "'");
668: }
669: group.addIWrapper(wrapper);
670: }
671: if (checkGroupActivity(group)) {
672: activegroups.add(group);
673: }
674: }
675: }
676:
677: private boolean checkGroupActivity(IWrapperGroup group)
678: throws Exception {
679: IWrapper[] gwrappers = group.getIWrappers();
680: for (int i = 0; i < gwrappers.length; i++) {
681: IHandler handler = gwrappers[i].gimmeIHandler();
682: if (handler.isActive(context)) {
683: return true;
684: }
685: }
686: return false;
687: }
688:
689: private boolean hasGroupDefinition() {
690: Properties props = context.getPropertiesForCurrentPageRequest();
691: HashMap<String, String> pmap = PropertiesUtils
692: .selectProperties(props, GROUP_PROP);
693: if (pmap.isEmpty()) {
694: LOG.debug("*** Properties say: Have NO group definition");
695: return false;
696: } else {
697: LOG.debug("*** Properties say: Have group definition");
698: return true;
699: }
700: }
701:
702: private IWrapperGroup getCurrentGroupFromRequest() throws Exception {
703: LOG.debug("* looking for group index: " + GROUP_CURR);
704: RequestParam page = preq.getRequestParam(GROUP_CURR);
705: // synchronized (activegroups) {
706: if (page == null || page.getValue().equals("")) {
707: LOG
708: .debug("*** Request specifies NO group index: Using index 0");
709: return (IWrapperGroup) activegroups.get(0);
710: } else {
711: LOG.debug("*** Request specifies group index: Using index "
712: + page);
713: Integer index = new Integer(page.getValue());
714: return (IWrapperGroup) activegroups.get(index.intValue());
715: }
716: // }
717: }
718:
719: private Integer checkForNextIndexInRequest() {
720: int current_idx = getCurrentIWrapperGroupIndex();
721: int last_idx = activegroups.size() - 1;
722: LOG.debug("* Current Idx: " + current_idx + " LastIdx: "
723: + last_idx);
724: String[] grpcmdvals = reqdata.getCommands(SELECT_GROUP);
725:
726: if (grpcmdvals != null && grpcmdvals.length > 0) {
727: if (grpcmdvals.length > 1) {
728: LOG
729: .warn(" *** WARNING: SELGRP commando was submitted more than once! *** ");
730: }
731: String val = grpcmdvals[0];
732:
733: if (val.equals(GROUP_NEXT)) {
734: LOG.debug("* CMD VAL is NEXT");
735: if (current_idx < last_idx) {
736: LOG.debug("* Setting idx to: " + (current_idx + 1));
737: return new Integer(current_idx + 1);
738: } else {
739: LOG.debug("* Next idx out of bounds; setting to: "
740: + last_idx);
741: return new Integer(last_idx);
742: }
743: } else if (val.equals(GROUP_PREV)) {
744: LOG.debug("* CMD VAL is PREV");
745: if (current_idx > 0) {
746: LOG.debug("* Setting idx to: " + (current_idx - 1));
747: return new Integer(current_idx - 1);
748: } else {
749: LOG
750: .debug("* Prev idx out of bounds; setting to: 0");
751: return new Integer(0);
752: }
753: } else {
754: LOG.debug("* CMD VAL is: " + val);
755: Integer index;
756: try {
757: index = new Integer(val);
758: } catch (Exception e) {
759: LOG.warn("Couldn't parse index into integer: '"
760: + val + "': " + e.toString());
761: return new Integer(current_idx);
762: }
763: if (index.intValue() >= 0
764: && index.intValue() <= last_idx) {
765: return index;
766: } else {
767: LOG
768: .debug("* Idx out of bounds; resetting to current value: "
769: + current_idx);
770: return new Integer(current_idx);
771: }
772: }
773:
774: }
775: LOG.debug("* Found no group index cmd; returning null");
776: return null;
777: }
778:
779: private int getCurrentIWrapperGroupIndex() {
780: return activegroups.indexOf(currentgroup);
781: }
782:
783: private void setCurrentIWrapperGroupByIndex(int index) {
784: if (index < 0 || index >= activegroups.size()) {
785: throw new RuntimeException(
786: "IWrapperGroup index must be between 0 and "
787: + (activegroups.size() - 1));
788: }
789: currentgroup = (IWrapperGroup) activegroups.get(index);
790: }
791:
792: private class IWrapperGroup {
793: private TreeSet<IWrapper> group = new TreeSet<IWrapper>();
794: private String name;
795:
796: public void setName(String name) {
797: this .name = name;
798: }
799:
800: public void addIWrapper(IWrapper wrapper) {
801: group.add(wrapper);
802: }
803:
804: public String getName() {
805: return name;
806: }
807:
808: public boolean isEmpty() {
809: return group.isEmpty();
810: }
811:
812: public boolean contains(IWrapper wrapper) {
813: return group.contains(wrapper);
814: }
815:
816: public boolean containsAll(IWrapperGroup ingroup) {
817: IWrapper[] in = ingroup.getIWrappers();
818: return group.containsAll(Arrays.asList(in));
819: }
820:
821: public IWrapper[] getIWrappers() {
822: // synchronized (group) {
823: return group.toArray(new IWrapper[] {});
824: // }
825: }
826: }// IWrapperGroup
827:
828: }// IWrapperSimpleContainer
|