[jboss-svn-commits] JBoss Portal SVN: r5246 - in trunk: common/src/main/org/jboss/portal/common/transaction common/src/main/org/jboss/portal/common/util core core/src/main/org/jboss/portal/core/impl/model/instance core/src/main/org/jboss/portal/core/model/instance core/src/main/org/jboss/portal/core/portlet/management core/src/main/org/jboss/portal/test/core/model/instance core/src/resources/portal-core-sar core/src/resources/portal-core-test-jar/org/jboss/portal/test/core/model/instance portlet/src/main/org/jboss/portal/portlet/state/producer portlet/src/main/org/jboss/portal/portlet/test/support/info test/src/etc test/src/main/org/jboss/portal/test/framework/embedded test/src/main/org/jboss/portal/test/framework/junit test/src/main/org/jboss/portal/test/framework/junit/metadata

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Mon Sep 25 10:52:17 EDT 2006


Author: julien at jboss.com
Date: 2006-09-25 10:51:47 -0400 (Mon, 25 Sep 2006)
New Revision: 5246

Added:
   trunk/core/src/main/org/jboss/portal/core/impl/model/instance/AbstractInstance.java
   trunk/test/src/main/org/jboss/portal/test/framework/junit/TestCaseFactory.java
   trunk/test/src/main/org/jboss/portal/test/framework/junit/metadata/
   trunk/test/src/main/org/jboss/portal/test/framework/junit/metadata/TestCaseMetaData.java
   trunk/test/src/main/org/jboss/portal/test/framework/junit/metadata/TestCaseParameterIterableValue.java
   trunk/test/src/main/org/jboss/portal/test/framework/junit/metadata/TestCaseParameterMetaData.java
   trunk/test/src/main/org/jboss/portal/test/framework/junit/metadata/TestCaseParameterValue.java
Modified:
   trunk/common/src/main/org/jboss/portal/common/transaction/Transactions.java
   trunk/common/src/main/org/jboss/portal/common/util/LocalizedString.java
   trunk/core/build.xml
   trunk/core/src/main/org/jboss/portal/core/impl/model/instance/InstanceContextImpl.java
   trunk/core/src/main/org/jboss/portal/core/impl/model/instance/InstanceImpl.java
   trunk/core/src/main/org/jboss/portal/core/impl/model/instance/PersistentInstanceContainer.java
   trunk/core/src/main/org/jboss/portal/core/impl/model/instance/UserInstance.java
   trunk/core/src/main/org/jboss/portal/core/model/instance/InstanceContainer.java
   trunk/core/src/main/org/jboss/portal/core/portlet/management/InstanceManagerBean.java
   trunk/core/src/main/org/jboss/portal/test/core/model/instance/InstanceContainerTestCase.java
   trunk/core/src/resources/portal-core-sar/portal-aop.xml
   trunk/core/src/resources/portal-core-test-jar/org/jboss/portal/test/core/model/instance/jboss-beans.xml
   trunk/portlet/src/main/org/jboss/portal/portlet/state/producer/ProducerPortletInvoker.java
   trunk/portlet/src/main/org/jboss/portal/portlet/test/support/info/MetaInfoSupport.java
   trunk/test/src/etc/datasources.xml
   trunk/test/src/main/org/jboss/portal/test/framework/embedded/DataSourceSupport.java
   trunk/test/src/main/org/jboss/portal/test/framework/junit/TransactionAssert.java
Log:
- updated the InstanceContainer to be able to handle state stored on the consumer
- updated InstanceContainer test case to test when state is stored on producer and on consumer
- improved junit tools by adding stuff to create parameterized test case
- make LocalizedValue really immutable and added getDefaultString() / getDefaultValue()

Modified: trunk/common/src/main/org/jboss/portal/common/transaction/Transactions.java
===================================================================
--- trunk/common/src/main/org/jboss/portal/common/transaction/Transactions.java	2006-09-23 12:29:49 UTC (rev 5245)
+++ trunk/common/src/main/org/jboss/portal/common/transaction/Transactions.java	2006-09-25 14:51:47 UTC (rev 5246)
@@ -41,10 +41,11 @@
 public class Transactions
 {
 
+   /** . */
    private static Logger log = Logger.getLogger(Transactions.class);
 
+   /** . */
    private static final String[] STATUS_NAMES = {
-      "CANNOT_GET_STATUS",
       "STATUS_ACTIVE",
       "STATUS_MARKED_ROLLBACK",
       "STATUS_PREPARED",
@@ -57,6 +58,24 @@
       "STATUS_ROLLING_BACK"};
 
    /**
+    * Decode the status name.
+    *
+    * @param status the status value
+    * @return the translated status name or null if it is not valid
+    */
+   public static String decodeStatus(int status)
+   {
+      if (status >= 0 && status <= STATUS_NAMES.length)
+      {
+         return STATUS_NAMES[status];
+      }
+      else
+      {
+         return null;
+      }
+   }
+
+   /**
     * Apply the transaction type before the unit of work.
     *
     * @param type the transaction type

Modified: trunk/common/src/main/org/jboss/portal/common/util/LocalizedString.java
===================================================================
--- trunk/common/src/main/org/jboss/portal/common/util/LocalizedString.java	2006-09-23 12:29:49 UTC (rev 5245)
+++ trunk/common/src/main/org/jboss/portal/common/util/LocalizedString.java	2006-09-25 14:51:47 UTC (rev 5246)
@@ -27,6 +27,7 @@
 import java.util.Iterator;
 import java.util.Locale;
 import java.util.Map;
+import java.util.Collections;
 
 /**
  * An immutable localized string.
@@ -38,57 +39,67 @@
 public class LocalizedString
 {
 
-   /**
-    * .
-    */
+   /** The logger. */
    private static final Logger log = Logger.getLogger(LocalizedString.class);
 
-   /**
-    * The descriptions.
-    */
-   private Map values;
+   /** The descriptions. */
+   private final Map values;
 
-   /**
-    * The default locale.
-    */
-   private Locale defaultLocale;
+   /** The default locale. */
+   private final Locale defaultLocale;
 
    /**
     * Convenience constructor for simple localized strings with only one value using the default locale.
     *
-    * @param value         the localized value using the specified default locale
+    * @param defaultValue         the localized value using the specified default locale
     * @param defaultLocale the default locale
     * @since 2.4
     */
-   public LocalizedString(String value, Locale defaultLocale)
+   public LocalizedString(String defaultValue, Locale defaultLocale) throws IllegalArgumentException
    {
-      this(defaultLocale);
-      values = new HashMap(3);
-      addValueForLocale(defaultLocale, value);
+      if (defaultValue == null)
+      {
+         throw new IllegalArgumentException("No null default value allowed");
+      }
+      if (defaultLocale == null)
+      {
+         throw new IllegalArgumentException("No null default locale allowed");
+      }
+
+      //
+      Map values = new HashMap(3);
+      addValueForLocale(values, defaultLocale, defaultValue);
+
+      //
+      this.defaultLocale = defaultLocale;
+      this.values = Collections.unmodifiableMap(values);
    }
 
-   public LocalizedString(Locale defaultLocale)
+   public LocalizedString(Locale defaultLocale) throws IllegalArgumentException
    {
       if (defaultLocale == null)
       {
          throw new IllegalArgumentException("No null default locale allowed");
       }
+
+      //
       this.defaultLocale = defaultLocale;
-      values = new HashMap(11);
+      this.values = Collections.EMPTY_MAP;
    }
 
-   public LocalizedString(Map values, Locale defaultLocale)
+   public LocalizedString(Map values, Locale defaultLocale) throws IllegalArgumentException
    {
-      this(defaultLocale);
-
       if (values == null)
       {
          throw new IllegalArgumentException("No null description map allowed");
       }
-      //
-      this.values = new HashMap(values.size());
+      if (defaultLocale == null)
+      {
+         throw new IllegalArgumentException("No null default locale allowed");
+      }
 
       // Convert strings to value
+      Map tmp = new HashMap(values.size());
       for (Iterator i = values.entrySet().iterator(); i.hasNext();)
       {
          Map.Entry entry = (Map.Entry)i.next();
@@ -102,9 +113,12 @@
          {
             throw new IllegalArgumentException("Value not a string " + entry.getValue());
          }
+         addValueForLocale(tmp, (Locale)key, (String)value);
+      }
 
-         addValueForLocale((Locale)key, (String)value);
-      }
+      //
+      this.defaultLocale = defaultLocale;
+      this.values = Collections.unmodifiableMap(tmp);
    }
 
    /**
@@ -115,7 +129,7 @@
     * @param value  the value
     * @since 2.4
     */
-   private void addValueForLocale(Locale locale, String value)
+   private void addValueForLocale(Map values, Locale locale, String value)
    {
       values.put(locale, new Value(locale, value));
    }
@@ -128,10 +142,30 @@
     */
    public boolean hasValues()
    {
-      return !values.isEmpty();
+      return values.isEmpty() == false;
    }
 
    /**
+    * Return the string for the default locale.
+    *
+    * @return the string for the default locale
+    */
+   public String getDefaultString()
+   {
+      return getString(defaultLocale, false);
+   }
+
+   /**
+    * Return the value for the default locale.
+    *
+    * @return the value for the default locale
+    */
+   public Value getDefaultValue()
+   {
+      return getValue(defaultLocale, false);
+   }
+
+   /**
     * Return the string of the localized value of the description.
     *
     * @param locale  the desired locale for the description

Modified: trunk/core/build.xml
===================================================================
--- trunk/core/build.xml	2006-09-23 12:29:49 UTC (rev 5245)
+++ trunk/core/build.xml	2006-09-25 14:51:47 UTC (rev 5246)
@@ -227,7 +227,7 @@
          <include name="org/jboss/portal/core/deployment/jboss/ObjectDeployment.class"/>
          <include name="org/jboss/portal/core/deployment/jboss/PortletAppDeployment.class"/>
          <include name="org/jboss/portal/core/impl/model/instance/PersistentInstanceContainer.class"/>
-         <include name="org/jboss/portal/core/impl/portlet/state/StatefulPortletInvoker.class"/>
+         <include name="org/jboss/portal/core/impl/portlet/state/ProducerPortletInvoker.class"/>
          <include name="org/jboss/portal/core/hibernate/SessionFactoryBinder.class"/>
       </aopc>
 
@@ -551,7 +551,7 @@
          </x-sysproperty>
          <x-test>
             <test todir="${test.reports}" name="org.jboss.portal.test.core.model.instance.InstanceContainerTestCase"/>
-            <test todir="${test.reports}" name="org.jboss.portal.test.core.state.ProducerTestCase"/>
+            <!--<test todir="${test.reports}" name="org.jboss.portal.test.core.state.ProducerTestCase"/>-->
             <test todir="${test.reports}" name="org.jboss.portal.test.core.deployment.JBossApplicationMetaDataFactoryTestCase"/>
          </x-test>
          <x-classpath>
@@ -736,11 +736,11 @@
    <!-- Build the tests report -->
    <target name="tests-report" depends="init" description="Build the tests report">
 
-      <junitreport todir="${test.reports}">
-         <fileset dir="${test.reports}">
+      <junitreport todir="output/reports">
+         <fileset dir="output/tests">
             <include name="TEST-*.xml"/>
          </fileset>
-         <report format="frames" todir="${test.reports}/html"/>
+         <report format="frames" todir="output/reports/html"/>
       </junitreport>
    </target>
 

Added: trunk/core/src/main/org/jboss/portal/core/impl/model/instance/AbstractInstance.java
===================================================================
--- trunk/core/src/main/org/jboss/portal/core/impl/model/instance/AbstractInstance.java	2006-09-23 12:29:49 UTC (rev 5245)
+++ trunk/core/src/main/org/jboss/portal/core/impl/model/instance/AbstractInstance.java	2006-09-25 14:51:47 UTC (rev 5246)
@@ -0,0 +1,97 @@
+/*
+* 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.core.impl.model.instance;
+
+import org.jboss.portal.portlet.PortletContext;
+import org.jboss.portal.portlet.StatefulPortletContext;
+
+/**
+ * @author <a href="mailto:julien at jboss.org">Julien Viet</a>
+ * @version $Revision: 1.1 $
+ */
+public class AbstractInstance
+{
+
+   /** . */
+   protected Long key;
+
+   /** . */
+   protected String portletRef;
+
+   /** . */
+   protected byte[] state;
+
+   public Long getKey()
+   {
+      return key;
+   }
+
+   public void setKey(Long key)
+   {
+      this.key = key;
+   }
+
+   public String getPortletRef()
+   {
+      return portletRef;
+   }
+
+   public void setPortletRef(String portletRef)
+   {
+      this.portletRef = portletRef;
+   }
+
+   public byte[] getState()
+   {
+      return state;
+   }
+
+   public void setState(byte[] state)
+   {
+      this.state = state;
+   }
+
+   public PortletContext getPortletContext()
+   {
+      if (state != null)
+      {
+         return new StatefulPortletContext(portletRef, state);
+      }
+      else
+      {
+         return new PortletContext(portletRef);
+      }
+   }
+
+   void setPortletContext(PortletContext portletContext)
+   {
+      portletRef = portletContext.getId();
+
+      //
+      if (portletContext instanceof StatefulPortletContext)
+      {
+         StatefulPortletContext statefulPortletContext = (StatefulPortletContext)portletContext;
+         state = statefulPortletContext.getMarshalldState();
+      }
+   }
+
+}

