You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jetspeed-dev@portals.apache.org by rw...@apache.org on 2009/01/11 22:58:24 UTC

svn commit: r733524 [2/6] - in /portals/jetspeed-2/portal/branches/JPA_BRANCH: components/jetspeed-page-manager/ components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/folder/jpa/ components/jetspeed-page-manager/src/main/java/org/apache...

Added: portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-registry/src/main/java/org/apache/jetspeed/components/portletentity/jpa/PortletEntityAccessComponentImpl.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-registry/src/main/java/org/apache/jetspeed/components/portletentity/jpa/PortletEntityAccessComponentImpl.java?rev=733524&view=auto
==============================================================================
--- portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-registry/src/main/java/org/apache/jetspeed/components/portletentity/jpa/PortletEntityAccessComponentImpl.java (added)
+++ portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-registry/src/main/java/org/apache/jetspeed/components/portletentity/jpa/PortletEntityAccessComponentImpl.java Sun Jan 11 13:58:21 2009
@@ -0,0 +1,395 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jetspeed.components.portletentity.jpa;
+
+import java.rmi.server.UID;
+import java.util.Collection;
+import java.util.Iterator;
+
+import javax.persistence.EntityManager;
+import javax.persistence.NoResultException;
+import javax.persistence.PersistenceContext;
+import javax.persistence.PersistenceContextType;
+import javax.persistence.Query;
+
+import org.apache.jetspeed.components.portletentity.PortletEntityAccessComponent;
+import org.apache.jetspeed.components.portletentity.PortletEntityNotDeletedException;
+import org.apache.jetspeed.components.portletentity.PortletEntityNotGeneratedException;
+import org.apache.jetspeed.components.portletentity.PortletEntityNotStoredException;
+import org.apache.jetspeed.components.portletregistry.PortletRegistry;
+import org.apache.jetspeed.components.portletregistry.jpa.RegistryManager;
+import org.apache.jetspeed.container.PortletEntity;
+import org.apache.jetspeed.om.page.ContentFragment;
+import org.apache.jetspeed.om.page.Fragment;
+import org.apache.jetspeed.om.portlet.PortletDefinition;
+import org.springframework.stereotype.Repository;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * PortletEntityAccessComponentImpl
+ *
+ * @author <a href="mailto:weaver@apache.org">Scott T. Weaver </a>
+ * @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
+ * @version $Id$
+ */
+@Repository
+public class PortletEntityAccessComponentImpl implements PortletEntityAccessComponent
+{
+    // Members
+    
+    private RegistryManager registryManager;
+    private PortletRegistry registry;
+    private boolean mergeSharedPreferences;
+    
+    // Constructors
+    
+    /**
+     * Construct portlet entity access component given the specified
+     * registry manager and registry with no merge configuration.
+     *
+     * @param registryManager registry manager.
+     * @param registry portlet registry.
+     */
+    public PortletEntityAccessComponentImpl(RegistryManager registryManager, PortletRegistry registry)
+    {
+        this(registryManager, registry, false);
+    }
+
+    /**
+     * Construct portlet entity access component given the specified
+     * registry manager, registry, and merge configuration.
+     * 
+     * 2006-08-22: by default, do not merge preferences from the shared preferences area 
+     * up until this point, all preferences were shared. With JS2-449, preferences are now
+     * stored 'per user'. The username is stored in the preferences FULL_PATH
+     * To turn on mergeSharedPreferences configure this property to true 
+     * in your Spring configuration
+     * 
+     * @param registryManager registry manager.
+     * @param registry portlet registry.
+     * @param mergeSharedPreferences merge shared preferences configuration.
+     */
+    public PortletEntityAccessComponentImpl(RegistryManager registryManager, PortletRegistry registry, boolean mergeSharedPreferences)
+    {
+        this.registryManager = registryManager;
+        this.registry = registry;
+        this.mergeSharedPreferences = mergeSharedPreferences;
+    }
+    
+    // Implementation
+    
+    /**
+     * Return entity manager associated with current thread from
+     * registered context or default transactional entity manager
+     * created for this request.
+     * 
+     * @return entity manager.
+     */
+    protected EntityManager getEntityManager()
+    {
+        return registryManager.getEntityManager();
+    }
+        
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.components.portletentity.PortletEntityAccessComponent#generateEntityFromFragment(org.apache.jetspeed.om.page.ContentFragment)
+     */
+    @Transactional (readOnly=true)
+    public PortletEntity generateEntityFromFragment(ContentFragment fragment) throws PortletEntityNotGeneratedException
+    {
+        // get associated portlet definition from registry
+        PortletDefinition pd = registry.getPortletDefinitionByUniqueName(fragment.getName());
+        // generate portlet entity
+        PortletEntity portletEntity = null;
+        if (pd != null)
+        {
+            portletEntity = newPortletEntityInstance(pd);
+        }
+        else
+        {
+            portletEntity = new PortletEntityImpl(fragment);
+            String msg = "Failed to retrieve Portlet Definition for " + fragment.getName();
+            fragment.overrideRenderedContent(msg);
+        }
+        String entityKey = generateEntityKey(fragment);
+        portletEntity.setId(entityKey);
+        return portletEntity;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.components.portletentity.PortletEntityAccessComponent#generateEntityKey(org.apache.jetspeed.om.page.Fragment)
+     */
+    public String generateEntityKey(Fragment fragment)
+    {
+        return fragment.getId();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.components.portletentity.PortletEntityAccessComponent#getPortletEntities(org.apache.jetspeed.om.portlet.PortletDefinition)
+     */
+    @Transactional (readOnly=true)
+    public Collection getPortletEntities(PortletDefinition portletDefinition)
+    {
+        // gather query parameters
+        String appName = portletDefinition.getApplication().getName();
+        String portletName = portletDefinition.getPortletName();
+        // perform query
+        EntityManager entityManager = getEntityManager();
+        Query portletEntitiesQuery = entityManager.createNamedQuery("PORTLET_ENTITES");
+        portletEntitiesQuery.setParameter("appName", appName);
+        portletEntitiesQuery.setParameter("portletName", portletName);
+        return portletEntitiesQuery.getResultList();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.components.portletentity.PortletEntityAccessComponent#getPortletEntities(java.lang.String)
+     */
+    @Transactional (readOnly=true)
+    public Collection getPortletEntities(String portletUniqueName)
+    {
+        // gather query parameters
+        String[] split = portletUniqueName.split(PortletRegistry.PORTLET_UNIQUE_NAME_SEPARATOR);
+        String appName = split[0];
+        String portletName = split[1];
+        // perform query
+        EntityManager entityManager = getEntityManager();
+        Query portletEntitiesQuery = entityManager.createNamedQuery("PORTLET_ENTITES");
+        portletEntitiesQuery.setParameter("appName", appName);
+        portletEntitiesQuery.setParameter("portletName", portletName);
+        return portletEntitiesQuery.getResultList();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.components.portletentity.PortletEntityAccessComponent#getPortletEntity(java.lang.String)
+     */
+    @Transactional (readOnly=true)
+    public PortletEntity getPortletEntity(String id)
+    {
+        try
+        {
+            return getPortletEntity(id, null);
+        }
+        catch (PortletEntityNotStoredException e)
+        {
+            // This exception is only thrown if a Fragment has been passed into the
+            // getPortletEntity() method.  This should never happen.
+            IllegalStateException ise = new IllegalStateException("Unexepected error while retrieving portlet entity "+id);
+            ise.initCause(e);
+            throw ise;
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.components.portletentity.PortletEntityAccessComponent#getPortletEntityForFragment(org.apache.jetspeed.om.page.ContentFragment)
+     */
+    @Transactional (readOnly=true)
+    public PortletEntity getPortletEntityForFragment(ContentFragment fragment) throws PortletEntityNotStoredException
+    {
+        return getPortletEntity(generateEntityKey(fragment), fragment);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.components.portletentity.PortletEntityAccessComponent#isMergeSharedPreferences()
+     */
+    public boolean isMergeSharedPreferences()
+    {
+        return mergeSharedPreferences;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.components.portletentity.PortletEntityAccessComponent#newPortletEntityInstance(org.apache.jetspeed.om.portlet.PortletDefinition, java.lang.String)
+     */
+    public PortletEntity newPortletEntityInstance(PortletDefinition portletDefinition, String id)
+    {
+        PortletEntityImpl portletEntity = new PortletEntityImpl();
+        portletEntity.setPortletDefinition(portletDefinition);
+        portletEntity.setId(id);
+        return portletEntity;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.components.portletentity.PortletEntityAccessComponent#newPortletEntityInstance(org.apache.jetspeed.om.portlet.PortletDefinition)
+     */
+    public PortletEntity newPortletEntityInstance(PortletDefinition portletDefinition)
+    {
+        return newPortletEntityInstance(portletDefinition, autoGenerateID(portletDefinition));
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.components.portletentity.PortletEntityAccessComponent#removeFromCache(org.apache.jetspeed.container.PortletEntity)
+     */
+    public void removeFromCache(PortletEntity entity)
+    {
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.components.portletentity.PortletEntityAccessComponent#removePortletEntities(org.apache.jetspeed.om.portlet.PortletDefinition)
+     */
+    @Transactional (readOnly=false)
+    public void removePortletEntities(PortletDefinition portletDefinition) throws PortletEntityNotDeletedException
+    {
+        Iterator entities = getPortletEntities(portletDefinition).iterator();
+        while (entities.hasNext())
+        {
+            PortletEntity entity = (PortletEntity) entities.next();
+            removePortletEntity(entity);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.components.portletentity.PortletEntityAccessComponent#removePortletEntity(org.apache.jetspeed.container.PortletEntity)
+     */
+    @Transactional (readOnly=false)
+    public void removePortletEntity(PortletEntity portletEntity) throws PortletEntityNotDeletedException
+    {
+        EntityManager entityManager = getEntityManager();
+        // remove, (potentially detached), portlet entity
+        if (!((PortletEntityImpl)portletEntity).isNew())
+        {
+            portletEntity = entityManager.merge(portletEntity);
+        }
+        entityManager.remove(portletEntity);
+        // explicitly flush entity manager after remove
+        entityManager.flush();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.components.portletentity.PortletEntityAccessComponent#storePortletEntity(org.apache.jetspeed.container.PortletEntity)
+     */
+    @Transactional (readOnly=false, rollbackFor=PortletEntityNotStoredException.class)
+    public void storePortletEntity(PortletEntity portletEntity) throws PortletEntityNotStoredException
+    {
+        try
+        {
+            EntityManager entityManager = getEntityManager();
+            // update, (potentially detached), portlet entity
+            if (!((PortletEntityImpl)portletEntity).isNew())
+            {
+                portletEntity = entityManager.merge(portletEntity);
+            }
+            entityManager.persist(portletEntity);
+            // explicitly flush entity manager after update
+            entityManager.flush();
+        }
+        catch (Exception e)
+        {
+            throw new PortletEntityNotStoredException("Failed to store portlet Entity: "+e.toString(), e);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.components.portletentity.PortletEntityAccessComponent#updatePortletEntity(org.apache.jetspeed.container.PortletEntity, org.apache.jetspeed.om.page.ContentFragment)
+     */
+    @Transactional (readOnly=true)
+    public void updatePortletEntity(PortletEntity portletEntity, ContentFragment fragment) throws PortletEntityNotStoredException
+    {
+        // validate portlet entity id
+        if (!fragment.getId().equals(portletEntity.getId().toString()))
+        {
+            throw new PortletEntityNotStoredException("Fragment and PortletEntity ids do not match, update skipped: " + fragment.getId() + " != " + portletEntity.getId() );
+        }
+
+        // update portlet definition from fragment
+        PortletDefinition pd = registry.getPortletDefinitionByUniqueName(fragment.getName());
+        if (pd != null)
+        {
+            ((PortletEntityImpl)portletEntity).setPortletDefinition(pd);
+        }
+        else
+        {
+            throw new PortletEntityNotStoredException("Fragment PortletDefinition not found: " + fragment.getName() );
+        }
+    }
+    
+    /**
+     * Get portlet entity by id and initialize with fragment.
+     * 
+     * @param id portlet entity id.
+     * @param fragment content fragment.
+     * @return portlet entity.
+     * @throws PortletEntityNotStoredException
+     */
+    private PortletEntity getPortletEntity(String id, ContentFragment fragment) throws PortletEntityNotStoredException
+    {
+        // perform query for single portlet entity
+        EntityManager entityManager = getEntityManager();
+        Query portletEntityQuery = entityManager.createNamedQuery("PORTLET_ENTITY");
+        portletEntityQuery.setParameter("id", id);        
+        PortletEntity portletEntity = null;
+        try
+        {
+            portletEntity = (PortletEntity)portletEntityQuery.getSingleResult();
+        }
+        catch (NoResultException nre)
+        {
+        }
+        // store associated portlet definition in registry
+        if (portletEntity != null)
+        {
+            String portletUniqueName = portletEntity.getPortletUniqueName();
+            PortletDefinition parentPortletDef = registry.getPortletDefinitionByUniqueName(portletUniqueName);
+            if (parentPortletDef != null)
+            {
+                // Indication that the fragment has changed the portlet it references.
+                if (fragment != null && !portletUniqueName.equals(fragment.getName()))
+                {
+                    parentPortletDef = registry.getPortletDefinitionByUniqueName(fragment.getName());
+                    portletEntity.setPortletDefinition(parentPortletDef);
+                    storePortletEntity(portletEntity);
+                }
+                else
+                {
+                    portletEntity.setPortletDefinition(parentPortletDef);
+                }
+            }
+            else if (fragment != null && parentPortletDef == null)
+            {
+                // If we have no portlet definition but have a fragment, we see if the
+                // unique name has changed and access the portlet definition
+                // using that unique name.
+                parentPortletDef = registry.getPortletDefinitionByUniqueName(fragment.getName());
+                if (parentPortletDef != null)
+                {
+                    portletEntity.setPortletDefinition(parentPortletDef);
+                    storePortletEntity(portletEntity);
+                }
+            }
+            if (parentPortletDef == null)
+            {
+                final String msg = "Portlet "+portletUniqueName+" not found";
+                String content = fragment.getOverriddenContent();
+                if (content == null || !content.equals(msg))
+                {
+                    fragment.overrideRenderedContent(msg);
+                }
+            }
+        }
+        return portletEntity;                
+    }    
+
+    /**
+     * Generate id for portlet definition.
+     * 
+     * @param pd portlet definition.
+     * @return generated id string.
+     */
+    private String autoGenerateID(PortletDefinition pd)
+    {
+        String appName = pd.getApplication().getName();
+        String portletName = pd.getPortletName();
+        return appName+PortletRegistry.PORTLET_UNIQUE_NAME_SEPARATOR+portletName+PortletRegistry.PORTLET_UNIQUE_NAME_SEPARATOR+(new UID().toString());
+    }
+}

Added: portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-registry/src/main/java/org/apache/jetspeed/components/portletentity/jpa/PortletEntityImpl.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-registry/src/main/java/org/apache/jetspeed/components/portletentity/jpa/PortletEntityImpl.java?rev=733524&view=auto
==============================================================================
--- portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-registry/src/main/java/org/apache/jetspeed/components/portletentity/jpa/PortletEntityImpl.java (added)
+++ portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-registry/src/main/java/org/apache/jetspeed/components/portletentity/jpa/PortletEntityImpl.java Sun Jan 11 13:58:21 2009
@@ -0,0 +1,252 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jetspeed.components.portletentity.jpa;
+
+import javax.persistence.Basic;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.NamedQuery;
+import javax.persistence.NamedQueries;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+import javax.persistence.Version;
+
+import org.apache.jetspeed.aggregator.RenderTrackable;
+import org.apache.jetspeed.components.portletregistry.PortletRegistry;
+import org.apache.jetspeed.container.PortletEntity;
+import org.apache.jetspeed.container.PortletWindow;
+import org.apache.jetspeed.om.page.Fragment;
+import org.apache.jetspeed.om.portlet.PortletDefinition;
+
+/**
+ * Portlet Entity default implementation.
+ * TODO: 2.2 - don't associate Fragment with Entity, should be with window
+ * 
+ * @author <a href="mailto:taylor@apache.org">David Sean Taylor </a>
+ * @author <a href="mailto:weaver@apache.org">Scott T. Weaver </a>
+ * @version $Id: PortletEntityImpl.java,v 1.9 2005/04/29 13:59:08 weaver Exp $
+ */
+@Entity (name="PortletEntity")
+@Table (name="PORTLET_ENTITY")
+@NamedQueries({@NamedQuery(name="PORTLET_ENTITIES", query="select pe from PortletEntity pe where pe.appName = :appName and pe.portletName = :portletName"),
+               @NamedQuery(name="PORTLET_ENTITY", query="select pe from PortletEntity pe where pe.id = :id")})
+public class PortletEntityImpl implements PortletEntity, RenderTrackable
+{
+    // Class Members
+    
+    private static PortletRegistry registry;
+
+    public static void setPortletRegistry(PortletRegistry registry)
+    {
+        PortletEntityImpl.registry = registry;
+    }
+ 
+    // Members
+    
+    @Id
+    @GeneratedValue (strategy=GenerationType.AUTO)
+    @Column (name="PEID")
+    private long oid;
+    @Version
+    @Column (name="JPA_VERSION")
+    private int jpaVersion;
+    @Basic
+    @Column (name="ID")
+    private String id;    
+    @Basic
+    @Column (name="PORTLET_NAME")
+    private String portletName;
+    @Basic
+    @Column (name="APP_NAME")
+    private String appName;
+
+    @Transient
+    private PortletWindow portletWindow = null;
+    @Transient
+    private PortletDefinition portletDefinition = null;  
+    @Transient
+    private Fragment fragment;
+    @Transient
+    private int timeoutCount = 0;
+    @Transient
+    private long expiration = 0;
+    
+    // Implementation
+    
+    /**
+     * Construct with fragment.
+     * 
+     * @param fragment fragment of portlet entity.
+     */
+    public PortletEntityImpl(Fragment fragment)
+    {
+        setFragment(fragment);
+    }
+
+    /**
+     * Default constructor.
+     */
+    public PortletEntityImpl()
+    {
+    }
+    
+    public Long getOid()
+    {
+        return oid;
+    }
+
+    public String getId()
+    {
+        return this.id;
+    }
+    
+    public void setId( String id )
+    {
+        this.id = id;
+    }
+
+    public void setPortletWindow(PortletWindow window)
+    {
+        this.portletWindow = window;
+    }    
+
+    public PortletWindow getPortletWindow()
+    {
+        return this.portletWindow;
+    }
+    
+    public PortletDefinition getPortletDefinition()
+    {
+        // there are cases when jetspeed gets initialized before
+        // all of the portlet web apps have.  In this event, premature
+        // access to the portal would cause portlet entities to be cached
+        // with their associated window without there corresponding PortletDefinition
+        // (because the PortletApplication has yet to be registered).
+        if (this.portletDefinition == null)
+        {
+            PortletDefinition pd = registry.getPortletDefinitionByUniqueName(getPortletUniqueName());
+            if (pd != null)
+            {
+                // only store a really found PortletDefinition
+                // to prevent an IllegalArgumentException to be thrown
+                setPortletDefinition(pd);
+            }
+            else
+            {
+                return null;
+            }
+        }            
+        return this.portletDefinition;
+    }
+
+    /**
+     * <p>
+     * setPortletDefinition
+     * </p>
+     * 
+     * @param composite
+     *  
+     */
+    public void setPortletDefinition(PortletDefinition pd)
+    {
+        if (pd != null)
+        {
+            portletDefinition = pd;
+            this.appName = portletDefinition.getApplication().getName();
+            this.portletName = portletDefinition.getPortletName();
+        }
+        else
+        {
+            throw new IllegalArgumentException("Cannot pass a null PortletDefinition to a PortletEntity.");
+        }
+    }
+    
+    public String getPortletUniqueName()
+    {
+        if(this.appName != null && this.portletName != null)
+        {
+            return this.appName+"::"+this.portletName;
+        }
+        else if(fragment != null)
+        {
+            return fragment.getName();
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+    public Fragment getFragment()
+    {
+        return this.fragment;
+    }
+    
+    public void setFragment(Fragment fragment)
+    {
+        this.fragment = fragment;
+    }
+
+    public int getRenderTimeoutCount()
+    {
+        return timeoutCount;
+    }
+    
+    public synchronized void incrementRenderTimeoutCount()
+    {
+        timeoutCount++;
+    }
+    
+    public synchronized void setExpiration(long expiration)
+    {
+        this.expiration = expiration;
+    }
+    
+    public long getExpiration()
+    {
+        return this.expiration;
+    }
+    
+    public void success()
+    {
+        timeoutCount = 0;
+    }
+    
+    public void setRenderTimeoutCount(int timeoutCount)
+    {
+        this.timeoutCount = timeoutCount;
+    }
+
+    protected String getEntityFragmentKey()
+    {
+        String entityId = (this.getId() == null) ? "-unknown-entity" : this.getId().toString();
+        return "org.apache.jetspeed" + entityId ;
+    }
+    
+    /**
+     * Get new persistent status.
+     * 
+     * @return whether object is new.
+     */
+    public boolean isNew()
+    {
+        return (oid == 0);
+    }
+}

Added: portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-registry/src/main/java/org/apache/jetspeed/components/portletpreferences/jpa/DatabasePreference.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-registry/src/main/java/org/apache/jetspeed/components/portletpreferences/jpa/DatabasePreference.java?rev=733524&view=auto
==============================================================================
--- portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-registry/src/main/java/org/apache/jetspeed/components/portletpreferences/jpa/DatabasePreference.java (added)
+++ portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-registry/src/main/java/org/apache/jetspeed/components/portletpreferences/jpa/DatabasePreference.java Sun Jan 11 13:58:21 2009
@@ -0,0 +1,292 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jetspeed.components.portletpreferences.jpa;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import javax.persistence.Basic;
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.NamedQuery;
+import javax.persistence.NamedQueries;
+import javax.persistence.OneToMany;
+import javax.persistence.PostLoad;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+import javax.persistence.Version;
+
+import org.apache.pluto.internal.InternalPortletPreference;
+
+/**
+ * <p>
+ * The database representation of a preference object
+ * </p>
+ * 
+ * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
+ * @version $Id: $
+ */
+@Entity (name="PortletPreference")
+@Table (name="PORTLET_PREFERENCE")
+@NamedQueries({@NamedQuery(name="PORTLET_PREFERENCES", query="select pp from PortletPreference pp where pp.dtype = :dtype and pp.applicationName = :applicationName and pp.portletName = :portletName"),
+               @NamedQuery(name="DELETE_PORTLET_PREFERENCES", query="delete from PortletPreference pp where pp.dtype = :dtype and pp.applicationName = :applicationName and pp.portletName = :portletName"),
+               @NamedQuery(name="PORTLET_DTYPE_PREFERENCES", query="select pp from PortletPreference pp where pp.dtype = :dtype"),
+               @NamedQuery(name="PORTLET_APPLICATION_PREFERENCES", query="select pp from PortletPreference pp where pp.dtype = :dtype and pp.applicationName = :applicationName"),
+               @NamedQuery(name="DELETE_PORTLET_APPLICATION_PREFERENCES", query="delete from PortletPreference pp where pp.dtype = :dtype and pp.applicationName = :applicationName"),
+               @NamedQuery(name="FULLY_QUALIFIED_PORTLET_PREFERENCES", query="select pp from PortletPreference pp where pp.dtype = :dtype and pp.applicationName = :applicationName and pp.portletName = :portletName and pp.entityId = :entityId and pp.userName = :userName")})
+public class DatabasePreference implements InternalPortletPreference
+{
+    // Members
+    
+    @Id
+    @GeneratedValue (strategy=GenerationType.AUTO)
+    @Column (name="ID")
+    private long id;
+    @Version
+    @Column (name="JPA_VERSION")
+    private int jpaVersion;
+    @Basic
+    @Column (name="DTYPE")
+    private String dtype;
+    @Basic
+    @Column (name="APPLICATION_NAME")
+    private String applicationName;
+    @Basic
+    @Column (name="PORTLET_NAME")
+    private String portletName;
+    @Basic
+    @Column (name="NAME")
+    private String name;
+    @Basic
+    @Column (name="USER_NAME")
+    private String userName;
+    @Basic
+    @Column (name="ENTITY_ID")
+    private String entityId;
+    @Basic
+    @Column (name="READONLY")
+    private boolean readOnly;    
+    @OneToMany (targetEntity=DatabasePreferenceValue.class, mappedBy="pref", fetch=FetchType.LAZY, cascade=CascadeType.ALL)
+    private Collection<DatabasePreferenceValue> values;
+    
+    @PostLoad
+    private void eagerFetchCollections()
+    {
+        if (values != null)
+        {
+            values.size();
+        }
+    }
+
+    @Transient
+    private DatabasePreferenceValueCollection valuesCollection;     
+    
+    // Implementation
+    
+    /**
+     * Default constructor.
+     */
+    public DatabasePreference()
+    {
+    }
+        
+    public String getDtype()
+    {
+        return dtype;
+    }
+    
+    public void setDtype(String dtype)
+    {
+        this.dtype = dtype;
+    }
+    
+    public String getApplicationName()
+    {
+        return applicationName;
+    }
+    
+    public void setApplicationName(String applicationName)
+    {
+        this.applicationName = applicationName;
+    }
+    
+    public String getPortletName()
+    {
+        return portletName;
+    }
+    
+    public void setPortletName(String portletName)
+    {
+        this.portletName = portletName;
+    }
+    
+    public String getName()
+    {
+        return name;
+    }
+    
+    public void setName(String name)
+    {
+        this.name = name;
+    }
+    
+    public String getUserName()
+    {
+        return userName;
+    }
+    
+    public void setUserName(String userName)
+    {
+        this.userName = userName;
+    }
+    
+    public String getEntityId()
+    {
+        return entityId;
+    }
+    
+    public void setEntityId(String entityId)
+    {
+        this.entityId = entityId;
+    }
+    
+    public boolean isReadOnly()
+    {
+        return readOnly;
+    }
+    
+    public void setReadOnly(boolean readOnly)
+    {
+        this.readOnly = readOnly;
+    }
+    
+    public long getId()
+    {
+        return id;
+    }
+
+    public Collection<DatabasePreferenceValue> getPreferenceValues()
+    {
+        if (values == null)
+        {
+            values = new ArrayList<DatabasePreferenceValue>();
+        }
+        if (valuesCollection == null)
+        {
+            valuesCollection = new DatabasePreferenceValueCollection(this, values);
+        }
+        return valuesCollection;
+    }
+
+    public String[] getValues()
+    {
+        // ensure initialized
+        int size = getPreferenceValues().size();
+        if (size == 0)
+        {
+            // Making changes for TCK compliance
+			return null;
+        }
+        String[] result = new String[size];
+        int index = 0;
+        for (DatabasePreferenceValue value : getPreferenceValues())
+        {
+            result[index] = value.getValue();
+            index++;
+        }
+        return result;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.pluto.internal.InternalPortletPreference#setValues(java.lang.String[])
+     */
+    public void setValues(String[] values)
+    {
+        getPreferenceValues().clear();
+        if ((values != null) && (values.length > 0))
+        {
+            for (int i = 0, limit = values.length; (i < limit); i++)
+            {
+                if (values[i] != null)
+                {
+                    DatabasePreferenceValue value = new DatabasePreferenceValue();
+                    value.setValue(values[i]);
+                    value.setIndex((short)i);
+                    getPreferenceValues().add(value);
+                }
+            }
+        }
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.pluto.internal.InternalPortletPreference#clone()
+     */
+    public InternalPortletPreference clone()
+    {
+        DatabasePreference clone = new DatabasePreference();
+        clone.setDtype(getDtype());
+        clone.setApplicationName(getApplicationName());
+        clone.setPortletName(getPortletName());
+        clone.setName(getName());
+        clone.setUserName(getUserName());
+        clone.setEntityId(getEntityId());
+        clone.setReadOnly(isReadOnly());
+        for (DatabasePreferenceValue value : getPreferenceValues())
+        {
+            DatabasePreferenceValue valueClone = new DatabasePreferenceValue();
+            valueClone.setValue(value.getValue());
+            valueClone.setIndex(value.getIndex());
+            clone.getPreferenceValues().add(valueClone);
+        }
+        return clone;
+    }
+    
+    public int hashCode()
+    {
+        return applicationName.hashCode()+portletName.hashCode()+name.hashCode();
+    }
+
+    // TODO: 2.2 going to probably want to break these up into a base class and two subclasses if we need the equals
+    public boolean equals(Object object)
+    {
+        if (this == object)
+        {
+            return true;
+        }
+        if ((object instanceof DatabasePreference))
+        {
+            DatabasePreference other = (DatabasePreference)object;            
+            return applicationName.equals(other.applicationName) && portletName.equals(other.applicationName) && name.equals(other.name);
+        }
+        return false;
+    }
+
+    /**
+     * Get new persistent status.
+     * 
+     * @return whether object is new.
+     */
+    public boolean isNew()
+    {
+        return (id == 0);
+    }
+}

Added: portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-registry/src/main/java/org/apache/jetspeed/components/portletpreferences/jpa/DatabasePreferenceValue.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-registry/src/main/java/org/apache/jetspeed/components/portletpreferences/jpa/DatabasePreferenceValue.java?rev=733524&view=auto
==============================================================================
--- portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-registry/src/main/java/org/apache/jetspeed/components/portletpreferences/jpa/DatabasePreferenceValue.java (added)
+++ portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-registry/src/main/java/org/apache/jetspeed/components/portletpreferences/jpa/DatabasePreferenceValue.java Sun Jan 11 13:58:21 2009
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jetspeed.components.portletpreferences.jpa;
+
+import javax.persistence.Basic;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import javax.persistence.Version;
+
+/**
+ * The database representation of a preference value object
+ * 
+ * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
+ * @version $Id: $
+ */
+@Entity (name="PortletPreferenceValue")
+@Table (name="PORTLET_PREFERENCE_VALUE")
+public class DatabasePreferenceValue
+{
+    // Members
+    
+    @Id
+    @GeneratedValue (strategy=GenerationType.AUTO)
+    @Column (name="ID")
+    private long id;
+    @Version
+    @Column (name="JPA_VERSION")
+    private int jpaVersion;
+    @ManyToOne (targetEntity=DatabasePreference.class, fetch=FetchType.LAZY, optional=false)
+    @JoinColumn (name="PREF_ID", referencedColumnName="ID")
+    private DatabasePreference pref;
+    @Basic
+    @Column (name="IDX")
+    private short index;
+    @Basic
+    @Column (name="PREF_VALUE")
+    private String value;
+
+    /**
+     * Accessor used to maintain JPA bidirectional relationships.
+     * 
+     * @param inverse bidirectional relationship inverse.
+     */
+    public void setInverseRelationship(Object inverse)
+    {
+        pref = (DatabasePreference)inverse;
+    }
+
+    // Implementation
+    
+    public DatabasePreferenceValue()
+    {
+    }
+    
+    public long getId()
+    {
+        return id;
+    }
+    
+    public short getIndex()
+    {
+        return index;
+    }
+    
+    public void setIndex(short index)
+    {
+        this.index = index;
+    }
+    
+    public String getValue()
+    {
+        return value;
+    }
+    
+    public void setValue(String value)
+    {
+        this.value = value;
+    }
+}

Added: portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-registry/src/main/java/org/apache/jetspeed/components/portletpreferences/jpa/DatabasePreferenceValueCollection.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-registry/src/main/java/org/apache/jetspeed/components/portletpreferences/jpa/DatabasePreferenceValueCollection.java?rev=733524&view=auto
==============================================================================
--- portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-registry/src/main/java/org/apache/jetspeed/components/portletpreferences/jpa/DatabasePreferenceValueCollection.java (added)
+++ portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-registry/src/main/java/org/apache/jetspeed/components/portletpreferences/jpa/DatabasePreferenceValueCollection.java Sun Jan 11 13:58:21 2009
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jetspeed.components.portletpreferences.jpa;
+
+import java.util.AbstractCollection;
+import java.util.Collection;
+import java.util.Iterator;
+
+/**
+ * DatabasePreferenceValueCollection
+ *
+ * @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
+ * @version $Id$
+ */
+
+public class DatabasePreferenceValueCollection extends AbstractCollection<DatabasePreferenceValue>
+{
+    private Object owningObject;
+    private Collection<DatabasePreferenceValue> collection;
+
+    /**
+     * Construct collection to maintain JPA inverse relationship.
+     * 
+     * @param owningObject owning object.
+     * @param collection managed collection.
+     */
+    public DatabasePreferenceValueCollection(Object owningObject, Collection<DatabasePreferenceValue> collection)
+    {
+        super();
+        this.owningObject = owningObject;
+        this.collection = collection;
+    }
+
+    /* (non-Javadoc)
+     * @see java.util.AbstractCollection#add(java.lang.Object)
+     */
+    public boolean add(DatabasePreferenceValue element)
+    {
+        element.setInverseRelationship(owningObject);
+        return collection.add(element);
+    }
+
+    /* (non-Javadoc)
+     * @see java.util.AbstractCollection#iterator()
+     */
+    public Iterator<DatabasePreferenceValue> iterator()
+    {
+        return new Iterator<DatabasePreferenceValue>()
+        {
+            private Iterator<DatabasePreferenceValue> iter = collection.iterator();
+            private DatabasePreferenceValue lastNext = null;
+
+            /* (non-Javadoc)
+             * @see java.util.Iterator#hasNext()
+             */
+            public boolean hasNext()
+            {
+                return iter.hasNext();
+            }
+
+            /* (non-Javadoc)
+             * @see java.util.Iterator#next()
+             */
+            public DatabasePreferenceValue next()
+            {
+                return lastNext = iter.next();
+            }
+
+            /* (non-Javadoc)
+             * @see java.util.Iterator#remove()
+             */
+            public void remove()
+            {
+                iter.remove();
+                lastNext.setInverseRelationship(null);
+            }            
+        };
+    }
+
+    /* (non-Javadoc)
+     * @see java.util.AbstractCollection#remove(java.lang.Object)
+     */
+    public boolean remove(Object element)
+    {
+        if (collection.remove(element))
+        {
+            ((DatabasePreferenceValue)element).setInverseRelationship(null);
+            return true;
+        }
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see java.util.AbstractCollection#size()
+     */
+    public int size()
+    {
+        return collection.size();
+    }
+}

Added: portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-registry/src/main/java/org/apache/jetspeed/components/portletpreferences/jpa/PortletPreferencesProviderImpl.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-registry/src/main/java/org/apache/jetspeed/components/portletpreferences/jpa/PortletPreferencesProviderImpl.java?rev=733524&view=auto
==============================================================================
--- portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-registry/src/main/java/org/apache/jetspeed/components/portletpreferences/jpa/PortletPreferencesProviderImpl.java (added)
+++ portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-registry/src/main/java/org/apache/jetspeed/components/portletpreferences/jpa/PortletPreferencesProviderImpl.java Sun Jan 11 13:58:21 2009
@@ -0,0 +1,535 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jetspeed.components.portletpreferences.jpa;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.PersistenceContextType;
+import javax.persistence.Query;
+
+import javax.portlet.PortletRequest;
+import javax.portlet.PreferencesValidator;
+import javax.portlet.ValidatorException;
+
+import org.apache.jetspeed.JetspeedActions;
+import org.apache.jetspeed.PortalReservedParameters;
+import org.apache.jetspeed.components.portletpreferences.PortletPreferencesProvider;
+import org.apache.jetspeed.components.portletregistry.jpa.RegistryManager;
+import org.apache.jetspeed.container.PortletWindow;
+import org.apache.jetspeed.factory.PortletFactory;
+import org.apache.jetspeed.om.portlet.PortletApplication;
+import org.apache.jetspeed.om.portlet.PortletDefinition;
+import org.apache.jetspeed.om.portlet.Preference;
+import org.apache.jetspeed.om.portlet.Preferences;
+import org.apache.jetspeed.om.preference.FragmentPreference;
+import org.apache.jetspeed.request.RequestContext;
+import org.apache.jetspeed.security.SubjectHelper;
+import org.apache.jetspeed.security.User;
+import org.apache.pluto.PortletContainerException;
+import org.apache.pluto.internal.InternalPortletPreference;
+import org.apache.pluto.internal.impl.PortletPreferenceImpl;
+import org.springframework.stereotype.Repository;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * PortletPreferencesProviderImpl
+ *
+ * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
+ * @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
+ * @version $Id$
+ */
+@Repository
+public class PortletPreferencesProviderImpl implements PortletPreferencesProvider
+{
+    // Constants
+    
+    private static final String DISCRIMINATOR_PORTLET = "portlet";
+    private static final String DISCRIMINATOR_USER = "user";
+    private static final String EMPTY_VALUE = "_";
+
+    // Members
+
+    private RegistryManager registryManager;
+    private PortletFactory portletFactory;
+    private List<String> preloadedApplications = null;
+    private boolean preloadEntities = false;
+    private boolean useEntityPreferences = true;
+    
+    // Constructors
+
+    /**
+     * Construct with specified registry manager, portlet factory, and
+     * default configuration.
+     * 
+     * @param registryManager registry manager.
+     * @param portletFactory portlet factory.
+     */
+    public PortletPreferencesProviderImpl(RegistryManager registryManager, PortletFactory portletFactory)
+    {
+        this.registryManager = registryManager;
+        this.portletFactory = portletFactory;
+    }
+
+    /**
+     * Construct with specified registry manager, portlet factory, and
+     * preload configuration.
+     * 
+     * @param registryManager registry manager.
+     * @param portletFactory portlet factory.
+     * @param apps preload portlet application names list.
+     * @param preloadEntities preload configuration flag.
+     */
+    public PortletPreferencesProviderImpl(RegistryManager registryManager, PortletFactory portletFactory, List<String> apps, boolean preloadEntities)
+    {
+        this(registryManager, portletFactory);
+        this.preloadedApplications = apps;
+        this.preloadEntities = preloadEntities;
+    }
+    
+    // Lifecycle
+
+    /**
+     * Return use entity preferences configuration.
+     *
+     * @return use entity preferences configuration.
+     */
+    public boolean isUseEntityPreferences()
+    {
+        return useEntityPreferences;
+    }
+    
+    /**
+     * Configure preferences provider to use entity preferences.
+     * 
+     * @param useEntityPreferences use entity preferences configuration.
+     */
+    public void setUseEntityPreferences(boolean useEntityPreferences)
+    {
+        this.useEntityPreferences = useEntityPreferences;
+    }
+        
+    /**
+     * Initialize preferences provider by preloading application
+     * and entity preferences.
+     * 
+     * @throws Exception
+     */
+    public void init() throws Exception
+    {
+        if (preloadedApplications != null)
+        {
+            Iterator<String> apps = this.preloadedApplications.iterator();
+            while (apps.hasNext())
+            {
+                String applicationName = (String)apps.next();
+                preloadApplicationPreferences(applicationName);
+            }
+        }
+        if (preloadEntities)
+        {
+            preloadAllEntities();
+        }
+    }    
+
+    /**
+     * Destroy preferences provider.
+     */
+    public void destroy()
+    {
+        preloadedApplications = null;
+        preloadEntities = false;
+    }
+
+    // Implementation
+    
+    /**
+     * Return entity manager associated with current thread from
+     * registered context or default transactional entity manager
+     * created for this request.
+     * 
+     * @return entity manager.
+     */
+    protected EntityManager getEntityManager()
+    {
+        return registryManager.getEntityManager();
+    }
+        
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.components.portletpreferences.PortletPreferencesProvider#getDefaultPreferences(org.apache.jetspeed.om.portlet.PortletDefinition)
+     */
+    @Transactional (readOnly=true)
+    public Map<String,InternalPortletPreference> getDefaultPreferences(PortletDefinition pd)
+    {
+        // gather query parameters
+        String applicationName = pd.getApplication().getName();
+        String portletName = pd.getPortletName();        
+        // perform query to extract preferences map
+        Map<String,InternalPortletPreference> defaultsMap = new HashMap<String,InternalPortletPreference>();
+        EntityManager entityManager = getEntityManager();
+        Query portletPreferencesQuery = entityManager.createNamedQuery("PORTLET_PREFERENCES");
+        portletPreferencesQuery.setParameter("dtype", DISCRIMINATOR_PORTLET);
+        portletPreferencesQuery.setParameter("applicationName", applicationName);
+        portletPreferencesQuery.setParameter("portletName", portletName);
+        Iterator<DatabasePreference> preferences = portletPreferencesQuery.getResultList().iterator();
+        while (preferences.hasNext())
+        {
+            DatabasePreference preference = preferences.next();
+            defaultsMap.put(preference.getName(), preference);
+        }
+        return defaultsMap;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.components.portletpreferences.PortletPreferencesProvider#preloadAllEntities()
+     */
+    @Transactional (readOnly=true)
+    public void preloadAllEntities()
+    {
+        // perform query to preload internal cache
+        EntityManager entityManager = getEntityManager();
+        Query portletPreferencesQuery = entityManager.createNamedQuery("PORTLET_DTYPE_PREFERENCES");
+        portletPreferencesQuery.setParameter("dtype", DISCRIMINATOR_USER);
+        Iterator<DatabasePreference> preferences = portletPreferencesQuery.getResultList().iterator();
+        for (; preferences.hasNext(); preferences.next());
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.components.portletpreferences.PortletPreferencesProvider#preloadApplicationPreferences(java.lang.String)
+     */
+    @Transactional (readOnly=true)
+    public void preloadApplicationPreferences(String portletApplicationName)
+    {
+        EntityManager entityManager = getEntityManager();
+        Query portletPreferencesQuery = entityManager.createNamedQuery("PORTLET_APPLICATION_PREFERENCES");
+        portletPreferencesQuery.setParameter("dtype", DISCRIMINATOR_PORTLET);
+        portletPreferencesQuery.setParameter("applicationName", portletApplicationName);
+        Iterator<DatabasePreference> preferences = portletPreferencesQuery.getResultList().iterator();
+        for (; preferences.hasNext(); preferences.next());
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.components.portletpreferences.PortletPreferencesProvider#removeDefaults(org.apache.jetspeed.om.portlet.PortletApplication)
+     */
+    @Transactional (readOnly=false)
+    public void removeDefaults(PortletApplication app)
+    {
+        // gather query parameters
+        String applicationName = app.getName();
+        // perform delete
+        EntityManager entityManager = getEntityManager();
+        Query portletPreferencesDelete = entityManager.createNamedQuery("DELETE_PORTLET_APPLICATION_PREFERENCES");
+        portletPreferencesDelete.setParameter("dtype", DISCRIMINATOR_PORTLET);
+        portletPreferencesDelete.setParameter("applicationName", applicationName);
+        portletPreferencesDelete.executeUpdate();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.components.portletpreferences.PortletPreferencesProvider#removeDefaults(org.apache.jetspeed.om.portlet.PortletDefinition)
+     */
+    @Transactional (readOnly=false)
+    public void removeDefaults(PortletDefinition pd)
+    {
+        // gather remove parameters
+        String applicationName = pd.getApplication().getName();
+        String portletName = pd.getPortletName();
+        // perform delete
+        EntityManager entityManager = getEntityManager();
+        Query portletPreferencesDelete = entityManager.createNamedQuery("DELETE_PORTLET_APPLICATION_PREFERENCES");
+        portletPreferencesDelete.setParameter("dtype", DISCRIMINATOR_PORTLET);
+        portletPreferencesDelete.setParameter("applicationName", applicationName);
+        portletPreferencesDelete.setParameter("portletName", portletName);
+        portletPreferencesDelete.executeUpdate();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.components.portletpreferences.PortletPreferencesProvider#storeDefaults(org.apache.jetspeed.om.portlet.PortletApplication)
+     */
+    @Transactional (readOnly=false)
+    public void storeDefaults(PortletApplication app)
+    {
+        for (PortletDefinition pd : app.getPortlets())
+        {
+            storeDefaults(pd);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.components.portletpreferences.PortletPreferencesProvider#storeDefaults(org.apache.jetspeed.om.portlet.PortletDefinition)
+     */
+    @Transactional (readOnly=false)
+    public void storeDefaults(PortletDefinition pd)
+    {
+        // store portlet definition preferences
+        EntityManager entityManager = getEntityManager();
+        Preferences preferences = pd.getDescriptorPreferences();
+        for (Preference preference : preferences.getPortletPreferences())
+        {
+            // create new database preference
+            DatabasePreference dbPref = new DatabasePreference();
+            dbPref.setDtype(DISCRIMINATOR_PORTLET);
+            dbPref.setApplicationName(pd.getApplication().getName());
+            dbPref.setPortletName(pd.getPortletName());
+            dbPref.setEntityId(EMPTY_VALUE);
+            dbPref.setUserName(EMPTY_VALUE);
+            dbPref.setName(preference.getName());
+            dbPref.setReadOnly(preference.isReadOnly());
+            short index = 0;
+            for (String value : preference.getValues())
+            {
+                DatabasePreferenceValue dbValue = new DatabasePreferenceValue();
+                dbValue.setIndex(index++);
+                dbValue.setValue(value);
+                dbPref.getPreferenceValues().add(dbValue);
+            }                       
+            // persist new database preference
+            entityManager.persist(preference);
+        }
+        // explicitly flush entity manager after update
+        entityManager.flush();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.pluto.spi.optional.PortletPreferencesService#getDefaultPreferences(org.apache.pluto.PortletWindow, javax.portlet.PortletRequest)
+     */
+    @Transactional (readOnly=true)
+    public Map<String,InternalPortletPreference> getDefaultPreferences(org.apache.pluto.PortletWindow plutoPW, PortletRequest request) throws PortletContainerException
+    {
+        // retrieve default preferences
+        PortletWindow window = (PortletWindow)plutoPW;
+        PortletDefinition pd = window.getPortletEntity().getPortletDefinition();
+        Map<String, InternalPortletPreference> defaultsMap = getDefaultPreferences(pd);
+        // retrieve fragment entity preferences
+        if (useEntityPreferences)
+        {
+            List<FragmentPreference> fragmentPrefs = window.getPortletEntity().getFragment().getPreferences();
+            if (fragmentPrefs.size() > 0)
+            {
+                for (FragmentPreference fragmentPref : fragmentPrefs)
+                {
+                    String name = fragmentPref.getName();
+                    boolean readOnly = fragmentPref.isReadOnly();
+                    String[] values = new String[fragmentPref.getValueList().size()];
+                    int ix = 0;
+                    for (Object value : fragmentPref.getValueList())
+                    {
+                        values[ix++] = (String)value;
+                    }
+                    PortletPreferenceImpl entityPref = new PortletPreferenceImpl(name, values, readOnly);
+                    defaultsMap.put(name, entityPref);
+                }
+            }
+        }
+        return defaultsMap;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.pluto.spi.optional.PortletPreferencesService#getPreferencesValidator(org.apache.pluto.om.portlet.PortletDefinition)
+     */
+    public PreferencesValidator getPreferencesValidator(org.apache.pluto.om.portlet.PortletDefinition plutoPD) throws ValidatorException
+    {
+        return portletFactory.getPreferencesValidator((org.apache.jetspeed.om.portlet.PortletDefinition)plutoPD);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.pluto.spi.optional.PortletPreferencesService#getStoredPreferences(org.apache.pluto.PortletWindow, javax.portlet.PortletRequest)
+     */
+    @Transactional (readOnly=true)
+    public Map<String,InternalPortletPreference> getStoredPreferences(org.apache.pluto.PortletWindow plutoPW, PortletRequest request) throws PortletContainerException
+    {
+        // gather query parameters
+        PortletWindow window = (PortletWindow)plutoPW;
+        if (request.getPortletMode().equals(JetspeedActions.EDIT_DEFAULTS_MODE))
+        {
+            return retrieveEntityPreferences(window, request);
+        }
+        String applicationName = window.getPortletEntity().getPortletDefinition().getApplication().getName();
+        String portletName = window.getPortletEntity().getPortletDefinition().getPortletName();
+        String entityId = window.getPortletEntity().getId();
+        String userName = request.getUserPrincipal() != null ? request.getUserPrincipal().getName() : null;
+        if (userName == null)
+        {
+            RequestContext rc = (RequestContext)request.getAttribute(PortalReservedParameters.REQUEST_CONTEXT_ATTRIBUTE);
+            userName = SubjectHelper.getPrincipal(rc.getSubject(), User.class).getName();
+        }
+        // perform query to extract preferences map
+        Map<String,InternalPortletPreference> map = new HashMap<String,InternalPortletPreference>();
+        EntityManager entityManager = getEntityManager();
+        Query portletPreferencesQuery = entityManager.createNamedQuery("FULLY_QUALIFIED_PORTLET_PREFERENCES");
+        portletPreferencesQuery.setParameter("dtype", DISCRIMINATOR_USER);
+        portletPreferencesQuery.setParameter("applicationName", applicationName);
+        portletPreferencesQuery.setParameter("portletName", portletName);
+        portletPreferencesQuery.setParameter("entityId", entityId);
+        portletPreferencesQuery.setParameter("userName", userName);
+        Iterator<DatabasePreference> preferences = portletPreferencesQuery.getResultList().iterator();
+        while (preferences.hasNext())
+        {
+            DatabasePreference preference = preferences.next();
+            map.put(preference.getName(), preference);
+        }
+        return map;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.pluto.spi.optional.PortletPreferencesService#store(org.apache.pluto.PortletWindow, javax.portlet.PortletRequest, java.util.Map)
+     */
+    @Transactional (readOnly=false)
+    public void store(org.apache.pluto.PortletWindow plutoPW, PortletRequest request, Map<String,InternalPortletPreference> map) throws PortletContainerException
+    {
+        // gather query parameters
+        PortletWindow window = (PortletWindow)plutoPW;
+        if (request.getPortletMode().equals(JetspeedActions.EDIT_DEFAULTS_MODE))
+        {
+            storeEntityPreferences(window, request, map);
+            return;
+        }        
+        String applicationName = window.getPortletEntity().getPortletDefinition().getApplication().getName();
+        String portletName = window.getPortletEntity().getPortletDefinition().getPortletName();
+        String entityId = window.getPortletEntity().getId();
+        String userName = request.getUserPrincipal() != null ? request.getUserPrincipal().getName() : null;
+        if (userName == null)
+        {
+            RequestContext rc = (RequestContext)request.getAttribute(PortalReservedParameters.REQUEST_CONTEXT_ATTRIBUTE);
+            userName = SubjectHelper.getPrincipal(rc.getSubject(), User.class).getName();
+        }
+        // track preference merge operation
+        List<DatabasePreference> deletes = new LinkedList<DatabasePreference>();
+        List<DatabasePreference> updates = new LinkedList<DatabasePreference>();
+        List<InternalPortletPreference> inserts = new LinkedList<InternalPortletPreference>();
+        Map<String,DatabasePreference> mergeMap = new HashMap<String, DatabasePreference>();
+        // perform query for merge
+        EntityManager entityManager = getEntityManager();
+        Query portletPreferencesQuery = entityManager.createNamedQuery("FULLY_QUALIFIED_PORTLET_PREFERENCES");
+        portletPreferencesQuery.setParameter("dtype", DISCRIMINATOR_USER);
+        portletPreferencesQuery.setParameter("applicationName", applicationName);
+        portletPreferencesQuery.setParameter("portletName", portletName);
+        portletPreferencesQuery.setParameter("entityId", entityId);
+        portletPreferencesQuery.setParameter("userName", userName);
+        Iterator<DatabasePreference> preferences = portletPreferencesQuery.getResultList().iterator();
+        while (preferences.hasNext())
+        {
+            DatabasePreference preference = preferences.next();
+            String name = preference.getName();
+            if (map.containsKey(name))
+            {
+                deletes.add(preference);
+            }
+            else
+            {
+                updates.add(preference);
+            }
+            mergeMap.put(name, preference);             
+        }
+        for (InternalPortletPreference preference : map.values())
+        {
+            DatabasePreference dbPref = mergeMap.get(preference.getName());
+            if (dbPref == null)
+            {
+                inserts.add(preference);
+            }                
+        }
+        // perform database manipulations for merge
+        for (DatabasePreference dbPref : deletes)
+        {
+            // remove, (potentially detached), database preference
+            if (!dbPref.isNew())
+            {
+                dbPref = entityManager.merge(dbPref);
+            }
+            entityManager.remove(dbPref);
+        }
+        for (InternalPortletPreference preference : inserts)
+        {
+            // create new database preference
+            DatabasePreference dbPref = new DatabasePreference();
+            dbPref.setDtype(DISCRIMINATOR_USER);
+            dbPref.setApplicationName(applicationName);
+            dbPref.setPortletName(portletName);
+            dbPref.setEntityId(entityId);
+            dbPref.setUserName(userName);
+            dbPref.setName(preference.getName());
+            dbPref.setReadOnly(preference.isReadOnly());
+            short index = 0;
+            for (String value : preference.getValues())
+            {
+                DatabasePreferenceValue dbValue = new DatabasePreferenceValue();
+                dbValue.setIndex(index++);
+                dbValue.setValue(value);
+                dbPref.getPreferenceValues().add(dbValue);                
+            }
+            // persist new database preference
+            entityManager.persist(dbPref);
+        }
+        for (DatabasePreference dbPref : updates)
+        {
+            dbPref.getPreferenceValues().clear();
+            InternalPortletPreference preference = map.get(dbPref.getName());
+            short index = 0;
+            for (String value : preference.getValues())
+            {
+                DatabasePreferenceValue dbValue = new DatabasePreferenceValue();
+                dbValue.setIndex(index++);
+                dbValue.setValue(value);
+                dbPref.getPreferenceValues().add(dbValue);
+            }            
+            // update, (potentially detached), database preference
+            if (!dbPref.isNew())
+            {
+                dbPref = entityManager.merge(dbPref);
+            }
+            entityManager.persist(dbPref);
+        }
+        // explicitly flush entity manager after remove/update
+        entityManager.flush();
+    }
+
+    /**
+     * Retrieve entity preferences, (not yet implemented).
+     * 
+     * @param window portlet window.
+     * @param request portlet request.
+     * @return entity preferences map
+     */
+    @Transactional (readOnly=true)
+    public Map<String,InternalPortletPreference> retrieveEntityPreferences(PortletWindow window, PortletRequest request)
+    {
+        // TODO: 2.2 implement - need to better look at use cases for edit defaults mode
+        // we are currently not storing entity preferences in the database. 
+        throw new UnsupportedOperationException();
+    }
+    
+    /**
+     * Store entity preferences, (not yet implemented).
+     * 
+     * @param pw portlet window.
+     * @param request portlet request.
+     * @param map entity preferences map.
+     * @throws PortletContainerException
+     */
+    @Transactional (readOnly=false)
+    public void storeEntityPreferences(PortletWindow pw, PortletRequest request, Map<String, InternalPortletPreference> map) throws PortletContainerException
+    {
+        // TODO: 2.2 implement - need to better look at use cases for edit defaults mode
+        // we are currently not storing entity preferences in the database. 
+        throw new UnsupportedOperationException();
+    }
+}

Modified: portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-registry/src/main/java/org/apache/jetspeed/components/portletregistry/PersistenceBrokerPortletRegistry.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-registry/src/main/java/org/apache/jetspeed/components/portletregistry/PersistenceBrokerPortletRegistry.java?rev=733524&r1=733523&r2=733524&view=diff
==============================================================================
--- portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-registry/src/main/java/org/apache/jetspeed/components/portletregistry/PersistenceBrokerPortletRegistry.java (original)
+++ portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-registry/src/main/java/org/apache/jetspeed/components/portletregistry/PersistenceBrokerPortletRegistry.java Sun Jan 11 13:58:21 2009
@@ -89,6 +89,14 @@
         this.preferenceService = preferenceService;
     }
     
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.components.portletregistry.PortletRegistry#newPortletApplication()
+     */
+    public PortletApplication newPortletApplication()
+    {
+        return new PortletApplicationDefinitionImpl();
+    }
+    
     public Collection<PortletDefinition> getAllPortletDefinitions()
     {
         Criteria c = new Criteria();
@@ -224,7 +232,6 @@
         try
         {
             getPersistenceBrokerTemplate().store(portlet);
-            ((PortletDefinition)portlet).storeChildren();
         }
         catch (DataAccessException e)
         {
@@ -295,4 +302,4 @@
         this.listeners.remove(listener);
     }
     
-}
\ No newline at end of file
+}

Added: portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-registry/src/main/java/org/apache/jetspeed/components/portletregistry/jpa/PortletRegistryImpl.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-registry/src/main/java/org/apache/jetspeed/components/portletregistry/jpa/PortletRegistryImpl.java?rev=733524&view=auto
==============================================================================
--- portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-registry/src/main/java/org/apache/jetspeed/components/portletregistry/jpa/PortletRegistryImpl.java (added)
+++ portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-registry/src/main/java/org/apache/jetspeed/components/portletregistry/jpa/PortletRegistryImpl.java Sun Jan 11 13:58:21 2009
@@ -0,0 +1,307 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jetspeed.components.portletregistry.jpa;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.NoResultException;
+import javax.persistence.PersistenceContext;
+import javax.persistence.PersistenceContextType;
+import javax.persistence.Query;
+
+import org.apache.jetspeed.components.portletpreferences.PortletPreferencesProvider;
+import org.apache.jetspeed.components.portletregistry.FailedToStorePortletDefinitionException;
+import org.apache.jetspeed.components.portletregistry.PortletRegistry;
+import org.apache.jetspeed.components.portletregistry.PortletRegistryHelper;
+import org.apache.jetspeed.components.portletregistry.RegistryEventListener;
+import org.apache.jetspeed.components.portletregistry.RegistryException;
+import org.apache.jetspeed.om.portlet.PortletApplication;
+import org.apache.jetspeed.om.portlet.PortletDefinition;
+import org.apache.jetspeed.om.portlet.jpa.PortletApplicationDefinitionImpl;
+import org.apache.jetspeed.om.portlet.jpa.PortletDefinitionImpl;
+import org.springframework.stereotype.Repository;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * PortletRegistryImpl
+ * 
+ * @author <a href="mailto:weaver@apache.org">Scott T. Weaver </a>
+ * @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
+ * @version $Id: PersistenceBrokerPortletRegistry.java 720914 2008-11-26 16:41:02Z ate $
+ */
+@Repository
+public class PortletRegistryImpl implements PortletRegistry
+{
+    // Members
+    
+    private RegistryManager registryManager;
+    private PortletPreferencesProvider preferenceService;
+    private List<RegistryEventListener> listeners = new ArrayList<RegistryEventListener>();
+
+    // Constructors
+
+    /**
+     * Construct with registry manager and preferences service.
+     * 
+     * @param registryManager registry manager.
+     * @param preferenceService preferences service.
+     */
+    public PortletRegistryImpl(RegistryManager registryManager, PortletPreferencesProvider preferenceService)
+    {
+        this.registryManager = registryManager;
+        this.preferenceService = preferenceService;
+    }
+    
+    // Implementation
+
+    /**
+     * Return entity manager associated with current thread from
+     * registered context or default transactional entity manager
+     * created for this request.
+     * 
+     * @return entity manager.
+     */
+    protected EntityManager getEntityManager()
+    {
+        return registryManager.getEntityManager();
+    }
+        
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.components.portletregistry.PortletRegistry#addRegistryListener(org.apache.jetspeed.components.portletregistry.RegistryEventListener)
+     */
+    public void addRegistryListener(RegistryEventListener listener)
+    {
+        listeners.add(listener);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.components.portletregistry.PortletRegistry#getAllPortletDefinitions()
+     */
+    @Transactional (readOnly=true)
+    public Collection<PortletDefinition> getAllPortletDefinitions()
+    {
+        // perform query
+        EntityManager entityManager = getEntityManager();
+        Query portletDefinitionsQuery = entityManager.createNamedQuery("PORTLET_DEFINITIONS");
+        return portletDefinitionsQuery.getResultList();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.components.portletregistry.PortletRegistry#getPortletApplication(java.lang.String)
+     */
+    @Transactional (readOnly=true)
+    public PortletApplication getPortletApplication(String name)
+    {
+        // perform query for single portlet application
+        EntityManager entityManager = getEntityManager();
+        Query portletApplicationQuery = entityManager.createNamedQuery("PORTLET_APPLICATION");
+        portletApplicationQuery.setParameter("name", name);
+        PortletApplication portletApplication = null;
+        try
+        {
+            portletApplication = (PortletApplication)portletApplicationQuery.getSingleResult();
+        }
+        catch (NoResultException nre)
+        {
+        }
+        return portletApplication;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.components.portletregistry.PortletRegistry#getPortletApplications()
+     */
+    @Transactional (readOnly=true)
+    public Collection<PortletApplication> getPortletApplications()
+    {
+        // perform query
+        EntityManager entityManager = getEntityManager();
+        Query portletApplicationsQuery = entityManager.createNamedQuery("PORTLET_APPLICATIONS");
+        return portletApplicationsQuery.getResultList();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.components.portletregistry.PortletRegistry#getPortletDefinitionByUniqueName(java.lang.String)
+     */
+    @Transactional (readOnly=true)
+    public PortletDefinition getPortletDefinitionByUniqueName(String name)
+    {
+        // gather query parameters
+        String appName = PortletRegistryHelper.parseAppName(name);
+        String portletName = PortletRegistryHelper.parsePortletName(name);
+        // perform query for single portlet definition
+        EntityManager entityManager = getEntityManager();
+        Query portletDefinitionQuery = entityManager.createNamedQuery("PORTLET_DEFINITION");
+        portletDefinitionQuery.setParameter("appName", appName);
+        portletDefinitionQuery.setParameter("portletName", portletName);
+        PortletDefinition portletDefinition = null;
+        try
+        {
+            portletDefinition = (PortletDefinition)portletDefinitionQuery.getSingleResult();
+        }
+        catch (NoResultException nre)
+        {
+        }
+        if ((portletDefinition != null) && (portletDefinition.getApplication() == null))
+        {
+            final String msg = "getPortletDefinitionByIdentifier() returned a PortletDefinition that has no parent PortletApplication.";
+            throw new IllegalStateException(msg);
+        }
+        return portletDefinition;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.components.portletregistry.PortletRegistry#newPortletApplication()
+     */
+    public PortletApplication newPortletApplication()
+    {
+        return new PortletApplicationDefinitionImpl();
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.components.portletregistry.PortletRegistry#portletApplicationExists(java.lang.String)
+     */
+    @Transactional (readOnly=true)
+    public boolean portletApplicationExists(String name)
+    {
+        return (getPortletApplication(name) != null);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.components.portletregistry.PortletRegistry#portletDefinitionExists(java.lang.String, org.apache.jetspeed.om.portlet.PortletApplication)
+     */
+    @Transactional (readOnly=true)
+    public boolean portletDefinitionExists(String portletName, PortletApplication app)
+    {
+        return (getPortletDefinitionByUniqueName(app.getName()+PORTLET_UNIQUE_NAME_SEPARATOR+portletName) != null);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.components.portletregistry.PortletRegistry#registerPortletApplication(org.apache.jetspeed.om.portlet.PortletApplication)
+     */
+    @Transactional (readOnly=false, rollbackFor=RegistryException.class)
+    public void registerPortletApplication(PortletApplication portletApplication) throws RegistryException
+    {
+        // store portlet application
+        updatePortletApplication(portletApplication);
+        // store portlet application default preferences
+        preferenceService.storeDefaults(portletApplication);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.components.portletregistry.PortletRegistry#removeApplication(org.apache.jetspeed.om.portlet.PortletApplication)
+     */
+    @Transactional (readOnly=false, rollbackFor=RegistryException.class)
+    public void removeApplication(PortletApplication portletApplication) throws RegistryException
+    {
+        // remove portlet application default preferences
+        preferenceService.removeDefaults(portletApplication);
+        // remove portlet application
+        EntityManager entityManager = getEntityManager();
+        // update, (potentially detached), portlet application
+        if (!((PortletApplicationDefinitionImpl)portletApplication).isNew())
+        {
+            portletApplication = entityManager.merge(portletApplication);
+        }
+        entityManager.remove(portletApplication);
+        // explicitly flush entity manager after remove
+        entityManager.flush();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.components.portletregistry.PortletRegistry#removeRegistryEventListener(org.apache.jetspeed.components.portletregistry.RegistryEventListener)
+     */
+    public void removeRegistryEventListener(RegistryEventListener listener)
+    {
+        listeners.remove(listener);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.components.portletregistry.PortletRegistry#savePortletDefinition(org.apache.jetspeed.om.portlet.PortletDefinition)
+     */
+    @Transactional (readOnly=false, rollbackFor=RegistryException.class)
+    public void savePortletDefinition(PortletDefinition portletDefinition) throws FailedToStorePortletDefinitionException
+    {
+        try
+        {
+            EntityManager entityManager = getEntityManager();
+            // update, (potentially detached), portlet definition
+            if (!((PortletDefinitionImpl)portletDefinition).isNew())
+            {
+                portletDefinition = entityManager.merge(portletDefinition);
+            }
+            entityManager.persist(portletDefinition);
+            // explicitly flush entity manager after update
+            entityManager.flush();
+        }
+        catch (Exception e)
+        {            
+            throw new FailedToStorePortletDefinitionException(portletDefinition, e);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.components.portletregistry.PortletRegistry#updatePortletApplication(org.apache.jetspeed.om.portlet.PortletApplication)
+     */
+    @Transactional (readOnly=false, rollbackFor=RegistryException.class)
+    public void updatePortletApplication(PortletApplication portletApplication) throws RegistryException
+    {
+        EntityManager entityManager = getEntityManager();
+        // update, (potentially detached), portlet application
+        if (!((PortletApplicationDefinitionImpl)portletApplication).isNew())
+        {
+            portletApplication = entityManager.merge(portletApplication);
+        }
+        entityManager.persist(portletApplication);
+        // explicitly flush entity manager after update
+        entityManager.flush();
+    }
+    
+    /**
+     * Notify registry event listeners that portlet definition
+     * may have been updated and removed from local cache.
+     * 
+     * @param pd updated portlet definition if known.
+     */
+    protected void notifyPortletUpdated(PortletDefinition pd)
+    {
+        // notify all listeners, (updated is equivalent to
+        // removal from local cache).
+        for (RegistryEventListener listener : listeners)
+        {
+            listener.portletRemoved(pd);
+        }
+    }
+
+    /**
+     * Notify registry event listeners that portlet application
+     * may have been updated and removed from local cache.
+     * 
+     * @param pd updated portlet application if known.
+     */
+    protected void notifyApplicationUpdated(PortletApplication pa)
+    {
+        // notify all listeners, (updated is equivalent to
+        // removal from local cache).
+        for (RegistryEventListener listener : listeners)
+        {
+            listener.applicationRemoved(pa);
+        }
+    }
+}

Added: portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-registry/src/main/java/org/apache/jetspeed/components/portletregistry/jpa/RegistryManager.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-registry/src/main/java/org/apache/jetspeed/components/portletregistry/jpa/RegistryManager.java?rev=733524&view=auto
==============================================================================
--- portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-registry/src/main/java/org/apache/jetspeed/components/portletregistry/jpa/RegistryManager.java (added)
+++ portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-registry/src/main/java/org/apache/jetspeed/components/portletregistry/jpa/RegistryManager.java Sun Jan 11 13:58:21 2009
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jetspeed.components.portletregistry.jpa;
+
+import javax.persistence.EntityManager;
+
+/**
+ * RegistryManager
+ * 
+ * @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
+ * @version $Id: $
+ */
+public interface RegistryManager
+{
+    /**
+     * Return entity manager associated with current thread from
+     * registered context or default transactional entity manager
+     * created for this request.
+     * 
+     * @return entity manager.
+     */
+    public EntityManager getEntityManager();
+
+    /**
+     * Register registry manager context with current thread.
+     * 
+     * @param context registry manager context.
+     */
+    public void registerContext(Object context);
+
+    /**
+     * Get registry manager context registered with current thread.
+     * 
+     * @return registry manager context.
+     */
+    public Object getContext();
+
+    /**
+     * Unregister page manager context with current thread.
+     * 
+     * @param context registry manager context.
+     */
+    public void unregisterContext(Object context);
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org
For additional commands, e-mail: jetspeed-dev-help@portals.apache.org