[jboss-cvs] jboss-portal/portlet/src/main/org/jboss/portal/portlet/state/producer ...
Julien Viet
julien at jboss.com
Sun Jul 30 08:36:23 EDT 2006
User: julien
Date: 06/07/30 08:36:23
Modified: portlet/src/main/org/jboss/portal/portlet/state/producer
State.java StateStore.java
StatefulPortletInvoker.java
Added: portlet/src/main/org/jboss/portal/portlet/state/producer
InvalidStateIdException.java
NoSuchStateException.java
Log:
JBPORTAL-973 : Portlet instance container integration testing
JBPORTAL-972 : Portlet stateful invoker testing
Revision Changes Path
1.3 +4 -4 jboss-portal/portlet/src/main/org/jboss/portal/portlet/state/producer/State.java
(In the diff below, changes in quantity of whitespace are not shown.)
Index: State.java
===================================================================
RCS file: /cvsroot/jboss/jboss-portal/portlet/src/main/org/jboss/portal/portlet/state/producer/State.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- State.java 12 May 2006 06:25:15 -0000 1.2
+++ State.java 30 Jul 2006 12:36:23 -0000 1.3
@@ -27,7 +27,7 @@
/**
* @author <a href="mailto:julien at jboss.org">Julien Viet</a>
- * @version $Revision: 1.2 $
+ * @version $Revision: 1.3 $
*/
public interface State
{
@@ -46,11 +46,11 @@
String getPortletId();
/**
- * The state value.
+ * The state properties.
*
- * @return the state value
+ * @return the state properties
*/
- ValueMap getValue();
+ ValueMap getProperties();
/**
* The scheduled termination time.
1.3 +33 -10 jboss-portal/portlet/src/main/org/jboss/portal/portlet/state/producer/StateStore.java
(In the diff below, changes in quantity of whitespace are not shown.)
Index: StateStore.java
===================================================================
RCS file: /cvsroot/jboss/jboss-portal/portlet/src/main/org/jboss/portal/portlet/state/producer/StateStore.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- StateStore.java 28 May 2006 14:32:48 -0000 1.2
+++ StateStore.java 30 Jul 2006 12:36:23 -0000 1.3
@@ -27,7 +27,7 @@
* An abstraction for enabling state management on the producer side.
*
* @author <a href="mailto:julien at jboss.org">Julien Viet</a>
- * @version $Revision: 1.2 $
+ * @version $Revision: 1.3 $
*/
public interface StateStore
{
@@ -36,39 +36,62 @@
*
* @param stateId the state id
* @return the value map or null if it does not exist
- * @throws IllegalArgumentException if the id is null
+ * @throws IllegalArgumentException if the state id is null
+ * @throws NoSuchStateException is the specified state does not exist
+ * @throws InvalidStateIdException if the state id is not valid
*/
- State loadState(String stateId);
+ State loadState(String stateId) throws IllegalArgumentException, NoSuchStateException, InvalidStateIdException;
/**
* Create the initial state.
*
* @param portletId the id that this state refers to
+ * @return the id of the state created
+ * @throws IllegalArgumentException if the portlet id is null
+ */
+ String createState(String portletId, ValueMap valueMap) throws IllegalArgumentException;
+
+ /**
+ * Clone an existing state.
+ *
+ * @param stateId the id that this state refers to
* @return the state id
+ * @throws IllegalArgumentException if the state id is null
+ * @throws NoSuchStateException is the specified state does not exist
+ * @throws InvalidStateIdException if the state id is not valid
*/
- String createState(String portletId, ValueMap valueMap);
+ String cloneState(String stateId) throws IllegalArgumentException, NoSuchStateException, InvalidStateIdException;
/**
* Clone an existing state.
*
* @param stateId the id that this state refers to
- * @param valueMap the values of the cloned state if not null
+ * @param valueMap the values of the cloned state
* @return the state id
+ * @throws IllegalArgumentException if the state id is null or the value is nul
+ * @throws NoSuchStateException is the specified state does not exist
+ * @throws InvalidStateIdException if the state id is not valid
*/
- String cloneState(String stateId, ValueMap valueMap);
+ String cloneState(String stateId, ValueMap valueMap) throws IllegalArgumentException, NoSuchStateException, InvalidStateIdException;
/**
* Update the state.
*
- * @param id the state id
+ * @param stateId
* @param valueMap the updated state
+ * @throws IllegalArgumentException if the state id is null or the values are null
+ * @throws NoSuchStateException is the specified state does not exist
+ * @throws InvalidStateIdException if the state id is not valid
*/
- void updateState(String id, ValueMap valueMap);
+ void updateState(String stateId, ValueMap valueMap) throws IllegalArgumentException, NoSuchStateException, InvalidStateIdException;
/**
* Destroy the state.
*
- * @param id the state id
+ * @param stateId
+ * @throws IllegalArgumentException if the state id is null
+ * @throws NoSuchStateException is the specified state does not exist
+ * @throws InvalidStateIdException if the state id is not valid
*/
- void destroyState(String id);
+ void destroyState(String stateId) throws IllegalArgumentException, NoSuchStateException, InvalidStateIdException;
}
1.9 +274 -61 jboss-portal/portlet/src/main/org/jboss/portal/portlet/state/producer/StatefulPortletInvoker.java
(In the diff below, changes in quantity of whitespace are not shown.)
Index: StatefulPortletInvoker.java
===================================================================
RCS file: /cvsroot/jboss/jboss-portal/portlet/src/main/org/jboss/portal/portlet/state/producer/StatefulPortletInvoker.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -b -r1.8 -r1.9
--- StatefulPortletInvoker.java 28 May 2006 14:32:48 -0000 1.8
+++ StatefulPortletInvoker.java 30 Jul 2006 12:36:23 -0000 1.9
@@ -30,6 +30,7 @@
import org.jboss.portal.portlet.Portlet;
import org.jboss.portal.portlet.PortletInvoker;
import org.jboss.portal.portlet.PortletInvokerException;
+import org.jboss.portal.portlet.InvalidPortletIdException;
import org.jboss.portal.portlet.state.AccessMode;
import org.jboss.portal.portlet.state.AbstractPropertyContext;
import org.jboss.portal.portlet.info.PreferenceInfo;
@@ -40,10 +41,11 @@
import java.util.Iterator;
import java.util.Set;
+import java.util.ArrayList;
/**
* @author <a href="mailto:julien at jboss.org">Julien Viet</a>
- * @version $Revision: 1.8 $
+ * @version $Revision: 1.9 $
*/
public class StatefulPortletInvoker extends AbstractJBossService implements PortletInvoker
{
@@ -77,6 +79,50 @@
this.stateStore = stateStore;
}
+ public String unwrapCCPId(String wrappedCCPId) throws InvalidPortletIdException
+ {
+ if (wrappedCCPId == null)
+ {
+ throw new IllegalArgumentException();
+ }
+ if (wrappedCCPId.startsWith("_") == false)
+ {
+ throw new InvalidPortletIdException(wrappedCCPId);
+ }
+ return wrappedCCPId.substring(1);
+ }
+
+ public String unwrapPOPId(String wrappedPOPId) throws InvalidPortletIdException
+ {
+ if (wrappedPOPId == null)
+ {
+ throw new IllegalArgumentException();
+ }
+ return wrappedPOPId;
+ }
+
+ public String wrapCCPId(String ccpId) throws InvalidPortletIdException
+ {
+ if (ccpId == null)
+ {
+ throw new IllegalArgumentException();
+ }
+ return "_" + ccpId;
+ }
+
+ public String wrapPOPId(String popId) throws InvalidPortletIdException
+ {
+ if (popId == null)
+ {
+ throw new IllegalArgumentException();
+ }
+ if (popId.startsWith("_"))
+ {
+ throw new IllegalArgumentException("Must not start with _");
+ }
+ return popId;
+ }
+
public Set getPortlets() throws PortletInvokerException
{
return portletInvoker.getPortlets();
@@ -90,10 +136,20 @@
}
if (portletId.startsWith(CLONE_ID_PREFIX))
{
+ try
+ {
State state = stateStore.loadState(portletId.substring(1));
-// ValueMap value = state.getValue();
return portletInvoker.getPortlet(state.getPortletId());
}
+ catch (NoSuchStateException e)
+ {
+ return null;
+ }
+ catch (InvalidStateIdException e)
+ {
+ throw new InvalidPortletIdException(e, portletId);
+ }
+ }
else
{
return portletInvoker.getPortlet(portletId);
@@ -102,9 +158,9 @@
public void invoke(PortletInvocation invocation) throws PortletInvokerException, InvocationException
{
- // Get the id
- String portletId = (String)invocation.getAttribute(PortletInvocation.PORTLET_ID_ATTRIBUTE);
- if (portletId == null)
+ // Get the id of the portlet that the client want
+ String wantedPortletId = (String)invocation.getAttribute(PortletInvocation.PORTLET_ID_ATTRIBUTE);
+ if (wantedPortletId == null)
{
throw new InvocationException("No portlet id provided");
}
@@ -135,19 +191,30 @@
// State id not null implies that we have an existing state
String stateId = null;
+ // The next portlet to invoke
+ String portletId = wantedPortletId;
+
//
- if (portletId.startsWith("_"))
+ if (wantedPortletId.startsWith("_"))
{
//
- stateId = portletId.substring(1);
- State state = stateStore.loadState(stateId);
- if (state == null)
+ stateId = wantedPortletId.substring(1);
+ State state;
+ try
+ {
+ state = stateStore.loadState(stateId);
+ }
+ catch (NoSuchStateException e)
{
- throw new NoSuchPortletException("No state found in the state store");
+ throw new NoSuchPortletException(e, wantedPortletId);
+ }
+ catch (InvalidStateIdException e)
+ {
+ throw new InvalidPortletIdException(e, wantedPortletId);
}
//
- valueMap = state.getValue();
+ valueMap = state.getProperties();
portletId = state.getPortletId();
}
@@ -174,6 +241,7 @@
//
try
{
+ invocation.setAttribute(PortletInvocation.PORTLET_ID_ATTRIBUTE, portletId);
invocation.setAttribute(PortletInvocation.PREFERENCES_ATTRIBUTE, prefs);
invocation.setInfo(info);
@@ -182,15 +250,19 @@
}
finally
{
+ invocation.setAttribute(PortletInvocation.PORTLET_ID_ATTRIBUTE, wantedPortletId);
invocation.removeAttribute(PortletInvocation.PREFERENCES_ATTRIBUTE);
invocation.setInfo(null);
}
- // Producer state management
- if (invocation instanceof ActionInvocation && prefs.isChanged())
+ //
+ int status = prefs.getStatus();
+
+ // Producer state management if the invocation was succesful
+ if (invocation instanceof ActionInvocation && status == AbstractPropertyContext.UPDATE_SUCCEDED)
{
- // Get the potentially update prefs
- valueMap = prefs.getPrefs();
+ // Get the potentially updated prefs
+ ValueMap newPrefs = prefs.getPrefs();
//
if (access == AccessMode.CLONE_BEFORE_WRITE)
@@ -198,23 +270,62 @@
// Create the state
if (stateId != null)
{
- stateId = stateStore.cloneState(stateId, valueMap);
+ try
+ {
+ // The state id should be ok as it was used before to load the state
+ stateId = stateStore.cloneState(stateId, newPrefs);
+ }
+ catch (NoSuchStateException e)
+ {
+ throw new PortletInvokerException("Unexpected exception", e);
+ }
+ catch (InvalidStateIdException e)
+ {
+ throw new PortletInvokerException("Unexpected exception", e);
+ }
}
else
{
- stateId = stateStore.createState(portletId, valueMap);
+ // Add the missing mutable portlet state
+ for (Iterator i = prefsInfo.getKeys().iterator(); i.hasNext();)
+ {
+ String key = (String)i.next();
+ if (!newPrefs.getKeys().contains(key))
+ {
+ PreferenceInfo pref = prefsInfo.getPreference(key);
+ if (Boolean.TRUE.equals(pref.isReadOnly()) == false)
+ {
+ newPrefs.setValue(key, pref.getDefaultValue());
+ }
+ }
+ }
+
+ // Create the new state
+ stateId = stateStore.createState(portletId, newPrefs);
}
// Return the new state id
String cloneId = CLONE_ID_PREFIX + stateId;
// Make a callback for the clone id creation
- invocation.getInstanceContext().portletCloned(portletId, cloneId);
+ invocation.getInstanceContext().portletCloned(cloneId);
}
else if (access == AccessMode.READ_WRITE)
{
// Update the state
- stateStore.updateState(stateId, valueMap);
+ try
+ {
+ // the state id should be ok as it was used before to load the state
+ stateStore.updateState(stateId, newPrefs);
+ }
+ catch (NoSuchStateException e)
+ {
+ throw new PortletInvokerException("Unexpected exception", e);
+ }
+ catch (InvalidStateIdException e)
+ {
+ throw new PortletInvokerException("Unexpected exception", e);
+ }
}
else if (access == AccessMode.READ_ONLY)
{
@@ -225,12 +336,27 @@
public String createClone(String portletId) throws PortletInvokerException
{
+ if (portletId == null)
+ {
+ throw new IllegalArgumentException("No null portlet id accepted");
+ }
if (portletId.startsWith(CLONE_ID_PREFIX))
{
+ try
+ {
String stateId = portletId.substring(1);
- String cloneId = CLONE_ID_PREFIX + stateStore.cloneState(stateId, null);
+ String cloneId = CLONE_ID_PREFIX + stateStore.cloneState(stateId);
return cloneId;
}
+ catch (NoSuchStateException e)
+ {
+ throw new NoSuchPortletException(e, portletId);
+ }
+ catch (InvalidStateIdException e)
+ {
+ throw new InvalidPortletIdException(e, portletId);
+ }
+ }
else
{
ValueMap originalState = portletInvoker.getProperties(portletId);
@@ -246,76 +372,163 @@
}
}
- public void destroyClone(String portletId)
+ public void destroyClone(String portletId) throws PortletInvokerException
+ {
+ if (portletId == null)
+ {
+ throw new IllegalArgumentException("PortletId cannot be null");
+ }
+ if (portletId.startsWith(CLONE_ID_PREFIX) == false)
+ {
+ throw new InvalidPortletIdException("Bad portletId format " + portletId);
+ }
+ try
{
stateStore.destroyState(portletId.substring(1));
}
+ catch (NoSuchStateException e)
+ {
+ throw new NoSuchPortletException(e, portletId);
+ }
+ catch (InvalidStateIdException e)
+ {
+ throw new InvalidPortletIdException(e, portletId);
+ }
+ }
- public ValueMap getProperties(String portletId) throws PortletInvokerException
+ public ValueMap getProperties(final String portletId) throws PortletInvokerException
{
+ if (portletId == null)
+ {
+ throw new IllegalArgumentException("No null portlet id is accepted");
+ }
if (portletId.startsWith(CLONE_ID_PREFIX))
{
// Get state id
String stateId = portletId.substring(1);
// Load state from store
+ try
+ {
State state = stateStore.loadState(stateId);
// Get the content
- ValueMap values = new SimpleValueMap(state.getValue());
+ ValueMap values = new SimpleValueMap(state.getProperties());
// Dereference the portlet
- portletId = state.getPortletId();
+ String referencedPortletId = state.getPortletId();
// Get the container
- Portlet container = portletInvoker.getPortlet(portletId);
+ Portlet referencedPortlet = portletInvoker.getPortlet(referencedPortletId);
+
+ // We need the referenced portlet
+ if (referencedPortlet == null)
+ {
+ throw new PortletInvokerException("The portlet " + referencedPortletId + " referenced by this clone " + portletId + " is not available");
+ }
- // Add missing properties from the referenced portlet
- PreferencesInfo prefs = container.getInfo().getPreferences();
+ // Get the portlet info
+ PortletInfo referencedPortletInfo = referencedPortlet.getInfo();
+
+ // Add missing or read only properties from the referenced portlet
+ PreferencesInfo prefs = referencedPortletInfo.getPreferences();
for (Iterator i = prefs.getKeys().iterator(); i.hasNext();)
{
String key = (String)i.next();
PreferenceInfo pref = prefs.getPreference(key);
- if (!values.getKeys().contains(pref.getKey()))
+ if (Boolean.TRUE.equals(pref.isReadOnly()) || values.getKeys().contains(pref.getKey()) == false)
{
- values.setValue(key, (Value)pref.getDefaultValue().clone());
+ Value defaultValue = pref.getDefaultValue();
+ values.setValue(key, (Value)defaultValue.clone());
}
}
//
return values;
}
+ catch (NoSuchStateException e)
+ {
+ throw new NoSuchPortletException(e, portletId);
+ }
+ catch (InvalidStateIdException e)
+ {
+ throw new InvalidPortletIdException(e, portletId);
+ }
+ }
else
{
// Get the container
- Portlet portlet = portletInvoker.getPortlet(portletId);
+ return portletInvoker.getProperties(portletId);
+ }
+ }
- // The prefs info
- PreferencesInfo prefs = portlet.getInfo().getPreferences();
+ public void setProperties(String portletId, ValueMap properties) throws PortletInvokerException
+ {
+ if (portletId == null)
+ {
+ throw new IllegalArgumentException("No null portlet id accepted");
+ }
+ if (properties == null)
+ {
+ throw new IllegalArgumentException("No null properties accepted");
+ }
+ if (portletId.startsWith(CLONE_ID_PREFIX) == false)
+ {
+ throw new InvalidPortletIdException("Cannot configure producer offered portlets", portletId);
+ }
+ try
+ {
+ String stateId = portletId.substring(1);
- // Get the state
- ValueMap value = new SimpleValueMap();
- for (Iterator i = prefs.getKeys().iterator(); i.hasNext();)
+ // Load the state
+ State state = stateStore.loadState(stateId);
+
+ // Dereference the portlet
+ String referencedPortletId = state.getPortletId();
+
+ // Get the container
+ Portlet referencedPortlet = portletInvoker.getPortlet(referencedPortletId);
+
+ // We need the referenced portlet
+ if (referencedPortlet == null)
{
- String key = (String)i.next();
- PreferenceInfo pref = prefs.getPreference(key);
- value.setValue(key, (Value)pref.getDefaultValue().clone());
+ throw new PortletInvokerException("The portlet " + referencedPortletId + " referenced by this clone " + portletId + " is not available");
}
+ // Get the portlet info
+ PortletInfo referencedPortletInfo = referencedPortlet.getInfo();
+
//
- return value;
+ PreferencesInfo prefs = referencedPortletInfo.getPreferences();
+
+ // Clone argument
+ properties = new SimpleValueMap(properties);
+
+ // Remove read only values
+ for (Iterator i = new ArrayList(properties.getKeys()).iterator();i.hasNext();)
+ {
+ String key = (String)i.next();
+ Value value = properties.getValue(key);
+ PreferenceInfo pref = prefs.getPreference(key);
+ if (pref != null)
+ {
+ if (Boolean.TRUE.equals(pref.isReadOnly()))
+ {
+ properties.setValue(key, null);
+ }
}
}
- public void setProperties(String portletId, ValueMap properties)
- {
- if (portletId.startsWith(CLONE_ID_PREFIX))
+ //
+ stateStore.updateState(stateId, properties);
+ }
+ catch (NoSuchStateException e)
{
- stateStore.updateState(portletId.substring(1), properties);
+ throw new NoSuchPortletException(e, portletId);
}
- else
+ catch (InvalidStateIdException e)
{
- throw new IllegalArgumentException();
+ throw new InvalidPortletIdException(e, portletId);
}
}
}
1.1 date: 2006/07/30 12:36:23; author: julien; state: Exp;jboss-portal/portlet/src/main/org/jboss/portal/portlet/state/producer/InvalidStateIdException.java
Index: InvalidStateIdException.java
===================================================================
/*
* JBoss, Home of Professional Open Source
* Copyright 2005, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.portal.portlet.state.producer;
/**
* @author <a href="mailto:julien at jboss.org">Julien Viet</a>
* @version $Revision: 1.1 $
*/
public class InvalidStateIdException extends Exception
{
private String stateId;
public InvalidStateIdException(String stateId)
{
super("No such state " + stateId);
this.stateId = stateId;
}
public InvalidStateIdException(String message, String portletId)
{
super(message);
this.stateId = portletId;
}
public InvalidStateIdException(Throwable cause, String portletId)
{
super(cause);
this.stateId = portletId;
}
public InvalidStateIdException(String message, Throwable cause, String portletId)
{
super(message, cause);
this.stateId = portletId;
}
public String getStateId()
{
return stateId;
}
}
1.1 date: 2006/07/30 12:36:23; author: julien; state: Exp;jboss-portal/portlet/src/main/org/jboss/portal/portlet/state/producer/NoSuchStateException.java
Index: NoSuchStateException.java
===================================================================
/*
* JBoss, Home of Professional Open Source
* Copyright 2005, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.portal.portlet.state.producer;
/**
* @author <a href="mailto:julien at jboss.org">Julien Viet</a>
* @version $Revision: 1.1 $
*/
public class NoSuchStateException extends Exception
{
private String stateId;
public NoSuchStateException(String stateId)
{
super("No such state " + stateId);
this.stateId = stateId;
}
public NoSuchStateException(String message, String portletId)
{
super(message);
this.stateId = portletId;
}
public NoSuchStateException(Throwable cause, String portletId)
{
super(cause);
this.stateId = portletId;
}
public NoSuchStateException(String message, Throwable cause, String portletId)
{
super(message, cause);
this.stateId = portletId;
}
public String getStateId()
{
return stateId;
}
}
More information about the jboss-cvs-commits
mailing list