Modified: trunk/core/src/main/org/jboss/portal/core/impl/model/instance/InstanceContextImpl.java
===================================================================
--- trunk/core/src/main/org/jboss/portal/core/impl/model/instance/InstanceContextImpl.java	2006-09-23 12:29:49 UTC (rev 5245)
+++ trunk/core/src/main/org/jboss/portal/core/impl/model/instance/InstanceContextImpl.java	2006-09-25 14:51:47 UTC (rev 5246)
@@ -36,10 +36,18 @@
 public class InstanceContextImpl implements InstanceContext
 {
 
+   /** . */
    protected final Instance instance;
+
+   /** . */
    protected final AccessMode accessMode;
+
+   /** . */
    protected PortletContext clonedContext;
 
+   /** . */
+   protected PortletContext modifiedContext;
+
    public InstanceContextImpl(Instance instance, AccessMode accessMode)
    {
       if (instance == null)
@@ -69,7 +77,8 @@
       }
       else if (event instanceof PortletModifiedEvent)
       {
-         throw new UnsupportedOperationException("todo");
+         PortletModifiedEvent pme = (PortletModifiedEvent)event;
+         modifiedContext = pme.getModifiedContext();
       }
    }
 }

Modified: trunk/core/src/main/org/jboss/portal/core/impl/model/instance/InstanceImpl.java
===================================================================
--- trunk/core/src/main/org/jboss/portal/core/impl/model/instance/InstanceImpl.java	2006-09-23 12:29:49 UTC (rev 5245)
+++ trunk/core/src/main/org/jboss/portal/core/impl/model/instance/InstanceImpl.java	2006-09-25 14:51:47 UTC (rev 5246)
@@ -23,7 +23,6 @@
 
 import org.hibernate.Query;
 import org.hibernate.Session;
-import org.hibernate.HibernateException;
 import org.jboss.portal.portlet.state.PropertyMap;
 import org.jboss.portal.core.model.instance.Instance;
 import org.jboss.portal.core.model.instance.InstanceContainer;
@@ -48,7 +47,7 @@
  * @author <a href="mailto:julien at jboss.org">Julien Viet</a>
  * @version $Revision$
  */
-public class InstanceImpl implements Instance, ContextObject
+public class InstanceImpl extends AbstractInstance implements Instance, ContextObject
 {
 
    /** The logger. */
@@ -56,11 +55,8 @@
 
    // Persistent fields
 
-   protected Long key;
    protected String instanceId;
    protected boolean modifiable;
-   protected String portletRef;
-   protected byte[] state;
    protected Map securityBindings;
    protected Set userInstances;
 
@@ -79,29 +75,21 @@
       this.state = null;
    }
 
-   public InstanceImpl(ContainerContext ctx, String id, String portletRef)
+   public InstanceImpl(ContainerContext ctx, String id, PortletContext portletContext)
    {
       this.context = ctx;
       this.modifiable = false;
-      this.portletRef = portletRef;
       this.instanceId = id;
       this.securityBindings = new HashMap();
       this.userInstances = new HashSet();
       this.state = null;
+
+      //
+      setPortletContext(portletContext);
    }
 
    // Hibernate ********************************************************************************************************
 
-   public Long getKey()
-   {
-      return key;
-   }
-
-   public void setKey(Long key)
-   {
-      this.key = key;
-   }
-
    public String getInstanceId()
    {
       return instanceId;
@@ -132,26 +120,12 @@
       this.userInstances = userInstances;
    }
 
-   public void setPortletRef(String portletRef)
-   {
-      this.portletRef = portletRef;
-   }
-
    public void setModifiable(boolean modifiable)
    {
       this.modifiable = modifiable;
    }
 
-   public byte[] getState()
-   {
-      return state;
-   }
 
-   public void setState(byte[] state)
-   {
-      this.state = state;
-   }
-
    // ContextObject implementation *************************************************************************************
 
    public void setContext(Object context)
@@ -159,13 +133,10 @@
       this.context = (ContainerContext)context;
    }
 
+   // Misc *************************************************************************************************************
+
    // Instance implementation ******************************************************************************************
 
-   public String getPortletRef()
-   {
-      return portletRef;
-   }
-
    public String getId()
    {
       return instanceId;
@@ -185,7 +156,7 @@
    {
       PersistentInstanceContainer container = (PersistentInstanceContainer)context.getContainer();
       PortletInvoker invoker = container.getPortletInvoker();
-      return invoker.getPortlet(new PortletContext(portletRef));
+      return invoker.getPortlet(getPortletContext());
    }
 
    public void setProperties(PropertyChange[] changes) throws PortletInvokerException
@@ -198,31 +169,31 @@
       if (!modifiable)
       {
          // Clone the portlet
-         String clonedPortletId = portletInvoker.createClone(new PortletContext(portletRef)).getId();
+         PortletContext clonedPortletContext = portletInvoker.createClone(getPortletContext());
 
          // Update the state
-         portletRef = clonedPortletId;
+         setPortletContext(clonedPortletContext);
          modifiable = true;
          Session session = container.getCurrentSession();
          session.update(this);
       }
 
       //
-      portletInvoker.setProperties(new PortletContext(portletRef), changes);
+      portletInvoker.setProperties(getPortletContext(), changes);
    }
 
    public PropertyMap getProperties() throws PortletInvokerException
    {
       PersistentInstanceContainer container = (PersistentInstanceContainer)context.getContainer();
       PortletInvoker invoker = container.getPortletInvoker();
-      return invoker.getProperties(new PortletContext(portletRef));
+      return invoker.getProperties(getPortletContext());
    }
 
    public PropertyMap getProperties(Set keys) throws PortletInvokerException
    {
       PersistentInstanceContainer container = (PersistentInstanceContainer)context.getContainer();
       PortletInvoker invoker = container.getPortletInvoker();
-      return invoker.getProperties(new PortletContext(portletRef), keys);
+      return invoker.getProperties(getPortletContext(), keys);
    }
 
    public void invoke(PortletInvocation invocation) throws PortletInvokerException
@@ -236,7 +207,7 @@
       String userId = ctx.getId();
 
       //
-      String portletId = portletRef;
+      AbstractInstance instance = this;
       AccessMode accessMode = AccessMode.READ_ONLY;
       if (userId != null)
       {
@@ -260,7 +231,7 @@
             // Use the instance in read_write if we have
             if (userInstance != null)
             {
-               portletId = userInstance.getPortletRef();
+               instance = userInstance;
                accessMode = AccessMode.READ_WRITE;
             }
             else
@@ -270,48 +241,66 @@
          }
       }
 
+      //
+      PortletContext portletContext = instance.getPortletContext();
+
       // The instance context for the invocation
       InstanceContextImpl instanceContext = new InstanceContextImpl(this, accessMode);
 
       try
       {
          invocation.setAttribute(PortletInvocation.REQUEST_SCOPE, PortletInvocation.INSTANCE_ID_ATTRIBUTE, instanceId);
-         invocation.setAttribute(PortletInvocation.REQUEST_SCOPE, PortletInvocation.PORTLET_CONTEXT_ATTRIBUTE, new PortletContext(portletId));
+         invocation.setAttribute(PortletInvocation.REQUEST_SCOPE, PortletInvocation.PORTLET_CONTEXT_ATTRIBUTE, portletContext);
          invocation.setInstanceContext(instanceContext);
 
          // Perform invocation
          container.invoke(invocation);
-      }
-      finally
-      {
-         // Reset state before invocation
-         invocation.removeAttribute(PortletInvocation.REQUEST_SCOPE, PortletInvocation.INSTANCE_ID_ATTRIBUTE);
-         invocation.removeAttribute(PortletInvocation.REQUEST_SCOPE, PortletInvocation.PORTLET_CONTEXT_ATTRIBUTE);
-         invocation.setInstanceContext(null);
 
          // Create user instance if a clone operation occured
-         if (instanceContext.accessMode == AccessMode.CLONE_BEFORE_WRITE && instanceContext.clonedContext != null)
+         if (instanceContext.accessMode == AccessMode.CLONE_BEFORE_WRITE)
          {
-            try
+            if (instanceContext.clonedContext != null)
             {
                if (debug)
                {
-                 log.debug("About to reference clone of (" + instanceId + "," + portletId +
-                           ") having id " + instanceContext.clonedContext + " for user " + userId);
+//                    log.debug("About to reference clone of (" + instanceId + "," + portletContext +
+//                              ") having id " + instanceContext.clonedContext + " for user " + userId);
                }
-               UserInstance userInstance = new UserInstance(userId, instanceContext.clonedContext.getId());
+               UserInstance userInstance = new UserInstance(userId, instanceContext.clonedContext);
                session.persist(userInstance);
                userInstance.setInstance(this);
                userInstances.add(userInstance);
                session.update(this);
             }
-            catch (HibernateException e)
+            else
             {
-               //
-               log.error("Cannot reference portlet clone", e);
-               throw e;
+               // Does not make sense
             }
          }
+         else if (instanceContext.accessMode == AccessMode.READ_WRITE)
+         {
+            if (instanceContext.modifiedContext != null)
+            {
+               if (debug)
+               {
+//                 log.debug("About to update portlet context (" + instanceId + "," + portletContext +
+//                           ") having id " + instanceContext.clonedContext + " for user " + userId);
+               }
+               instance.setPortletContext(instanceContext.modifiedContext);
+               session.update(instance);
+            }
+            else
+            {
+               // Does not make sense
+            }
+         }
       }
+      finally
+      {
+         // Reset state before invocation
+         invocation.removeAttribute(PortletInvocation.REQUEST_SCOPE, PortletInvocation.INSTANCE_ID_ATTRIBUTE);
+         invocation.removeAttribute(PortletInvocation.REQUEST_SCOPE, PortletInvocation.PORTLET_CONTEXT_ATTRIBUTE);
+         invocation.setInstanceContext(null);
+      }
    }
 }

Modified: trunk/core/src/main/org/jboss/portal/core/impl/model/instance/PersistentInstanceContainer.java
===================================================================
--- trunk/core/src/main/org/jboss/portal/core/impl/model/instance/PersistentInstanceContainer.java	2006-09-23 12:29:49 UTC (rev 5245)
+++ trunk/core/src/main/org/jboss/portal/core/impl/model/instance/PersistentInstanceContainer.java	2006-09-25 14:51:47 UTC (rev 5246)
@@ -81,6 +81,9 @@
    /** . */
    protected SessionFactory sessionFactory;
 
