Return-Path: Delivered-To: apmail-portals-jetspeed-dev-archive@www.apache.org Received: (qmail 1123 invoked from network); 2 Oct 2007 15:50:56 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 2 Oct 2007 15:50:56 -0000 Received: (qmail 73820 invoked by uid 500); 2 Oct 2007 15:50:44 -0000 Delivered-To: apmail-portals-jetspeed-dev-archive@portals.apache.org Received: (qmail 73796 invoked by uid 500); 2 Oct 2007 15:50:44 -0000 Mailing-List: contact jetspeed-dev-help@portals.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: "Jetspeed Developers List" Delivered-To: mailing list jetspeed-dev@portals.apache.org Received: (qmail 73785 invoked by uid 99); 2 Oct 2007 15:50:44 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 02 Oct 2007 08:50:44 -0700 X-ASF-Spam-Status: No, hits=-100.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 02 Oct 2007 15:50:53 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 23CD91A9832; Tue, 2 Oct 2007 08:50:03 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r581285 - in /portals/jetspeed-2/branches/JETSPEED-2.1.3: commons/src/java/org/apache/jetspeed/portlet/ commons/src/java/org/apache/jetspeed/util/ components/portal/src/java/org/apache/jetspeed/decoration/ components/portlet-factory/src/jav... Date: Tue, 02 Oct 2007 15:49:53 -0000 To: jetspeed-dev@portals.apache.org From: woonsan@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20071002155003.23CD91A9832@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: woonsan Date: Tue Oct 2 08:49:52 2007 New Revision: 581285 URL: http://svn.apache.org/viewvc?rev=581285&view=rev Log: [JS2-634] More advanced feature added: If a portlet does not support edit_defaults mode, but it supports edit mode, then Jetspeed can optionally provide automatic dispatching to doEdit() when the current portlet mode is edit_defaults. To enable this option: a) Set *autoSwitchingToEditDefaultsModes* to true for decorationValve in pipelines.xml like the following: true b) Set the first constructor arg to true for portletFactory bean in registry.xml like the following: false Limitations or Assumptions: a) If the doEdit() method of a portlet is not public, then the system will not provide auto-dispatching for the portlet with no error. b) If a portlet provide edit_defaults mode, then the system will not provide auto-dispatching. Instead, it will hand over rendering to the portlet. Added: portals/jetspeed-2/branches/JETSPEED-2.1.3/commons/src/java/org/apache/jetspeed/portlet/PortletObjectProxy.java portals/jetspeed-2/branches/JETSPEED-2.1.3/commons/src/java/org/apache/jetspeed/util/BaseObjectProxy.java portals/jetspeed-2/branches/JETSPEED-2.1.3/components/portlet-factory/src/java/org/apache/jetspeed/factory/JetspeedPortletProxyInstance.java Modified: portals/jetspeed-2/branches/JETSPEED-2.1.3/components/portal/src/java/org/apache/jetspeed/decoration/DecorationValve.java portals/jetspeed-2/branches/JETSPEED-2.1.3/components/portlet-factory/src/java/org/apache/jetspeed/factory/JetspeedPortletFactory.java portals/jetspeed-2/branches/JETSPEED-2.1.3/src/webapp/WEB-INF/assembly/pipelines.xml portals/jetspeed-2/branches/JETSPEED-2.1.3/src/webapp/WEB-INF/assembly/registry.xml Added: portals/jetspeed-2/branches/JETSPEED-2.1.3/commons/src/java/org/apache/jetspeed/portlet/PortletObjectProxy.java URL: http://svn.apache.org/viewvc/portals/jetspeed-2/branches/JETSPEED-2.1.3/commons/src/java/org/apache/jetspeed/portlet/PortletObjectProxy.java?rev=581285&view=auto ============================================================================== --- portals/jetspeed-2/branches/JETSPEED-2.1.3/commons/src/java/org/apache/jetspeed/portlet/PortletObjectProxy.java (added) +++ portals/jetspeed-2/branches/JETSPEED-2.1.3/commons/src/java/org/apache/jetspeed/portlet/PortletObjectProxy.java Tue Oct 2 08:49:52 2007 @@ -0,0 +1,193 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.jetspeed.portlet; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.lang.reflect.Modifier; + +import java.io.IOException; + +import javax.portlet.Portlet; +import javax.portlet.GenericPortlet; +import javax.portlet.PortletConfig; +import javax.portlet.PortletException; +import javax.portlet.PortletMode; +import javax.portlet.WindowState; +import javax.portlet.ActionRequest; +import javax.portlet.ActionResponse; +import javax.portlet.RenderRequest; +import javax.portlet.RenderResponse; + +import org.apache.pluto.om.portlet.PortletDefinition; +import org.apache.pluto.om.portlet.ContentTypeSet; + +import org.apache.jetspeed.JetspeedActions; +import org.apache.jetspeed.util.BaseObjectProxy; +import org.apache.jetspeed.container.JetspeedPortletConfig; + +/** + * PortletObjectProxy + * + * @author Woonsan Ko + * @version $Id: PortletObjectProxy.java 516448 2007-03-09 16:25:47Z ate $ + */ +public class PortletObjectProxy extends BaseObjectProxy +{ + + private static Method renderMethod; + + static + { + try + { + renderMethod = Portlet.class.getMethod("render", new Class [] { RenderRequest.class, RenderResponse.class }); + } + catch (NoSuchMethodException e) + { + throw new NoSuchMethodError(e.getMessage()); + } + } + + private Object portletObject; + private boolean genericPortletInvocable; + private Method portletDoEditMethod; + private ContentTypeSet portletContentTypeSet; + + public static Object createProxy(Object proxiedObject) + { + Class proxiedClass = proxiedObject.getClass(); + ClassLoader classLoader = proxiedClass.getClassLoader(); + Class [] proxyInterfaces = new Class [] { Portlet.class }; + InvocationHandler handler = new PortletObjectProxy(proxiedObject); + return Proxy.newProxyInstance(classLoader, proxyInterfaces, handler); + } + + private PortletObjectProxy(Object portletObject) + { + this.portletObject = portletObject; + + if (portletObject instanceof GenericPortlet) + { + try + { + this.portletDoEditMethod = this.portletObject.getClass().getMethod("doEdit", new Class [] { RenderRequest.class, RenderResponse.class }); + + if (Modifier.isPublic(this.portletDoEditMethod.getModifiers())) + { + this.genericPortletInvocable = true; + } + } + catch (NoSuchMethodException e) + { + } + } + else + { + System.out.println("!!!!! not generic portlet: " + this.portletObject); + } + } + + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable + { + Object result = null; + boolean handledHere = false; + Class declaringClass = method.getDeclaringClass(); + + if (declaringClass == Portlet.class) + { + if (renderMethod.equals(method)) + { + proxyRender((RenderRequest) args[0], (RenderResponse) args[1]); + return null; + } + else + { + result = method.invoke(this.portletObject, args); + } + } + else + { + result = super.invoke(proxy, method, args); + } + + return result; + } + + protected void proxyRender(RenderRequest request, RenderResponse response) throws PortletException, IOException, Exception + { + boolean autoSwitchToEditMode = false; + + if (this.genericPortletInvocable) + { + PortletMode mode = request.getPortletMode(); + + if (JetspeedActions.EDIT_DEFAULTS_MODE.equals(mode)) + { + if (!isSupportingEditDefaultsMode((GenericPortlet) this.portletObject)) + { + autoSwitchToEditMode = true; + } + } + } + + if (autoSwitchToEditMode) + { + GenericPortlet genericPortlet = (GenericPortlet) this.portletObject; + + // Override GenericPortlet#render.... + WindowState state = request.getWindowState(); + + if (!WindowState.MINIMIZED.equals(state)) + { + String title = genericPortlet.getPortletConfig().getResourceBundle(request.getLocale()).getString("javax.portlet.title"); + response.setTitle(title); + + this.portletDoEditMethod.invoke(genericPortlet, new Object [] { request, response }); + } + } + else + { + ((Portlet) this.portletObject).render(request, response); + } + } + + private boolean isSupportingEditDefaultsMode(GenericPortlet portlet) + { + if (this.portletContentTypeSet == null) + { + try + { + JetspeedPortletConfig config = (JetspeedPortletConfig) portlet.getPortletConfig(); + PortletDefinition portletDef = config.getPortletDefinition(); + this.portletContentTypeSet = portletDef.getContentTypeSet(); + } + catch (Exception e) + { + } + } + + if (this.portletContentTypeSet != null) + { + return this.portletContentTypeSet.supportsPortletMode(JetspeedActions.EDIT_DEFAULTS_MODE); + } + + return false; + } +} Added: portals/jetspeed-2/branches/JETSPEED-2.1.3/commons/src/java/org/apache/jetspeed/util/BaseObjectProxy.java URL: http://svn.apache.org/viewvc/portals/jetspeed-2/branches/JETSPEED-2.1.3/commons/src/java/org/apache/jetspeed/util/BaseObjectProxy.java?rev=581285&view=auto ============================================================================== --- portals/jetspeed-2/branches/JETSPEED-2.1.3/commons/src/java/org/apache/jetspeed/util/BaseObjectProxy.java (added) +++ portals/jetspeed-2/branches/JETSPEED-2.1.3/commons/src/java/org/apache/jetspeed/util/BaseObjectProxy.java Tue Oct 2 08:49:52 2007 @@ -0,0 +1,96 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.jetspeed.util; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; + +/** + * BaseObjectProxy + * + * @author Woonsan Ko + * @version $Id: BaseObjectProxy.java 516448 2007-03-09 16:25:47Z ate $ + */ +public class BaseObjectProxy implements InvocationHandler +{ + + protected static Method hashCodeMethod; + protected static Method equalsMethod; + protected static Method toStringMethod; + + static + { + try + { + hashCodeMethod = Object.class.getMethod("hashCode", null); + equalsMethod = Object.class.getMethod("equals", new Class [] { Object.class }); + toStringMethod = Object.class.getMethod("toString", null); + } + catch (NoSuchMethodException e) + { + throw new NoSuchMethodError(e.getMessage()); + } + } + + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable + { + Object result = null; + Class declaringClass = method.getDeclaringClass(); + + if (declaringClass == Object.class) + { + if (hashCodeMethod.equals(method)) + { + result = proxyHashCode(proxy); + } + else if (equalsMethod.equals(method)) + { + result = proxyEquals(proxy, args[0]); + } + else if (toStringMethod.equals(method)) + { + result = proxyToString(proxy); + } + else + { + throw new InternalError("unexpected Object method dispatched: " + method); + } + } + else + { + throw new InternalError("unexpected Object method dispatched: " + method); + } + + return result; + } + + protected Integer proxyHashCode(Object proxy) + { + return new Integer(System.identityHashCode(proxy)); + } + + protected Boolean proxyEquals(Object proxy, Object other) + { + return (proxy == other ? Boolean.TRUE : Boolean.FALSE); + } + + protected String proxyToString(Object proxy) + { + return proxy.getClass().getName() + '@' + Integer.toHexString(proxy.hashCode()); + } + +} Modified: portals/jetspeed-2/branches/JETSPEED-2.1.3/components/portal/src/java/org/apache/jetspeed/decoration/DecorationValve.java URL: http://svn.apache.org/viewvc/portals/jetspeed-2/branches/JETSPEED-2.1.3/components/portal/src/java/org/apache/jetspeed/decoration/DecorationValve.java?rev=581285&r1=581284&r2=581285&view=diff ============================================================================== --- portals/jetspeed-2/branches/JETSPEED-2.1.3/components/portal/src/java/org/apache/jetspeed/decoration/DecorationValve.java (original) +++ portals/jetspeed-2/branches/JETSPEED-2.1.3/components/portal/src/java/org/apache/jetspeed/decoration/DecorationValve.java Tue Oct 2 08:49:52 2007 @@ -88,6 +88,8 @@ private boolean useSessionForThemeCaching = false; private boolean maxOnEdit = false; + + private boolean autoSwitchingToEditDefaultsModes = true; /** * For security constraint checks @@ -386,7 +388,7 @@ } if ( ! equalsCurrentMode || isAjaxRequest ) { - if ( content.supportsPortletMode(customMode) + if ( (content.supportsPortletMode(customMode) || isAutoSwitchableCustomMode(customMode)) && (!PortletMode.EDIT.equals(customMode) || pageActionAccess.isEditAllowed()) && pageActionAccess.checkPortletMode(fragmentId, portletName, mappedMode) ) @@ -632,5 +634,28 @@ public boolean getMaximizeOnEdit() { return this.maxOnEdit; + } + + public void setAutoSwitchingToEditDefaultsModes(boolean autoSwitchingToEditDefaultsModes) + { + this.autoSwitchingToEditDefaultsModes = autoSwitchingToEditDefaultsModes; + } + + public boolean getAutoSwitchingToEditDefaultsModes() + { + return this.autoSwitchingToEditDefaultsModes; + } + + private boolean isAutoSwitchableCustomMode(PortletMode customMode) + { + if (this.autoSwitchingToEditDefaultsModes) + { + if (JetspeedActions.EDIT_DEFAULTS_MODE.equals(customMode)) + { + return true; + } + } + + return false; } } Modified: portals/jetspeed-2/branches/JETSPEED-2.1.3/components/portlet-factory/src/java/org/apache/jetspeed/factory/JetspeedPortletFactory.java URL: http://svn.apache.org/viewvc/portals/jetspeed-2/branches/JETSPEED-2.1.3/components/portlet-factory/src/java/org/apache/jetspeed/factory/JetspeedPortletFactory.java?rev=581285&r1=581284&r2=581285&view=diff ============================================================================== --- portals/jetspeed-2/branches/JETSPEED-2.1.3/components/portlet-factory/src/java/org/apache/jetspeed/factory/JetspeedPortletFactory.java (original) +++ portals/jetspeed-2/branches/JETSPEED-2.1.3/components/portlet-factory/src/java/org/apache/jetspeed/factory/JetspeedPortletFactory.java Tue Oct 2 08:49:52 2007 @@ -56,15 +56,24 @@ private static final Log log = LogFactory.getLog(JetspeedPortletFactory.class); private final Map classLoaderMap; + + private boolean portletProxyUsed = false; /** * */ public JetspeedPortletFactory() { + this(false); + } + + public JetspeedPortletFactory(boolean portletProxyUsed) + { this.portletCache = Collections.synchronizedMap(new HashMap()); this.validatorCache = Collections.synchronizedMap(new HashMap()); classLoaderMap = Collections.synchronizedMap(new HashMap()); + + this.portletProxyUsed = portletProxyUsed; } public void registerPortletApplication(PortletApplication pa, ClassLoader cl) @@ -205,7 +214,15 @@ // wrap new Portlet inside PortletInstance which ensures the destroy // method will wait for all its invocation threads to complete // and thereby releasing all its ClassLoader locks as needed for local portlets. - portlet = new JetspeedPortletInstance(pd.getName(), (Portlet)clazz.newInstance()); + + if (this.portletProxyUsed) + { + portlet = new JetspeedPortletProxyInstance(pd.getName(), (Portlet)clazz.newInstance()); + } + else + { + portlet = new JetspeedPortletInstance(pd.getName(), (Portlet)clazz.newInstance()); + } } finally { Added: portals/jetspeed-2/branches/JETSPEED-2.1.3/components/portlet-factory/src/java/org/apache/jetspeed/factory/JetspeedPortletProxyInstance.java URL: http://svn.apache.org/viewvc/portals/jetspeed-2/branches/JETSPEED-2.1.3/components/portlet-factory/src/java/org/apache/jetspeed/factory/JetspeedPortletProxyInstance.java?rev=581285&view=auto ============================================================================== --- portals/jetspeed-2/branches/JETSPEED-2.1.3/components/portlet-factory/src/java/org/apache/jetspeed/factory/JetspeedPortletProxyInstance.java (added) +++ portals/jetspeed-2/branches/JETSPEED-2.1.3/components/portlet-factory/src/java/org/apache/jetspeed/factory/JetspeedPortletProxyInstance.java Tue Oct 2 08:49:52 2007 @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.jetspeed.factory; + +import javax.portlet.Portlet; + +import org.apache.jetspeed.portlet.PortletObjectProxy; + +/** + * JetspeedPortletProxyInstance + * + * @author Woonsan Ko + * @version $Id: JetspeedPortletProxyInstance.java 516448 2007-03-09 16:25:47Z ate $ + * + */ +public class JetspeedPortletProxyInstance extends JetspeedPortletInstance +{ + public JetspeedPortletProxyInstance(String portletName, Portlet portlet) + { + super(portletName, (Portlet) PortletObjectProxy.createProxy(portlet)); + } +} Modified: portals/jetspeed-2/branches/JETSPEED-2.1.3/src/webapp/WEB-INF/assembly/pipelines.xml URL: http://svn.apache.org/viewvc/portals/jetspeed-2/branches/JETSPEED-2.1.3/src/webapp/WEB-INF/assembly/pipelines.xml?rev=581285&r1=581284&r2=581285&view=diff ============================================================================== --- portals/jetspeed-2/branches/JETSPEED-2.1.3/src/webapp/WEB-INF/assembly/pipelines.xml (original) +++ portals/jetspeed-2/branches/JETSPEED-2.1.3/src/webapp/WEB-INF/assembly/pipelines.xml Tue Oct 2 08:49:52 2007 @@ -323,6 +323,7 @@ --> false + false - + + + + false + + --------------------------------------------------------------------- To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org For additional commands, e-mail: jetspeed-dev-help@portals.apache.org