001: /******************************************************************************
002: * JBoss, a division of Red Hat *
003: * Copyright 2006, Red Hat Middleware, LLC, and individual *
004: * contributors as indicated by the @authors tag. See the *
005: * copyright.txt in the distribution for a full listing of *
006: * individual contributors. *
007: * *
008: * This is free software; you can redistribute it and/or modify it *
009: * under the terms of the GNU Lesser General Public License as *
010: * published by the Free Software Foundation; either version 2.1 of *
011: * the License, or (at your option) any later version. *
012: * *
013: * This software is distributed in the hope that it will be useful, *
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of *
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
016: * Lesser General Public License for more details. *
017: * *
018: * You should have received a copy of the GNU Lesser General Public *
019: * License along with this software; if not, write to the Free *
020: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
021: * 02110-1301 USA, or see the FSF site: http://www.fsf.org. *
022: ******************************************************************************/package org.jboss.portal.core.impl.model.content;
023:
024: import org.jboss.logging.Logger;
025: import org.jboss.portal.Mode;
026: import org.jboss.portal.WindowState;
027: import org.jboss.portal.core.aspects.portlet.AjaxInterceptor;
028: import org.jboss.portal.core.controller.ControllerResponse;
029: import org.jboss.portal.core.controller.command.response.SecurityErrorResponse;
030: import org.jboss.portal.core.controller.command.response.UnavailableResourceResponse;
031: import org.jboss.portal.core.model.content.Content;
032: import org.jboss.portal.core.model.content.ContentType;
033: import org.jboss.portal.core.model.content.spi.ContentProvider;
034: import org.jboss.portal.core.model.instance.Instance;
035: import org.jboss.portal.core.model.instance.InstancePermission;
036: import org.jboss.portal.core.model.portal.Portal;
037: import org.jboss.portal.core.model.portal.Window;
038: import org.jboss.portal.core.model.portal.PortalObject;
039: import org.jboss.portal.core.model.portal.command.response.MarkupResponse;
040: import org.jboss.portal.core.model.portal.content.ContentRenderer;
041: import org.jboss.portal.core.model.portal.content.WindowRendition;
042: import org.jboss.portal.core.model.portal.content.ContentRendererContext;
043: import org.jboss.portal.core.model.portal.navstate.WindowNavigationalState;
044: import org.jboss.portal.portlet.NoSuchPortletException;
045: import org.jboss.portal.portlet.PortletInvokerException;
046: import org.jboss.portal.portlet.info.CapabilitiesInfo;
047: import org.jboss.portal.portlet.info.ModeInfo;
048: import org.jboss.portal.portlet.info.WindowStateInfo;
049: import org.jboss.portal.portlet.invocation.PortletInvocation;
050: import org.jboss.portal.portlet.invocation.RenderInvocation;
051: import org.jboss.portal.portlet.invocation.response.ErrorResponse;
052: import org.jboss.portal.portlet.invocation.response.FragmentResponse;
053: import org.jboss.portal.portlet.invocation.response.InsufficientPrivilegesResponse;
054: import org.jboss.portal.portlet.invocation.response.InsufficientTransportGuaranteeResponse;
055: import org.jboss.portal.portlet.invocation.response.PortletInvocationResponse;
056: import org.jboss.portal.portlet.invocation.response.UnavailableResponse;
057: import org.jboss.portal.security.spi.auth.PortalAuthorizationManager;
058: import org.jboss.portal.security.spi.auth.PortalAuthorizationManagerFactory;
059: import org.jboss.portal.theme.impl.render.dynamic.DynaRenderOptions;
060:
061: import java.util.ArrayList;
062: import java.util.Collections;
063: import java.util.HashMap;
064: import java.util.Iterator;
065: import java.util.List;
066: import java.util.Map;
067: import java.util.Set;
068:
069: /**
070: * @author <a href="mailto:julien@jboss.org">Julien Viet</a>
071: * @version $Revision: 9006 $
072: */
073: public abstract class InternalContentProvider implements
074: ContentRenderer {
075:
076: /** . */
077: private final Logger log = Logger.getLogger(getClass());
078:
079: /** . */
080: private InternalContentProviderRegistry registry;
081:
082: /** . */
083: private String contentType;
084:
085: /** . */
086: private PortalAuthorizationManagerFactory pamf;
087:
088: /** . */
089: ContentType registeredContentType;
090:
091: /** . */
092: ContentProvider contentProvider;
093:
094: public PortalAuthorizationManagerFactory getPortalAuthorizationManagerFactory() {
095: return pamf;
096: }
097:
098: public void setPortalAuthorizationManagerFactory(
099: PortalAuthorizationManagerFactory portalAuthorizationManagerFactory) {
100: this .pamf = portalAuthorizationManagerFactory;
101: }
102:
103: public String getContentType() {
104: return contentType;
105: }
106:
107: public void setContentType(String contentType) {
108: this .contentType = contentType;
109: }
110:
111: public ContentType getRegisteredContentType() {
112: return registeredContentType;
113: }
114:
115: public InternalContentProviderRegistry getRegistry() {
116: return registry;
117: }
118:
119: public void setRegistry(InternalContentProviderRegistry registry) {
120: this .registry = registry;
121: }
122:
123: public void start() throws Exception {
124: registeredContentType = ContentType.create(contentType);
125:
126: //
127: contentProvider = createProvider();
128:
129: //
130: registry.registerContentProvider(this );
131: }
132:
133: protected abstract ContentProvider createProvider();
134:
135: public void stop() {
136: if (registeredContentType != null) {
137: registry.unregisterContentProvider(registeredContentType);
138: }
139: }
140:
141: /**
142: * Returns the portlet instance to render view mode.
143: *
144: * @param rendererContext
145: * @return the portlet instance for the view mode
146: */
147: protected abstract Instance getPortletInstance(
148: ContentRendererContext rendererContext);
149:
150: public WindowRendition renderWindow(
151: ContentRendererContext rendererContext) {
152: Window window = rendererContext.getWindow();
153:
154: // Get the parent portal
155: Portal portal = null;
156: for (PortalObject current = window; current != null; current = current
157: .getParent()) {
158: if (current.getType() == PortalObject.TYPE_PORTAL) {
159: portal = (Portal) current;
160: break;
161: }
162: }
163:
164: //
165: WindowNavigationalState windowNS = rendererContext
166: .getNavigationalState();
167:
168: //
169: if (windowNS == null) {
170: windowNS = new WindowNavigationalState(window
171: .getInitialWindowState(), window.getInitialMode(),
172: null);
173: rendererContext.setNavigationalState(windowNS);
174: }
175:
176: //
177: Map windowProps = new HashMap(window.getProperties());
178: Mode mode = windowNS.getMode();
179: WindowState windowState = windowNS.getWindowState();
180:
181: // Obtain instance
182: Instance instance = getPortletInstance(rendererContext);
183:
184: // No instance means we can't continue
185: if (instance == null) {
186: String ref = null;
187: Content content = window.getContent();
188: if (content != null) {
189: ref = content.getURI();
190: }
191: if (ref == null) {
192: ref = window.getId().toString();
193: }
194: UnavailableResourceResponse cr = new UnavailableResourceResponse(
195: ref, false);
196: return new WindowRendition(windowProps, windowState, mode,
197: Collections.singletonList(windowState), Collections
198: .singletonList(mode), cr);
199: }
200:
201: // Create invocation
202: RenderInvocation invocation = rendererContext
203: .createRenderInvocation(new WindowNavigationalState(
204: windowState, mode, windowNS.getContentState()));
205:
206: //
207: List supportedWindowStates = Collections.EMPTY_LIST;
208: List supportedModes = Collections.EMPTY_LIST;
209: PortletInvocationResponse response;
210:
211: //
212: try {
213: CapabilitiesInfo capabilitiesInfo = instance.getPortlet()
214: .getInfo().getCapabilities();
215:
216: //
217: Set windowStatesInfo = capabilitiesInfo
218: .getAllWindowStates();
219: supportedWindowStates = new ArrayList(windowStatesInfo
220: .size());
221: for (Iterator i = windowStatesInfo.iterator(); i.hasNext();) {
222: WindowStateInfo windowStateInfo = (WindowStateInfo) i
223: .next();
224: WindowState tmp = windowStateInfo.getWindowState();
225: if (portal.getSupportedWindowStates().contains(tmp)) {
226: supportedWindowStates.add(tmp);
227: }
228: }
229:
230: //
231: Set modesInfo = capabilitiesInfo.getAllModes();
232: supportedModes = new ArrayList(modesInfo.size());
233: for (Iterator i = modesInfo.iterator(); i.hasNext();) {
234: ModeInfo modeInfo = (ModeInfo) i.next();
235: Mode tmp = modeInfo.getMode();
236: if (portal.getSupportedModes().contains(tmp)) {
237: supportedModes.add(tmp);
238: }
239: }
240:
241: // Remove edit mode if the user is not logged it
242: if (rendererContext.getUser() == null) {
243: supportedModes.remove(Mode.EDIT);
244: }
245:
246: //
247: InstancePermission perm = new InstancePermission(instance
248: .getId(), InstancePermission.ADMIN_ACTION);
249: PortalAuthorizationManager pam = pamf.getManager();
250: boolean authorized = pam.checkPermission(perm);
251: if (!authorized) {
252: // Remove the modes that we know only admin are authorized to use
253: supportedModes.remove(Mode.ADMIN);
254: }
255:
256: //
257: response = instance.invoke(invocation);
258: } catch (PortletInvokerException e) {
259: ControllerResponse cr;
260:
261: //
262: if (e instanceof NoSuchPortletException) {
263: cr = new UnavailableResourceResponse(
264: ((NoSuchPortletException) e).getPortletId(),
265: false);
266: } else {
267: log
268: .error(
269: "Portlet invoker exception during portlet window rendering",
270: e);
271: cr = new org.jboss.portal.core.controller.command.response.ErrorResponse(
272: e, false);
273: }
274:
275: //
276: return new WindowRendition(windowProps, windowState, mode,
277: supportedWindowStates, supportedModes, cr);
278: }
279:
280: //
281: ControllerResponse cr;
282: if (response instanceof FragmentResponse) {
283: FragmentResponse fragment = (FragmentResponse) response;
284:
285: //
286: String windowTitle = fragment.getTitle();
287: if (windowTitle == null) {
288: windowTitle = window.getName();
289: }
290:
291: //
292: String headerChars = fragment.getHeader();
293:
294: // Handle minimized here
295: String contentChars;
296: if (WindowState.MINIMIZED == windowNS.getWindowState()) {
297: contentChars = "";
298: } else {
299: contentChars = fragment.getContent();
300: }
301:
302: // Update window props after render if needed
303: Boolean partialRefresh = (Boolean) invocation.getAttribute(
304: PortletInvocation.RESPONSE_PROPERTIES_SCOPE,
305: AjaxInterceptor.PARTIAL_REFRESH);
306: if (partialRefresh != null
307: && Boolean.FALSE.equals(partialRefresh)) {
308: DynaRenderOptions options = DynaRenderOptions
309: .getOptions(null, partialRefresh);
310: options.setOptions(windowProps);
311: }
312:
313: //
314: cr = new MarkupResponse(windowTitle, contentChars,
315: headerChars);
316: } else if (response instanceof ErrorResponse) {
317: cr = new org.jboss.portal.core.controller.command.response.ErrorResponse(
318: ((ErrorResponse) response).getCause(), false);
319: } else if (response instanceof UnavailableResponse) {
320: cr = new UnavailableResourceResponse(instance.getId(),
321: false);
322: } else if (response instanceof InsufficientPrivilegesResponse) {
323: cr = new SecurityErrorResponse(
324: SecurityErrorResponse.NOT_AUTHORIZED, false);
325: } else if (response instanceof InsufficientTransportGuaranteeResponse) {
326: cr = new SecurityErrorResponse(
327: SecurityErrorResponse.NOT_SECURE, false);
328: } else {
329: return null;
330: }
331:
332: //
333: return new WindowRendition(windowProps, windowState, mode,
334: supportedWindowStates, supportedModes, cr);
335: }
336: }
|