+   /** If true clone the portlet on an instance creation. */
+   protected boolean cloneOnCreate;
+
    /** . */
    protected PortletInvoker portletInvoker;
 
@@ -99,9 +102,6 @@
    /** . */
    protected ObjectContextualizer contextualizer;
 
-   /** If true clone the portlet on an instance creation. */
-   protected boolean cloneOnCreate;
-
    /** . */
    protected InvocationHandler handler = new InvocationHandler()
    {
@@ -235,15 +235,18 @@
       //
       log.debug("Creating instance " + id + " of portlet " + portletId);
 
+      //
+      PortletContext portletContext = new PortletContext(portletId);
+
       // Check that the portlet exist before creating an instance of it
-      portletInvoker.getPortlet(new PortletContext(portletId));
+      portletInvoker.getPortlet(portletContext);
 
       //
       InstanceImpl instance = null;
       try
       {
          // Create the persistent instance which may raise a constraint violation exception if it already exist
-         instance = new InstanceImpl(ctx, id, portletId);
+         instance = new InstanceImpl(ctx, id, portletContext);
          Session session = getCurrentSession();
          session.persist(instance);
       }
@@ -256,8 +259,8 @@
       if (clone)
       {
          // Clone the portlet state now and update the instance
-         String clonedPortletId = portletInvoker.createClone(new PortletContext(portletId)).getId();
-         instance.setPortletRef(clonedPortletId);
+         PortletContext clonedPortletContext = portletInvoker.createClone(portletContext);
+         instance.setPortletContext(clonedPortletContext);
          instance.setModifiable(true);
       }
 
@@ -283,30 +286,38 @@
       }
       Set userInstances = instance.getUserInstances();
 
-      // Collect portlet ids to destroy
+      // Collect portlet info to destroy for logging purpose
       StringBuffer destroyLog = new StringBuffer("About to destroy portlets for instance=").
          append(instance.getInstanceId()).
          append(" [");
+
+      //
       List toDestroy = new ArrayList(userInstances.size());
       for (Iterator i = userInstances.iterator(); i.hasNext();)
       {
          UserInstance userInstance = (UserInstance)i.next();
 
-         // Destroy state
-         String userPortletId = userInstance.getPortletRef();
-         toDestroy.add(userPortletId);
-         destroyLog.append(userPortletId);
+         // Get the user portlet context
+         PortletContext userPortletContext = userInstance.getPortletContext();
+
+         // Add the portlet context
+         toDestroy.add(userPortletContext);
+
+         //
+         destroyLog.append(userPortletContext);
          if (i.hasNext())
          {
             destroyLog.append(',');
          }
       }
+
+      //
       if (instance.modifiable)
       {
          // Destroy the state only if it is not a producer offered portlet
-         String instancePortletId = instance.getPortletRef();
-         toDestroy.add(instancePortletId);
-         destroyLog.append(instancePortletId);
+         PortletContext sharedPortletContext = instance.getPortletContext();
+         toDestroy.add(sharedPortletContext);
+         destroyLog.append(sharedPortletContext);
       }
       destroyLog.append(']');
       log.debug(destroyLog);

Modified: trunk/core/src/main/org/jboss/portal/core/impl/model/instance/UserInstance.java
===================================================================
--- trunk/core/src/main/org/jboss/portal/core/impl/model/instance/UserInstance.java	2006-09-23 12:29:49 UTC (rev 5245)
+++ trunk/core/src/main/org/jboss/portal/core/impl/model/instance/UserInstance.java	2006-09-25 14:51:47 UTC (rev 5246)
@@ -21,35 +21,40 @@
 */
 package org.jboss.portal.core.impl.model.instance;
 
+import org.jboss.portal.portlet.PortletContext;
+import org.jboss.portal.portlet.StatefulPortletContext;
+
 /**
  * @author <a href="mailto:julien at jboss.org">Julien Viet</a>
  * @version $Revision$
  */
