portals-jetspeed-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rwat...@apache.org
Subject svn commit: r731466 [10/12] - in /portals/jetspeed-2/portal/branches/JPA_BRANCH: ./ components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/ components/jetspeed-cm/src/main/java/org/apache/jetspeed/test/ components/jetspeed-page-manager/ co...
Date Mon, 05 Jan 2009 06:04:18 GMT
Added: portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/page/jpa/DatabasePageManagerImpl.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/page/jpa/DatabasePageManagerImpl.java?rev=731466&view=auto
==============================================================================
--- portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/page/jpa/DatabasePageManagerImpl.java (added)
+++ portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/page/jpa/DatabasePageManagerImpl.java Sun Jan  4 22:04:13 2009
@@ -0,0 +1,2106 @@
+/*
+ * 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.page.jpa;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.persistence.EntityExistsException;
+import javax.persistence.EntityManager;
+import javax.persistence.NoResultException;
+import javax.persistence.PersistenceContext;
+import javax.persistence.Query;
+import javax.security.auth.Subject;
+
+import org.apache.jetspeed.JetspeedActions;
+import org.apache.jetspeed.om.common.SecurityConstraint;
+import org.apache.jetspeed.om.common.SecurityConstraintsContext;
+import org.apache.jetspeed.om.folder.Folder;
+import org.apache.jetspeed.om.folder.FolderNotFoundException;
+import org.apache.jetspeed.om.folder.InvalidFolderException;
+import org.apache.jetspeed.om.folder.MenuDefinition;
+import org.apache.jetspeed.om.folder.MenuExcludeDefinition;
+import org.apache.jetspeed.om.folder.MenuIncludeDefinition;
+import org.apache.jetspeed.om.folder.MenuOptionsDefinition;
+import org.apache.jetspeed.om.folder.MenuSeparatorDefinition;
+import org.apache.jetspeed.om.folder.jpa.FolderImpl;
+import org.apache.jetspeed.om.folder.jpa.FolderMenuDefinitionImpl;
+import org.apache.jetspeed.om.folder.jpa.FolderMenuExcludeDefinitionImpl;
+import org.apache.jetspeed.om.folder.jpa.FolderMenuIncludeDefinitionImpl;
+import org.apache.jetspeed.om.folder.jpa.FolderMenuOptionsDefinitionImpl;
+import org.apache.jetspeed.om.folder.jpa.FolderMenuSeparatorDefinitionImpl;
+import org.apache.jetspeed.om.folder.jpa.FolderSecurityConstraintImpl;
+import org.apache.jetspeed.om.page.ContentPage;
+import org.apache.jetspeed.om.page.ContentPageImpl;
+import org.apache.jetspeed.om.page.Fragment;
+import org.apache.jetspeed.om.page.Link;
+import org.apache.jetspeed.om.page.Page;
+import org.apache.jetspeed.om.page.PageSecurity;
+import org.apache.jetspeed.om.page.SecurityConstraintsDef;
+import org.apache.jetspeed.om.page.jpa.BaseElementImpl;
+import org.apache.jetspeed.om.page.jpa.FragmentImpl;
+import org.apache.jetspeed.om.page.jpa.FragmentPreferenceImpl;
+import org.apache.jetspeed.om.page.jpa.FragmentSecurityConstraintImpl;
+import org.apache.jetspeed.om.page.jpa.GenericSecurityConstraintsContextImpl;
+import org.apache.jetspeed.om.page.jpa.LinkImpl;
+import org.apache.jetspeed.om.page.jpa.LinkSecurityConstraintImpl;
+import org.apache.jetspeed.om.page.jpa.PageImpl;
+import org.apache.jetspeed.om.page.jpa.PageMenuDefinitionImpl;
+import org.apache.jetspeed.om.page.jpa.PageMenuExcludeDefinitionImpl;
+import org.apache.jetspeed.om.page.jpa.PageMenuIncludeDefinitionImpl;
+import org.apache.jetspeed.om.page.jpa.PageMenuOptionsDefinitionImpl;
+import org.apache.jetspeed.om.page.jpa.PageMenuSeparatorDefinitionImpl;
+import org.apache.jetspeed.om.page.jpa.PageSecurityConstraintImpl;
+import org.apache.jetspeed.om.page.jpa.PageSecurityImpl;
+import org.apache.jetspeed.om.page.jpa.PageSecuritySecurityConstraintImpl;
+import org.apache.jetspeed.om.page.jpa.SecurityConstraintsDefImpl;
+import org.apache.jetspeed.om.preference.FragmentPreference;
+import org.apache.jetspeed.page.DelegatingPageManager;
+import org.apache.jetspeed.page.FolderNotRemovedException;
+import org.apache.jetspeed.page.FolderNotUpdatedException;
+import org.apache.jetspeed.page.LinkNotRemovedException;
+import org.apache.jetspeed.page.LinkNotUpdatedException;
+import org.apache.jetspeed.page.PageManagerEventListener;
+import org.apache.jetspeed.page.PageManagerSecurityUtils;
+import org.apache.jetspeed.page.PageManagerUtils;
+import org.apache.jetspeed.page.PageNotFoundException;
+import org.apache.jetspeed.page.PageNotRemovedException;
+import org.apache.jetspeed.page.PageNotUpdatedException;
+import org.apache.jetspeed.page.document.DocumentException;
+import org.apache.jetspeed.page.document.DocumentNotFoundException;
+import org.apache.jetspeed.page.document.FailedToDeleteDocumentException;
+import org.apache.jetspeed.page.document.FailedToUpdateDocumentException;
+import org.apache.jetspeed.page.document.Node;
+import org.apache.jetspeed.page.document.NodeException;
+import org.apache.jetspeed.page.document.NodeSet;
+import org.apache.jetspeed.page.document.jpa.NodeImpl;
+import org.springframework.stereotype.Repository;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * DatabasePageManagerImpl
+ * 
+ * @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 DatabasePageManagerImpl implements DatabasePageManager
+{
+    private static Map modelClasses = new HashMap();
+    static
+    {
+        modelClasses.put("FragmentImpl", FragmentImpl.class);
+        modelClasses.put("PageImpl", PageImpl.class);
+        modelClasses.put("FolderImpl", FolderImpl.class);
+        modelClasses.put("LinkImpl", LinkImpl.class);
+        modelClasses.put("PageSecurityImpl", PageSecurityImpl.class);
+        modelClasses.put("FolderMenuDefinitionImpl", FolderMenuDefinitionImpl.class);
+        modelClasses.put("FolderMenuExcludeDefinitionImpl", FolderMenuExcludeDefinitionImpl.class);
+        modelClasses.put("FolderMenuIncludeDefinitionImpl", FolderMenuIncludeDefinitionImpl.class);
+        modelClasses.put("FolderMenuOptionsDefinitionImpl", FolderMenuOptionsDefinitionImpl.class);
+        modelClasses.put("FolderMenuSeparatorDefinitionImpl", FolderMenuSeparatorDefinitionImpl.class);
+        modelClasses.put("PageMenuDefinitionImpl", PageMenuDefinitionImpl.class);
+        modelClasses.put("PageMenuExcludeDefinitionImpl", PageMenuExcludeDefinitionImpl.class);
+        modelClasses.put("PageMenuIncludeDefinitionImpl", PageMenuIncludeDefinitionImpl.class);
+        modelClasses.put("PageMenuOptionsDefinitionImpl", PageMenuOptionsDefinitionImpl.class);
+        modelClasses.put("PageMenuSeparatorDefinitionImpl", PageMenuSeparatorDefinitionImpl.class);
+        modelClasses.put("SecurityConstraintsContextImpl", GenericSecurityConstraintsContextImpl.class);
+        modelClasses.put("FolderSecurityConstraintImpl", FolderSecurityConstraintImpl.class);
+        modelClasses.put("PageSecurityConstraintImpl", PageSecurityConstraintImpl.class);
+        modelClasses.put("FragmentSecurityConstraintImpl", FragmentSecurityConstraintImpl.class);
+        modelClasses.put("LinkSecurityConstraintImpl", LinkSecurityConstraintImpl.class);
+        modelClasses.put("PageSecuritySecurityConstraintImpl", PageSecuritySecurityConstraintImpl.class);
+        modelClasses.put("SecurityConstraintsDefImpl", SecurityConstraintsDefImpl.class);
+        modelClasses.put("FragmentPreferenceImpl", FragmentPreferenceImpl.class);
+    }
+
+    private DelegatingPageManager delegator;
+    private EntityManager entityManager;
+    private ThreadLocal contexts;
+    private DatabasePageManager databasePageManagerProxy;
+    private long cachedConstraintsVersion;
+
+    /**
+     * Construct with permissions and constraints settings.
+     * 
+     * @param isPermissionsSecurity
+     * @param isConstraintsSecurity
+     */
+    public DatabasePageManagerImpl(boolean isPermissionsSecurity, boolean isConstraintsSecurity)
+    {
+        delegator = new DelegatingPageManager(isPermissionsSecurity, isConstraintsSecurity, modelClasses);
+        contexts = new ThreadLocal();
+    }
+
+    /**
+     * Inject shared entity manager from assembly; this entity
+     * manager is expected to honor existing entity manager
+     * context attached to current thread, (otherwise, a new
+     * temporary entity manager is created).
+     * 
+     * @param entityManager injected shared entity manager
+     */
+    @PersistenceContext (unitName="jetspeed-page-manager")
+    public void setEntityManager(EntityManager entityManager) 
+    {
+        this.entityManager = entityManager;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#registerContext(java.lang.Object)
+     */
+    public void registerContext(Object context)
+    {
+        DatabasePageManagerContext registeredContext = (DatabasePageManagerContext)contexts.get();
+        if ((registeredContext == null) && (context instanceof DatabasePageManagerContext))
+        {
+            contexts.set(context);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#getContext()
+     */
+    public Object getContext()
+    {
+        return (DatabasePageManagerContext)contexts.get();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#unregisterContext(java.lang.Object)
+     */
+    public void unregisterContext(Object context)
+    {
+        DatabasePageManagerContext registeredContext = (DatabasePageManagerContext)contexts.get();
+        if (context == registeredContext)
+        {
+            contexts.remove();
+        }
+    }
+
+    /**
+     * 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()
+    {
+        DatabasePageManagerContext context = (DatabasePageManagerContext)getContext();
+        return ((context != null) ? context.getExtendedEntityManager() : entityManager);
+    }
+    
+    /**
+     * Inject proxied page manager interface used to
+     * inject into Folder instances to provide
+     * transaction/interception.
+     *
+     * @param proxy proxied page manager interface.
+     */
+    public void setDatabasePageManagerProxy(DatabasePageManager proxy)
+    {
+        databasePageManagerProxy = proxy;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.jpa.DatabasePageManager#getCachedConstraintsVersion()
+     */
+    public long getCachedConstraintsVersion()
+    {
+        return cachedConstraintsVersion;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#getConstraintsEnabled()
+     */
+    public boolean getConstraintsEnabled()
+    {
+        return delegator.getConstraintsEnabled();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#getPermissionsEnabled()
+     */
+    public boolean getPermissionsEnabled()
+    {
+        return delegator.getPermissionsEnabled();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#newPage(java.lang.String)
+     */
+    public Page newPage(String path)
+    {
+        Page newPage = delegator.newPage(path);
+        infuseElement(newPage);
+        return newPage;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#newFolder(java.lang.String)
+     */
+    public Folder newFolder(String path)
+    {
+        Folder newFolder = delegator.newFolder(path);
+        infuseElement(newFolder);
+        return newFolder;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#newLink(java.lang.String)
+     */
+    public Link newLink(String path)
+    {
+        Link newLink = delegator.newLink(path);
+        infuseElement(newLink);
+        return newLink;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#newPageSecurity()
+     */
+    public PageSecurity newPageSecurity()
+    {
+        PageSecurity newPageSecurity = delegator.newPageSecurity();
+        infuseElement(newPageSecurity);
+        return newPageSecurity;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#newFragment()
+     */
+    public Fragment newFragment()
+    {
+        Fragment newFragment = delegator.newFragment();
+        infuseElement(newFragment);
+        return newFragment;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#newPortletFragment()
+     */
+    public Fragment newPortletFragment()
+    {
+        Fragment newPortletFragment = delegator.newPortletFragment();
+        infuseElement(newPortletFragment);
+        return newPortletFragment;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#newFolderMenuDefinition()
+     */
+    public MenuDefinition newFolderMenuDefinition()
+    {
+        return delegator.newFolderMenuDefinition();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#newFolderMenuExcludeDefinition()
+     */
+    public MenuExcludeDefinition newFolderMenuExcludeDefinition()
+    {
+        return delegator.newFolderMenuExcludeDefinition();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#newFolderMenuIncludeDefinition()
+     */
+    public MenuIncludeDefinition newFolderMenuIncludeDefinition()
+    {
+        return delegator.newFolderMenuIncludeDefinition();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#newFolderMenuOptionsDefinition()
+     */
+    public MenuOptionsDefinition newFolderMenuOptionsDefinition()
+    {
+        return delegator.newFolderMenuOptionsDefinition();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#newFolderMenuSeparatorDefinition()
+     */
+    public MenuSeparatorDefinition newFolderMenuSeparatorDefinition()
+    {
+        return delegator.newFolderMenuSeparatorDefinition();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#newPageMenuDefinition()
+     */
+    public MenuDefinition newPageMenuDefinition()
+    {
+        return delegator.newPageMenuDefinition();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#newPageMenuExcludeDefinition()
+     */
+    public MenuExcludeDefinition newPageMenuExcludeDefinition()
+    {
+        return delegator.newPageMenuExcludeDefinition();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#newPageMenuIncludeDefinition()
+     */
+    public MenuIncludeDefinition newPageMenuIncludeDefinition()
+    {
+        return delegator.newPageMenuIncludeDefinition();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#newPageMenuOptionsDefinition()
+     */
+    public MenuOptionsDefinition newPageMenuOptionsDefinition()
+    {
+        return delegator.newPageMenuOptionsDefinition();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#newPageMenuSeparatorDefinition()
+     */
+    public MenuSeparatorDefinition newPageMenuSeparatorDefinition()
+    {
+        return delegator.newPageMenuSeparatorDefinition();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#newSecurityConstraintsContext()
+     */
+    public SecurityConstraintsContext newSecurityConstraintsContext()
+    {
+        return delegator.newSecurityConstraintsContext();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#newFolderSecurityConstraint()
+     */
+    public SecurityConstraint newFolderSecurityConstraint()
+    {
+        return delegator.newFolderSecurityConstraint();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#newPageSecurityConstraint()
+     */
+    public SecurityConstraint newPageSecurityConstraint()
+    {
+        return delegator.newPageSecurityConstraint();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#newFragmentSecurityConstraint()
+     */
+    public SecurityConstraint newFragmentSecurityConstraint()
+    {
+        return delegator.newFragmentSecurityConstraint();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#newLinkSecurityConstraint()
+     */
+    public SecurityConstraint newLinkSecurityConstraint()
+    {
+        return delegator.newLinkSecurityConstraint();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#newPageSecuritySecurityConstraint()
+     */
+    public SecurityConstraint newPageSecuritySecurityConstraint()
+    {
+        return delegator.newPageSecuritySecurityConstraint();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#newSecurityConstraintsDef()
+     */
+    public SecurityConstraintsDef newSecurityConstraintsDef()
+    {
+        return delegator.newSecurityConstraintsDef();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#newFragmentPreference()
+     */
+    public FragmentPreference newFragmentPreference()
+    {
+        return delegator.newFragmentPreference();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#addListener(org.apache.jetspeed.page.PageManagerEventListener)
+     */
+    public void addListener(PageManagerEventListener listener)
+    {
+        delegator.addListener(listener);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#removeListener(org.apache.jetspeed.page.PageManagerEventListener)
+     */
+    public void removeListener(PageManagerEventListener listener)
+    {
+        delegator.removeListener(listener);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#reset()
+     */
+    @Transactional (readOnly=false)
+    public void reset()
+    {
+        // propagate to delegator
+        delegator.reset();
+
+        // clear cache to force subsequent refreshes from persistent store
+        EntityManager entityManager = getEntityManager();
+        entityManager.flush();
+        entityManager.clear();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#shutdown()
+     */
+    public void shutdown()
+    {
+        // delegate
+        delegator.shutdown();
+    }
+
+     /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#getPage(java.lang.String)
+     */
+    @Transactional (readOnly=true)
+    public Page getPage(String path) throws PageNotFoundException, NodeException
+    {
+        // construct page attributes from path
+        path = NodeImpl.getCanonicalNodePath(path);
+
+        // retrieve page from database
+        try
+        {
+            // query for page by path
+            EntityManager entityManager = getEntityManager();
+            Query pageQuery = entityManager.createNamedQuery("PAGE");
+            pageQuery.setParameter("path", path);
+            Page page = null;
+            try
+            {
+                page = (Page)pageQuery.getSingleResult();
+                infuseElement(page);
+            }
+            catch (NoResultException nre)
+            {
+            }
+            
+            // return page or throw exception
+            if (page == null)
+            {
+                throw new PageNotFoundException("Page " + path + " not found.");
+            }
+
+            // check for view access on page
+            page.checkAccess(JetspeedActions.VIEW);
+
+            return page;
+        }
+        catch (PageNotFoundException pnfe)
+        {
+            throw pnfe;
+        }
+        catch (SecurityException se)
+        {
+            throw se;
+        }
+        catch (Exception e)
+        {
+            throw new PageNotFoundException("Page " + path + " not found.", e);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#getContentPage(java.lang.String)
+     */
+    @Transactional (readOnly=true)
+    public ContentPage getContentPage(String path) throws PageNotFoundException, NodeException
+    {
+        // return proxied page
+        return new ContentPageImpl(getPage(path));
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#getLink(java.lang.String)
+     */
+    @Transactional (readOnly=true)
+    public Link getLink(String path) throws DocumentNotFoundException, NodeException
+    {
+        // construct link attributes from path
+        path = NodeImpl.getCanonicalNodePath(path);
+
+        // retrieve link from database
+        try
+        {
+            // query for link by path
+            EntityManager entityManager = getEntityManager();
+            Query linkQuery = entityManager.createNamedQuery("LINK");
+            linkQuery.setParameter("path", path);
+            Link link = null;
+            try
+            {
+                link = (Link)linkQuery.getSingleResult();
+                infuseElement(link);
+            }
+            catch (NoResultException nre)
+            {
+            }
+            
+            // return link or throw exception
+            if (link == null)
+            {
+                throw new DocumentNotFoundException("Link " + path + " not found.");
+            }
+
+            // check for view access on link
+            link.checkAccess(JetspeedActions.VIEW);
+
+            return link;
+        }
+        catch (DocumentNotFoundException dnfe)
+        {
+            throw dnfe;
+        }
+        catch (SecurityException se)
+        {
+            throw se;
+        }
+        catch (Exception e)
+        {
+            throw new DocumentNotFoundException("Link " + path + " not found.", e);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#checkConstraint(java.lang.String, java.lang.String)
+     */
+    @Transactional (readOnly=true)
+    public boolean checkConstraint(String securityConstraintName, String actions)
+    {
+        try
+        {
+            PageSecurity security = getPageSecurity();
+            SecurityConstraintsDef def = security.getSecurityConstraintsDef(securityConstraintName);
+            if (def != null)
+            {
+                return PageManagerSecurityUtils.checkConstraint(def, actions);
+            }            
+        }
+        catch (Exception e)
+        {
+        }           
+        return false;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#getPageSecurity()
+     */
+    @Transactional (readOnly=true)
+    public PageSecurity getPageSecurity() throws DocumentNotFoundException, NodeException
+    {
+        // construct document attributes from path
+        String path = Folder.PATH_SEPARATOR + PageSecurity.DOCUMENT_TYPE;
+
+        // retrieve document from database
+        try
+        {
+            // query for page security by path
+            EntityManager entityManager = getEntityManager();
+            Query pageSecurityQuery = entityManager.createNamedQuery("PAGE_SECURITY");
+            pageSecurityQuery.setParameter("path", path);
+            PageSecurity pageSecurity = null;
+            try
+            {
+                pageSecurity = (PageSecurity)pageSecurityQuery.getSingleResult();
+                infuseElement(pageSecurity);
+            }
+            catch (NoResultException nre)
+            {
+            }
+            
+            // return page security or throw exception
+            if (pageSecurity == null)
+            {
+                throw new DocumentNotFoundException("Page security " + path + " not found.");
+            }
+
+            // check for view access on page security
+            pageSecurity.checkAccess(JetspeedActions.VIEW);
+
+            return pageSecurity;
+        }
+        catch (DocumentNotFoundException dnfe)
+        {
+            throw dnfe;
+        }
+        catch (SecurityException se)
+        {
+            throw se;
+        }
+        catch (Exception e)
+        {
+            throw new DocumentNotFoundException("Page security " + path + " not found.", e);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#getFolder(java.lang.String)
+     */
+    @Transactional (readOnly=true)
+    public Folder getFolder(String folderPath) throws FolderNotFoundException, InvalidFolderException, NodeException
+    {
+        // construct folder attributes from path
+        folderPath = NodeImpl.getCanonicalNodePath(folderPath);
+
+        // retrieve folder from database
+        try
+        {
+            // query for folder by path
+            EntityManager entityManager = getEntityManager();
+            Query folderQuery = entityManager.createNamedQuery("FOLDER");
+            folderQuery.setParameter("path", folderPath);
+            
+            Folder folder = null;
+            try
+            {
+                folder = (Folder)folderQuery.getSingleResult();
+                infuseElement(folder);
+            }
+            catch (NoResultException nre)
+            {
+            }
+            
+            // return folder or throw exception
+            if (folder == null)
+            {
+                throw new FolderNotFoundException("Folder " + folderPath + " not found.");
+            }
+
+            // check for view access on folder
+            folder.checkAccess(JetspeedActions.VIEW);
+
+            return folder;
+        }
+        catch (FolderNotFoundException fnfe)
+        {
+            throw fnfe;
+        }
+        catch (SecurityException se)
+        {
+            throw se;
+        }
+        catch (Exception e)
+        {
+            throw new FolderNotFoundException("Folder " + folderPath + " not found.", e);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#getFolders(org.apache.jetspeed.om.folder.Folder)
+     */
+    @Transactional (readOnly=true)
+    public NodeSet getFolders(Folder folder) throws DocumentException
+    {
+        FolderImpl folderImpl = (FolderImpl)folder;
+
+        // perform lookup of folder folders collection and cache in folder
+        try
+        {
+            // query for folders by parent
+            EntityManager entityManager = getEntityManager();
+            Query foldersQuery = entityManager.createNamedQuery("FOLDER_FOLDERS");
+            foldersQuery.setParameter("folder", folder);
+            Collection folders = foldersQuery.getResultList();
+            infuseElements(folders);
+
+            // cache folders in folder
+            synchronized (folderImpl.accessCacheLock())
+            {
+                folderImpl.accessFolders().clear();
+                if (folders != null)
+                {
+                    folderImpl.accessFolders().addAll(folders);
+                }
+                folderImpl.resetFolders(true);
+            }
+        }
+        catch (Exception e)
+        {
+            // reset cache in folder
+            synchronized (folderImpl.accessCacheLock())
+            {
+                folderImpl.resetFolders(false);
+            }
+            throw new DocumentException("Unable to access folders for folder " + folder.getPath() + ".");
+        }
+
+        // folder folders cache populated, get folders from folder
+        // to provide packaging as filtered node set
+        return folder.getFolders();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#getFolder(org.apache.jetspeed.om.folder.Folder,java.lang.String)
+     */
+    @Transactional (readOnly=true)
+    public Folder getFolder(Folder folder, String name) throws FolderNotFoundException, DocumentException
+    {
+        // perform lookup by path so that cache can be used
+        String folderPath = folder.getPath() + Folder.PATH_SEPARATOR + name;
+        try
+        {
+            return getFolder(folderPath);
+        }
+        catch (FolderNotFoundException fnfe)
+        {
+            throw fnfe;
+        }
+        catch (Exception e)
+        {
+            throw new FolderNotFoundException("Folder " + folderPath + " not found.", e);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#getPages(org.apache.jetspeed.om.folder.Folder)
+     */
+    @Transactional (readOnly=true)
+    public NodeSet getPages(Folder folder) throws NodeException
+    {
+        FolderImpl folderImpl = (FolderImpl)folder;
+
+        // perform lookup of folder pages collection and cache in folder
+        try
+        {
+            // query for pages by parent
+            EntityManager entityManager = getEntityManager();
+            Query pagesQuery = entityManager.createNamedQuery("FOLDER_PAGES");
+            pagesQuery.setParameter("folder", folder);
+            Collection pages = pagesQuery.getResultList();
+            infuseElements(pages);
+
+            // cache pages in folder
+            synchronized (folderImpl.accessCacheLock())
+            {
+                folderImpl.accessPages().clear();
+                if (pages != null)
+                {
+                    folderImpl.accessPages().addAll(pages);
+                }
+                folderImpl.resetPages(true);
+            }
+        }
+        catch (Exception e)
+        {
+            // reset cache in folder
+            synchronized (folderImpl.accessCacheLock())
+            {
+                folderImpl.resetPages(false);
+            }
+            throw new NodeException("Unable to access pages for folder " + folder.getPath() + ".");
+        }
+
+        // folder pages cache populated, get pages from folder
+        // to provide packaging as filtered node set
+        return folder.getPages();
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#getPage(org.apache.jetspeed.om.folder.Folder,java.lang.String)
+     */
+    @Transactional (readOnly=true)
+    public Page getPage(Folder folder, String name) throws PageNotFoundException, NodeException
+    {
+        // perform lookup by path so that cache can be used
+        String pagePath = folder.getPath() + Folder.PATH_SEPARATOR + name;
+        try
+        {
+            return getPage(pagePath);
+        }
+        catch (PageNotFoundException pnfe)
+        {
+            throw pnfe;
+        }
+        catch (Exception e)
+        {
+            throw new PageNotFoundException("Page " + pagePath + " not found.", e);
+        }
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#getLinks(org.apache.jetspeed.om.folder.Folder)
+     */    
+    @Transactional (readOnly=true)
+    public NodeSet getLinks(Folder folder) throws NodeException
+    {
+        FolderImpl folderImpl = (FolderImpl)folder;
+
+        // perform lookup of folder links collection and cache in folder
+        try
+        {
+            // query for links by parent
+            EntityManager entityManager = getEntityManager();
+            Query linksQuery = entityManager.createNamedQuery("FOLDER_LINKS");
+            linksQuery.setParameter("folder", folder);
+            Collection links = linksQuery.getResultList();
+            infuseElements(links);
+
+            // cache links in folder
+            synchronized (folderImpl.accessCacheLock())
+            {
+                folderImpl.accessLinks().clear();
+                if (links != null)
+                {
+                    folderImpl.accessLinks().addAll(links);
+                }
+                folderImpl.resetLinks(true);
+            }
+        }
+        catch (Exception e)
+        {
+            // reset cache in folder
+            synchronized (folderImpl.accessCacheLock())
+            {
+                folderImpl.resetLinks(false);
+            }
+            throw new NodeException("Unable to access links for folder " + folder.getPath() + ".");
+        }
+
+        // folder links cache populated, get links from folder
+        // to provide packaging as filtered node set
+        return folder.getLinks();
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#getLink(org.apache.jetspeed.om.folder.Folder,java.lang.String)
+     */    
+    @Transactional (readOnly=true)
+    public Link getLink(Folder folder, String name) throws DocumentNotFoundException, NodeException
+    {
+        // perform lookup by path so that cache can be used
+        String linkPath = folder.getPath() + Folder.PATH_SEPARATOR + name;
+        try
+        {
+            return getLink(linkPath);
+        }
+        catch (DocumentNotFoundException dnfe)
+        {
+            throw dnfe;
+        }
+        catch (Exception e)
+        {
+            throw new DocumentNotFoundException("Link " + linkPath + " not found.", e);
+        }
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#getPageSecurity(org.apache.jetspeed.om.folder.Folder)
+     */    
+    @Transactional (readOnly=true)
+    public PageSecurity getPageSecurity(Folder folder) throws DocumentNotFoundException, NodeException
+    {
+        FolderImpl folderImpl = (FolderImpl)folder;
+
+        // perform lookup of page security document and cache
+        // in folder; limit lookup to root folder since page
+        // security document is currently supported only as a
+        // root folder singleton
+        if (folder.getPath().equals(Folder.PATH_SEPARATOR))
+        {
+            try
+            {
+                // query for page security by parent
+                EntityManager entityManager = getEntityManager();
+                Query pageSecurityQuery = entityManager.createNamedQuery("FOLDER_PAGE_SECURITY");
+                pageSecurityQuery.setParameter("folder", folder);
+                PageSecurity pageSecurity = null;
+                try
+                {
+                    pageSecurity = (PageSecurity)pageSecurityQuery.getSingleResult();
+                    infuseElement(pageSecurity);
+                }
+                catch (NoResultException nre)
+                {
+                }
+
+                // cache page security in folder
+                folderImpl.resetPageSecurity((PageSecurityImpl)pageSecurity, true);
+            }
+            catch (Exception e)
+            {
+                // reset page security in folder
+                folderImpl.resetPageSecurity(null, true);
+                throw new NodeException("Unable to access page security for folder " + folder.getPath() + ".");
+            }
+        }
+        else
+        {
+            // cache page security in folder
+            folderImpl.resetPageSecurity(null, true);
+        }
+
+        // folder page security instance cache populated, get
+        // instance from folder to provide security checks
+        return folder.getPageSecurity();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#getAll(org.apache.jetspeed.om.folder.Folder)
+     */
+    @Transactional (readOnly=true)
+    public NodeSet getAll(Folder folder) throws DocumentException
+    {
+        FolderImpl folderImpl = (FolderImpl)folder;
+
+        // perform lookup of folder nodes collection and cache in folder
+        try
+        {
+            EntityManager entityManager = getEntityManager();
+
+            // query for all nodes
+            List all = new ArrayList();
+            // query for folders by parent
+            Query foldersQuery = entityManager.createNamedQuery("FOLDER_FOLDERS");
+            foldersQuery.setParameter("folder", folder);
+            Collection folders = foldersQuery.getResultList();
+            infuseElements(folders);
+            if (folders != null)
+            {
+                all.addAll(folders);
+            }
+            // query for pages by parent
+            Query pagesQuery = entityManager.createNamedQuery("FOLDER_PAGES");
+            pagesQuery.setParameter("folder", folder);
+            Collection pages = pagesQuery.getResultList();
+            infuseElements(pages);
+            if (pages != null)
+            {
+                all.addAll(pages);
+            }
+            // query for links by parent
+            Query linksQuery = entityManager.createNamedQuery("FOLDER_LINKS");
+            linksQuery.setParameter("folder", folder);
+            Collection links = linksQuery.getResultList();
+            infuseElements(links);
+            if (links != null)
+            {
+                all.addAll(links);
+            }
+            // query for page security by parent
+            Query pageSecurityQuery = entityManager.createNamedQuery("FOLDER_PAGE_SECURITY");
+            pageSecurityQuery.setParameter("folder", folder);
+            try
+            {
+                PageSecurity pageSecurity = (PageSecurity)pageSecurityQuery.getSingleResult();
+                infuseElement(pageSecurity);
+                all.add(pageSecurity);
+            }
+            catch (NoResultException nre)
+            {
+            }
+
+            // cache links in folder
+            synchronized (folderImpl.accessCacheLock())
+            {
+                folderImpl.accessAll().clear();
+                folderImpl.accessAll().addAll(all);
+                folderImpl.resetAll(true);
+            }
+        }
+        catch (Exception e)
+        {
+            // reset cache in folder
+            synchronized (folderImpl.accessCacheLock())
+            {
+                folderImpl.resetAll(false);
+            }
+            throw new DocumentException("Unable to access all nodes for folder " + folder.getPath() + ".");
+        }
+
+        // folder all nodes cache populated, get all from folder
+        // to provide packaging as filtered node set
+        return folder.getAll();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#updatePage(org.apache.jetspeed.om.page.Page)
+     */
+    @Transactional (readOnly=false, rollbackFor=NodeException.class)
+    public void updatePage(Page page) throws NodeException, PageNotUpdatedException
+    {
+        try
+        {
+            // dereference page in case proxy is supplied
+            if (page instanceof ContentPageImpl)
+            {
+                page = ((ContentPageImpl)page).getPage();
+            }
+
+            // look up and set parent folder if necessary
+            FolderImpl parent = (FolderImpl)page.getParent();
+            if (parent == null)
+            {
+                // access folder by path
+                String pagePath = page.getPath();
+                String parentPath = pagePath.substring(0, pagePath.lastIndexOf(Folder.PATH_SEPARATOR));
+                if (parentPath.length() == 0)
+                {
+                    parentPath = Folder.PATH_SEPARATOR;
+                }
+                try
+                {
+                    parent = (FolderImpl)getFolder(parentPath);                    
+                }
+                catch (FolderNotFoundException fnfe)
+                {
+                    throw new PageNotUpdatedException("Missing parent folder: " + parentPath);
+                }
+                
+                // check for edit access on parent folder; page
+                // access not checked on create
+                parent.checkAccess(JetspeedActions.EDIT);
+
+                // update page
+                page.setParent(parent);
+                // store page object
+                persistElement(page);
+
+                // reset parent folder pages cache
+                if (parent != null)
+                {
+                    parent.resetPages(false);
+                }
+
+                // notify page manager listeners
+                delegator.notifyNewNode(page);
+            }
+            else
+            {
+                // check for edit access on page and parent folder
+                page.checkAccess(JetspeedActions.EDIT);
+
+                // update page object
+                persistElement(page);
+                
+                // reset parent folder pages cache in case
+                // parent is holding an out of date copy of
+                // this page that was removed from the cache
+                // before this one was accessed
+                if (parent != null)
+                {
+                    parent.resetPages(false);
+                }
+
+                // notify page manager listeners
+                delegator.notifyUpdatedNode(page);
+            }
+        }
+        catch (PageNotUpdatedException pnue)
+        {
+            throw pnue;
+        }
+        catch (SecurityException se)
+        {
+            throw se;
+        }
+        catch (Exception e)
+        {
+            throw new PageNotUpdatedException("Page " + page.getPath() + " not updated.", e);
+        }        
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#removePage(org.apache.jetspeed.om.page.Page)
+     */
+    @Transactional (readOnly=false, rollbackFor=NodeException.class)
+    public void removePage(Page page) throws NodeException, PageNotRemovedException
+    {
+        try
+        {
+            // dereference page in case proxy is supplied
+            if (page instanceof ContentPageImpl)
+            {
+                page = ((ContentPageImpl)page).getPage();
+            }
+
+            // check for edit access on page and parent folder
+            page.checkAccess(JetspeedActions.EDIT);
+
+            // look up and update parent folder if necessary
+            if (page.getParent() != null)
+            {
+                FolderImpl parent = (FolderImpl)page.getParent();
+                
+                // delete page object
+                removeElement(page);
+                
+                // reset parent folder pages cache
+                if (parent != null)
+                {
+                    parent.resetPages(false);
+                }
+            }
+            else
+            {
+                // delete page object
+                removeElement(page);
+            }
+
+            // notify page manager listeners
+            delegator.notifyRemovedNode(page);
+        }
+        catch (SecurityException se)
+        {
+            throw se;
+        }
+        catch (Exception e)
+        {
+            throw new PageNotRemovedException("Page " + page.getPath() + " not removed.", e);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#updateFolder(org.apache.jetspeed.om.folder.Folder)
+     */
+    @Transactional (readOnly=false, rollbackFor=NodeException.class)
+    public void updateFolder(Folder folder) throws NodeException, FolderNotUpdatedException
+    {
+        // shallow update by default
+        updateFolder(folder, false);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#updateFolder(org.apache.jetspeed.om.folder.Folder,boolean)
+     */
+    @Transactional (readOnly=false, rollbackFor=NodeException.class)
+    public void updateFolder(Folder folder, boolean deep) throws NodeException, FolderNotUpdatedException
+    {
+        try
+        {
+            // look up and set parent folder if required
+            FolderImpl parent = (FolderImpl)folder.getParent();
+            if ((parent == null) && !folder.getPath().equals(Folder.PATH_SEPARATOR))
+            {
+                // access folder by path
+                String folderPath = folder.getPath();
+                String parentPath = folderPath.substring(0, folderPath.lastIndexOf(Folder.PATH_SEPARATOR));
+                if (parentPath.length() == 0)
+                {
+                    parentPath = Folder.PATH_SEPARATOR;
+                }
+                try
+                {
+                    parent = (FolderImpl)getFolder(parentPath);
+                }
+                catch (FolderNotFoundException fnfe)
+                {
+                    throw new FolderNotUpdatedException("Missing parent folder: " + parentPath);
+                }
+                
+                // check for edit access on parent folder; folder
+                // access not checked on create
+                parent.checkAccess(JetspeedActions.EDIT);
+
+                // update folder object
+                folder.setParent(parent);
+                persistElement(folder);
+
+                // reset parent folder folders cache
+                if (parent != null)
+                {
+                    parent.resetFolders(false);
+                }
+
+                // notify page manager listeners
+                delegator.notifyNewNode(folder);
+            }
+            else
+            {
+                // determine if folder is new
+                FolderImpl folderImpl = (FolderImpl)folder;
+                boolean newFolder = folderImpl.isNew();
+
+                // check for edit access on folder and parent folder
+                // if not being initially created; access is not
+                // checked on create
+                String folderPath = folder.getPath();
+                if (!newFolder || !folderPath.equals(Folder.PATH_SEPARATOR))
+                {
+                    folder.checkAccess(JetspeedActions.EDIT);
+                }
+
+                // create root folder or update folder
+                FolderImpl persistedFolderImpl = (FolderImpl)persistElement(folder);
+
+                // reset parent folder folders cache in case
+                // parent is holding an out of date copy of
+                // this folder that was removed from the cache
+                // before this one was accessed
+                if (parent != null)
+                {
+                    parent.resetFolders(false);
+                }
+
+                // notify page manager listeners
+                if (newFolder && !persistedFolderImpl.isNew())
+                {
+                    delegator.notifyNewNode(folder);
+                }
+                else
+                {
+                    delegator.notifyUpdatedNode(folder);
+                }
+            }
+
+            // update deep recursively if specified
+            if (deep)
+            {
+                // update recursively, (breadth first)
+                updateFolderNodes(folder);
+            }
+        }
+        catch (FolderNotUpdatedException fnue)
+        {
+            throw fnue;
+        }
+        catch (SecurityException se)
+        {
+            throw se;
+        }
+        catch (Exception e)
+        {
+            throw new FolderNotUpdatedException("Folder " + folder.getPath() + " not updated.", e);
+        }
+    }
+
+    /**
+     * updateFolderNodes - recursively update all folder nodes
+     *
+     * @param folderImpl folder whose nodes are to be updated
+     * @param throws FolderNotUpdatedException
+     */
+    private void updateFolderNodes(Folder folder) throws FolderNotUpdatedException
+    {
+        try
+        {
+            EntityManager entityManager = getEntityManager();
+
+            // update pages, query for pages by parent
+            Query pagesQuery = entityManager.createNamedQuery("FOLDER_PAGES");
+            pagesQuery.setParameter("folder", folder);
+            Collection pages = pagesQuery.getResultList();
+            infuseElements(pages);
+            if (pages != null)
+            {
+                Iterator pagesIter = pages.iterator();
+                while (pagesIter.hasNext())
+                {
+                    updatePage((Page)pagesIter.next());
+                }
+            }
+
+            // update links, query for links by parent
+            Query linksQuery = entityManager.createNamedQuery("FOLDER_LINKS");
+            linksQuery.setParameter("folder", folder);
+            Collection links = linksQuery.getResultList();
+            infuseElements(links);
+            if (links != null)
+            {
+                Iterator linksIter = links.iterator();
+                while (linksIter.hasNext())
+                {
+                    updateLink((Link)linksIter.next());
+                }
+            }
+
+            // update page security, query for page security by parent
+            Query pageSecurityQuery = entityManager.createNamedQuery("FOLDER_PAGE_SECURITY");
+            pageSecurityQuery.setParameter("folder", folder);
+            try
+            {
+                PageSecurity pageSecurity = (PageSecurity)pageSecurityQuery.getSingleResult();            
+                infuseElement(pageSecurity);
+                updatePageSecurity(pageSecurity);
+            }
+            catch (NoResultException nre)
+            {
+            }
+
+            // update folders last, (breadth first recursion),
+            // query for folders by parent
+            Query foldersQuery = entityManager.createNamedQuery("FOLDER_FOLDERS");
+            foldersQuery.setParameter("folder", folder);
+            Collection folders = foldersQuery.getResultList();
+            infuseElements(folders);
+            if (folders != null)
+            {
+                Iterator foldersIter = folders.iterator();
+                while (foldersIter.hasNext())
+                {
+                    updateFolder((Folder)foldersIter.next(), true);
+                }
+            }
+        }
+        catch (FolderNotUpdatedException fnue)
+        {
+            throw fnue;
+        }
+        catch (SecurityException se)
+        {
+            throw se;
+        }
+        catch (Exception e)
+        {
+            throw new FolderNotUpdatedException("Folder " + folder.getPath() + " not updated.", e);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#removeFolder(org.apache.jetspeed.om.folder.Folder)
+     */
+    @Transactional (readOnly=false, rollbackFor=NodeException.class)
+    public void removeFolder(Folder folder) throws NodeException, FolderNotRemovedException
+    {
+        try
+        {
+            // check for edit access on folder and parent folder
+            folder.checkAccess(JetspeedActions.EDIT);
+
+            // reset folder nodes cache
+            ((FolderImpl)folder).resetAll(false);
+
+            // remove recursively, (depth first)
+            removeFolderNodes(folder);
+
+            // look up and update parent folder if necessary
+            if (folder.getParent() != null)
+            {
+                FolderImpl parent = (FolderImpl)folder.getParent();
+
+                // delete folder object
+                removeElement(folder);
+
+                // reset parent folder folders cache
+                if (parent != null)
+                {
+                    parent.resetFolders(false);
+                }
+            }
+            else
+            {
+                // delete folder object
+                removeElement(folder);
+            }
+
+            // notify page manager listeners
+            delegator.notifyRemovedNode((FolderImpl)folder);
+        }
+        catch (SecurityException se)
+        {
+            throw se;
+        }
+        catch (Exception e)
+        {
+            throw new FolderNotRemovedException("Folder " + folder.getPath() + " not removed.", e);
+        }
+    }
+
+    /**
+     * removeFolderNodes - recursively remove all folder nodes
+     *
+     * @param folder folder whose nodes are to be removed
+     * @param throws FolderNotRemovedException
+     */
+    private void removeFolderNodes(Folder folder) throws FolderNotRemovedException
+    {
+        try
+        {
+            EntityManager entityManager = getEntityManager();
+
+            // remove folders first, (depth first recursion),
+            // query for folders by parent
+            Query foldersQuery = entityManager.createNamedQuery("FOLDER_FOLDERS");
+            foldersQuery.setParameter("folder", folder);
+            Collection folders = foldersQuery.getResultList();
+            infuseElements(folders);
+            if (folders != null)
+            {
+                Iterator foldersIter = folders.iterator();
+                while (foldersIter.hasNext())
+                {
+                    removeFolder((Folder)foldersIter.next());
+                }
+            }
+
+            // remove pages, query for pages by parent
+            Query pagesQuery = entityManager.createNamedQuery("FOLDER_PAGES");
+            pagesQuery.setParameter("folder", folder);
+            Collection pages = pagesQuery.getResultList();
+            infuseElements(pages);
+            if (pages != null)
+            {
+                Iterator pagesIter = pages.iterator();
+                while (pagesIter.hasNext())
+                {
+                    removePage((Page)pagesIter.next());
+                }
+            }
+
+            // remove links, query for links by parent
+            Query linksQuery = entityManager.createNamedQuery("FOLDER_LINKS");
+            linksQuery.setParameter("folder", folder);
+            Collection links = linksQuery.getResultList();
+            infuseElements(links);
+            if (links != null)
+            {
+                Iterator linksIter = links.iterator();
+                while (linksIter.hasNext())
+                {
+                    removeLink((Link)linksIter.next());
+                }
+            }
+
+            // remove page security, query for page security by parent
+            Query pageSecurityQuery = entityManager.createNamedQuery("FOLDER_PAGE_SECURITY");
+            pageSecurityQuery.setParameter("folder", folder);
+            try
+            {
+                PageSecurity pageSecurity = (PageSecurity)pageSecurityQuery.getSingleResult();            
+                infuseElement(pageSecurity);
+                removePageSecurity(pageSecurity);
+            }
+            catch (NoResultException nre)
+            {
+            }
+        }
+        catch (FolderNotRemovedException fnre)
+        {
+            throw fnre;
+        }
+        catch (SecurityException se)
+        {
+            throw se;
+        }
+        catch (Exception e)
+        {
+            throw new FolderNotRemovedException("Folder " + folder.getPath() + " not removed.", e);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#updateLink(org.apache.jetspeed.om.page.Link)
+     */
+    @Transactional (readOnly=false, rollbackFor=NodeException.class)
+    public void updateLink(Link link) throws NodeException, LinkNotUpdatedException
+    {
+        try
+        {
+            // look up and set parent folder if necessary
+            FolderImpl parent = (FolderImpl)link.getParent();
+            if (parent == null)
+            {
+                // access folder by path
+                String linkPath = link.getPath();
+                String parentPath = linkPath.substring(0, linkPath.lastIndexOf(Folder.PATH_SEPARATOR));
+                if (parentPath.length() == 0)
+                {
+                    parentPath = Folder.PATH_SEPARATOR;
+                }
+                try
+                {
+                    parent = (FolderImpl)getFolder(parentPath);
+                }
+                catch (FolderNotFoundException fnfe)
+                {
+                    throw new FailedToUpdateDocumentException("Missing parent folder: " + parentPath);
+                }
+                
+                // check for edit access on parent folder; link
+                // access not checked on create
+                parent.checkAccess(JetspeedActions.EDIT);
+
+                // store link object
+                link.setParent(parent);
+                persistElement(link);
+
+                // reset parent folder links cache
+                if (parent != null)
+                {
+                    parent.resetLinks(false);
+                }
+
+                // notify page manager listeners
+                delegator.notifyNewNode(link);
+            }
+            else
+            {
+                // check for edit access on link and parent folder
+                link.checkAccess(JetspeedActions.EDIT);
+
+                // update link object
+                persistElement(link);
+
+                // reset parent folder links cache in case
+                // parent is holding an out of date copy of
+                // this link that was removed from the cache
+                // before this one was accessed
+                if (parent != null)
+                {
+                    parent.resetLinks(false);
+                }
+
+                // notify page manager listeners
+                delegator.notifyUpdatedNode(link);
+            }
+        }
+        catch (FailedToUpdateDocumentException fude)
+        {
+            throw fude;
+        }
+        catch (SecurityException se)
+        {
+            throw se;
+        }
+        catch (Exception e)
+        {
+            throw new FailedToUpdateDocumentException("Link " + link.getPath() + " not updated.", e);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#removeLink(org.apache.jetspeed.om.page.Link)
+     */
+    @Transactional (readOnly=false, rollbackFor=NodeException.class)
+    public void removeLink(Link link) throws NodeException, LinkNotRemovedException
+    {
+        try
+        {
+            // check for edit access on link and parent folder
+            link.checkAccess(JetspeedActions.EDIT);
+
+            // look up and update parent folder if necessary
+            if (link.getParent() != null)
+            {
+                FolderImpl parent = (FolderImpl)link.getParent();
+
+                // delete link object
+                removeElement(link);
+
+                // reset parent folder links cache
+                if (parent != null)
+                {                
+                    parent.resetLinks(false);
+                }
+            }
+            else
+            {
+                // delete link object
+                removeElement(link);
+            }
+
+            // notify page manager listeners
+            delegator.notifyRemovedNode(link);
+        }
+        catch (SecurityException se)
+        {
+            throw se;
+        }
+        catch (Exception e)
+        {
+            throw new FailedToDeleteDocumentException("Link " + link.getPath() + " not removed.", e);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#updatePageSecurity(org.apache.jetspeed.om.page.PageSecurity)
+     */
+    @Transactional (readOnly=false, rollbackFor=NodeException.class)
+    public void updatePageSecurity(PageSecurity pageSecurity) throws NodeException, FailedToUpdateDocumentException
+    {
+        try
+        {
+            // look up and set parent folder if necessary
+            FolderImpl parent = (FolderImpl)pageSecurity.getParent();
+            if (parent == null)
+            {
+                // access folder by path
+                String pageSecurityPath = pageSecurity.getPath();
+                String parentPath = pageSecurityPath.substring(0, pageSecurityPath.lastIndexOf(Folder.PATH_SEPARATOR));
+                if (parentPath.length() == 0)
+                {
+                    parentPath = Folder.PATH_SEPARATOR;
+                }
+                try
+                {
+                    parent = (FolderImpl)getFolder(parentPath);
+                }
+                catch (FolderNotFoundException fnfe)
+                {
+                    throw new FailedToUpdateDocumentException("Missing parent folder: " + parentPath);
+                }
+
+                // do not replace existing page security documents
+                try
+                {
+                    parent.getPageSecurity();
+                    throw new FailedToUpdateDocumentException("Parent folder page security exists: " + parentPath);
+                }
+                catch (DocumentNotFoundException dnfe)
+                {
+                    // check for edit access on parent folder; document
+                    // access not checked on create
+                    parent.checkAccess(JetspeedActions.EDIT);
+                    
+                    // store page security object
+                    pageSecurity.setParent(parent);
+                    persistElement(pageSecurity);
+                    
+                    // reset parent folder page security cache
+                    if (parent != null)
+                    {                    
+                        parent.resetPageSecurity((PageSecurityImpl)pageSecurity, true);
+                    }
+                }
+                catch (Exception e)
+                {
+                    throw new FailedToUpdateDocumentException("Parent folder page security exists: " + parentPath);
+                }
+
+                // notify page manager listeners
+                delegator.notifyNewNode(pageSecurity);
+            }
+            else
+            {
+                // check for edit access on document and parent folder
+                pageSecurity.checkAccess(JetspeedActions.EDIT);
+
+                // update page security object
+                persistElement(pageSecurity);
+
+                // reset parent folder page security cache in case
+                // parent is holding an out of date copy of this
+                // page security that was removed from the cache
+                // before this one was accessed
+                if (parent != null)
+                {                
+                    parent.resetPageSecurity((PageSecurityImpl)pageSecurity, true);
+                }
+
+                // notify page manager listeners
+                delegator.notifyUpdatedNode(pageSecurity);
+            }
+
+            // reset all cached security constraints
+            resetCachedConstraintsVersion();
+        }
+        catch (FailedToUpdateDocumentException fude)
+        {
+            throw fude;
+        }
+        catch (SecurityException se)
+        {
+            throw se;
+        }
+        catch (Exception e)
+        {
+            throw new FailedToUpdateDocumentException("Document " + pageSecurity.getPath() + " not updated.", e);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#removePageSecurity(org.apache.jetspeed.om.page.PageSecurity)
+     */
+    @Transactional (readOnly=false, rollbackFor=NodeException.class)
+    public void removePageSecurity(PageSecurity pageSecurity) throws NodeException, FailedToDeleteDocumentException
+    {
+        try
+        {
+            // check for edit access on document and parent folder
+            pageSecurity.checkAccess(JetspeedActions.EDIT);
+
+            // look up and update parent folder if necessary
+            if (pageSecurity.getParent() != null)
+            {
+                FolderImpl parent = (FolderImpl)pageSecurity.getParent();
+
+                // delete page security object
+                removeElement(pageSecurity);
+
+                // reset parent folder page security cache
+                if (parent != null)
+                {                
+                    parent.resetPageSecurity(null, true);
+                }
+            }
+            else
+            {
+                // delete page security object
+                removeElement(pageSecurity);
+            }
+
+            // reset all cached security constraints
+            resetCachedConstraintsVersion();
+
+            // notify page manager listeners
+            delegator.notifyRemovedNode(pageSecurity);
+        }
+        catch (SecurityException se)
+        {
+            throw se;
+        }
+        catch (Exception e)
+        {
+            throw new FailedToDeleteDocumentException("Document " + pageSecurity.getPath() + " not removed.", e);
+        }
+    }
+    
+    /**
+     * Reset cached constraints version with monotonically
+     * increasing timestamp value; this has the effect of
+     * resetting cached constraints in all elements managed
+     * by this page manager.
+     */
+    private void resetCachedConstraintsVersion()
+    {
+        long now = System.currentTimeMillis();
+        cachedConstraintsVersion = ((now <= cachedConstraintsVersion) ? cachedConstraintsVersion+1 : now);        
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#copyPage(org.apache.jetspeed.om.page.Page,java.lang.String)
+     */
+    public Page copyPage(Page source, String path) throws NodeException, PageNotUpdatedException
+    {
+        return delegator.copyPage(source, path);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#copyLink(org.apache.jetspeed.om.page.Link,java.lang.String)
+     */
+    public Link copyLink(Link source, String path) throws NodeException, LinkNotUpdatedException
+    {
+        return delegator.copyLink(source, path);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#copyFolder(org.apache.jetspeed.om.folder.Folder,java.lang.String)
+     */
+    public Folder copyFolder(Folder source, String path) throws NodeException, PageNotUpdatedException
+    {
+        return delegator.copyFolder(source, path);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#copyFragment(org.apache.jetspeed.om.page.Fragment,java.lang.String)
+     */
+    public Fragment copyFragment(Fragment source, String name) throws NodeException, PageNotUpdatedException
+    {
+        return delegator.copyFragment(source, name);
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#copyPageSecurity(org.apache.jetspeed.om.page.PageSecurity)
+     */
+    public PageSecurity copyPageSecurity(PageSecurity source) throws NodeException
+    {
+        return delegator.copyPageSecurity(source);
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#getUserPage(java.lang.String,java.lang.String)
+     */
+    @Transactional (readOnly=true)
+    public Page getUserPage(String userName, String pageName) throws PageNotFoundException, NodeException
+    {
+        return getPage(Folder.USER_FOLDER + userName + Folder.PATH_SEPARATOR + pageName);
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#getUserFolder(java.lang.String)
+     */
+    @Transactional (readOnly=true)
+    public Folder getUserFolder(String userName) throws FolderNotFoundException, InvalidFolderException, NodeException
+    {
+        return getFolder(Folder.USER_FOLDER + userName);        
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#folderExists(java.lang.String)
+     */
+    @Transactional (readOnly=true)
+    public boolean folderExists(String folderName)
+    {
+        try
+        {
+            getFolder(folderName);
+        }
+        catch (Exception e)
+        {
+            return false;
+        }
+        return true;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#pageExists(java.lang.String)
+     */
+    @Transactional (readOnly=true)
+    public boolean pageExists(String pageName)
+    {
+        try
+        {
+            getPage(pageName);
+        }
+        catch (Exception e)
+        {
+            return false;
+        }
+        return true;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#linkExists(java.lang.String)
+     */
+    @Transactional (readOnly=true)
+    public boolean linkExists(String linkName)
+    {
+        try
+        {
+            getLink(linkName);
+        }
+        catch (Exception e)
+        {
+            return false;
+        }
+        return true;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#userFolderExists(java.lang.String)
+     */
+    @Transactional (readOnly=true)
+    public boolean userFolderExists(String userName)
+    {
+        try
+        {
+            getFolder(Folder.USER_FOLDER + userName);
+        }
+        catch (Exception e)
+        {
+            return false;
+        }
+        return true;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#userPageExists(java.lang.String)
+     */
+    @Transactional (readOnly=true)
+    public boolean userPageExists(String userName, String pageName)
+    {
+        try
+        {
+            getPage(Folder.USER_FOLDER + userName + Folder.PATH_SEPARATOR + pageName);
+        }
+        catch (Exception e)
+        {
+            return false;
+        }
+        return true;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#createUserHomePagesFromRoles(java.security.auth.Subject)
+     */
+    @Transactional (readOnly=false, rollbackFor=NodeException.class)
+    public void createUserHomePagesFromRoles(Subject subject) throws NodeException
+    {
+        PageManagerUtils.createUserHomePagesFromRoles(this, subject);
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#deepCopyFolder(org.apache.jetspeed.om.folder.Folder,java.lang.String,java.lang.String)
+     */
+    @Transactional (readOnly=false, rollbackFor=NodeException.class)
+    public void deepCopyFolder(Folder srcFolder, String destinationPath, String owner) throws NodeException, PageNotUpdatedException
+    {
+        PageManagerUtils.deepCopyFolder(this, srcFolder, destinationPath, owner);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#deepMergeFolder(org.apache.jetspeed.om.folder.Folder, java.lang.String, java.lang.String)
+     */
+    public void deepMergeFolder(Folder srcFolder, String destinationPath, String owner) throws NodeException, PageNotUpdatedException
+    {
+        PageManagerUtils.deepMergeFolder(this, srcFolder, destinationPath, owner);
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#addPages(org.apache.jetspeed.om.page.Page[])
+     */
+    @Transactional (readOnly=false, rollbackFor=NodeException.class)
+    public int addPages(Page[] pages) throws NodeException
+    {   
+        if (pages.length > 0 && pages[0].getPath().equals("/tx__test1.psml"))
+        {
+            // for tx testing
+            updatePage(pages[0]);
+            updatePage(pages[1]);
+            throw new NodeException("Its gonna blow captain!");
+        }
+        for (int ix = 0; ix < pages.length; ix++)
+        {
+            updatePage(pages[ix]);
+        }
+        return pages.length;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#isDistributed()
+     */
+    public boolean isDistributed()
+    {
+        // default JPA implementation not distributed
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#notifyUpdatedNode(org.apache.jetspeed.page.document.Node)
+     */
+    public void notifyUpdatedNode(Node node)
+    {
+        // notify page manager listeners
+        delegator.notifyUpdatedNode(node);
+    }
+    
+    /**
+     * Infuses page manager state into managed elements.
+     * 
+     * @param elements collection of managed elements to infuse.
+     */
+    private void infuseElements(Collection elements)
+    {
+        if (elements != null)
+        {
+            for (Iterator iter = elements.iterator(); iter.hasNext();)
+            {
+                infuseElement(iter.next());
+            }
+        }
+    }
+
+    /**
+     * Infuses page manager state into managed element.
+     * 
+     * @param element managed element to infuse.
+     */
+    private void infuseElement(Object element)
+    {
+        if (element != null)
+        {
+            // skip if previously infused
+            BaseElementImpl baseElement = (BaseElementImpl)element;
+            if (baseElement.getPageManager() != databasePageManagerProxy)
+            {
+                // infuse base element
+                baseElement.setPageManager(databasePageManagerProxy);
+                baseElement.setConstraintsEnabled(getConstraintsEnabled());
+                baseElement.setPermissionsEnabled(getPermissionsEnabled());
+                if (baseElement instanceof Node)
+                {
+                    // ensure parent nodes are infused
+                    infuseElement(((Node)baseElement).getParent());
+                }
+            }
+        }
+    }
+    
+    /**
+     * Persist element using current entity manager; attempt
+     * to merge/attach detached objects that may result from
+     * security or other exceptions that triggered a rollback
+     * on the entity manager.
+     * 
+     * @param element element to persist
+     */
+    private Object persistElement(Object element)
+    {
+        // get current entity manager
+        EntityManager entityManager = getEntityManager();
+        // persist, (potentially detached), element
+        BaseElementImpl baseElement = (BaseElementImpl)element;
+        if (!baseElement.isNew())
+        {
+            Object mergedElement = entityManager.merge(element);
+            if (mergedElement != element)
+            {
+                element = mergedElement;
+                infuseElement(element);
+            }
+        }
+        entityManager.persist(element);
+        // explicitly flush entity manager after update
+        entityManager.flush();
+        return element;
+    }
+
+    /**
+     * Remove element using current entity manager; attempt
+     * to merge/attach detached objects that may result from
+     * security or other exceptions that triggered a rollback
+     * on the entity manager.
+     * 
+     * @param element element to persist
+     */
+    private Object removeElement(Object element)
+    {
+        // get current entity manager
+        EntityManager entityManager = getEntityManager();
+        // remove, (potentially detached), element
+        BaseElementImpl baseElement = (BaseElementImpl)element;
+        if (!baseElement.isNew())
+        {
+            Object mergedElement = entityManager.merge(element);
+            if (mergedElement != element)
+            {
+                element = mergedElement;
+                infuseElement(element);
+            }
+        }
+        entityManager.remove(element);
+        // explicitly flush entity manager after update
+        entityManager.flush();
+        return element;
+    }
+}

Added: portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/page/jpa/DatabasePageManagerUtils.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/page/jpa/DatabasePageManagerUtils.java?rev=731466&view=auto
==============================================================================
--- portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/page/jpa/DatabasePageManagerUtils.java (added)
+++ portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/page/jpa/DatabasePageManagerUtils.java Sun Jan  4 22:04:13 2009
@@ -0,0 +1,42 @@
+/*
+ * 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.page.jpa;
+
+import java.util.Vector;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * DatabasePageManagerUtils
+ * 
+ * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
+ * @version $Id: $
+ */
+public class DatabasePageManagerUtils
+{
+    public static Collection createCollection()
+    {
+        // synchronized collection compatible with EntityManager.merge()
+        return new Vector();
+    }
+    
+    public static List createList()
+    {
+        // synchronized list compatible with EntityManager.merge()
+        return new Vector();
+    }
+}

Added: portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/page/jpa/OpenJPADatabasePageManagerImpl.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/page/jpa/OpenJPADatabasePageManagerImpl.java?rev=731466&view=auto
==============================================================================
--- portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/page/jpa/OpenJPADatabasePageManagerImpl.java (added)
+++ portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/page/jpa/OpenJPADatabasePageManagerImpl.java Sun Jan  4 22:04:13 2009
@@ -0,0 +1,132 @@
+/*
+ * 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.page.jpa;
+
+import javax.persistence.EntityExistsException;
+
+import org.apache.openjpa.conf.OpenJPAConfiguration;
+import org.apache.openjpa.event.RemoteCommitEvent;
+import org.apache.openjpa.event.RemoteCommitEventManager;
+import org.apache.openjpa.event.RemoteCommitListener;
+import org.apache.openjpa.event.RemoteCommitProvider;
+import org.apache.openjpa.event.SingleJVMRemoteCommitProvider;
+import org.apache.openjpa.persistence.EntityManagerImpl;
+
+/**
+ * OpenJPADatabasePageManagerImpl
+ * 
+ * @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
+ * @version $Id: $
+ */
+public class OpenJPADatabasePageManagerImpl extends DatabasePageManagerImpl
+{
+    private RemoteCommitEventManager openJPAEventManager;
+    private boolean distributed;
+    private RemoteCommitListener listener;
+    
+    /**
+     * Construct with permissions and constraints settings.
+     * 
+     * @param isPermissionsSecurity
+     * @param isConstraintsSecurity
+     */
+    public OpenJPADatabasePageManagerImpl(boolean isPermissionsSecurity, boolean isConstraintsSecurity)
+    {
+        super(isPermissionsSecurity, isConstraintsSecurity);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.PageManager#isDistributed()
+     */
+    public boolean isDistributed()
+    {
+        return distributed;
+    }
+    
+    /**
+     * Initialize by registering an event listener.
+     */
+    public void initialize()
+    {
+        // get OpenJPA entity manager and event manager
+        EntityManagerImpl openJPAEntityManager = (EntityManagerImpl)getEntityManager().getDelegate();
+        if (openJPAEntityManager != null)
+        {
+            // check OpenJPA configuration for distributed operation
+            OpenJPAConfiguration configuration = openJPAEntityManager.getConfiguration();
+            openJPAEventManager = configuration.getRemoteCommitEventManager();
+            if (openJPAEventManager.areRemoteEventsEnabled())
+            {
+                RemoteCommitProvider provider = openJPAEventManager.getRemoteCommitProvider();
+                distributed = ((provider != null) && !(provider instanceof SingleJVMRemoteCommitProvider));
+            }
+        }
+        // register remote listener for distributed operation
+        if ((openJPAEventManager != null) && distributed)
+        {
+            listener = new RemoteCommitListener()
+            {
+                /* (non-Javadoc)
+                 * @see org.apache.openjpa.event.RemoteCommitListener#afterCommit(org.apache.openjpa.event.RemoteCommitEvent)
+                 */
+                public void afterCommit(RemoteCommitEvent event)
+                {
+                    switch (event.getPayloadType())
+                    {
+                        case RemoteCommitEvent.PAYLOAD_EXTENTS :
+                        case RemoteCommitEvent.PAYLOAD_OIDS :
+                        case RemoteCommitEvent.PAYLOAD_OIDS_WITH_ADDS :
+                        {
+                            // node instance not generally available or worth
+                            // creating transactional scope to lookup from oids:
+                            // notify page manager listeners with unspecified
+                            // updated node
+                            notifyUpdatedNode(null);
+                        }
+                        break;
+                        case RemoteCommitEvent.PAYLOAD_LOCAL_STALE_DETECTION :
+                        default :
+                        {
+                            // ignore local or unknown payloads.
+                        }
+                        break;
+                    }
+                }
+
+                /* (non-Javadoc)
+                 * @see org.apache.openjpa.event.RemoteCommitListener#close()
+                 */
+                public void close()
+                {
+                }                
+            };
+            openJPAEventManager.addListener(listener);
+        }
+    }
+
+    /**
+     * Terminate by unregistering the event listener.
+     */
+    public void terminate()
+    {
+        // unregister remote listener for distributed operation
+        if ((openJPAEventManager != null) && distributed && (listener != null))
+        {
+            openJPAEventManager.removeListener(listener);
+        }
+    }    
+}

Added: portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/page/jpa/OpenJPADatabasePageManagerProperties.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/page/jpa/OpenJPADatabasePageManagerProperties.java?rev=731466&view=auto
==============================================================================
--- portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/page/jpa/OpenJPADatabasePageManagerProperties.java (added)
+++ portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/page/jpa/OpenJPADatabasePageManagerProperties.java Sun Jan  4 22:04:13 2009
@@ -0,0 +1,78 @@
+/*
+ * 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.page.jpa;
+
+import org.apache.jetspeed.components.rdbms.jpa.OpenJPAConfigurationProperties;
+
+/**
+ * OpenJPADatabasePageManagerProperties
+ * 
+ * @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
+ * @version $Id: $
+ */
+public class OpenJPADatabasePageManagerProperties extends OpenJPAConfigurationProperties
+{
+    private static final long serialVersionUID = 6838501896860524641L;
+
+    // Constants
+    
+    public static final String PAGE_MANAGER_CACHE_SIZE_LEGACY_PROP_NAME = "db.page.manager.cache.size";
+    public static final String PAGE_MANAGER_CACHE_TIMEOUT_LEGACY_PROP_NAME = "db.page.manager.cache.expire";    
+    
+    // Singleton implementation
+    
+    private static OpenJPADatabasePageManagerProperties instance;
+    
+    public static OpenJPADatabasePageManagerProperties getInstance(final String cachePort, final String cacheAddresses)
+    {
+        // construct and return a default instance
+        if (instance == null)
+        {
+            instance = new OpenJPADatabasePageManagerProperties();
+            instance.setCachePort(cachePort);
+            instance.setCacheAddresses(cacheAddresses);
+            instance.afterPropertiesSet();
+        }
+        return instance;
+    }
+    
+    // OpenJPAConfigurationProperties implementation
+    
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.components.rdbms.jpa.OpenJPAConfigurationProperties#defaultCacheSizePropertyName()
+     */
+    protected String defaultCacheSizePropertyName()
+    {
+        return PAGE_MANAGER_CACHE_SIZE_LEGACY_PROP_NAME;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.components.rdbms.jpa.OpenJPAConfigurationProperties#defaultCacheTimeoutPropertyName()
+     */
+    protected String defaultCacheTimeoutPropertyName()
+    {
+        return PAGE_MANAGER_CACHE_TIMEOUT_LEGACY_PROP_NAME;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.components.rdbms.jpa.OpenJPAConfigurationProperties#defaultQueryCacheSizePropertyName()
+     */
+    protected String defaultQueryCacheSizePropertyName()
+    {
+        return PAGE_MANAGER_CACHE_SIZE_LEGACY_PROP_NAME;
+    }
+}

Modified: portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/page/psml/CastorXmlPageManager.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/page/psml/CastorXmlPageManager.java?rev=731466&r1=731465&r2=731466&view=diff
==============================================================================
--- portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/page/psml/CastorXmlPageManager.java (original)
+++ portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/page/psml/CastorXmlPageManager.java Sun Jan  4 22:04:13 2009
@@ -52,7 +52,7 @@
 import org.apache.jetspeed.om.page.psml.PageImpl;
 import org.apache.jetspeed.om.page.psml.PageSecurityImpl;
 import org.apache.jetspeed.om.page.psml.SecurityConstraintsDefImpl;
-import org.apache.jetspeed.om.page.psml.SecurityConstraintsImpl;
+import org.apache.jetspeed.om.page.psml.SecurityConstraintsContextImpl;
 import org.apache.jetspeed.page.AbstractPageManager;
 import org.apache.jetspeed.page.FolderNotUpdatedException;
 import org.apache.jetspeed.page.PageManager;
@@ -100,7 +100,7 @@
         modelClasses.put("PageMenuIncludeDefinitionImpl", MenuIncludeDefinitionImpl.class);
         modelClasses.put("PageMenuOptionsDefinitionImpl", MenuOptionsDefinitionImpl.class);
         modelClasses.put("PageMenuSeparatorDefinitionImpl", MenuSeparatorDefinitionImpl.class);
-        modelClasses.put("SecurityConstraintsImpl", SecurityConstraintsImpl.class);
+        modelClasses.put("SecurityConstraintsContextImpl", SecurityConstraintsContextImpl.class);
         modelClasses.put("FolderSecurityConstraintImpl", SecurityConstraintImpl.class);
         modelClasses.put("PageSecurityConstraintImpl", SecurityConstraintImpl.class);
         modelClasses.put("FragmentSecurityConstraintImpl", SecurityConstraintImpl.class);



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


Mime
View raw message