You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jetspeed-dev@portals.apache.org by wo...@apache.org on 2007/10/02 17:49:53 UTC
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...
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:
<property name="autoSwitchingToEditDefaultsModes"><value>true</value></property>
b) Set the first constructor arg to true for portletFactory bean in registry.xml like the following:
<bean id="portletFactory" class="org.apache.jetspeed.factory.JetspeedPortletFactory">
<!--
If the following argument is true, then this factory will create proxy instances for actual portlet instances.
Proxy instances will switch edit_defaults mode to edit mode automatically for portlets not supporting edit_defaults mode.
-->
<constructor-arg index="0">
<value>false</value>
</constructor-arg>
</bean>
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 <a href="mailto:woonsan@apache.org">Woonsan Ko</a>
+ * @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 <a href="mailto:woonsan@apache.org">Woonsan Ko</a>
+ * @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 <a href="mailto:woonsan@apache.org">Woonsan Ko</a>
+ * @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 @@
-->
<!-- When clicking on Edit Mode, also switch to Maximize -->
<property name="maximizeOnEdit"><value>false</value></property>
+ <property name="autoSwitchingToEditDefaultsModes"><value>false</value></property>
</bean>
<bean id="loginViewValve"
Modified: portals/jetspeed-2/branches/JETSPEED-2.1.3/src/webapp/WEB-INF/assembly/registry.xml
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/branches/JETSPEED-2.1.3/src/webapp/WEB-INF/assembly/registry.xml?rev=581285&r1=581284&r2=581285&view=diff
==============================================================================
--- portals/jetspeed-2/branches/JETSPEED-2.1.3/src/webapp/WEB-INF/assembly/registry.xml (original)
+++ portals/jetspeed-2/branches/JETSPEED-2.1.3/src/webapp/WEB-INF/assembly/registry.xml Tue Oct 2 08:49:52 2007
@@ -19,7 +19,15 @@
<beans>
<!-- Portlet Factory -->
- <bean id="portletFactory" class="org.apache.jetspeed.factory.JetspeedPortletFactory"></bean>
+ <bean id="portletFactory" class="org.apache.jetspeed.factory.JetspeedPortletFactory">
+ <!--
+ If the following argument is true, then this factory will create proxy instances for actual portlet instances.
+ Proxy instances will switch edit_defaults mode to edit mode automatically for portlets not supporting edit_defaults mode.
+ -->
+ <constructor-arg index="0">
+ <value>false</value>
+ </constructor-arg>
+ </bean>
<!-- Portlet Registry DAO-->
<bean id="portletRegistryImpl" class="org.apache.jetspeed.components.portletregistry.PersistenceBrokerPortletRegistry" init-method="init">
---------------------------------------------------------------------
To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org
For additional commands, e-mail: jetspeed-dev-help@portals.apache.org