-public class UserInstance
+public class UserInstance extends AbstractInstance
 {
 
-   protected Long key;
+   // Persistent fields
+
    protected InstanceImpl instance;
    protected String userId;
-   protected String portletRef;
-   protected byte[] state;
 
    /**
     *
     */
-   public UserInstance(String userId, String portletRef)
+   public UserInstance(String userId, PortletContext portletContext)
    {
       if (userId == null)
       {
          throw new IllegalArgumentException();
       }
-      if (portletRef == null)
+      if (portletContext == null)
       {
          throw new IllegalArgumentException();
       }
+
+      //
       this.userId = userId;
-      this.portletRef = portletRef;
-      this.state = null;
+
+      //
+      setPortletContext(portletContext);
    }
 
    /**
@@ -59,16 +64,6 @@
    {
    }
 
-   public Long getKey()
-   {
-      return key;
-   }
-
-   public void setKey(Long key)
-   {
-      this.key = key;
-   }
-
    public InstanceImpl getInstance()
    {
       return instance;
@@ -88,24 +83,4 @@
    {
       this.userId = userId;
    }
-
-   public String getPortletRef()
-   {
-      return portletRef;
-   }
-
-   public void setPortletRef(String portletRef)
-   {
-      this.portletRef = portletRef;
-   }
-
-   public byte[] getState()
-   {
-      return state;
-   }
-
-   public void setState(byte[] state)
-   {
-      this.state = state;
-   }
 }

Modified: trunk/core/src/main/org/jboss/portal/core/model/instance/InstanceContainer.java
===================================================================
--- trunk/core/src/main/org/jboss/portal/core/model/instance/InstanceContainer.java	2006-09-23 12:29:49 UTC (rev 5245)
+++ trunk/core/src/main/org/jboss/portal/core/model/instance/InstanceContainer.java	2006-09-25 14:51:47 UTC (rev 5246)
@@ -22,8 +22,8 @@
 package org.jboss.portal.core.model.instance;
  
 import org.jboss.portal.security.spi.provider.AuthorizationDomain;
+import org.jboss.portal.portlet.PortletInvokerException;
 import org.jboss.portal.portlet.PortletInvoker;
-import org.jboss.portal.portlet.PortletInvokerException;
 
 import java.util.Collection;
 
@@ -38,7 +38,7 @@
 
    /**
     * Return the underlying portlet invoker for the instance container.
-    * 
+    *
     * @return the portlet invoker
     */
    PortletInvoker getPortletInvoker();

Modified: trunk/core/src/main/org/jboss/portal/core/portlet/management/InstanceManagerBean.java
===================================================================
--- trunk/core/src/main/org/jboss/portal/core/portlet/management/InstanceManagerBean.java	2006-09-23 12:29:49 UTC (rev 5245)
+++ trunk/core/src/main/org/jboss/portal/core/portlet/management/InstanceManagerBean.java	2006-09-25 14:51:47 UTC (rev 5246)
@@ -37,7 +37,6 @@
 import org.jboss.portal.identity.RoleModule;
 import org.jboss.portal.portlet.Portlet;
 import org.jboss.portal.portlet.PortletInvokerException;
-import org.jboss.portal.portlet.PortletContext;
 import org.jboss.portal.portlet.info.PreferencesInfo;
 import org.jboss.portal.portlet.info.MetaInfo;
 import org.jboss.portal.security.AuthorizationDomainRegistry;
@@ -243,7 +242,7 @@
          Instance instance = (Instance)i.next();
          try
          {
-            Portlet portlet = instanceContainer.getPortletInvoker().getPortlet(new PortletContext(instance.getPortletRef()));
+            Portlet portlet = instance.getPortlet();
             Object[] line = new Object[]
                {
                   instance,

Modified: trunk/core/src/main/org/jboss/portal/test/core/model/instance/InstanceContainerTestCase.java
===================================================================
--- trunk/core/src/main/org/jboss/portal/test/core/model/instance/InstanceContainerTestCase.java	2006-09-23 12:29:49 UTC (rev 5245)
+++ trunk/core/src/main/org/jboss/portal/test/core/model/instance/InstanceContainerTestCase.java	2006-09-25 14:51:47 UTC (rev 5246)
@@ -13,26 +13,34 @@
 import org.jboss.portal.core.impl.model.instance.InstanceImpl;
 import org.jboss.portal.core.impl.model.instance.UserInstance;
 import org.jboss.portal.core.impl.portlet.state.PersistentStateStore;
-import org.jboss.portal.core.impl.portlet.state.PersistentStateEntry;
-import org.jboss.portal.core.impl.portlet.state.PersistentState;
 import org.jboss.portal.core.model.instance.Instance;
 import org.jboss.portal.portlet.test.support.info.PreferencesInfoSupport;
 import org.jboss.portal.portlet.test.support.PortletInvokerSupport;
 import org.jboss.portal.portlet.test.support.PortletSupport;
 import org.jboss.portal.portlet.test.ActionContextImpl;
 import org.jboss.portal.portlet.test.UserContextImpl;
+import org.jboss.portal.portlet.test.ValueMapAssert;
 import org.jboss.portal.portlet.state.producer.ProducerPortletInvoker;
 import org.jboss.portal.portlet.state.AbstractPropertyContext;
 import org.jboss.portal.portlet.state.PropertyChange;
+import org.jboss.portal.portlet.state.PropertyMap;
+import org.jboss.portal.portlet.state.SimplePropertyMap;
 import org.jboss.portal.Mode;
 import org.jboss.portal.portlet.NoSuchPortletException;
 import org.jboss.portal.portlet.PortletContext;
+import org.jboss.portal.portlet.PortletInvokerException;
+import org.jboss.portal.portlet.PortletInvoker;
+import org.jboss.portal.portlet.Portlet;
+import org.jboss.portal.portlet.info.MetaInfo;
 import org.jboss.portal.portlet.invocation.ActionInvocation;
 import org.jboss.portal.portlet.invocation.PortletInvocation;
 import org.jboss.portal.test.framework.embedded.DataSourceSupport;
 import org.jboss.portal.test.framework.embedded.HibernateSupport;
-import org.jboss.portal.test.framework.junit.DatabaseTestSuite;
 import org.jboss.portal.test.framework.junit.TransactionAssert;
+import org.jboss.portal.test.framework.junit.TestCaseFactory;
+import org.jboss.portal.test.framework.junit.metadata.TestCaseMetaData;
+import org.jboss.portal.test.framework.junit.metadata.TestCaseParameterMetaData;
+import org.jboss.portal.test.framework.junit.metadata.TestCaseParameterIterableValue;
 import org.jboss.portal.test.framework.TestRuntimeContext;
 import org.jboss.portal.common.value.StringValue;
 import org.apache.log4j.Appender;
@@ -41,12 +49,11 @@
 import org.apache.log4j.Logger;
 import org.apache.log4j.Level;
 
-import javax.transaction.UserTransaction;
-import javax.transaction.Status;
 import java.net.URL;
 import java.util.List;
 import java.util.Set;
 import java.util.Map;
+import java.util.Arrays;
 
 /**
  * Test Case that tests the authorization for instances
@@ -71,24 +78,73 @@
    {
       Appender appender = new ConsoleAppender(new SimpleLayout());
       Logger.getRoot().addAppender(appender);
-      Logger.getRoot().setLevel(Level.DEBUG);
+      Logger.getRoot().setLevel(Level.ERROR);
       Logger.getLogger("org.hibernate").setLevel(Level.ERROR);
    }
 
    public static TestSuite suite() throws Exception
    {
       URL configsURL = Thread.currentThread().getContextClassLoader().getResource("datasources.xml");
-      DataSourceSupport.Config[] configs = DataSourceSupport.Config.fromXML(configsURL);
-      DatabaseTestSuite suite = new DatabaseTestSuite(configs);
-      suite.addTestCase(InstanceContainerTestCase.class);
+      TestCaseMetaData testCaseMD = new TestCaseMetaData();
+      testCaseMD.bindParameter(new TestCaseParameterMetaData("DataSourceConfig"), DataSourceSupport.Config.fromXML2(configsURL));
+      testCaseMD.bindParameter(new TestCaseParameterMetaData("PersistLocally"), new TestCaseParameterIterableValue(Arrays.asList(new Object[]{Boolean.TRUE,Boolean.FALSE})));
+      TestSuite suite = TestCaseFactory.create(testCaseMD, InstanceContainerTestCase.class);
       return suite;
    }
 
+   private class TestPortletSupport extends PortletSupport
+   {
+
+      private PortletInvocation invocation;
+
+      public TestPortletSupport()
+      {
+         PreferencesInfoSupport prefs = this.info.getPreferencesSupport();
+         prefs.addPreference("_abc", new StringValue("_def"));
+         this.info.getMetaSupport().setDisplayName("Foo");
+      }
+
+      public void invoke(PortletInvocation invocation)
+      {
+         this.invocation = invocation;
+         try
+         {
+            execute();
+         }
+         finally
+         {
+            this.invocation = null;
+         }
+      }
+
+      public void execute()
+      {
+      }
+
+      public void setProperty(String key, String value) throws IllegalStateException
+      {
+         AbstractPropertyContext props = (AbstractPropertyContext)invocation.getAttribute(PortletInvocation.REQUEST_SCOPE, PortletInvocation.PREFERENCES_ATTRIBUTE);
+         props.update(new PropertyChange[]{PropertyChange.newUpdate(key, new StringValue(value))});
+      }
+   }
+
+   public InstanceContainerTestCase(Map parametrization)
+   {
+      dataSourceConfig = (DataSourceSupport.Config)parametrization.get("DataSourceConfig");
+      persistLocally = ((Boolean)parametrization.get("PersistLocally")).booleanValue();
+
+      //
+      setName((String)parametrization.get(TestCaseParameterMetaData.TESTCASE_METHOD));
+   }
+
    /** . */
+   private boolean persistLocally;
+
+   /** . */
    private TestRuntimeContext runtimeContext;
 
    /** . */
-   private DataSourceSupport.Config dsCfg;
+   private DataSourceSupport.Config dataSourceConfig;
 
    /** . */
    private HibernateSupport instanceHibernateSupport;
@@ -108,16 +164,31 @@
    /** . */
    private PortletInvokerSupport portletContainer;
 
-   public InstanceContainerTestCase(DataSourceSupport.Config config)
+   public String getName()
    {
-      this.dsCfg = config;
+      return super.getName() + ",persistLocally=" + persistLocally + ",ds=" + dataSourceConfig.getDisplayName();
    }
 
-   public String getName()
+   public boolean getPersistLocally()
    {
-      return super.getName() + "_" + dsCfg.getDriverClass().replaceAll("\\.", "_");
+      return persistLocally;
    }
 
+   public void setPersistLocally(boolean persistLocally)
+   {
+      this.persistLocally = persistLocally;
+   }
+
+   public DataSourceSupport.Config getDataSourceConfig()
+   {
+      return dataSourceConfig;
+   }
+
+   public void setDataSourceConfig(DataSourceSupport.Config dataSourceConfig)
+   {
+      this.dataSourceConfig = dataSourceConfig;
+   }
+
    public HibernateSupport getInstanceHibernateSupport()
    {
       return instanceHibernateSupport;
@@ -180,21 +251,20 @@
 
    protected void setUp() throws Exception
    {
+      //
       runtimeContext = new TestRuntimeContext("org/jboss/portal/test/core/model/instance/jboss-beans.xml");
+      runtimeContext.addBean("TestCaseConfig", this);
       runtimeContext.addBean("TestBean", this);
-      runtimeContext.addBean("DataSourceConfig", dsCfg);
+      runtimeContext.addBean("DataSourceConfig", dataSourceConfig);
       runtimeContext.start();
    }
 
    protected void tearDown() throws Exception
    {
       // Cleanup any pending transaction
-      UserTransaction ut = TransactionAssert.getUserTransaction();
-      if (ut.getStatus() != Status.STATUS_NO_TRANSACTION)
-      {
-         ut.commit();
-      }
+      TransactionAssert.endTransaction();
 
+      //
       runtimeContext.stop();
    }
 
@@ -219,12 +289,6 @@
       assertEquals(1, instances.size());
       InstanceImpl instanceImpl = (InstanceImpl)instances.get(0);
       assertEquals(true, instanceImpl.isModifiable());
-      List states = portletHibernateSupport.getCurrentSession().createQuery("from PersistentState").list();
-      assertEquals(1, states.size());
-      PersistentState state = (PersistentState)states.get(0);
-      assertEquals(0, state.getChildren().size());
-      assertEquals(null, state.getParent());
-      assertEquals("MyPortlet", state.getPortletId());
       TransactionAssert.commitTransaction();
 
       //
@@ -264,183 +328,327 @@
       TransactionAssert.commitTransaction();
    }
 
+   public Portlet getSinglePOP() throws PortletInvokerException
+   {
+      assertNotNull(instanceContainer);
+      PortletInvoker portletInvoker = instanceContainer.getPortletInvoker();
+      assertNotNull(portletInvoker);
+      Set portlets = portletInvoker.getPortlets();
+      assertNotNull(portlets);
+      assertEquals(1, portlets.size());
+      Portlet p = (Portlet)portlets.iterator().next();
+      assertNotNull(p);
+      return p;
+   }
+
+   private abstract class TestCloneBeforeWrite
+   {
+
+      /** . */
+      private final String identity;
+
+      /** . */
+      private final boolean cloneInstance;
+
+      /** . */
+      private final boolean expectException;
+
+      /** . */
+      private final TransactionAssert.Terminator terminator;
+
+      public TestCloneBeforeWrite(String identity, boolean cloneInstance, boolean expectException, TransactionAssert.Terminator terminator)
+      {
+         this.identity = identity;
+         this.cloneInstance = cloneInstance;
+         this.expectException = expectException;
+         this.terminator = terminator;
+      }
+
+      public abstract void execute(TestPortletSupport portlet);
+
+      public void execute() throws Exception
+      {
+         portletContainer.addPortlet("MyPortlet", new TestPortletSupport()
+         {
+            public void execute()
+            {
+               TestCloneBeforeWrite.this.execute(this);
+            }
+         });
+         String popId = getSinglePOP().getContext().getId();
+
+         //
+         TransactionAssert.beginTransaction();
+         instanceContainer.createInstance("MyInstance", popId, cloneInstance);
+         TransactionAssert.commitTransaction();
+
+         //
+         TransactionAssert.beginTransaction();
+         Instance instance = instanceContainer.getInstance("MyInstance");
+         PortletInvocation action = new ActionInvocation(new ActionContextImpl(Mode.VIEW));
+         action.setUserContext(identity == null ? new UserContextImpl() :new UserContextImpl(identity));
+         try
+         {
+            instance.invoke(action);
+            if (expectException)
+            {
+               fail("Was expecting runtime exception");
+            }
+         }
+         catch (RuntimeException e)
+         {
+            if (expectException)
+            {
+               assertEquals("custom_message", e.getMessage());
+            }
+            else
+            {
+               e.printStackTrace();
+               fail("Was not expecting a runtime exception");
+            }
+         }
+         TransactionAssert.endTransaction(terminator);
+      }
+   }
+
    /**
-    * Runtime clone of a producer offered portlet.
+    * .
     */
-   public void testCloneBeforeWrite() throws Exception
+   public void testInvokePOPReadOnly() throws Exception
    {
-      portletContainer.addPortlet("MyPortlet", new PortletSupport()
+      TestCloneBeforeWrite test = new TestCloneBeforeWrite(null, false, false, TransactionAssert.MUST_COMMIT)
       {
+         public void execute(TestPortletSupport portlet)
          {
-            PreferencesInfoSupport prefs = info.getPreferencesSupport();
-            prefs.addPreference("_abc", new StringValue("_def"));
+            try
+            {
+               portlet.setProperty("abc", "def");
+               fail("Was expecting an IllegalStateException");
+            }
+            catch (IllegalStateException expected)
+            {
+            }
          }
-         public void invoke(PortletInvocation invocation)
+      };
+      test.execute();
+
+      // Check state
+      TransactionAssert.beginTransaction();
+      InstanceImpl instanceImpl = (InstanceImpl)instanceContainer.getInstance("MyInstance");
+      assertNotNull(instanceImpl);
+      Set userInstances = instanceImpl.getUserInstances();
+      assertNotNull(userInstances);
+      assertEquals(0, userInstances.size());
+      TransactionAssert.commitTransaction();
+   }
+
+   /**
+    * .
+    */
+   public void testInvokeCCPReadOnly() throws Exception
+   {
+      TestCloneBeforeWrite test = new TestCloneBeforeWrite(null, true, false, TransactionAssert.MUST_COMMIT)
+      {
+         public void execute(TestPortletSupport portlet)
          {
-            AbstractPropertyContext props = (AbstractPropertyContext)invocation.getAttribute(PortletInvocation.REQUEST_SCOPE, PortletInvocation.PREFERENCES_ATTRIBUTE);
-            props.update(new PropertyChange[]{PropertyChange.newUpdate("abc", new StringValue("def"))});
+            try
+            {
+               portlet.setProperty("abc", "def");
+               fail("Was expecting an IllegalStateException");
+            }
+            catch (IllegalStateException expected)
+            {
+            }
          }
-      });
+      };
+      test.execute();
 
-      //
+      // Check state
       TransactionAssert.beginTransaction();
-      Instance instance = instanceContainer.createInstance("MyInstance", "MyPortlet", true);
+      InstanceImpl instanceImpl = (InstanceImpl)instanceContainer.getInstance("MyInstance");
+      assertNotNull(instanceImpl);
+      Set userInstances = instanceImpl.getUserInstances();
+      assertNotNull(userInstances);
+      assertEquals(0, userInstances.size());
       TransactionAssert.commitTransaction();
+   }
 
-      //
+   /**
+    * .
+    */
+   public void testInvokePOPCloneBeforeWrite() throws Exception
+   {
+      TestCloneBeforeWrite test = new TestCloneBeforeWrite("julien", false, false, TransactionAssert.MUST_COMMIT)
+      {
+         public void execute(TestPortletSupport portlet)
+         {
+            portlet.setProperty("abc", "def");
+         }
+      };
+      test.execute();
+
+      // Check state
       TransactionAssert.beginTransaction();
-      instance = instanceContainer.getInstance("MyInstance");
-      PortletInvocation action = new ActionInvocation(new ActionContextImpl(Mode.VIEW));
-      action.setUserContext(new UserContextImpl("julien"));
-      instance.invoke(action);
+      InstanceImpl instanceImpl = (InstanceImpl)instanceContainer.getInstance("MyInstance");
+      assertNotNull(instanceImpl);
+      Set userInstances = instanceImpl.getUserInstances();
+      assertNotNull(userInstances);
+      assertEquals(1, userInstances.size());
+      UserInstance userInstance = (UserInstance)userInstances.iterator().next();
+      PortletContext userPortletContext = userInstance.getPortletContext();
+      assertNotNull(userPortletContext);
+      PropertyMap userProps = instanceContainer.getPortletInvoker().getProperties(userPortletContext);
+      assertNotNull(userProps);
+      PropertyMap expectedProps = new SimplePropertyMap();
+      expectedProps.setProperty("abc", new StringValue("def"));
+      expectedProps.setProperty("_abc", new StringValue("_def"));
+      ValueMapAssert.assertEquals(expectedProps, userProps);
+      Portlet userPortlet = instanceContainer.getPortletInvoker().getPortlet(userPortletContext);
+      assertNotNull(userPortlet);
+      assertEquals("Foo", userPortlet.getInfo().getMeta().getMetaValue(MetaInfo.DISPLAY_NAME).getDefaultString());
       TransactionAssert.commitTransaction();
+   }
 
+   /**
+    * .
+    */
+   public void testInvokeCCPCloneBeforeWrite() throws Exception
+   {
+      TestCloneBeforeWrite test = new TestCloneBeforeWrite("julien", true, false, TransactionAssert.MUST_COMMIT)
+      {
+         public void execute(TestPortletSupport portlet)
+         {
+            portlet.setProperty("abc", "def");
+         }
+      };
+      test.execute();
+
       // Check state
       TransactionAssert.beginTransaction();
-      Session session = instanceHibernateSupport.getCurrentSession();
-      List instances = session.createQuery("from InstanceImpl").list();
-      assertEquals(1, instances.size());
-      InstanceImpl instanceImpl = (InstanceImpl)instances.get(0);
-      String ccpId = producer.unwrapCCP(new PortletContext(instanceImpl.getPortletRef()));
-      Long instanceStateKey = new Long(ccpId);
-      PersistentState instanceState = (PersistentState)portletHibernateSupport.getCurrentSession().get(PersistentState.class, instanceStateKey);
+      InstanceImpl instanceImpl = (InstanceImpl)instanceContainer.getInstance("MyInstance");
+      assertNotNull(instanceImpl);
       Set userInstances = instanceImpl.getUserInstances();
       assertNotNull(userInstances);
       assertEquals(1, userInstances.size());
       UserInstance userInstance = (UserInstance)userInstances.iterator().next();
-      assertEquals("julien", userInstance.getUserId());
-      assertNotNull(userInstance.getInstance());
-      String portletRef = userInstance.getPortletRef();
-      assertNotNull(portletRef);
-      assertTrue(portletRef.startsWith("_"));
-      Long userInstanceStateKey = new Long(portletRef.substring(1));
-      PersistentState userInstanceState = (PersistentState)portletHibernateSupport.getCurrentSession().get(PersistentState.class, userInstanceStateKey);
-      assertNotNull(userInstanceState);
-      assertEquals("MyPortlet", userInstanceState.getPortletId());
-      assertNotNull(userInstanceState.getParent());
-      assertEquals(instanceState.getKey(), userInstanceState.getParent().getKey());
-      assertEquals(0, userInstanceState.getChildren().size());
-      Map entries = userInstanceState.getEntries();
-      assertNotNull(entries);
-      assertEquals(2, entries.size());
-      PersistentStateEntry abcEntry = (PersistentStateEntry)entries.get("abc");
-      assertEquals(new StringValue("def"), abcEntry.getValue());
-      PersistentStateEntry _abcEntry = (PersistentStateEntry)entries.get("_abc");
-      assertEquals(new StringValue("_def"), _abcEntry.getValue());
+      System.out.println("userInstance.getPortletRef() = " + userInstance.getPortletRef());
+      System.out.println("userInstance.getState() = " + userInstance.getState());
+      PortletContext userPortletContext = userInstance.getPortletContext();
+      assertNotNull(userPortletContext);
+      PropertyMap userProps = instanceContainer.getPortletInvoker().getProperties(userPortletContext);
+      assertNotNull(userProps);
+      PropertyMap expectedProps = new SimplePropertyMap();
+      expectedProps.setProperty("abc", new StringValue("def"));
+      expectedProps.setProperty("_abc", new StringValue("_def"));
+      ValueMapAssert.assertEquals(expectedProps, userProps);
+      Portlet userPortlet = instanceContainer.getPortletInvoker().getPortlet(userPortletContext);
+      assertNotNull(userPortlet);
+      assertEquals("Foo", userPortlet.getInfo().getMeta().getMetaValue(MetaInfo.DISPLAY_NAME).getDefaultString());
       TransactionAssert.commitTransaction();
    }
 
    /**
-    * Runtime clone of a producer offered portlet.
+    * .
     */
-   public void testCloneBeforeWriteRollback() throws Exception
+   public void testInvokePOPCloneBeforeWriteRollback() throws Exception
    {
-      portletContainer.addPortlet("MyPortlet", new PortletSupport()
+      TestCloneBeforeWrite test = new TestCloneBeforeWrite("julien", false, false, TransactionAssert.MUST_ROLLBACK)
       {
+         public void execute(TestPortletSupport portlet)
          {
-            PreferencesInfoSupport prefs = info.getPreferencesSupport();
-            prefs.addPreference("_abc", new StringValue("_def"));
+            portlet.setProperty("abc", "def");
          }
-         public void invoke(PortletInvocation invocation)
-         {
-            AbstractPropertyContext props = (AbstractPropertyContext)invocation.getAttribute(PortletInvocation.REQUEST_SCOPE, PortletInvocation.PREFERENCES_ATTRIBUTE);
-            props.update(new PropertyChange[]{PropertyChange.newUpdate("abc", new StringValue("def"))});
-         }
-      });
+      };
+      test.execute();
 
-      //
+      // Check state
       TransactionAssert.beginTransaction();
-      instanceContainer.createInstance("MyInstance", "MyPortlet");
+      InstanceImpl instanceImpl = (InstanceImpl)instanceContainer.getInstance("MyInstance");
+      Set userInstances = instanceImpl.getUserInstances();
+      assertNotNull(userInstances);
+      assertEquals(0, userInstances.size());
       TransactionAssert.commitTransaction();
+   }
 
-      //
-      TransactionAssert.beginTransaction();
-      Instance instance = instanceContainer.getInstance("MyInstance");
+   /**
+    * .
+    */
+   public void testInvokeCCPCloneBeforeWriteRollback() throws Exception
+   {
+      TestCloneBeforeWrite test = new TestCloneBeforeWrite("julien", true, false, TransactionAssert.MUST_ROLLBACK)
+      {
+         public void execute(TestPortletSupport portlet)
+         {
+            portlet.setProperty("abc", "def");
+         }
+      };
+      test.execute();
 
-      //
-      PortletInvocation action = new ActionInvocation(new ActionContextImpl(Mode.VIEW));
-      action.setUserContext(new UserContextImpl("julien"));
-      instance.invoke(action);
-      TransactionAssert.rollbackTransaction(false);
-
       // Check state
       TransactionAssert.beginTransaction();
-      Session session = instanceHibernateSupport.getCurrentSession();
-      List instances = session.createQuery("from InstanceImpl").list();
-      assertEquals(1, instances.size());
-      InstanceImpl instanceImpl = (InstanceImpl)instances.get(0);
+      InstanceImpl instanceImpl = (InstanceImpl)instanceContainer.getInstance("MyInstance");
       Set userInstances = instanceImpl.getUserInstances();
       assertNotNull(userInstances);
       assertEquals(0, userInstances.size());
-      List states = portletHibernateSupport.getCurrentSession().createQuery("from PersistentState").list();
-      assertEquals(0, states.size());
       TransactionAssert.commitTransaction();
    }
 
-   public void testCloneBeforeWriteThrowable() throws Exception
+   /**
+    * .
+    */
+   public void testInvokePOPCloneBeforeWritePortletThrowsRuntimeException() throws Exception
    {
-      portletContainer.addPortlet("MyPortlet", new PortletSupport()
+      TestCloneBeforeWrite test = new TestCloneBeforeWrite("julien", false, true, TransactionAssert.MARKED_AS_ROLLBACK)
       {
+         public void execute(TestPortletSupport portlet)
          {
-            PreferencesInfoSupport prefs = info.getPreferencesSupport();
-            prefs.addPreference("_abc", new StringValue("_def"));
-         }
-         public void invoke(PortletInvocation invocation)
-         {
-            AbstractPropertyContext props = (AbstractPropertyContext)invocation.getAttribute(PortletInvocation.REQUEST_SCOPE, PortletInvocation.PREFERENCES_ATTRIBUTE);
-            props.update(new PropertyChange[]{PropertyChange.newUpdate("abc", new StringValue("def"))});
+            portlet.setProperty("abc", "def");
             throw new RuntimeException("custom_message");
          }
-      });
+      };
+      test.execute();
 
-      //
+      // Check state
       TransactionAssert.beginTransaction();
-      instanceContainer.createInstance("MyInstance", "MyPortlet", true);
+      InstanceImpl instanceImpl = (InstanceImpl)instanceContainer.getInstance("MyInstance");
+      Set userInstances = instanceImpl.getUserInstances();
+      assertNotNull(userInstances);
+      assertEquals(0, userInstances.size());
       TransactionAssert.commitTransaction();
+   }
 
