001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.jetspeed.decoration;
018:
019: import java.util.ArrayList;
020: import java.util.Collections;
021: import java.util.HashMap;
022: import java.util.Iterator;
023: import java.util.List;
024: import java.util.Properties;
025:
026: import javax.portlet.PortletMode;
027: import javax.portlet.WindowState;
028:
029: import org.apache.commons.logging.Log;
030: import org.apache.commons.logging.LogFactory;
031: import org.apache.jetspeed.JetspeedActions;
032: import org.apache.jetspeed.PortalReservedParameters;
033: import org.apache.jetspeed.cache.CacheElement;
034: import org.apache.jetspeed.cache.ContentCacheKey;
035: import org.apache.jetspeed.cache.JetspeedContentCache;
036: import org.apache.jetspeed.components.portletentity.PortletEntityNotStoredException;
037: import org.apache.jetspeed.container.url.PortalURL;
038: import org.apache.jetspeed.container.window.FailedToRetrievePortletWindow;
039: import org.apache.jetspeed.container.window.PortletWindowAccessor;
040: import org.apache.jetspeed.decoration.caches.SessionPathResolverCache;
041: import org.apache.jetspeed.om.common.portlet.PortletApplication;
042: import org.apache.jetspeed.om.common.portlet.PortletDefinitionComposite;
043: import org.apache.jetspeed.om.page.ContentFragment;
044: import org.apache.jetspeed.om.page.ContentPage;
045: import org.apache.jetspeed.om.page.Fragment;
046: import org.apache.jetspeed.om.page.Page;
047: import org.apache.jetspeed.pipeline.PipelineException;
048: import org.apache.jetspeed.pipeline.valve.AbstractValve;
049: import org.apache.jetspeed.pipeline.valve.Valve;
050: import org.apache.jetspeed.pipeline.valve.ValveContext;
051: import org.apache.jetspeed.request.RequestContext;
052: import org.apache.jetspeed.security.SecurityAccessController;
053: import org.apache.pluto.om.portlet.ContentTypeSet;
054: import org.apache.pluto.om.window.PortletWindow;
055:
056: /**
057: * Assigns decorations and page actions to all of the portlet Fragments within
058: * the current request.
059: *
060: * @see org.apache.jetspeed.om.page.Fragment
061: * @see org.apache.jetspeed.om.page.Page
062: * @see org.apache.jetspeed.decoration.Decoration
063: * @see org.apache.jetspeed.decoration.LayoutDecoration
064: * @see org.apache.jetspeed.decoration.PortletDecoration
065: * @see org.apache.jetspeed.decoration.Theme
066: *
067: * @author <href a="mailto:weaver@apache.org">Scott T. Weaver</a>
068: * @author <href a="mailto:firevelocity@gmail.com">Vivek Kumar</a>
069: *
070: */
071: public class DecorationValve extends AbstractValve implements Valve {
072: public static final String ACTION_IMAGE_EXTENSION_ATTR = "actionImageExtension";
073: public static final String IS_AJAX_DECORATION_REQUEST = "org.apache.jetspeed.decoration.ajax";
074:
075: protected final static Log log = LogFactory
076: .getLog(DecorationValve.class);
077:
078: private final DecorationFactory decorationFactory;
079:
080: private final PortletWindowAccessor windowAccessor;
081:
082: private HashMap decoratorActionsAdapterCache = new HashMap();
083:
084: private DecoratorActionsFactory defaultDecoratorActionsFactory;
085:
086: private JetspeedContentCache cache = null;
087:
088: private boolean useSessionForThemeCaching = false;
089:
090: private boolean maxOnEdit = false;
091:
092: private boolean maxOnConfig = false;
093:
094: private boolean maxOnEditDefaults = false;
095:
096: /**
097: * When edit_defaults mode is not supported by a portlet, support the mode automatically.
098: */
099: private boolean autoSwitchingForConfigMode = false;
100:
101: /**
102: * When edit_defaults mode is not supported by a portlet, support the mode automatically.
103: */
104: private boolean autoSwitchingToEditDefaultsModes = true;
105:
106: /**
107: * For security constraint checks
108: */
109: protected SecurityAccessController accessController;
110:
111: public DecorationValve(DecorationFactory decorationFactory,
112: PortletWindowAccessor windowAccessor,
113: SecurityAccessController accessController) {
114: this (decorationFactory, windowAccessor, accessController, null);
115: }
116:
117: public DecorationValve(DecorationFactory decorationFactory,
118: PortletWindowAccessor windowAccessor,
119: SecurityAccessController accessController,
120: JetspeedContentCache cache) {
121: this (decorationFactory, windowAccessor, accessController,
122: cache, false);
123: }
124:
125: public DecorationValve(DecorationFactory decorationFactory,
126: PortletWindowAccessor windowAccessor,
127: SecurityAccessController accessController,
128: JetspeedContentCache cache,
129: boolean useSessionForThemeCaching) {
130: this .decorationFactory = decorationFactory;
131: this .windowAccessor = windowAccessor;
132: this .defaultDecoratorActionsFactory = new DefaultDecoratorActionsFactory();
133: //added the accessController in portlet decorater for checking the actions
134: this .accessController = accessController;
135: this .cache = cache;
136: this .useSessionForThemeCaching = useSessionForThemeCaching;
137: }
138:
139: public void invoke(RequestContext requestContext,
140: ValveContext context) throws PipelineException {
141: //long start = System.currentTimeMillis();
142: boolean isAjaxRequest = (context == null);
143: initFragments(requestContext, isAjaxRequest, null);
144: //long end = System.currentTimeMillis();
145: //System.out.println(end - start);
146: if (!isAjaxRequest) {
147: context.invokeNext(requestContext);
148: }
149: }
150:
151: public void initFragments(RequestContext requestContext,
152: boolean isAjaxRequest, List fragments) {
153: if (isAjaxRequest) {
154: requestContext.setAttribute(IS_AJAX_DECORATION_REQUEST,
155: new Boolean(true));
156: }
157:
158: ContentPage page = requestContext.getPage();
159:
160: // Globaly override all psml themes if override session attribute has been set
161: if (requestContext
162: .getSessionAttribute(PortalReservedParameters.PAGE_THEME_OVERRIDE_ATTRIBUTE) != null) {
163: String decoratorName = (String) requestContext
164: .getSessionAttribute(PortalReservedParameters.PAGE_THEME_OVERRIDE_ATTRIBUTE);
165: page.setDefaultDecorator(decoratorName, Fragment.LAYOUT);
166: }
167:
168: PageActionAccess pageActionAccess = (PageActionAccess) requestContext
169: .getAttribute(PortalReservedParameters.PAGE_EDIT_ACCESS_ATTRIBUTE);
170: String themeCacheKey = null;
171: ContentCacheKey themeContentCacheKey = null;
172: Theme theme = null;
173:
174: if (useCache()) {
175: if (pageActionAccess.isEditing() == false) {
176: // user helps us with the funky way jetspeed doesn't create a new session on login
177: if (this .useSessionForThemeCaching) {
178: themeCacheKey = cache
179: .createSessionKey(requestContext);
180: theme = (Theme) requestContext
181: .getSessionAttribute(themeCacheKey);
182: } else {
183: themeContentCacheKey = cache.createCacheKey(
184: requestContext, page.getId());
185: CacheElement themeCacheElem = cache
186: .get(themeContentCacheKey);
187:
188: if (themeCacheElem != null) {
189: theme = (Theme) themeCacheElem.getContent();
190: }
191: }
192: }
193: }
194:
195: if (theme != null) {
196: theme.init(page, decorationFactory, requestContext);
197: requestContext.setAttribute(
198: PortalReservedParameters.PAGE_THEME_ATTRIBUTE,
199: theme);
200: boolean solo = isSoloMode(requestContext);
201: SessionPathResolverCache sessionPathResolver = new SessionPathResolverCache(
202: requestContext.getRequest().getSession());
203: initDepthFragmentDecorations(requestContext, theme, page
204: .getRootContentFragment(), pageActionAccess,
205: isAjaxRequest,
206: ((DecorationFactoryImpl) decorationFactory)
207: .getResourceValidator(),
208: sessionPathResolver,
209: (theme.isInvalidated() && !solo));
210:
211: if (theme.isInvalidated() && !solo) {
212: if (this .useSessionForThemeCaching) {
213: requestContext.setSessionAttribute(themeCacheKey,
214: theme);
215: } else {
216: CacheElement themeCacheElem = cache.createElement(
217: themeContentCacheKey, theme);
218: cache.put(themeCacheElem);
219: }
220: theme.setInvalidated(false);
221: }
222: return;
223: }
224: theme = decorationFactory.getTheme(page, requestContext);
225: requestContext.setAttribute(
226: PortalReservedParameters.PAGE_THEME_ATTRIBUTE, theme);
227: if (fragments == null || fragments.size() == 0) {
228: ContentFragment rootFragment = page
229: .getRootContentFragment();
230: initDepthFragments(requestContext, theme, rootFragment,
231: pageActionAccess, isAjaxRequest, fragments);
232: } else {
233: Iterator fragmentsIter = fragments.iterator();
234: while (fragmentsIter.hasNext()) {
235: ContentFragment fragment = (ContentFragment) fragmentsIter
236: .next();
237: initFragment(requestContext, theme, fragment,
238: pageActionAccess, isAjaxRequest);
239: }
240: }
241:
242: if (useCache() && !isSoloMode(requestContext)) {
243: if (themeContentCacheKey == null && themeCacheKey == null) {
244: if (this .useSessionForThemeCaching) {
245: themeCacheKey = cache
246: .createSessionKey(requestContext);
247: requestContext.getRequest().getSession()
248: .removeAttribute(themeCacheKey);
249: } else {
250: themeContentCacheKey = cache.createCacheKey(
251: requestContext, page.getId());
252: cache.remove(themeContentCacheKey);
253: }
254: } else {
255: if (this .useSessionForThemeCaching) {
256: themeContentCacheKey = cache.createCacheKey(
257: requestContext, page.getId());
258: requestContext.setSessionAttribute(themeCacheKey,
259: theme);
260: } else {
261: CacheElement themeCacheElem = cache.createElement(
262: themeContentCacheKey, theme);
263: cache.put(themeCacheElem);
264: }
265: }
266: }
267: }
268:
269: protected boolean isSoloMode(RequestContext requestContext) {
270: boolean solo = false;
271: PortletWindow window = requestContext.getPortalURL()
272: .getNavigationalState().getMaximizedWindow();
273: boolean maximized = (window != null);
274: if (maximized) {
275: solo = JetspeedActions.SOLO_STATE.equals(requestContext
276: .getPortalURL().getNavigationalState()
277: .getMappedState(window));
278: }
279: return solo;
280: }
281:
282: protected boolean useCache() {
283: return this .cache != null;
284: }
285:
286: public String toString() {
287: return "DecorationValve";
288: }
289:
290: public DecoratorActionsFactory getDecoratorActionsAdapter(
291: Decoration decoration) {
292: // FIXME: why always get this property
293: String decoratorActionsAdapterClassName = decoration
294: .getProperty("actions.factory");
295: if (decoratorActionsAdapterClassName == null) {
296: decoratorActionsAdapterClassName = defaultDecoratorActionsFactory
297: .getClass().getName();
298: }
299: synchronized (decoratorActionsAdapterCache) {
300: DecoratorActionsFactory adapter = (DecoratorActionsFactory) decoratorActionsAdapterCache
301: .get(decoratorActionsAdapterClassName);
302: if (adapter == null) {
303: try {
304: adapter = (DecoratorActionsFactory) Class.forName(
305: decoratorActionsAdapterClassName)
306: .newInstance();
307: adapter.setMaximizeOnEdit(this .maxOnEdit);
308: adapter.setMaximizeOnConfig(this .maxOnConfig);
309: adapter
310: .setMaximizeOnEditDefaults(this .maxOnEditDefaults);
311: } catch (Exception e) {
312: log.error(
313: "Failed to instantiate custom DecoratorActionsAdaptor "
314: + decoratorActionsAdapterClassName
315: + ", falling back to default.", e);
316: adapter = (DecoratorActionsFactory) decoratorActionsAdapterCache
317: .get(defaultDecoratorActionsFactory
318: .getClass().getName());
319: if (adapter == null) {
320: adapter = defaultDecoratorActionsFactory;
321: }
322: }
323: decoratorActionsAdapterCache.put(
324: decoratorActionsAdapterClassName, adapter);
325: }
326: return adapter;
327: }
328: }
329:
330: /**
331: * Builds and assigns a list of available portlet modes and window states for
332: * the target <code>Fragment</code>.
333: *
334: * @param requestContext RequestContext of the current portal request.
335: * @param fragment Fragment to initialize modes and states for.
336: * @return
337: * @throws PortletEntityNotStoredException
338: * @throws FailedToRetrievePortletWindow
339: */
340: protected boolean initActionsForFragment(
341: RequestContext requestContext, ContentFragment fragment,
342: PageActionAccess pageActionAccess, Decoration decoration,
343: boolean isAjaxRequest)
344: throws FailedToRetrievePortletWindow,
345: PortletEntityNotStoredException {
346: boolean fragmentSupportsActions = false;
347: PortletWindow window = windowAccessor
348: .getPortletWindow(fragment);
349: PortletDefinitionComposite portlet = (PortletDefinitionComposite) window
350: .getPortletEntity().getPortletDefinition();
351:
352: if (null == portlet) {
353: return fragmentSupportsActions; // allow nothing
354: }
355:
356: List actions = Collections.EMPTY_LIST;
357:
358: PortletMode currentMode = requestContext.getPortalURL()
359: .getNavigationalState().getMode(window);
360: WindowState currentState = requestContext.getPortalURL()
361: .getNavigationalState().getState(window);
362: ContentTypeSet content = portlet.getContentTypeSet();
363:
364: if (fragment.equals(requestContext.getPage().getRootFragment())) {
365: fragmentSupportsActions = true;
366: actions = getPageModes(requestContext, window, content,
367: currentMode, currentState, pageActionAccess,
368: decoration, isAjaxRequest);
369: } else if (!Fragment.LAYOUT.equals(fragment.getType())) {
370: fragmentSupportsActions = true;
371: String fragmentId = fragment.getId();
372: PortletApplication pa = (PortletApplication) window
373: .getPortletEntity().getPortletDefinition()
374: .getPortletApplicationDefinition();
375:
376: String portletName = portlet.getUniqueName();
377:
378: PortletMode currentMappedMode = pa
379: .getMappedPortletMode(currentMode);
380: WindowState currentMappedState = pa
381: .getMappedWindowState(currentState);
382:
383: Object action;
384: PortletMode mappedMode;
385: PortletMode customMode;
386: WindowState mappedState;
387: WindowState customState;
388:
389: ArrayList actionTemplates = new ArrayList();
390:
391: DecoratorActionsFactory actionsAdapter = getDecoratorActionsAdapter(decoration);
392:
393: List supportedActions = actionsAdapter.getSupportedActions(
394: requestContext, pa, window, currentMappedMode,
395: currentMappedState, decoration);
396: Iterator iter = supportedActions.iterator();
397:
398: String currentModeAction = null;
399: String currentStateAction = null;
400:
401: while (iter.hasNext()) {
402: action = iter.next();
403: if (action instanceof PortletMode) {
404: mappedMode = (PortletMode) action;
405: customMode = pa.getCustomPortletMode(mappedMode);
406:
407: if (customMode != null) {
408: boolean equalsCurrentMode = customMode
409: .equals(currentMode);
410: if (equalsCurrentMode) {
411: currentModeAction = mappedMode.toString();
412: }
413: if (!equalsCurrentMode || isAjaxRequest) {
414: if ((content
415: .supportsPortletMode(customMode) || isAutoSwitchableCustomMode(
416: content, customMode))
417: && (!PortletMode.EDIT
418: .equals(customMode) || pageActionAccess
419: .isEditAllowed())
420: && pageActionAccess
421: .checkPortletMode(
422: fragmentId,
423: portletName,
424: mappedMode)) {
425: actionTemplates
426: .add(new DecoratorActionTemplate(
427: mappedMode, customMode));
428: }
429: }
430: }
431: } else if (action instanceof WindowState) {
432: mappedState = (WindowState) action;
433: customState = pa.getCustomWindowState(mappedState);
434:
435: if (customState != null) {
436: boolean equalsCurrentState = customState
437: .equals(currentState);
438: if (equalsCurrentState) {
439: currentStateAction = mappedState.toString();
440: }
441: if (!equalsCurrentState || isAjaxRequest) {
442: if (pageActionAccess.checkWindowState(
443: fragmentId, portletName,
444: mappedState)) {
445: actionTemplates
446: .add(new DecoratorActionTemplate(
447: mappedState,
448: customState));
449: }
450: }
451: }
452: }
453: }
454: actions = actionsAdapter.getDecoratorActions(
455: requestContext, pa, window, currentMode,
456: currentState, decoration, actionTemplates, portlet,
457: fragment, accessController);
458:
459: decoration.setCurrentModeAction(currentModeAction);
460: decoration.setCurrentStateAction(currentStateAction);
461: }
462:
463: decoration.setActions(actions);
464:
465: return fragmentSupportsActions;
466: }
467:
468: /**
469: * Builds a list of portlet modes that can be executed on the current
470: * <code>fragment</code> excluding the portlet's current mode.
471: *
472: * @param requestContext RequestContext of the current portal request.
473: * @param pageActionAccess
474: * @param mode
475: * @param content
476: * @param portletName
477: * @param window
478: * @param fragment
479: * @return <code>java.util.List</code> of modes excluding the current one.
480: * @throws PortletEntityNotStoredException
481: */
482: protected List getPageModes(RequestContext requestContext,
483: PortletWindow window, ContentTypeSet content,
484: PortletMode mode, WindowState state,
485: PageActionAccess pageActionAccess, Decoration decoration,
486: boolean isAjaxRequest) {
487: List pageModes = new ArrayList();
488:
489: try {
490: if (mode.equals(PortletMode.HELP)
491: || !state.equals(WindowState.NORMAL)) {
492: // switch back to VIEW mode and NORMAL state.
493: PortalURL portalURL = requestContext.getPortalURL();
494: String action = requestContext.getResponse().encodeURL(
495: (isAjaxRequest) ? portalURL
496: .createNavigationalEncoding(window,
497: PortletMode.VIEW,
498: WindowState.NORMAL) : portalURL
499: .createPortletURL(window,
500: PortletMode.VIEW,
501: WindowState.NORMAL,
502: portalURL.isSecure())
503: .toString());
504: String actionName = PortletMode.VIEW.toString();
505: pageModes.add(new DecoratorAction(actionName,
506: requestContext.getLocale(), decoration
507: .getResource("images/" + actionName
508: + ".gif"), action,
509: DecoratorActionTemplate.ACTION_TYPE_MODE));
510: } else if (pageActionAccess.isEditAllowed()) {
511: String targetMode = pageActionAccess.isEditing() ? PortletMode.VIEW
512: .toString()
513: : PortletMode.EDIT.toString();
514: PortalURL portalURL = requestContext.getPortalURL();
515: HashMap parameters = new HashMap();
516: String[] paramValues = new String[] { targetMode };
517: parameters.put("pageMode", paramValues);
518:
519: // Use an ActionURL to set the oposite pageMode and always set VIEW mode and state NORMAL
520: String action = requestContext.getResponse().encodeURL(
521: (isAjaxRequest) ? portalURL
522: .createNavigationalEncoding(window,
523: parameters, PortletMode.VIEW,
524: WindowState.NORMAL, true)
525: : portalURL.createPortletURL(window,
526: parameters, PortletMode.VIEW,
527: WindowState.NORMAL, true,
528: portalURL.isSecure())
529: .toString());
530: pageModes.add(new DecoratorAction(targetMode,
531: requestContext.getLocale(), decoration
532: .getResource("images/" + targetMode
533: + ".gif"), action,
534: DecoratorActionTemplate.ACTION_TYPE_MODE));
535:
536: //window.getPortletEntity().getPortletDefinition().getInitParameterSet().get( "xxxx" );
537:
538: if (content.supportsPortletMode(PortletMode.HELP)) {
539: if (pageActionAccess.isEditing()) {
540: // force it back to VIEW mode first with an ActionURL, as well as setting HELP mode and MAXIMIZED state
541: paramValues[0] = PortletMode.VIEW.toString();
542: action = requestContext
543: .getResponse()
544: .encodeURL(
545: (isAjaxRequest) ? portalURL
546: .createNavigationalEncoding(
547: window,
548: parameters,
549: PortletMode.HELP,
550: WindowState.MAXIMIZED,
551: true)
552: : portalURL
553: .createPortletURL(
554: window,
555: parameters,
556: PortletMode.HELP,
557: WindowState.MAXIMIZED,
558: true,
559: portalURL
560: .isSecure())
561: .toString());
562: } else {
563: // switch to mode HELP and state MAXIMIZED
564: action = requestContext
565: .getResponse()
566: .encodeURL(
567: (isAjaxRequest) ? portalURL
568: .createNavigationalEncoding(
569: window,
570: PortletMode.HELP,
571: WindowState.MAXIMIZED)
572: : portalURL
573: .createPortletURL(
574: window,
575: PortletMode.HELP,
576: WindowState.MAXIMIZED,
577: portalURL
578: .isSecure())
579: .toString());
580: }
581: String actionName = PortletMode.HELP.toString();
582: pageModes.add(new DecoratorAction(actionName,
583: requestContext.getLocale(), decoration
584: .getResource("images/" + actionName
585: + ".gif"), action,
586: DecoratorActionTemplate.ACTION_TYPE_MODE));
587: }
588: }
589: } catch (Exception e) {
590: log.warn("Unable to initalize PageLayout actions", e);
591: pageModes = null;
592: }
593:
594: return pageModes;
595: }
596:
597: /**
598: * Intializes all fragments with there decorations and portlet modes
599: * and winodw states.
600: *
601: *
602: * @param requestContext RequestContext of the current portal request.
603: * @param theme
604: * @param fragment
605: * @param pageActionAccess
606: */
607: protected void initDepthFragments(RequestContext requestContext,
608: Theme theme, ContentFragment fragment,
609: PageActionAccess pageActionAccess, boolean isAjaxRequest,
610: List collectFragments) {
611: final List contentFragments = fragment.getContentFragments();
612:
613: if (contentFragments != null && contentFragments.size() > 0) {
614: Iterator itr = contentFragments.iterator();
615: while (itr.hasNext()) {
616: ContentFragment aFragment = (ContentFragment) itr
617: .next();
618: initDepthFragments(requestContext, theme, aFragment,
619: pageActionAccess, isAjaxRequest,
620: collectFragments);
621: }
622: }
623:
624: if (initFragment(requestContext, theme, fragment,
625: pageActionAccess, isAjaxRequest)) {
626: if (collectFragments != null) {
627: collectFragments.add(fragment);
628: }
629: }
630: }
631:
632: protected boolean initFragment(RequestContext requestContext,
633: Theme theme, ContentFragment fragment,
634: PageActionAccess pageActionAccess, boolean isAjaxRequest) {
635: boolean fragmentSupportsActions = false;
636: try {
637: Decoration decoration = theme.getDecoration(fragment);
638: fragment.setDecoration(decoration);
639: fragmentSupportsActions = initActionsForFragment(
640: requestContext, fragment, pageActionAccess,
641: decoration, isAjaxRequest);
642: } catch (Exception e) {
643: log.warn("Unable to initalize actions for fragment "
644: + fragment.getId(), e);
645: }
646: return fragmentSupportsActions;
647: }
648:
649: /**
650: * Reintializes all fragments with there decorations and portlet modes
651: * and winodw states after theme is restored from cache.
652: *
653: * @param requestContext RequestContext of the current portal request.
654: * @param theme
655: * @param fragment
656: * @param pageActionAccess
657: * @param isAjaxRequest
658: * @param validator
659: * @param pathResolverCache
660: */
661: protected void initDepthFragmentDecorations(
662: RequestContext requestContext, Theme theme,
663: ContentFragment fragment,
664: PageActionAccess pageActionAccess, boolean isAjaxRequest,
665: ResourceValidator validator,
666: PathResolverCache pathResolverCache,
667: boolean reloadActionList) {
668: final List contentFragments = fragment.getContentFragments();
669:
670: if (contentFragments != null && contentFragments.size() > 0) {
671: Iterator itr = contentFragments.iterator();
672: while (itr.hasNext()) {
673: ContentFragment aFragment = (ContentFragment) itr
674: .next();
675: initDepthFragmentDecorations(requestContext, theme,
676: aFragment, pageActionAccess, isAjaxRequest,
677: validator, pathResolverCache, reloadActionList);
678: }
679: }
680:
681: try {
682: // PageTheme::getDecoration retrieves cached decoration only.
683: Decoration decoration = theme.getDecoration(fragment);
684: // re-init to set transient memebers.
685: Properties config = ((DecorationFactoryImpl) decorationFactory)
686: .getConfiguration(decoration.getName(), fragment
687: .getType());
688: ((BaseDecoration) decoration).init(config, validator,
689: pathResolverCache);
690: // fragment is newly created on every request, so reset decoration for fragment.
691: fragment.setDecoration(decoration);
692:
693: if (reloadActionList) {
694: initActionsForFragment(requestContext, fragment,
695: pageActionAccess, decoration, isAjaxRequest);
696: }
697: } catch (Exception e) {
698: log.warn("Unable to initalize actions for fragment "
699: + fragment.getId(), e);
700: }
701: }
702:
703: public void setMaximizeOnEdit(boolean maxOnEdit) {
704: this .maxOnEdit = maxOnEdit;
705: this .defaultDecoratorActionsFactory
706: .setMaximizeOnEdit(maxOnEdit);
707: }
708:
709: public boolean getMaximizeOnEdit() {
710: return this .maxOnEdit;
711: }
712:
713: public void setMaximizeOnConfig(boolean maxOnConfig) {
714: this .maxOnConfig = maxOnConfig;
715: this .defaultDecoratorActionsFactory
716: .setMaximizeOnConfig(maxOnConfig);
717: }
718:
719: public boolean getMaximizeOnConfig() {
720: return this .maxOnConfig;
721: }
722:
723: public void setMaximizeOnEditDefaults(boolean maxOnEditDefaults) {
724: this .maxOnEditDefaults = maxOnEditDefaults;
725: this .defaultDecoratorActionsFactory
726: .setMaximizeOnEditDefaults(maxOnEditDefaults);
727: }
728:
729: public boolean getMaximizeOnEditDefaults() {
730: return this .maxOnEditDefaults;
731: }
732:
733: public void setAutoSwitchingToEditDefaultsModes(
734: boolean autoSwitchingToEditDefaultsModes) {
735: this .autoSwitchingToEditDefaultsModes = autoSwitchingToEditDefaultsModes;
736: }
737:
738: public boolean getAutoSwitchingToEditDefaultsModes() {
739: return this .autoSwitchingToEditDefaultsModes;
740: }
741:
742: public void setAutoSwitchingForConfigMode(
743: boolean autoSwitchingForConfigMode) {
744: this .autoSwitchingForConfigMode = autoSwitchingForConfigMode;
745: }
746:
747: public boolean getAutoSwitchingForConfigMode() {
748: return this .autoSwitchingForConfigMode;
749: }
750:
751: private boolean isAutoSwitchableCustomMode(ContentTypeSet content,
752: PortletMode customMode) {
753: if (this .autoSwitchingForConfigMode
754: && JetspeedActions.CONFIG_MODE.equals(customMode)) {
755: return true;
756: }
757:
758: if (this .autoSwitchingToEditDefaultsModes) {
759: if (content.supportsPortletMode(PortletMode.EDIT)
760: && JetspeedActions.EDIT_DEFAULTS_MODE
761: .equals(customMode)) {
762: return true;
763: }
764: }
765:
766: return false;
767: }
768: }
|