-      //
-      TransactionAssert.beginTransaction();
-      Instance instance = instanceContainer.getInstance("MyInstance");
-      PortletInvocation action = new ActionInvocation(new ActionContextImpl(Mode.VIEW));
-      action.setUserContext(new UserContextImpl("julien"));
-      try
+   /**
+    * .
+    */
+   public void testInvokeCCPCloneBeforeWritePortletThrowsRuntimeException() throws Exception
+   {
+      TestCloneBeforeWrite test = new TestCloneBeforeWrite("julien", true, true, TransactionAssert.MARKED_AS_ROLLBACK)
       {
-         instance.invoke(action);
-         fail("Was expecting runtime exception");
-      }
-      catch (RuntimeException e)
-      {
-         assertEquals("custom_message", e.getMessage());
-      }
-      TransactionAssert.commitTransaction();
+         public void execute(TestPortletSupport portlet)
+         {
+            portlet.setProperty("abc", "def");
+            throw new RuntimeException("custom_message");
+         }
+      };
+      test.execute();
 
       // Check state
-//      beginTransaction();
-//      Session session = instanceHibernateSupport.getCurrentSession();
-//      List instances = session.createQuery("from InstanceImpl").list();
-//      assertEquals(1, instances.size());
-//      InstanceImpl instanceImpl = (InstanceImpl)instances.get(0);
-//      Set userInstances = instanceImpl.getUserInstances();
-//      assertNotNull(userInstances);
-//      assertEquals(0, userInstances.size());
-//      List states = portletHibernateSupport.getCurrentSession().createQuery("from PersistentState").list();
-//      assertEquals(1, states.size());
-//      commitTransaction();
+      TransactionAssert.beginTransaction();
+      InstanceImpl instanceImpl = (InstanceImpl)instanceContainer.getInstance("MyInstance");
+      Set userInstances = instanceImpl.getUserInstances();
+      assertNotNull(userInstances);
+      assertEquals(0, userInstances.size());
+      TransactionAssert.commitTransaction();
    }
 
-   public void testDeleteDestroyInstance() throws Exception
+   public void testDestroyCCPInstance() throws Exception
    {
-      portletContainer.addPortlet("MyPortlet", new PortletSupport()
+      portletContainer.addPortlet("MyPortlet", new TestPortletSupport()
       {
+         public void execute()
          {
-            PreferencesInfoSupport prefs = info.getPreferencesSupport();
-            prefs.addPreference("_abc", new StringValue("_def"));
+            setProperty("abc", "def");
          }
-         public void invoke(PortletInvocation invocation)
-         {
-            AbstractPropertyContext props = (AbstractPropertyContext)invocation.getAttribute(PortletInvocation.REQUEST_SCOPE, PortletInvocation.PREFERENCES_ATTRIBUTE);
-            props.update(new PropertyChange[]{PropertyChange.newUpdate("abc", new StringValue("def"))});
-         }
       });
 
       // Create the instance
@@ -456,17 +664,18 @@
       instance.invoke(action);
       TransactionAssert.commitTransaction();
 
+      //
       TransactionAssert.beginTransaction();
       InstanceImpl instanceImpl = (InstanceImpl)instanceContainer.getInstance("MyInstance");
-      String instancePortletRefId = instanceImpl.getPortletRef();
-      assertNotNull(producer.getPortlet(new PortletContext(instancePortletRefId)));
+      PortletContext sharedPortletContext = instanceImpl.getPortletContext();
+      assertNotNull(producer.getPortlet(sharedPortletContext));
       assertNotNull(instance);
       Set children = instanceImpl.getUserInstances();
       assertNotNull(children);
       assertEquals(1, children.size());
       UserInstance userInstance = (UserInstance)children.iterator().next();
-      String userPortletRefId = userInstance.getPortletRef();
-      assertNotNull(producer.getPortlet(new PortletContext(userPortletRefId)));
+      PortletContext userPortletContext = userInstance.getPortletContext();
+      assertNotNull(producer.getPortlet(userPortletContext));
       assertNotNull(userInstance);
       TransactionAssert.commitTransaction();
 
@@ -476,136 +685,119 @@
       TransactionAssert.commitTransaction();
 
       //
-      TransactionAssert.beginTransaction();
-      try
+      if (persistLocally)
       {
-         producer.getPortlet(new PortletContext(userPortletRefId));
-         fail("Was expecting a NoSuchPortletException");
+         TransactionAssert.beginTransaction();
+         try
+         {
+            producer.getPortlet(userPortletContext);
+            fail("Was expecting a NoSuchPortletException");
+         }
+         catch (NoSuchPortletException expected)
+         {
+         }
+         try
+         {
+            producer.getPortlet(sharedPortletContext);
+            fail("Was expecting a NoSuchPortletException");
+         }
+         catch (NoSuchPortletException expected)
+         {
+         }
+         TransactionAssert.commitTransaction();
       }
-      catch (NoSuchPortletException expected)
-      {
-      }
-      try
-      {
-         producer.getPortlet(new PortletContext(instancePortletRefId));
-         fail("Was expecting a NoSuchPortletException");
-      }
-      catch (NoSuchPortletException expected)
-      {
-      }
-      TransactionAssert.commitTransaction();
    }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-//   /**Tests the authorization of portal objects */
-//   public void _testInstanceAuthorization() throws Exception
-//   {
-//      container.start();
 //
-//      //Populate the container with constraints
-//      hibernate.beginTransaction();
-//      constructInstances();
-//      setUpSecurity("portletInstanceA","view", SecurityConstants.UNCHECKED_ROLE_NAME);
-//      setUpSecurity("portletInstanceB","view", SecurityConstants.UNCHECKED_ROLE_NAME);
-//      setUpSecurity("portletInstanceC","view", SecurityConstants.UNCHECKED_ROLE_NAME);
-//      hibernate.commitTransaction();
+////   /**Tests the authorization of portal objects */
+////   public void _testInstanceAuthorization() throws Exception
+////   {
+////      container.start();
+////
+////      //Populate the container with constraints
+////      hibernate.beginTransaction();
+////      constructInstances();
+////      setUpSecurity("portletInstanceA","view", SecurityConstants.UNCHECKED_ROLE_NAME);
+////      setUpSecurity("portletInstanceB","view", SecurityConstants.UNCHECKED_ROLE_NAME);
+////      setUpSecurity("portletInstanceC","view", SecurityConstants.UNCHECKED_ROLE_NAME);
+////      hibernate.commitTransaction();
+////
+////      hibernate.beginTransaction();
+////      SecurityAssociation.setSubject(new Subject());
+////      PortalAuthorizationManager manager = container.getPortalAuthorizationManagerFactory().getManager();
+////      assertTrue("view perm on portletInstanceA",  manager.hasPermission("portletInstanceA", "view",type));
+////      assertTrue("view perm on portletInstanceB",  manager.hasPermission("portletInstanceB", "view",type));
+////      assertTrue("view perm on portletInstanceC",  manager.hasPermission("portletInstanceC", "view",type));
+////      hibernate.commitTransaction();
+////      container.stop();
+////   }
+////
+////   /**Tests the authorization of portal objects */
+////   public void _testInstanceAuthorizationForAdmin() throws Exception
+////   {
+////      container.start();
+////
+////      //Populate the container with constraints
+////      hibernate.beginTransaction();
+////      constructInstances();
+////      setUpSecurity("portletInstanceA","view", "admin");
+////      setUpSecurity("portletInstanceB","view", "admin");
+////      setUpSecurity("portletInstanceC","view", "admin");
+////      hibernate.commitTransaction();
+////
+////      hibernate.beginTransaction();
+////      setUpSubjectForRole("admin",new String[]{"admin"});
+////
+////      PortalAuthorizationManager manager = container.getPortalAuthorizationManagerFactory().getManager();
+////      assertTrue("view perm on portletInstanceA",
+////            manager.hasPermission("portletInstanceA", "view",type));
+////      assertTrue("view perm on portletInstanceB",
+////            manager.hasPermission("portletInstanceB", "view",type));
+////      assertTrue("view perm on portletInstanceC",
+////            manager.hasPermission("portletInstanceC", "view",type));
+////      hibernate.commitTransaction();
+////      container.stop();
+////   }
+////
 //
-//      hibernate.beginTransaction();
-//      SecurityAssociation.setSubject(new Subject());
-//      PortalAuthorizationManager manager = container.getPortalAuthorizationManagerFactory().getManager();
-//      assertTrue("view perm on portletInstanceA",  manager.hasPermission("portletInstanceA", "view",type));
-//      assertTrue("view perm on portletInstanceB",  manager.hasPermission("portletInstanceB", "view",type));
-//      assertTrue("view perm on portletInstanceC",  manager.hasPermission("portletInstanceC", "view",type));
-//      hibernate.commitTransaction();
-//      container.stop();
-//   }
 //
-//   /**Tests the authorization of portal objects */
-//   public void _testInstanceAuthorizationForAdmin() throws Exception
-//   {
-//      container.start();
-//
-//      //Populate the container with constraints
-//      hibernate.beginTransaction();
-//      constructInstances();
-//      setUpSecurity("portletInstanceA","view", "admin");
-//      setUpSecurity("portletInstanceB","view", "admin");
-//      setUpSecurity("portletInstanceC","view", "admin");
-//      hibernate.commitTransaction();
-//
-//      hibernate.beginTransaction();
-//      setUpSubjectForRole("admin",new String[]{"admin"});
-//
-//      PortalAuthorizationManager manager = container.getPortalAuthorizationManagerFactory().getManager();
-//      assertTrue("view perm on portletInstanceA",
-//            manager.hasPermission("portletInstanceA", "view",type));
-//      assertTrue("view perm on portletInstanceB",
-//            manager.hasPermission("portletInstanceB", "view",type));
-//      assertTrue("view perm on portletInstanceC",
-//            manager.hasPermission("portletInstanceC", "view",type));
-//      hibernate.commitTransaction();
-//      container.stop();
-//   }
-//
-
-
-//
-//
-//   /**
-//    * Should be automated to construct from a xxx-yyy.xml
-//    * Example : portal-object.xml
-//    */
-//   private void constructInstances() throws Exception
-//   {
-//      assertNotNull("portletInstanceA is not null", constructInstance("portletInstanceA", null));
-//      assertNotNull("portletInstanceB is not null", constructInstance("portletInstanceB", null));
-//      assertNotNull("portletInstanceC is not null", constructInstance("portletInstanceC", null));
-//   }
-//
-//
-//   private InstanceImpl constructInstance(String instanceA, String portletId) throws DuplicateInstanceException, NoSuchPortletException
-//   {
-//      InstanceImpl instanceImpl = (InstanceImpl)container.getInstance(instanceA);
-//      if(instanceImpl == null)
-//      {
-//         instanceImpl = (InstanceImpl)container.createInstances(instanceA, portletId);
-//      }
-//      return instanceImpl;
-//   }
-//
-//
-//   private void setUpSecurity(String uri,String perm, String role) throws  Exception
-//   {
-//      PolicyContext.setContextID(CONTEXT_ID);
-//      AuthorizationDomain authDomain = container.getAuthorizationDomain();
-//      assertNotNull("AuthorizationDomain != null", authDomain);
-//      DomainConfigurator dc = authDomain.getConfigurator();
-//      assertNotNull("DomainConfigurator != null", dc);
-//      JACCPortalAuthorizationManagerFactory factory = new JACCPortalAuthorizationManagerFactory();
-//      JBossAuthorizationDomainRegistryImpl registry = new JBossAuthorizationDomainRegistryImpl();
-//      registry.addDomain(container);
-//      factory.setAuthorizationDomainRegistry(registry);
-//      container.setAuthorizationDomainRegistry(registry);
-//      container.setPortalAuthorizationManagerFactory(factory);
-//      dc.setConstraints(uri, this.getSecurityConstraints(perm,role));
-//   }
+////
+////
+////   /**
+////    * Should be automated to construct from a xxx-yyy.xml
+////    * Example : portal-object.xml
+////    */
+////   private void constructInstances() throws Exception
+////   {
+////      assertNotNull("portletInstanceA is not null", constructInstance("portletInstanceA", null));
+////      assertNotNull("portletInstanceB is not null", constructInstance("portletInstanceB", null));
+////      assertNotNull("portletInstanceC is not null", constructInstance("portletInstanceC", null));
+////   }
+////
+////
+////   private InstanceImpl constructInstance(String instanceA, String portletId) throws DuplicateInstanceException, NoSuchPortletException
+////   {
+////      InstanceImpl instanceImpl = (InstanceImpl)container.getInstance(instanceA);
+////      if(instanceImpl == null)
+////      {
+////         instanceImpl = (InstanceImpl)container.createInstances(instanceA, portletId);
+////      }
+////      return instanceImpl;
+////   }
+////
+////
+////   private void setUpSecurity(String uri,String perm, String role) throws  Exception
+////   {
+////      PolicyContext.setContextID(CONTEXT_ID);
+////      AuthorizationDomain authDomain = container.getAuthorizationDomain();
+////      assertNotNull("AuthorizationDomain != null", authDomain);
+////      DomainConfigurator dc = authDomain.getConfigurator();
+////      assertNotNull("DomainConfigurator != null", dc);
+////      JACCPortalAuthorizationManagerFactory factory = new JACCPortalAuthorizationManagerFactory();
+////      JBossAuthorizationDomainRegistryImpl registry = new JBossAuthorizationDomainRegistryImpl();
+////      registry.addDomain(container);
+////      factory.setAuthorizationDomainRegistry(registry);
+////      container.setAuthorizationDomainRegistry(registry);
+////      container.setPortalAuthorizationManagerFactory(factory);
+////      dc.setConstraints(uri, this.getSecurityConstraints(perm,role));
+////   }
 }

Modified: trunk/core/src/resources/portal-core-sar/portal-aop.xml
===================================================================
--- trunk/core/src/resources/portal-core-sar/portal-aop.xml	2006-09-23 12:29:49 UTC (rev 5245)
+++ trunk/core/src/resources/portal-core-sar/portal-aop.xml	2006-09-25 14:51:47 UTC (rev 5246)
@@ -85,6 +85,9 @@
       <method name="getInstances">
          <trans-attribute>Required</trans-attribute>
       </method>
+      <method name="invoke">
+         <trans-attribute>Required</trans-attribute>
+      </method>
    </metadata>
    <metadata
       tag="transaction"

Modified: trunk/core/src/resources/portal-core-test-jar/org/jboss/portal/test/core/model/instance/jboss-beans.xml
===================================================================
--- trunk/core/src/resources/portal-core-test-jar/org/jboss/portal/test/core/model/instance/jboss-beans.xml	2006-09-23 12:29:49 UTC (rev 5245)
+++ trunk/core/src/resources/portal-core-test-jar/org/jboss/portal/test/core/model/instance/jboss-beans.xml	2006-09-25 14:51:47 UTC (rev 5246)
@@ -1,9 +1,15 @@
 <?xml version="1.0" encoding="UTF-8"?>
-
 <deployment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="urn:jboss:bean-deployer bean-deployer_1_0.xsd"
             xmlns="urn:jboss:bean-deployer">
 
+   <bean name="TestCaseConfig" class="org.jboss.portal.test.core.model.instance.InstanceContainerTestCase">
+      <constructor factoryMethod="getBean">
+         <factory bean="BeanFactory"/>
+         <parameter>TestCaseConfig</parameter>
+      </constructor>
+   </bean>
+
    <bean name="DataSourceConfig" class="org.jboss.portal.test.framework.embedded.DataSourceSupport$Config">
       <constructor factoryMethod="getBean">
          <factory bean="BeanFactory"/>
@@ -51,7 +57,7 @@
    <bean name="StateConverter" class="org.jboss.portal.portlet.impl.state.StateConverterService">
    </bean>
    <bean name="StateManagementPolicy" class="org.jboss.portal.portlet.impl.state.StateManagementPolicyService">
-      <property name="persistLocally">true</property>
+      <property name="persistLocally"><inject bean="TestCaseConfig" property="persistLocally"/></property>
    </bean>
    <bean name="PersistenceManager" class="org.jboss.portal.core.impl.portlet.state.PersistentStateStore">
       <property name="sessionFactoryJNDIName">java:/PortletSessionFactory</property>

Modified: trunk/portlet/src/main/org/jboss/portal/portlet/state/producer/ProducerPortletInvoker.java
===================================================================
--- trunk/portlet/src/main/org/jboss/portal/portlet/state/producer/ProducerPortletInvoker.java	2006-09-23 12:29:49 UTC (rev 5245)
+++ trunk/portlet/src/main/org/jboss/portal/portlet/state/producer/ProducerPortletInvoker.java	2006-09-25 14:51:47 UTC (rev 5246)
@@ -120,50 +120,6 @@
       this.stateConverter = stateConverter;
    }
 
-   public String unwrapCCP(PortletContext wrappedCCPCtx) throws InvalidPortletIdException
-   {
-      if (wrappedCCPCtx == null)
-      {
-         throw new IllegalArgumentException();
-      }
-      if (wrappedCCPCtx.getId().startsWith(PRODUCER_CLONE_ID_PREFIX) == false)
-      {
-         throw new InvalidPortletIdException(wrappedCCPCtx.getId());
-      }
-      return wrappedCCPCtx.getId().substring(1);
-   }
-
-   public String unwrapPOP(PortletContext wrappedPOPCtx) throws InvalidPortletIdException
-   {
-      if (wrappedPOPCtx == null)
-      {
-         throw new IllegalArgumentException();
-      }
-      return wrappedPOPCtx.getId();
-   }
-
-   public PortletContext wrapCCP(String ccpId) throws InvalidPortletIdException
-   {
-      if (ccpId == null)
-      {
-         throw new IllegalArgumentException();
-      }
-      return new PortletContext(PRODUCER_CLONE_ID_PREFIX + ccpId);
-   }
-
-   public PortletContext wrapPOP(String popId) throws InvalidPortletIdException
-   {
-      if (popId == null)
-      {
-         throw new IllegalArgumentException();
-      }
-      if (popId.startsWith(PRODUCER_CLONE_ID_PREFIX))
-      {
-         throw new IllegalArgumentException("Must not start with " + PRODUCER_CLONE_ID_PREFIX);
-      }
-      return new PortletContext(popId);
-   }
-
    public Set getPortlets() throws PortletInvokerException
    {
       return portletInvoker.getPortlets();
@@ -231,7 +187,7 @@
       String targetPortletId = portletContext.getId();
 
       // Try to get state
-      ProducerState state = getState(portletContext);
+      ProducerState state = getProducerState(portletContext);
       if (state != null)
       {
          propertyMap = state.getProperties();
@@ -320,7 +276,7 @@
                {
                   ProducerState cloneState = new ProducerState(state.getPortletId(), newPrefs);
                   byte[] bytes = stateConverter.marshall(cloneState);
-                  PortletContext clonedCtx = new StatefulPortletContext(CONSUMER_CLONE_ID, bytes);
+                  StatefulPortletContext clonedCtx = new StatefulPortletContext(CONSUMER_CLONE_ID, bytes);
                   PortletClonedEvent event = new PortletClonedEvent(clonedCtx);
                   instanceCtx.onStateEvent(event);
                }
@@ -395,7 +351,7 @@
 
       //
       String portletId = portletContext.getId();
-      ProducerState state = getState(portletContext);
+      ProducerState state = getProducerState(portletContext);
       boolean useStore = stateManagementPolicy.persistLocally();
 
       //
@@ -517,7 +473,7 @@
 
       //
       String portletId = portletContext.getId();
-      ProducerState state = getState(portletContext);
+      ProducerState state = getProducerState(portletContext);
 
       //
       if (state != null)
@@ -585,7 +541,7 @@
 
       //
       String portletId = portletContext.getId();
-      ProducerState state = getState(portletContext);
+      ProducerState state = getProducerState(portletContext);
 
       //
       if (state == null)
@@ -705,7 +661,7 @@
     * @throws NoSuchPortletException if the underlying state does not exist
     * @throws InvalidPortletIdException if the state id is not valid
     */
-   private ProducerState getState(PortletContext portletContext) throws NoSuchPortletException, InvalidPortletIdException
+   private ProducerState getProducerState(PortletContext portletContext) throws NoSuchPortletException, InvalidPortletIdException
    {
       if (portletContext instanceof StatefulPortletContext == false)
       {

Modified: trunk/portlet/src/main/org/jboss/portal/portlet/test/support/info/MetaInfoSupport.java
===================================================================
--- trunk/portlet/src/main/org/jboss/portal/portlet/test/support/info/MetaInfoSupport.java	2006-09-23 12:29:49 UTC (rev 5245)
+++ trunk/portlet/src/main/org/jboss/portal/portlet/test/support/info/MetaInfoSupport.java	2006-09-25 14:51:47 UTC (rev 5246)
@@ -56,7 +56,7 @@
       LocalizedString string = new LocalizedString(value, locale);
       if (values.put(key, string) != null)
       {
-         throw new IllegalStateException();
+         throw new IllegalStateException("Already existing");
       }
    }
 

Modified: trunk/test/src/etc/datasources.xml
===================================================================
--- trunk/test/src/etc/datasources.xml	2006-09-23 12:29:49 UTC (rev 5245)
+++ trunk/test/src/etc/datasources.xml	2006-09-25 14:51:47 UTC (rev 5246)
@@ -1,5 +1,6 @@
 <datasources>
    <datasource>
+      <display-name>hsqldb</display-name>
       <connection-url>jdbc:hsqldb:file:test</connection-url>
       <driver-class>org.hsqldb.jdbcDriver</driver-class>
       <user-name>sa</user-name>

Modified: trunk/test/src/main/org/jboss/portal/test/framework/embedded/DataSourceSupport.java
===================================================================
--- trunk/test/src/main/org/jboss/portal/test/framework/embedded/DataSourceSupport.java	2006-09-23 12:29:49 UTC (rev 5245)
+++ trunk/test/src/main/org/jboss/portal/test/framework/embedded/DataSourceSupport.java	2006-09-25 14:51:47 UTC (rev 5246)
@@ -25,6 +25,7 @@
 import org.jboss.resource.adapter.jdbc.local.LocalTxDataSource;
 import org.jboss.portal.common.util.XML;
 import org.jboss.portal.common.util.Tools;
+import org.jboss.portal.test.framework.junit.metadata.TestCaseParameterIterableValue;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
@@ -33,6 +34,8 @@
 import java.util.Hashtable;
 import java.util.ArrayList;
 import java.util.Iterator;
+import java.util.Arrays;
+import java.util.List;
 import java.net.URL;
 import java.sql.Connection;
 import java.sql.Statement;
@@ -68,7 +71,7 @@
 
    public DataSourceSupport()
    {
-      this(new Config("", "", "", ""));
+      this(new Config("", "", "", "", ""));
    }
 
    public void create()
@@ -204,19 +207,26 @@
    public static class Config
    {
 
+      private String displayName;
       private String connectionURL;
       private String driverClass;
       private String userName;
       private String password;
 
-      public Config(String connectionURL, String driverClass, String userName, String password)
+      public Config(String displayName, String connectionURL, String driverClass, String userName, String password)
       {
+         this.displayName = displayName;
          this.connectionURL = connectionURL;
          this.driverClass = driverClass;
          this.userName = userName;
          this.password = password;
       }
 
+      public String getDisplayName()
+      {
+         return displayName;
+      }
+
       public String getConnectionURL()
       {
          return connectionURL;
@@ -237,6 +247,13 @@
          return password;
       }
 
+      public static TestCaseParameterIterableValue fromXML2(URL url) throws Exception
+      {
+         Config[] configs = fromXML(url);
+         List list = Arrays.asList(configs);
+         return new TestCaseParameterIterableValue(list);
+      }
+
       public static Config[] fromXML(URL url) throws Exception
       {
          ArrayList configs = new ArrayList();
@@ -248,15 +265,18 @@
             for (Iterator i = XML.getChildrenIterator(doc.getDocumentElement(), "datasource");i.hasNext();)
             {
                Element childElt = (Element)i.next();
+               Element displayNameElt = XML.getUniqueChild(childElt, "display-name", true);
                Element connectionURLElt = XML.getUniqueChild(childElt, "connection-url", true);
                Element driverClassElt = XML.getUniqueChild(childElt, "driver-class", true);
                Element userNameElt = XML.getUniqueChild(childElt, "user-name", true);
                Element passwordElt = XML.getUniqueChild(childElt, "password", true);
+               String displayName = XML.asString(displayNameElt);
                String connectionURL = XML.asString(connectionURLElt);
                String driverClass = XML.asString(driverClassElt);
                String userName = XML.asString(userNameElt);
                String password = XML.asString(passwordElt);
                Config dsCfg = new Config(
+                  displayName,
                   connectionURL,
                   driverClass,
                   userName,
@@ -270,6 +290,5 @@
             Tools.safeClose(in);
          }
       }
-
    }
 }

Added: trunk/test/src/main/org/jboss/portal/test/framework/junit/TestCaseFactory.java
===================================================================
--- trunk/test/src/main/org/jboss/portal/test/framework/junit/TestCaseFactory.java	2006-09-23 12:29:49 UTC (rev 5245)
+++ trunk/test/src/main/org/jboss/portal/test/framework/junit/TestCaseFactory.java	2006-09-25 14:51:47 UTC (rev 5246)
@@ -0,0 +1,101 @@
+/*
+* 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.test.framework.junit;
+
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Method;
+import java.util.Map;
+import java.util.Iterator;
+
+import org.jboss.portal.test.framework.junit.metadata.TestCaseMetaData;
+
+/**
+ * @author <a href="mailto:julien at jboss.org">Julien Viet</a>
+ * @version $Revision: 1.1 $
+ */
+public class TestCaseFactory
+{
+
+   public static TestSuite create(TestCaseMetaData testCaseMD, Class clazz) 
+   {
+      TestSuite suite = new TestSuite();
+      for (Iterator i = testCaseMD.getParametrizations().iterator();i.hasNext();)
+      {
+         Map parametrization = (Map)i.next();
+
+         //
+         introspect(suite, parametrization, clazz);
+      }
+      return suite;
+   }
+
+   private static void introspect(TestSuite suite, Map parametrization, Class clazz)
+   {
+      try
+      {
+         Constructor ctor = clazz.getConstructor(new Class[]{Map.class});
+
+         //
+         Method[] methods = clazz.getMethods();
+         for (int j = 0; j < methods.length; j++)
+         {
+            Method method = methods[j];
+            int modifiers = method.getModifiers();
+            if (Modifier.isPublic(modifiers) && !Modifier.isAbstract(modifiers) && !Modifier.isStatic(modifiers) && method.getName().startsWith("test"))
+            {
+               TestCase testCase = (TestCase)ctor.newInstance(new Object[]{parametrization});
+               testCase.setName(method.getName());
+               suite.addTest(testCase);
+            }
+         }
+      }
+      catch (InstantiationException e)
+      {
+         IllegalArgumentException iae = new IllegalArgumentException();
+         iae.initCause(e);
+         throw iae;
+      }
+      catch (NoSuchMethodException e)
+      {
+         IllegalArgumentException iae = new IllegalArgumentException();
+         iae.initCause(e);
+         throw iae;
+      }
+      catch (IllegalAccessException e)
+      {
+         IllegalArgumentException iae = new IllegalArgumentException();
+         iae.initCause(e);
+         throw iae;
+      }
+      catch (InvocationTargetException e)
+      {
+         IllegalArgumentException iae = new IllegalArgumentException();
+         iae.initCause(e);
+         throw iae;
+      }
+   }
+}

Modified: trunk/test/src/main/org/jboss/portal/test/framework/junit/TransactionAssert.java
===================================================================
--- trunk/test/src/main/org/jboss/portal/test/framework/junit/TransactionAssert.java	2006-09-23 12:29:49 UTC (rev 5245)
+++ trunk/test/src/main/org/jboss/portal/test/framework/junit/TransactionAssert.java	2006-09-25 14:51:47 UTC (rev 5246)
@@ -22,6 +22,7 @@
 package org.jboss.portal.test.framework.junit;
 
 import junit.framework.Assert;
+import junit.framework.AssertionFailedError;
 
 import javax.transaction.UserTransaction;
 import javax.transaction.Status;
@@ -35,7 +36,64 @@
 public class TransactionAssert extends Assert
 {
 
+   private static final String[] STATUS_NAMES = {
+      "STATUS_ACTIVE",
+      "STATUS_MARKED_ROLLBACK",
+      "STATUS_PREPARED",
+      "STATUS_COMMITTED",
+      "STATUS_ROLLEDBACK",
+      "STATUS_UNKNOWN",
+      "STATUS_NO_TRANSACTION",
+      "STATUS_PREPARING",
+      "STATUS_COMMITTING",
+      "STATUS_ROLLING_BACK"};
+
    /**
+    * Decode the status name.
+    *
+    * @param status the status value
+    * @return the translated status name or null if it is not valid
+    */
+   public static String decodeStatus(int status)
+   {
+      if (status >= 0 && status <= STATUS_NAMES.length)
+      {
+         return STATUS_NAMES[status];
+      }
+      else
+      {
+         return null;
+      }
+   }
+
+   /** . */
+   public static final Terminator NONE = new Terminator("NONE");
+
+   /** . */
+   public static final Terminator MARKED_AS_ROLLBACK = new Terminator("MARKED_AS_ROLLBACK");
+
+   /** . */
+   public static final Terminator MUST_COMMIT = new Terminator("MUST_COMMIT");
+
+   /** . */
+   public static final Terminator MUST_ROLLBACK = new Terminator("MUST ROLLBACK");
+
+   /**
+    *
+    */
+   public static final class Terminator
+   {
+
+      /** . */
+      private final String name;
+
+      public Terminator(String name)
+      {
+         this.name = name;
+      }
+   }
+
+   /**
     * Assert the status of the current transaction.
     *
     * @param expectedStatus the expected status
@@ -91,6 +149,10 @@
          if (status == Status.STATUS_MARKED_ROLLBACK)
          {
             ut.rollback();
+            if (marked == false)
+            {
+               fail("Transaction should have been marked as rollback");
+            }
          }
          else if (status == Status.STATUS_ACTIVE)
          {
@@ -135,7 +197,7 @@
     * If no transaction do nothing.
     * End the transaction if it is active or marked for rollback otherwise fail.
     */
-   public static void endTransaction()
+   public static int endTransaction()
    {
       try
       {
@@ -157,14 +219,72 @@
          {
             fail("Unexpected transaction status " + status);
          }
+         return status;
       }
       catch (Exception e)
       {
          e.printStackTrace();
-         fail("Cannot end transaction");
+         throw new AssertionFailedError("Cannot end transaction");
       }
    }
 
+   /**
+    * If no transaction do nothing.
+    * End the transaction if it is active or marked for rollback otherwise fail.
+    */
+   public static int endTransaction(Terminator expectedTerminator)
+   {
+      if (expectedTerminator == null)
+      {
+         throw new IllegalArgumentException();
+      }
+      try
+      {
+         UserTransaction ut = getUserTransaction();
+         int status = ut.getStatus();
+         if (status == Status.STATUS_MARKED_ROLLBACK)
+         {
+            ut.rollback();
+            if (expectedTerminator != MARKED_AS_ROLLBACK)
+            {
+               fail("Was expecting the transaction to be marked as rollback instead got " + decodeStatus(status));
+            }
+         }
+         else if (status == Status.STATUS_ACTIVE)
+         {
+            if (expectedTerminator == MUST_COMMIT)
+            {
+               ut.commit();
+            }
+            else if (expectedTerminator == MUST_ROLLBACK)
+            {
+               ut.rollback();
+            }
+            else
+            {
+               fail("Was expecting the transaction to be either commiting or rollbacking instead got " + decodeStatus(status));
+            }
+         }
+         else if (status == Status.STATUS_NO_TRANSACTION)
+         {
+            if (expectedTerminator != NONE)
+            {
+               fail("Was expecting no transaction instead got " + decodeStatus(status));
+            }
+         }
+         else
+         {
+            fail("Unexpected transaction status " + decodeStatus(status));
+         }
+         return status;
+      }
+      catch (Exception e)
+      {
+         e.printStackTrace();
+         throw new AssertionFailedError("Cannot end transaction");
+      }
+   }
+
    public static UserTransaction getUserTransaction()
    {
       try

Added: trunk/test/src/main/org/jboss/portal/test/framework/junit/metadata/TestCaseMetaData.java
===================================================================
--- trunk/test/src/main/org/jboss/portal/test/framework/junit/metadata/TestCaseMetaData.java	2006-09-23 12:29:49 UTC (rev 5245)
+++ trunk/test/src/main/org/jboss/portal/test/framework/junit/metadata/TestCaseMetaData.java	2006-09-25 14:51:47 UTC (rev 5246)
@@ -0,0 +1,130 @@
+/*
+* 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.test.framework.junit.metadata;
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Collection;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+/**
+ * @author <a href="mailto:julien at jboss.org">Julien Viet</a>
+ * @version $Revision: 1.1 $
+ */
+public class TestCaseMetaData
+{
+
+   /** . */
+   private Map parameters;
+
+   /** . */
+   private Map parametrization;
+
+   public TestCaseMetaData()
+   {
+      this.parameters = new HashMap();
+      this.parametrization = new HashMap();
+   }
+
+   public void addParameter(TestCaseParameterMetaData parameter)
+   {
+      if (parameter == null)
+      {
+         throw new IllegalArgumentException("No null accepted");
+      }
+      if (parameters.containsKey(parameter.getName()))
+      {
+         throw new IllegalArgumentException("Duplicate parameter " + parameter.getName());
+      }
+
+      //
+      parameters.put(parameter.getName(), parameter);
+   }
+
+   public void bindParameter(TestCaseParameterMetaData parameter, TestCaseParameterValue value)
+   {
+      if (parameter == null)
+      {
+         throw new IllegalArgumentException("No null accepted");
+      }
+      if (parameters.containsKey(parameter.getName()))
+      {
+         throw new IllegalArgumentException("Duplicate parameter " + parameter.getName());
+      }
+
+      //
+      parameters.put(parameter.getName(), parameter);
+      parametrization.put(parameter.getName(), value);
+   }
+
+   public Collection getParametrizations()
+   {
+      ArrayList c = new ArrayList();
+      c.add(new HashMap());
+
+      //
+      for (Iterator i = parameters.values().iterator(); i.hasNext();)
+      {
+         TestCaseParameterMetaData parameter = (TestCaseParameterMetaData)i.next();
+
+         //
+         if (parametrization.containsKey(parameter.getName()) == false)
+         {
+            throw new IllegalStateException("Parameter not bound " + parameter.getName());
+         }
+
+         //
+         TestCaseParameterValue value = (TestCaseParameterValue)parametrization.get(parameter.getName());
+
+         //
+         if (value instanceof TestCaseParameterIterableValue)
+         {
+            TestCaseParameterIterableValue iterableValue = (TestCaseParameterIterableValue)value;
+            ArrayList tmp = new ArrayList();
+            for (Iterator j = iterableValue.iterator();j.hasNext();)
+            {
+               Object o = j.next();
+               ArrayList copy = new ArrayList(c.size());
+               for (Iterator k = c.iterator();k.hasNext();)
+               {
+                  Map parametrization = (Map)k.next();
+                  parametrization = new HashMap(parametrization);
+                  parametrization.put(parameter.getName(), o);
+                  copy.add(parametrization);
+               }
+               tmp.addAll(copy);
+            }
+            c = tmp;
+         }
+         else
+         {
+            for (int j = 0; j < c.size(); j++)
+            {
+               Map parametrization = (Map)c.get(j);
+               parametrization.put(parameter.getName(), value.get());
+            }
+         }
+      }
+      return c;
+   }
+}

Added: trunk/test/src/main/org/jboss/portal/test/framework/junit/metadata/TestCaseParameterIterableValue.java
===================================================================
--- trunk/test/src/main/org/jboss/portal/test/framework/junit/metadata/TestCaseParameterIterableValue.java	2006-09-23 12:29:49 UTC (rev 5245)
+++ trunk/test/src/main/org/jboss/portal/test/framework/junit/metadata/TestCaseParameterIterableValue.java	2006-09-25 14:51:47 UTC (rev 5246)
@@ -0,0 +1,49 @@
+/*
+* 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.test.framework.junit.metadata;
+
+import java.util.Collection;
+import java.util.Iterator;
+
+/**
+ * @author <a href="mailto:julien at jboss.org">Julien Viet</a>
+ * @version $Revision: 1.1 $
+ */
+public class TestCaseParameterIterableValue extends TestCaseParameterValue
+{
+
+   public TestCaseParameterIterableValue(Collection values)
+   {
+      super(values);
+
+      //
+      if (values == null)
+      {
+         throw new IllegalArgumentException();
+      }
+   }
+
+   public Iterator iterator()
+   {
+      return ((Collection)value).iterator();
+   }
+}

Added: trunk/test/src/main/org/jboss/portal/test/framework/junit/metadata/TestCaseParameterMetaData.java
===================================================================
--- trunk/test/src/main/org/jboss/portal/test/framework/junit/metadata/TestCaseParameterMetaData.java	2006-09-23 12:29:49 UTC (rev 5245)
+++ trunk/test/src/main/org/jboss/portal/test/framework/junit/metadata/TestCaseParameterMetaData.java	2006-09-25 14:51:47 UTC (rev 5246)
@@ -0,0 +1,53 @@
+/*
+* 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.test.framework.junit.metadata;
+
+/**
+ * @author <a href="mailto:julien at jboss.org">Julien Viet</a>
+ * @version $Revision: 1.1 $
+ */
+public class TestCaseParameterMetaData
+{
+
+   /** . */
+   public static final String TESTCASE_CONSTRUCTOR = "TESTCASE_CONSTRUCTOR";
+
+   /** . */
+   public static final String TESTCASE_METHOD = "TESTCASE_METHOD";
+
+   /** . */
+   private String name;
+
+   public TestCaseParameterMetaData(String name)
+   {
+      if (name == null)
+      {
+         throw new IllegalArgumentException();
+      }
+      this.name = name;
+   }
+
+   public String getName()
+   {
+      return name;
+   }
+}

Added: trunk/test/src/main/org/jboss/portal/test/framework/junit/metadata/TestCaseParameterValue.java
===================================================================
--- trunk/test/src/main/org/jboss/portal/test/framework/junit/metadata/TestCaseParameterValue.java	2006-09-23 12:29:49 UTC (rev 5245)
+++ trunk/test/src/main/org/jboss/portal/test/framework/junit/metadata/TestCaseParameterValue.java	2006-09-25 14:51:47 UTC (rev 5246)
@@ -0,0 +1,43 @@
+/*
+* 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.test.framework.junit.metadata;
+
+/**
+ * @author <a href="mailto:julien at jboss.org">Julien Viet</a>
+ * @version $Revision: 1.1 $
+ */
+public class TestCaseParameterValue
+{
+
+   /** . */
+   protected final Object value;
+
+   public TestCaseParameterValue(Object value)
+   {
+      this.value = value;
+   }
+
+   public Object get()
+   {
+      return value;
+   }
+}




More information about the jboss-svn-commits mailing list