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/05 07:04:18 UTC

svn commit: r731466 [6/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/ com...

Added: portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/jpa/LinkImpl.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/jpa/LinkImpl.java?rev=731466&view=auto
==============================================================================
--- portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/jpa/LinkImpl.java (added)
+++ portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/jpa/LinkImpl.java Sun Jan  4 22:04:13 2009
@@ -0,0 +1,399 @@
+/*
+ * 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.om.page.jpa;
+
+import java.util.Collection;
+import java.util.List;
+
+import javax.persistence.AttributeOverride;
+import javax.persistence.AttributeOverrides;
+import javax.persistence.Basic;
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.NamedQuery;
+import javax.persistence.NamedQueries;
+import javax.persistence.OneToMany;
+import javax.persistence.OrderBy;
+import javax.persistence.PostLoad;
+import javax.persistence.Table;
+
+import org.apache.jetspeed.om.folder.jpa.FolderImpl;
+import org.apache.jetspeed.om.common.SecurityConstraint;
+import org.apache.jetspeed.om.common.SecurityConstraintsContext;
+import org.apache.jetspeed.om.page.Link;
+import org.apache.jetspeed.om.page.PageMetadataImpl;
+import org.apache.jetspeed.page.document.Node;
+import org.apache.jetspeed.page.document.jpa.DocumentImpl;
+import org.apache.jetspeed.page.jpa.DatabasePageManagerUtils;
+
+/**
+ * LinkImpl
+ *
+ * @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
+ * @version $Id$
+ */
+@Entity (name="Link")
+@Inheritance (strategy=InheritanceType.TABLE_PER_CLASS)
+@Table (name="LINK")
+@AttributeOverrides ({@AttributeOverride (name="id", column=@Column(name="LINK_ID"))})
+@NamedQueries({@NamedQuery(name="FOLDER_LINKS", query="select l from Link l where l.parent = :folder"),
+               @NamedQuery(name="LINK", query="select l from Link l where l.path = :path")})
+public class LinkImpl extends DocumentImpl implements Link
+{
+    @Basic
+    @Column (name="TITLE")
+    private String title;
+    @Basic
+    @Column (name="SHORT_TITLE")
+    private String shortTitle;
+    @Basic
+    @Column (name="IS_HIDDEN")
+    private boolean hidden;
+
+    @ManyToOne (targetEntity=FolderImpl.class, fetch=FetchType.LAZY, optional=true, cascade=CascadeType.PERSIST)
+    @JoinColumn (name="PARENT_ID", referencedColumnName="FOLDER_ID")
+    private FolderImpl parent;
+    @OneToMany (targetEntity=LinkMetadataLocalizedFieldImpl.class, mappedBy="link", fetch=FetchType.LAZY, cascade=CascadeType.ALL)
+    private Collection metadataFields;
+    @Basic
+    @Column (name="SKIN")
+    private String skin;
+    @Basic
+    @Column (name="TARGET")
+    private String target;
+    @Basic
+    @Column (name="URL")
+    private String url;
+
+    @PostLoad
+    private void eagerFetchCollections()
+    {
+        if (metadataFields != null)
+        {
+            metadataFields.size();
+        }
+        eagerFetchEmbeddedCollections();
+    }
+
+    /**
+     * Default constructor.
+     */
+    public LinkImpl()
+    {
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.common.SecuredResource#newSecurityConstraintsContext()
+     */
+    public SecurityConstraintsContext newSecurityConstraintsContext()
+    {
+        // return generic security constraints context instance
+        // since the context is embedded in this, (see below).
+        return new GenericSecurityConstraintsContextImpl();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.common.SecuredResource#newSecurityConstraint()
+     */
+    public SecurityConstraint newSecurityConstraint()
+    {
+        // return constraints specific security constraint instance
+        return new LinkSecurityConstraintImpl();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.document.jpa.NodeImpl#getMetadataFields()
+     */
+    protected Collection getMetadataFields()
+    {
+        // create initial collection if necessary
+        if (metadataFields == null)
+        {
+            metadataFields = DatabasePageManagerUtils.createList();
+        }
+        // wrap collection to maintain JPA inverse relationships
+        return new MetadataLocalizedFieldCollection(this, metadataFields);        
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.document.jpa.NodeImpl#getParentNode()
+     */
+    protected Node getParentNode()
+    {
+        return parent;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.document.jpa.NodeImpl#setParentNode(org.apache.jetspeed.page.document.Node)
+     */
+    protected void setParentNode(Node parent)
+    {
+        this.parent = (FolderImpl)parent;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.jpa.BaseElementImpl#accessSecurityConstraintsContext()
+     */
+    protected SecurityConstraintsContextImpl accessSecurityConstraintsContext()
+    {
+        // return this since the context is embedded in this, (see below).
+        return this;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.document.jpa.NodeImpl#newPageMetadata(java.util.Collection)
+     */
+    public PageMetadataImpl newPageMetadata(Collection fields)
+    {
+        PageMetadataImpl pageMetadata = new PageMetadataImpl(LinkMetadataLocalizedFieldImpl.class);
+        pageMetadata.setFields(fields);
+        return pageMetadata;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.jpa.BaseElementImpl#grantViewActionAccess()
+     */
+    public boolean grantViewActionAccess()
+    {
+        // always allow links that reference absolute urls since these
+        // are probably not a security related concern but rather
+        // should always be viewable, (subject to folder access)
+        String hrefUrl = getUrl();
+        return ((hrefUrl != null) && (hrefUrl.startsWith("http://") || hrefUrl.startsWith("https://")));
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.document.Node#getUrl()
+     */
+    public String getUrl()
+    {
+        return url;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.Link#setUrl(java.lang.String)
+     */
+    public void setUrl(String url)
+    {
+        this.url = url;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.Link#getSkin()
+     */
+    public String getSkin()
+    {
+        return skin;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.Link#setSkin(java.lang.String)
+     */
+    public void setSkin(String skin)
+    {
+        this.skin = skin;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.Link#getTarget()
+     */
+    public String getTarget()
+    {
+        return target;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.Link#setTarget(java.lang.String)
+     */
+    public void setTarget(String target)
+    {
+        this.target = target;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.document.Node#getType()
+     */
+    public String getType()
+    {
+        return DOCUMENT_TYPE;
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.BaseElement#getTitle()
+     */
+    public String getTitle()
+    {
+        // default title to link name
+        if (title == null)
+        {
+            title = defaultTitleFromName();
+        }
+        return title;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.BaseElement#setTitle(java.lang.String)
+     */
+    public void setTitle(String title)
+    {
+        this.title = title;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.BaseElement#getShortTitle()
+     */
+    public String getShortTitle()
+    {
+        return shortTitle;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.BaseElement#setShortTitle(java.lang.String)
+     */
+    public void setShortTitle(String shortTitle)
+    {
+        this.shortTitle = shortTitle;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.document.Node#isHidden()
+     */
+    public boolean isHidden()
+    {
+        return hidden;
+    }    
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.document.Node#setHidden(boolean)
+     */
+    public void setHidden(boolean hidden)
+    {
+        this.hidden = hidden;
+    }    
+
+    // **************************************************************************
+    // Begin Embedded SecurityConstraintsContextImpl
+    //
+    // Embeddable/Embedded with relationships not supported in JPA 1.0;
+    // otherwise, this should have been implemented as an embedded type
+    // derived from SecurityConstraintsContextImpl. Instead, BaseElementImpl
+    // derives from SecurityConstraintsContextImpl and the context
+    // protocol is implemented on this object.
+
+    @Basic
+    @Column (name="OWNER_PRINCIPAL")
+    private String owner;
+    @OneToMany (targetEntity=LinkSecurityConstraintImpl.class, mappedBy="link", fetch=FetchType.LAZY, cascade=CascadeType.ALL)
+    @OrderBy (value="applyOrder ASC")
+    private List constraints;
+    @OneToMany (targetEntity=LinkSecurityConstraintsRef.class, mappedBy="link", fetch=FetchType.LAZY, cascade=CascadeType.ALL)
+    @OrderBy (value="applyOrder ASC")
+    private List constraintsRefs;
+
+    private void eagerFetchEmbeddedCollections()
+    {
+        if (constraints != null)
+        {
+            constraints.size();
+        }
+        if (constraintsRefs != null)
+        {
+            constraintsRefs.size();
+        }
+    }    
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.common.SecurityConstraints#getOwner()
+     */
+    public String getOwner()
+    {
+        return owner;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.common.SecurityConstraints#setOwner(java.lang.String)
+     */
+    public void setOwner(String owner)
+    {
+        // save new setting and reset cached security constraints
+        this.owner = owner;
+        clearAllSecurityConstraints();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.jpa.SecurityConstraintsContextImpl#accessConstraintsRefs()
+     */
+    protected List accessConstraintsRefs()
+    {
+        // create initial collection if necessary
+        if (constraintsRefs == null)
+        {
+            constraintsRefs = DatabasePageManagerUtils.createList();
+        }
+        return constraintsRefs;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.jpa.SecurityConstraintsContextImpl#accessConstraints()
+     */
+    protected List accessConstraints()
+    {
+        // create initial collection if necessary
+        if (constraints == null)
+        {
+            constraints = DatabasePageManagerUtils.createList();
+        }
+        return constraints;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.jpa.SecurityConstraintsContextImpl#getSecurityConstraintClass()
+     */
+    protected Class getSecurityConstraintClass()
+    {
+        return LinkSecurityConstraintImpl.class;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.jpa.SecurityConstraintsContextImpl#getSecurityConstraintsRefClass()
+     */
+    protected Class getSecurityConstraintsRefClass()
+    {
+        return LinkSecurityConstraintsRef.class;        
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.common.SecurityConstraints#isEmpty()
+     */
+    public boolean isEmpty()
+    {
+        // test only persistent members for any specified constraints
+        return ((owner == null) &&
+                ((constraints == null) || constraints.isEmpty()) &&
+                ((constraintsRefs == null) || constraintsRefs.isEmpty()));
+    }
+
+    // End Embedded SecurityConstraintsContextImpl
+    // **************************************************************************
+}

Added: portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/jpa/LinkMetadataLocalizedFieldImpl.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/jpa/LinkMetadataLocalizedFieldImpl.java?rev=731466&view=auto
==============================================================================
--- portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/jpa/LinkMetadataLocalizedFieldImpl.java (added)
+++ portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/jpa/LinkMetadataLocalizedFieldImpl.java Sun Jan  4 22:04:13 2009
@@ -0,0 +1,51 @@
+/*
+ * 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.om.page.jpa;
+
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+
+/**
+ * LinkMetadataLocalizedFieldImpl
+ *
+ * @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
+ * @version $Id$
+ */
+@Entity (name="LinkMetadata")
+@Inheritance (strategy=InheritanceType.TABLE_PER_CLASS)
+@Table (name="LINK_METADATA")
+public class LinkMetadataLocalizedFieldImpl extends BaseMetadataLocalizedFieldImpl
+{
+    // new class defined only to facilitate JPA table/class mapping
+
+    @ManyToOne (targetEntity=LinkImpl.class, fetch=FetchType.LAZY, optional=false)
+    @JoinColumn (name="LINK_ID", referencedColumnName="LINK_ID")
+    private LinkImpl link;
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.jpa.BaseMetadataLocalizedFieldImpl#setInverseRelationship(java.lang.Object)
+     */
+    public void setInverseRelationship(Object inverse)
+    {
+        link = (LinkImpl)inverse;
+    }
+}

Added: portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/jpa/LinkSecurityConstraintImpl.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/jpa/LinkSecurityConstraintImpl.java?rev=731466&view=auto
==============================================================================
--- portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/jpa/LinkSecurityConstraintImpl.java (added)
+++ portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/jpa/LinkSecurityConstraintImpl.java Sun Jan  4 22:04:13 2009
@@ -0,0 +1,55 @@
+/*
+ * 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.om.page.jpa;
+
+import javax.persistence.AttributeOverride;
+import javax.persistence.AttributeOverrides;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+
+/**
+ * LinkSecurityConstraintImpl
+ *
+ * @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
+ * @version $Id$
+ */
+@Entity (name="LinkConstraint")
+@Inheritance (strategy=InheritanceType.TABLE_PER_CLASS)
+@Table (name="LINK_CONSTRAINT")
+@AttributeOverrides ({@AttributeOverride (name="id", column=@Column(name="CONSTRAINT_ID"))})
+public class LinkSecurityConstraintImpl extends BaseSecurityConstraintImpl
+{
+    // new class defined only to facilitate JPA table/class mapping
+
+    @ManyToOne (targetEntity=LinkImpl.class, fetch=FetchType.LAZY, optional=false)
+    @JoinColumn (name="LINK_ID", referencedColumnName="LINK_ID")
+    private LinkImpl link;
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.jpa.BaseSecurityConstraintImpl#setInverseRelationship(java.lang.Object)
+     */
+    public void setInverseRelationship(Object inverse)
+    {
+        link = (LinkImpl)inverse;
+    }
+}

Added: portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/jpa/LinkSecurityConstraintsRef.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/jpa/LinkSecurityConstraintsRef.java?rev=731466&view=auto
==============================================================================
--- portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/jpa/LinkSecurityConstraintsRef.java (added)
+++ portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/jpa/LinkSecurityConstraintsRef.java Sun Jan  4 22:04:13 2009
@@ -0,0 +1,55 @@
+/*
+ * 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.om.page.jpa;
+
+import javax.persistence.AttributeOverride;
+import javax.persistence.AttributeOverrides;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+
+/**
+ * LinkSecurityConstraintsRef
+ *
+ * @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
+ * @version $Id$
+ */
+@Entity (name="LinkConstraintsRef")
+@Inheritance (strategy=InheritanceType.TABLE_PER_CLASS)
+@Table (name="LINK_CONSTRAINTS_REF")
+@AttributeOverrides ({@AttributeOverride (name="id", column=@Column(name="CONSTRAINTS_REF_ID"))})
+public class LinkSecurityConstraintsRef extends BaseSecurityConstraintsRef
+{
+    // new class defined only to facilitate JPA table/class mapping
+
+    @ManyToOne (targetEntity=LinkImpl.class, fetch=FetchType.LAZY, optional=false)
+    @JoinColumn (name="LINK_ID", referencedColumnName="LINK_ID")
+    private LinkImpl link;
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.jpa.BaseSecurityConstraintsRef#setInverseRelationship(java.lang.Object)
+     */
+    public void setInverseRelationship(Object inverse)
+    {
+        link = (LinkImpl)inverse;
+    }
+}

Added: portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/jpa/MetadataLocalizedFieldCollection.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/jpa/MetadataLocalizedFieldCollection.java?rev=731466&view=auto
==============================================================================
--- portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/jpa/MetadataLocalizedFieldCollection.java (added)
+++ portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/jpa/MetadataLocalizedFieldCollection.java Sun Jan  4 22:04:13 2009
@@ -0,0 +1,116 @@
+/*
+ * 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.om.page.jpa;
+
+import java.util.AbstractCollection;
+import java.util.Collection;
+import java.util.Iterator;
+
+/**
+ * MetadataLocalizedFieldCollection
+ *
+ * @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
+ * @version $Id$
+ */
+public class MetadataLocalizedFieldCollection extends AbstractCollection
+{
+    private Object owningObject;
+    private Collection collection;
+
+    /**
+     * Construct localized field wrapper collection to maintain JPA inverse relationship.
+     * 
+     * @param owningObject owning object.
+     * @param collection collection of localized field objects.
+     */
+    public MetadataLocalizedFieldCollection(Object owningObject, Collection collection)
+    {
+        super();
+        this.owningObject = owningObject;
+        this.collection = collection;
+    }
+
+    /* (non-Javadoc)
+     * @see java.util.AbstractCollection#add(java.lang.Object)
+     */
+    public boolean add(Object element)
+    {
+        BaseMetadataLocalizedFieldImpl field = (BaseMetadataLocalizedFieldImpl)element;
+        field.setInverseRelationship(owningObject);
+        return collection.add(element);
+    }
+
+    /* (non-Javadoc)
+     * @see java.util.AbstractCollection#iterator()
+     */
+    public Iterator iterator()
+    {
+        return new Iterator()
+        {
+            private Iterator iter = collection.iterator();
+            private Object lastNext = null;
+
+            /* (non-Javadoc)
+             * @see java.util.Iterator#hasNext()
+             */
+            public boolean hasNext()
+            {
+                return iter.hasNext();
+            }
+
+            /* (non-Javadoc)
+             * @see java.util.Iterator#next()
+             */
+            public Object next()
+            {
+                return lastNext = iter.next();
+            }
+
+            /* (non-Javadoc)
+             * @see java.util.Iterator#remove()
+             */
+            public void remove()
+            {
+                iter.remove();
+                BaseMetadataLocalizedFieldImpl field = (BaseMetadataLocalizedFieldImpl)lastNext;
+                field.setInverseRelationship(null);
+            }            
+        };
+    }
+
+    /* (non-Javadoc)
+     * @see java.util.AbstractCollection#remove(java.lang.Object)
+     */
+    public boolean remove(Object element)
+    {
+        BaseMetadataLocalizedFieldImpl field = (BaseMetadataLocalizedFieldImpl)element;
+        if (collection.remove(field))
+        {
+            field.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-page-manager/src/main/java/org/apache/jetspeed/om/page/jpa/PageBaseMenuDefinitionElement.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/jpa/PageBaseMenuDefinitionElement.java?rev=731466&view=auto
==============================================================================
--- portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/jpa/PageBaseMenuDefinitionElement.java (added)
+++ portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/jpa/PageBaseMenuDefinitionElement.java Sun Jan  4 22:04:13 2009
@@ -0,0 +1,91 @@
+/*
+ * 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.om.page.jpa;
+
+import javax.persistence.Basic;
+import javax.persistence.Column;
+import javax.persistence.DiscriminatorColumn;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import javax.persistence.Version;
+
+/**
+ * PageBaseMenuDefinitionElement
+ * 
+ * @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
+ * @version $Id:$
+ */
+@Entity
+@Inheritance (strategy=InheritanceType.SINGLE_TABLE)
+@Table (name="PAGE_MENU")
+@DiscriminatorColumn (name="CLASS_NAME")
+public abstract class PageBaseMenuDefinitionElement
+{
+    @Id
+    @GeneratedValue (strategy=GenerationType.AUTO)
+    @Column (name="MENU_ID")
+    private int id;
+    @Version
+    @Column (name="JPA_VERSION")
+    private int jpaVersion;
+    @ManyToOne (targetEntity=PageMenuDefinitionImpl.class, fetch=FetchType.LAZY, optional=true)
+    @JoinColumn (name="PARENT_ID", referencedColumnName="MENU_ID")
+    private PageMenuDefinitionImpl parent;
+    @Basic
+    @Column (name="ELEMENT_ORDER")
+    private int elementOrder;    
+
+    /**
+     * Explicitly set inverse relationship when this object
+     * is added to a one-to-many collection. JPA does not
+     * manage bidirectional relationships.
+     * 
+     * @param inverse inverse relationship owning object.
+     */
+    public void setInverseRelationship(Object inverse)
+    {
+        parent = (PageMenuDefinitionImpl)inverse;
+    }
+    
+    /**
+     * getElementOrder
+     *
+     * @return element order
+     */
+    public int getElementOrder()
+    {
+        return elementOrder;
+    }
+
+    /**
+     * setElementOrder
+     *
+     * @param order element order
+     */
+    public void setElementOrder(int order)
+    {
+        elementOrder = order;
+    }
+}

Added: portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/jpa/PageBaseMenuDefinitionMetadata.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/jpa/PageBaseMenuDefinitionMetadata.java?rev=731466&view=auto
==============================================================================
--- portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/jpa/PageBaseMenuDefinitionMetadata.java (added)
+++ portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/jpa/PageBaseMenuDefinitionMetadata.java Sun Jan  4 22:04:13 2009
@@ -0,0 +1,182 @@
+/*
+ * 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.om.page.jpa;
+
+import java.util.Collection;
+import java.util.Locale;
+
+import javax.persistence.CascadeType;
+import javax.persistence.DiscriminatorColumn;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.OneToMany;
+import javax.persistence.PostLoad;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+
+import org.apache.jetspeed.om.page.PageMetadataImpl;
+import org.apache.jetspeed.om.portlet.GenericMetadata;
+import org.apache.jetspeed.page.impl.DatabasePageManagerUtils;
+
+/**
+ * PageBaseMenuDefinitionMetadata
+ * 
+ * @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
+ * @version $Id:$
+ */
+@Entity
+@Inheritance (strategy=InheritanceType.SINGLE_TABLE)
+@Table (name="PAGE_MENU")
+@DiscriminatorColumn (name="CLASS_NAME")
+public abstract class PageBaseMenuDefinitionMetadata extends PageBaseMenuDefinitionElement 
+{
+    @OneToMany (targetEntity=PageMenuMetadataLocalizedFieldImpl.class, mappedBy="menu", fetch=FetchType.LAZY, cascade=CascadeType.ALL)
+    private Collection metadataFields;
+
+    @PostLoad
+    private void eagerFetchCollections()
+    {
+        if (metadataFields != null)
+        {
+            metadataFields.size();
+        }
+    }
+
+    @Transient
+    private PageMetadataImpl pageMetadata;
+
+    /**
+     * newPageMetadata
+     *
+     * Construct page manager specific metadata implementation.
+     *
+     * @param fields mutable fields collection
+     * @return page metadata
+     */
+    public abstract PageMetadataImpl newPageMetadata(Collection fields);
+
+    /**
+     * getPageMetadata
+     *
+     * Get page manager specific metadata implementation.
+     *
+     * @return page metadata
+     */
+    public PageMetadataImpl getPageMetadata()
+    {
+        if (pageMetadata == null)
+        {
+            if (metadataFields == null)
+            {
+                metadataFields = DatabasePageManagerUtils.createList();
+            }
+            pageMetadata = newPageMetadata(new MetadataLocalizedFieldCollection(this, metadataFields));
+        }
+        return pageMetadata;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.folder.MenuDefinition#getTitle()
+     * @see org.apache.jetspeed.om.folder.MenuSeparatorDefinition#getTitle()
+     */
+    public String getTitle()
+    {
+        // no title available by default
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.folder.MenuDefinition#getShortTitle()
+     */
+    public String getShortTitle()
+    {
+        // no short title available by default
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.folder.MenuSeparatorDefinition#getText()
+     */
+    public String getText()
+    {
+        // no text available by default
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.folder.MenuDefinition#getTitle(java.util.Locale)
+     * @see org.apache.jetspeed.om.folder.MenuSeparatorDefinition#getTitle(java.util.Locale)
+     */
+    public String getTitle(Locale locale)
+    {
+        // get title from metadata or use default title
+        String title = getPageMetadata().getText("title", locale);
+        if (title == null)
+        {
+            title = getTitle();
+        }
+        return title;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.folder.MenuDefinition#getShortTitle(java.util.Locale)
+     */
+    public String getShortTitle(Locale locale)
+    {
+        // get short title from metadata or use title from metadata,
+        // default short title, or default title
+        String shortTitle = getPageMetadata().getText("short-title", locale);
+        if (shortTitle == null)
+        {
+            shortTitle = getPageMetadata().getText("title", locale);
+            if (shortTitle == null)
+            {
+                shortTitle = getShortTitle();
+                if (shortTitle == null)
+                {
+                    shortTitle = getTitle();
+                }
+            }
+        }
+        return shortTitle;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.folder.MenuSeparatorDefinition#getText(java.util.Locale)
+     */
+    public String getText(Locale locale)
+    {
+        // get title from metadata or use default title
+        String text = getPageMetadata().getText("text", locale);
+        if (text == null)
+        {
+            text = getText();
+        }
+        return text;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.folder.MenuDefinition#getMetadata()
+     * @see org.apache.jetspeed.om.folder.MenuSeparatorDefinition#getMetadata()
+     */
+    public GenericMetadata getMetadata()
+    {
+        return getPageMetadata();
+    }
+}

Added: portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/jpa/PageImpl.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/jpa/PageImpl.java?rev=731466&view=auto
==============================================================================
--- portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/jpa/PageImpl.java (added)
+++ portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/jpa/PageImpl.java Sun Jan  4 22:04:13 2009
@@ -0,0 +1,734 @@
+/*
+ * 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.om.page.jpa;
+
+import java.util.Collection;
+import java.util.List;
+
+import javax.persistence.AttributeOverride;
+import javax.persistence.AttributeOverrides;
+import javax.persistence.Basic;
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.NamedQuery;
+import javax.persistence.NamedQueries;
+import javax.persistence.OneToMany;
+import javax.persistence.OrderBy;
+import javax.persistence.PostLoad;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+
+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.jpa.FolderImpl;
+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.page.Fragment;
+import org.apache.jetspeed.om.page.Page;
+import org.apache.jetspeed.om.page.PageMetadataImpl;
+import org.apache.jetspeed.page.document.Node;
+import org.apache.jetspeed.page.document.jpa.DocumentImpl;
+import org.apache.jetspeed.page.jpa.DatabasePageManager;
+import org.apache.jetspeed.page.jpa.DatabasePageManagerUtils;
+
+/**
+ * PageImpl
+ *
+ * @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
+ * @version $Id$
+ */
+@Entity (name="Page")
+@Inheritance (strategy=InheritanceType.TABLE_PER_CLASS)
+@Table (name="PAGE")
+@AttributeOverrides ({@AttributeOverride (name="id", column=@Column(name="PAGE_ID"))})
+@NamedQueries({@NamedQuery(name="FOLDER_PAGES", query="select p from Page p where p.parent = :folder"),
+               @NamedQuery(name="PAGE", query="select p from Page p where p.path = :path")})
+public class PageImpl extends DocumentImpl implements Page
+{
+    @Basic
+    @Column (name="TITLE")
+    private String title;
+    @Basic
+    @Column (name="SHORT_TITLE")
+    private String shortTitle;
+    @Basic
+    @Column (name="IS_HIDDEN")
+    private boolean hidden;
+
+    @ManyToOne (targetEntity=FolderImpl.class, fetch=FetchType.LAZY, optional=true, cascade=CascadeType.PERSIST)
+    @JoinColumn (name="PARENT_ID", referencedColumnName="FOLDER_ID")
+    private FolderImpl parent;
+    @OneToMany (targetEntity=PageMetadataLocalizedFieldImpl.class, mappedBy="page", fetch=FetchType.LAZY, cascade=CascadeType.ALL)
+    private Collection metadataFields;
+    @OneToMany (targetEntity=FragmentImpl.class, mappedBy="page", fetch=FetchType.LAZY, cascade=CascadeType.ALL)
+    private Collection fragment;
+    @Basic
+    @Column (name="SKIN")
+    private String skin;
+    @Basic
+    @Column (name="DEFAULT_LAYOUT_DECORATOR")
+    private String defaultLayoutDecorator;
+    @Basic
+    @Column (name="DEFAULT_PORTLET_DECORATOR")
+    private String defaultPortletDecorator;
+    @OneToMany (targetEntity=PageMenuDefinitionImpl.class, mappedBy="page", fetch=FetchType.LAZY, cascade=CascadeType.ALL)
+    @OrderBy (value="name ASC")
+    private List menus;
+
+    @PostLoad
+    private void eagerFetchCollections()
+    {
+        if (metadataFields != null)
+        {
+            metadataFields.size();
+        }
+        if (fragment != null)
+        {
+            fragment.size();
+        }
+        if (menus != null)
+        {
+            menus.size();
+        }
+        eagerFetchEmbeddedCollections();
+    }
+
+    @Transient
+    private PageMenuDefinitionList menuDefinitions;
+    @Transient
+    private FragmentImpl removedFragment;
+
+    /**
+     * Default constructor.
+     */
+    public PageImpl()
+    {
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.common.SecuredResource#newSecurityConstraintsContext()
+     */
+    public SecurityConstraintsContext newSecurityConstraintsContext()
+    {
+        // return generic security constraints context instance
+        // since the context is embedded in this, (see below).
+        return new GenericSecurityConstraintsContextImpl();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.common.SecuredResource#newSecurityConstraint()
+     */
+    public SecurityConstraint newSecurityConstraint()
+    {
+        // return constraints specific security constraint instance
+        return new PageSecurityConstraintImpl();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.document.jpa.NodeImpl#getMetadataFields()
+     */
+    protected Collection getMetadataFields()
+    {
+        // create initial collection if necessary
+        if (metadataFields == null)
+        {
+            metadataFields = DatabasePageManagerUtils.createList();
+        }
+        // wrap collection to maintain JPA inverse relationships
+        return new MetadataLocalizedFieldCollection(this, metadataFields);        
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.document.jpa.NodeImpl#getParentNode()
+     */
+    protected Node getParentNode()
+    {
+        return parent;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.document.jpa.NodeImpl#setParentNode(org.apache.jetspeed.page.document.Node)
+     */
+    protected void setParentNode(Node parent)
+    {
+        this.parent = (FolderImpl)parent;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.jpa.BaseElementImpl#accessSecurityConstraintsContext()
+     */
+    protected SecurityConstraintsContextImpl accessSecurityConstraintsContext()
+    {
+        // return this since the context is embedded in this, (see below).
+        return this;
+    }
+    
+    /**
+     * accessMenus
+     *
+     * Access mutable persistent collection member for List wrappers.
+     *
+     * @return persistent collection
+     */
+    List accessMenus()
+    {
+        // create initial collection if necessary
+        if (menus == null)
+        {
+            menus = DatabasePageManagerUtils.createList();
+        }
+        return menus;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.jpa.BaseElementImpl#setPageManager(org.apache.jetspeed.page.jpa.DatabasePageManager)
+     */
+    public void setPageManager(DatabasePageManager pageManager)
+    {
+        // propagate to super and fragments
+        super.setPageManager(pageManager);
+        FragmentImpl rootFragment = (FragmentImpl)getRootFragment();
+        if (rootFragment != null)
+        {
+            rootFragment.setPageManager(pageManager);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.jpa.BaseElementImpl#setConstraintsEnabled(boolean)
+     */
+    public void setConstraintsEnabled(boolean enabled)
+    {
+        // propagate to super and fragments
+        super.setConstraintsEnabled(enabled);
+        FragmentImpl rootFragment = (FragmentImpl)getRootFragment();
+        if (rootFragment != null)
+        {
+            rootFragment.setConstraintsEnabled(enabled);
+        }
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.jpa.BaseElementImpl#setPermissionsEnabled(boolean)
+     */
+    public void setPermissionsEnabled(boolean enabled)
+    {
+        // propagate to super and fragments
+        super.setPermissionsEnabled(enabled);
+        FragmentImpl rootFragment = (FragmentImpl)getRootFragment();
+        if (rootFragment != null)
+        {
+            rootFragment.setPermissionsEnabled(enabled);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.jpa.BaseElementImpl#resetCachedSecurityConstraints()
+     */
+    public void resetCachedSecurityConstraints()
+    {
+        // propagate to super and fragments
+        super.resetCachedSecurityConstraints();
+        FragmentImpl rootFragment = (FragmentImpl)getRootFragment();
+        if (rootFragment != null)
+        {
+            rootFragment.resetCachedSecurityConstraints();
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.document.jpa.NodeImpl#newPageMetadata(java.util.Collection)
+     */
+    public PageMetadataImpl newPageMetadata(Collection fields)
+    {
+        PageMetadataImpl pageMetadata = new PageMetadataImpl(PageMetadataLocalizedFieldImpl.class);
+        pageMetadata.setFields(fields);
+        return pageMetadata;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.Page#getSkin()
+     */
+    public String getSkin()
+    {
+        return skin;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.Page#setSkin(java.lang.String)
+     */
+    public void setSkin(String skinName)
+    {
+        this.skin = skinName;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.Page#getEffectiveDefaultDecorator(java.lang.String)
+     */
+    public String getEffectiveDefaultDecorator(String fragmentType)
+    {
+        // get locally defined decorator
+        String decorator = getDefaultDecorator(fragmentType);
+        if (decorator == null)
+        {
+            // delegate to parent folder
+            Folder parentFolder = (Folder)getParent();
+            if (parentFolder != null)
+            {
+                return parentFolder.getEffectiveDefaultDecorator(fragmentType);
+            }
+        }
+        return decorator;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.Page#getDefaultDecorator(java.lang.String)
+     */
+    public String getDefaultDecorator(String fragmentType)
+    {
+        // retrieve supported decorator types
+        if (fragmentType != null)
+        {
+            if (fragmentType.equals(Fragment.LAYOUT))
+            {
+                return defaultLayoutDecorator; 
+            }
+            if (fragmentType.equals(Fragment.PORTLET))
+            {
+                return defaultPortletDecorator; 
+            }
+        }
+        return null;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.Page#getDefaultDecorator(java.lang.String,java.lang.String)
+     */
+    public void setDefaultDecorator(String decoratorName, String fragmentType)
+    {
+        // save supported decorator types
+        if (fragmentType != null)
+        {
+            if (fragmentType.equals(Fragment.LAYOUT))
+            {
+                defaultLayoutDecorator = decoratorName; 
+            }
+            if (fragmentType.equals(Fragment.PORTLET))
+            {
+                defaultPortletDecorator = decoratorName; 
+            }
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.Page#getRootFragment()
+     */
+    public Fragment getRootFragment()
+    {
+        // get singleton fragment; no access checks to
+        // be made for root fragment
+        if ((fragment != null) && !fragment.isEmpty())
+        {
+            FragmentImpl rootFragment = (FragmentImpl)fragment.iterator().next();
+            if (rootFragment.getFragmentsPage() == null)
+            {
+                // set page implementation in root and children fragments
+                rootFragment.setFragmentsPage(this);
+            }
+            return rootFragment;
+        }
+        return null;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.Page#setRootFragment(org.apache.jetspeed.om.page.Fragment)
+     */
+    public void setRootFragment(Fragment fragment)
+    {
+        // add new or reuse singleton fragment
+        if (fragment instanceof FragmentImpl)
+        {
+            // create singleton collection or remove existing
+            // root fragment and save for reuse
+            if (this.fragment == null)
+            {
+                this.fragment = DatabasePageManagerUtils.createList();
+            }
+            else if (!this.fragment.isEmpty())
+            {
+                removedFragment = (FragmentImpl)this.fragment.iterator().next();
+                removedFragment.setInverseTopLevelRelationship(null);
+                this.fragment.clear();
+            }
+
+            // add new fragment or copy configuration
+            // from previously removed fragment
+            FragmentImpl addFragment = (FragmentImpl)fragment;
+            if (removedFragment != null)
+            {
+                // reuse previously removed fragment
+                fragment = removedFragment;
+                removedFragment = null;
+                // TODO: move this logic to copy methods on implementations
+                fragment.setName(addFragment.getName());
+                fragment.setTitle(addFragment.getTitle());
+                fragment.setShortTitle(addFragment.getShortTitle());
+                fragment.setType(addFragment.getType());
+                fragment.setSkin(addFragment.getSkin());
+                fragment.setDecorator(addFragment.getDecorator());
+                fragment.setState(addFragment.getState());
+                fragment.setSecurityConstraintsContext(addFragment.getSecurityConstraintsContext());
+                fragment.getProperties().clear();
+                fragment.getProperties().putAll(addFragment.getProperties());
+                fragment.setPreferences(addFragment.getPreferences());
+                fragment.getFragments().clear();
+                fragment.getFragments().addAll(addFragment.getFragments());
+                addFragment = (FragmentImpl)fragment;
+            }
+            addFragment.setInverseTopLevelRelationship(this);
+            this.fragment.add(addFragment);
+
+            // set page implementation in root and children fragments
+            addFragment.setFragmentsPage(this);
+        }
+        else if (fragment == null)
+        {
+            // delete existing fragment if required, saving
+            // removed fragment for later reuse
+            if ((this.fragment != null) && !this.fragment.isEmpty())
+            {
+                removedFragment = (FragmentImpl)this.fragment.iterator().next();
+                this.fragment.clear();
+            }
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.Page#getFragmentById(java.lang.String)
+     */
+    public Fragment getFragmentById(String id)
+    {
+        // get fragment by id and check access
+        FragmentImpl rootFragment = (FragmentImpl)getRootFragment();
+        if (rootFragment != null)
+        {
+            Fragment fragment = rootFragment.getFragmentById(id);
+            if (fragment != null)
+            {
+                try
+                {
+                    fragment.checkAccess(JetspeedActions.VIEW);
+                }
+                catch (SecurityException se)
+                {
+                    fragment = null;
+                }
+            }
+            return fragment;
+        }
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.Page#removeFragmentById(java.lang.String)
+     */
+    public Fragment removeFragmentById(String id)
+    {
+        // remove fragment by id
+        FragmentImpl rootFragment = (FragmentImpl)getRootFragment();
+        if (rootFragment != null)
+        {
+            if (rootFragment.getId().equals(id))
+            {
+                setRootFragment(null);
+                return rootFragment;
+            }
+            else
+            {
+                return rootFragment.removeFragmentById(id);
+            }
+        }
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.Page#getFragmentsByName(java.lang.String)
+     */
+    public List getFragmentsByName(String name)
+    {
+        // get fragments by name and filter by access
+        FragmentImpl rootFragment = (FragmentImpl)getRootFragment();
+        if (rootFragment != null)
+        {
+            // return immutable filtered fragment list
+            return rootFragment.filterFragmentsByAccess(rootFragment.getFragmentsByName(name), false);
+        }
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.Page#getMenuDefinitions()
+     */
+    public List getMenuDefinitions()
+    {
+        // return mutable menu definition list
+        // by using list wrapper to manage
+        // element uniqueness
+        if (menuDefinitions == null)
+        {
+            menuDefinitions = new PageMenuDefinitionList(this);
+        }
+        return menuDefinitions;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.Page#newMenuDefinition()
+     */
+    public MenuDefinition newMenuDefinition()
+    {
+        return new PageMenuDefinitionImpl();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.Page#newMenuExcludeDefinition()
+     */
+    public MenuExcludeDefinition newMenuExcludeDefinition()
+    {
+        return new PageMenuExcludeDefinitionImpl();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.Page#newMenuIncludeDefinition()
+     */
+    public MenuIncludeDefinition newMenuIncludeDefinition()
+    {
+        return new PageMenuIncludeDefinitionImpl();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.Page#newMenuOptionsDefinition()
+     */
+    public MenuOptionsDefinition newMenuOptionsDefinition()
+    {
+        return new PageMenuOptionsDefinitionImpl();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.Page#newMenuSeparatorDefinition()
+     */
+    public MenuSeparatorDefinition newMenuSeparatorDefinition()
+    {
+        return new PageMenuSeparatorDefinitionImpl();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.Page#setMenuDefinitions(java.util.List)
+     */
+    public void setMenuDefinitions(List definitions)
+    {
+        // set menu definitions by replacing
+        // existing entries with new elements if
+        // new collection is specified
+        List menuDefinitions = getMenuDefinitions();
+        if (definitions != menuDefinitions)
+        {
+            // replace all menu definitions
+            menuDefinitions.clear();
+            if (definitions != null)
+            {
+                menuDefinitions.addAll(definitions);
+            }
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.document.Node#getType()
+     */
+    public String getType()
+    {
+        return DOCUMENT_TYPE;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.BaseElement#getTitle()
+     */
+    public String getTitle()
+    {
+        // default title to page name
+        if (title == null)
+        {
+            title = defaultTitleFromName();
+        }
+        return title;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.BaseElement#setTitle(java.lang.String)
+     */
+    public void setTitle(String title)
+    {
+        this.title = title;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.BaseElement#getShortTitle()
+     */
+    public String getShortTitle()
+    {
+        return shortTitle;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.BaseElement#setShortTitle(java.lang.String)
+     */
+    public void setShortTitle(String shortTitle)
+    {
+        this.shortTitle = shortTitle;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.document.Node#isHidden()
+     */
+    public boolean isHidden()
+    {
+        return hidden;
+    }    
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.page.document.Node#setHidden(boolean)
+     */
+    public void setHidden(boolean hidden)
+    {
+        this.hidden = hidden;
+    }    
+
+    // **************************************************************************
+    // Begin Embedded SecurityConstraintsContextImpl
+    //
+    // Embeddable/Embedded with relationships not supported in JPA 1.0;
+    // otherwise, this should have been implemented as an embedded type
+    // derived from SecurityConstraintsContextImpl. Instead, BaseElementImpl
+    // derives from SecurityConstraintsContextImpl and the context
+    // protocol is implemented on this object.
+
+    @Basic
+    @Column (name="OWNER_PRINCIPAL")
+    private String owner;
+    @OneToMany (targetEntity=PageSecurityConstraintImpl.class, mappedBy="page", fetch=FetchType.LAZY, cascade=CascadeType.ALL)
+    @OrderBy (value="applyOrder ASC")
+    private List constraints;
+    @OneToMany (targetEntity=PageSecurityConstraintsRef.class, mappedBy="page", fetch=FetchType.LAZY, cascade=CascadeType.ALL)
+    @OrderBy (value="applyOrder ASC")
+    private List constraintsRefs;
+
+    private void eagerFetchEmbeddedCollections()
+    {
+        if (constraints != null)
+        {
+            constraints.size();
+        }
+        if (constraintsRefs != null)
+        {
+            constraintsRefs.size();
+        }
+    }    
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.common.SecurityConstraints#getOwner()
+     */
+    public String getOwner()
+    {
+        return owner;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.common.SecurityConstraints#setOwner(java.lang.String)
+     */
+    public void setOwner(String owner)
+    {
+        // save new setting and reset cached security constraints
+        this.owner = owner;
+        clearAllSecurityConstraints();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.jpa.SecurityConstraintsContextImpl#accessConstraintsRefs()
+     */
+    protected List accessConstraintsRefs()
+    {
+        // create initial collection if necessary
+        if (constraintsRefs == null)
+        {
+            constraintsRefs = DatabasePageManagerUtils.createList();
+        }
+        return constraintsRefs;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.jpa.SecurityConstraintsContextImpl#accessConstraints()
+     */
+    protected List accessConstraints()
+    {
+        // create initial collection if necessary
+        if (constraints == null)
+        {
+            constraints = DatabasePageManagerUtils.createList();
+        }
+        return constraints;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.jpa.SecurityConstraintsContextImpl#getSecurityConstraintClass()
+     */
+    protected Class getSecurityConstraintClass()
+    {
+        return PageSecurityConstraintImpl.class;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.page.jpa.SecurityConstraintsContextImpl#getSecurityConstraintsRefClass()
+     */
+    protected Class getSecurityConstraintsRefClass()
+    {
+        return PageSecurityConstraintsRef.class;        
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.common.SecurityConstraints#isEmpty()
+     */
+    public boolean isEmpty()
+    {
+        // test only persistent members for any specified constraints
+        return ((owner == null) &&
+                ((constraints == null) || constraints.isEmpty()) &&
+                ((constraintsRefs == null) || constraintsRefs.isEmpty()));
+    }
+
+    // End Embedded SecurityConstraintsContextImpl
+    // **************************************************************************
+}

Added: portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/jpa/PageMenuDefinitionElementList.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/jpa/PageMenuDefinitionElementList.java?rev=731466&view=auto
==============================================================================
--- portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/jpa/PageMenuDefinitionElementList.java (added)
+++ portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/jpa/PageMenuDefinitionElementList.java Sun Jan  4 22:04:13 2009
@@ -0,0 +1,147 @@
+/*
+ * 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.om.page.jpa;
+
+import java.util.AbstractList;
+
+/**
+ * PageMenuDefinitionElementList
+ *
+ * @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
+ * @version $Id$
+ */
+class PageMenuDefinitionElementList extends AbstractList
+{
+    private PageMenuDefinitionImpl menuDefinition;
+
+    PageMenuDefinitionElementList(PageMenuDefinitionImpl menuDefinition)
+    {
+        super();
+        this.menuDefinition = menuDefinition;
+    }
+
+    /**
+     * validateMenuElementForAdd
+     *
+     * Validates element to be added to this list.
+     *
+     * @param menuElement element to add
+     * @return list element to add
+     */
+    private PageBaseMenuDefinitionElement validateMenuElementForAdd(PageBaseMenuDefinitionElement menuElement)
+    {
+        // validate element instance
+        if (menuElement == null)
+        {
+            throw new NullPointerException("Unable to add null to list.");
+        }
+        return menuElement;
+    }
+
+    /* (non-Javadoc)
+     * @see java.util.List#add(int,java.lang.Object)
+     */
+    public synchronized void add(int index, Object element)
+    {
+        // implement for modifiable AbstractList:
+        // validate index
+        if ((index < 0) || (index > menuDefinition.accessElements().size()))
+        {
+            throw new IndexOutOfBoundsException("Unable to add to list at index: " + index);
+        }
+        // verify element
+        PageBaseMenuDefinitionElement menuElement = validateMenuElementForAdd((PageBaseMenuDefinitionElement)element);
+        // add to underlying ordered list
+        menuElement.setInverseRelationship(menuDefinition);
+        menuDefinition.accessElements().add(index, menuElement);
+        // set element order in added element
+        if (index > 0)
+        {
+            menuElement.setElementOrder(((PageBaseMenuDefinitionElement)menuDefinition.accessElements().get(index-1)).getElementOrder() + 1);
+        }
+        else
+        {
+            menuElement.setElementOrder(0);
+        }
+        // maintain element order in subsequent elements
+        for (int i = index, limit = menuDefinition.accessElements().size() - 1; (i < limit); i++)
+        {
+            PageBaseMenuDefinitionElement nextMenuElement = (PageBaseMenuDefinitionElement)menuDefinition.accessElements().get(i + 1);
+            if (nextMenuElement.getElementOrder() <= menuElement.getElementOrder())
+            {
+                // adjust element order for next element
+                nextMenuElement.setElementOrder(menuElement.getElementOrder() + 1);
+                menuElement = nextMenuElement;
+            }
+            else
+            {
+                // element order maintained for remaining list elements
+                break;
+            }
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see java.util.List#get(int)
+     */
+    public synchronized Object get(int index)
+    {
+        // implement for modifiable AbstractList
+        return menuDefinition.accessElements().get(index);
+    }
+
+    /* (non-Javadoc)
+     * @see java.util.List#remove(int)
+     */
+    public synchronized Object remove(int index)
+    {
+        // implement for modifiable AbstractList
+        PageBaseMenuDefinitionElement removed = (PageBaseMenuDefinitionElement)menuDefinition.accessElements().remove(index);
+        if (removed != null)
+        {
+            removed.setInverseRelationship(null);
+        }
+        return removed;
+    }
+
+    /* (non-Javadoc)
+     * @see java.util.List#set(int,java.lang.Object)
+     */
+    public synchronized Object set(int index, Object element)
+    {
+        // implement for modifiable AbstractList:
+        // verify element
+        PageBaseMenuDefinitionElement newMenuElement = validateMenuElementForAdd((PageBaseMenuDefinitionElement)element);
+        // set in underlying ordered list
+        newMenuElement.setInverseRelationship(menuDefinition);
+        PageBaseMenuDefinitionElement menuElement = (PageBaseMenuDefinitionElement)menuDefinition.accessElements().set(index, newMenuElement);
+        menuElement.setInverseRelationship(null);
+        // set element order in new element
+        newMenuElement.setElementOrder(menuElement.getElementOrder());
+        // return element
+        return menuElement;
+    }
+
+    /* (non-Javadoc)
+     * @see java.util.List#size()
+     */
+    public synchronized int size()
+    {
+        // implement for modifiable AbstractList
+        return menuDefinition.accessElements().size();
+    }
+}

Added: portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/jpa/PageMenuDefinitionImpl.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/jpa/PageMenuDefinitionImpl.java?rev=731466&view=auto
==============================================================================
--- portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/jpa/PageMenuDefinitionImpl.java (added)
+++ portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/jpa/PageMenuDefinitionImpl.java Sun Jan  4 22:04:13 2009
@@ -0,0 +1,369 @@
+/*
+ * 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.om.page.jpa;
+
+import java.util.Collection;
+import java.util.List;
+
+import javax.persistence.Basic;
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.FetchType;
+import javax.persistence.DiscriminatorColumn;
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToMany;
+import javax.persistence.OrderBy;
+import javax.persistence.PostLoad;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+
+import org.apache.jetspeed.om.folder.MenuDefinition;
+import org.apache.jetspeed.om.page.PageMetadataImpl;
+import org.apache.jetspeed.page.jpa.DatabasePageManagerUtils;
+
+/**
+ * PageMenuDefinitionImpl
+ * 
+ * @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
+ * @version $Id:$
+ */
+@Entity (name="PageMenuDefinition")
+@Inheritance (strategy=InheritanceType.SINGLE_TABLE)
+@Table (name="PAGE_MENU")
+@DiscriminatorColumn (name="CLASS_NAME")
+@DiscriminatorValue (value="org.apache.jetspeed.om.page.impl.PageMenuDefinitionImpl")
+public class PageMenuDefinitionImpl extends PageBaseMenuDefinitionMetadata implements MenuDefinition
+{
+    @ManyToOne (targetEntity=PageImpl.class, fetch=FetchType.LAZY, optional=true)
+    @JoinColumn (name="PAGE_ID", referencedColumnName="PAGE_ID")
+    private PageImpl page;
+    @Basic
+    @Column (name="NAME")
+    private String name;
+    @Basic
+    @Column (name="OPTIONS")
+    private String options;
+    @Basic
+    @Column (name="DEPTH")
+    private int depth;
+    @Basic
+    @Column (name="IS_PATHS")
+    private boolean paths;
+    @Basic
+    @Column (name="IS_REGEXP")
+    private boolean regexp;
+    @Basic
+    @Column (name="PROFILE")
+    private String profile;
+    @Basic
+    @Column (name="OPTIONS_ORDER")
+    private String order;
+    @Basic
+    @Column (name="SKIN")
+    private String skin;
+    @Basic
+    @Column (name="TITLE")
+    private String title;
+    @Basic
+    @Column (name="SHORT_TITLE")
+    private String shortTitle;
+    @OneToMany (targetEntity=PageBaseMenuDefinitionElement.class, mappedBy="parent", fetch=FetchType.LAZY, cascade=CascadeType.ALL)
+    @OrderBy (value="elementOrder ASC")
+    private List elements;
+    
+    @PostLoad
+    private void eagerFetchCollections()
+    {
+        if (elements != null)
+        {
+            elements.size();
+        }
+    }
+    
+    @Transient
+    private PageMenuDefinitionElementList menuElements;
+
+    /**
+     * Explicitly set inverse relationship when this object
+     * is added to a one-to-many collection. JPA does not
+     * manage bidirectional relationships.
+     * 
+     * @param inverse inverse relationship owning object.
+     */
+    public void setInverseTopLevelRelationship(Object inverse)
+    {
+        page = (PageImpl)inverse;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.folder.jpa.PageBaseMenuDefinitionMetadata#newPageMetadata()
+     */
+    public PageMetadataImpl newPageMetadata(Collection fields)
+    {
+        PageMetadataImpl pageMetadata = new PageMetadataImpl(PageMenuMetadataLocalizedFieldImpl.class);
+        pageMetadata.setFields(fields);
+        return pageMetadata;
+    }
+
+    /**
+     * accessElements
+     *
+     * Access mutable persistent collection member for List wrappers.
+     *
+     * @return persistent collection
+     */
+    List accessElements()
+    {
+        // create initial collection if necessary
+        if (elements == null)
+        {
+            elements = DatabasePageManagerUtils.createList();
+        }
+        return elements;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.folder.MenuDefinition#getName()
+     */
+    public String getName()
+    {
+        return name;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.folder.MenuDefinition#setName(java.lang.String)
+     */
+    public void setName(String name)
+    {
+        this.name = name;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.folder.MenuDefinition#getOptions()
+     */
+    public String getOptions()
+    {
+        return options;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.folder.MenuDefinition#setOptions(java.lang.String)
+     */
+    public void setOptions(String options)
+    {
+        this.options = options;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.folder.MenuDefinition#getDepth()
+     */
+    public int getDepth()
+    {
+        return depth;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.folder.MenuDefinition#setDepth(int)
+     */
+    public void setDepth(int depth)
+    {
+        this.depth = depth;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.folder.MenuDefinition#getPaths()
+     */
+    public boolean isPaths()
+    {
+        return paths;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.folder.MenuDefinition#setPaths(boolean)
+     */
+    public void setPaths(boolean paths)
+    {
+        this.paths = paths;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.folder.MenuDefinition#getRegexp()
+     */
+    public boolean isRegexp()
+    {
+        return regexp;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.folder.MenuDefinition#setRegexp(boolean)
+     */
+    public void setRegexp(boolean regexp)
+    {
+        this.regexp = regexp;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.folder.MenuDefinition#getProfile()
+     */
+    public String getProfile()
+    {
+        return profile;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.folder.MenuDefinition#setProfile(java.lang.String)
+     */
+    public void setProfile(String locatorName)
+    {
+        profile = locatorName;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.folder.MenuDefinition#getOrder()
+     */
+    public String getOrder()
+    {
+        return order;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.folder.MenuDefinition#setOrder(java.lang.String)
+     */
+    public void setOrder(String order)
+    {
+        this.order = order;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.folder.MenuDefinition#getSkin()
+     */
+    public String getSkin()
+    {
+        return skin;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.folder.MenuDefinition#setSkin(java.lang.String)
+     */
+    public void setSkin(String name)
+    {
+        skin = name;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.folder.MenuDefinition#getTitle()
+     */
+    public String getTitle()
+    {
+        return title;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.folder.MenuDefinition#setTitle(java.lang.String)
+     */
+    public void setTitle(String title)
+    {
+        this.title = title;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.folder.MenuDefinition#getShortTitle()
+     */
+    public String getShortTitle()
+    {
+        return shortTitle; 
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.folder.MenuDefinition#setShortTitle(java.lang.String)
+     */
+    public void setShortTitle(String title)
+    {
+        this.shortTitle = title;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.folder.MenuDefinition#getMenuElements()
+     */
+    public List getMenuElements()
+    {
+        // return mutable menu element list
+        // by using list wrapper to manage
+        // element order
+        if (menuElements == null)
+        {
+            menuElements = new PageMenuDefinitionElementList(this);
+        }
+        return menuElements;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.om.folder.MenuDefinition#setMenuElements(java.util.List)
+     */
+    public void setMenuElements(List elements)
+    {
+        // set menu elements by replacing
+        // existing entries with new elements if
+        // new collection is specified
+        List menuElements = getMenuElements();
+        if (elements != menuElements)
+        {
+            // replace all menu elements
+            menuElements.clear();
+            if (elements != null)
+            {
+                menuElements.addAll(elements);
+            }
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    public boolean equals(Object o)
+    {
+        if (o instanceof PageMenuDefinitionImpl)
+        {
+            if (name != null)
+            {
+                return name.equals(((PageMenuDefinitionImpl)o).getName());
+            }
+            else
+            {
+                return (((PageMenuDefinitionImpl)o).getName() == null);
+            }
+        }
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see java.lang.Object#hashCode()
+     */
+    public int hashCode()
+    {
+        if (name != null)
+        {
+            return name.hashCode();
+        }
+        return 0;
+    }
+}

Added: portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/jpa/PageMenuDefinitionList.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/jpa/PageMenuDefinitionList.java?rev=731466&view=auto
==============================================================================
--- portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/jpa/PageMenuDefinitionList.java (added)
+++ portals/jetspeed-2/portal/branches/JPA_BRANCH/components/jetspeed-page-manager/src/main/java/org/apache/jetspeed/om/page/jpa/PageMenuDefinitionList.java Sun Jan  4 22:04:13 2009
@@ -0,0 +1,183 @@
+/*
+ * 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.om.page.jpa;
+
+import java.util.AbstractList;
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * PageMenuDefinitionList
+ *
+ * @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
+ * @version $Id$
+ */
+class PageMenuDefinitionList extends AbstractList
+{
+    private PageImpl page;
+
+    private List removedMenuDefinitions;
+
+    PageMenuDefinitionList(PageImpl page)
+    {
+        super();
+        this.page = page;
+    }
+
+    /**
+     * validateDefinitionForAdd
+     *
+     * Validates menu definition to be added to this list.
+     *
+     * @param definition menu definition to add
+     * @return list element to add
+     */
+    private PageMenuDefinitionImpl validateDefinitionForAdd(PageMenuDefinitionImpl definition)
+    {
+        // only non-null definitions supported
+        if (definition == null)
+        {
+            throw new NullPointerException("Unable to add null to list.");
+        }
+        // make sure element is unique
+        if (page.accessMenus().contains(definition))
+        {
+            throw new IllegalArgumentException("Unable to add duplicate entry to list: " + (definition).getName());
+        }
+        // retrieve from removed list to reuse
+        // previously removed element copying
+        // menu definition data
+        if (removedMenuDefinitions != null)
+        {
+            int removedIndex = removedMenuDefinitions.indexOf(definition);
+            if (removedIndex >= 0)
+            {
+                // reuse menu definition with matching name
+                PageMenuDefinitionImpl addDefinition = definition;
+                definition = (PageMenuDefinitionImpl)removedMenuDefinitions.remove(removedIndex);
+                // TODO: move this logic to copy methods on implementations
+                // copy menu definition members
+                definition.setOptions(addDefinition.getOptions());
+                definition.setDepth(addDefinition.getDepth());
+                definition.setPaths(addDefinition.isPaths());
+                definition.setRegexp(addDefinition.isRegexp());
+                definition.setProfile(addDefinition.getProfile());
+                definition.setOrder(addDefinition.getOrder());
+                definition.setSkin(addDefinition.getSkin());
+                definition.setTitle(addDefinition.getTitle());
+                definition.setShortTitle(addDefinition.getShortTitle());
+                definition.setMenuElements(addDefinition.getMenuElements());
+                // copy menu definition metadata members
+                // TODO: strengthen... this code is not robust
+                // and may fail if multiple edits without a db
+                // update occur and duplicate metadata members
+                // are removed in one operation and reinserted
+                // in a subsequent operation because the
+                // metadata members are required to be unique
+                // and a removal list is not maintained for the
+                // metadata fields collections yet
+                definition.getMetadata().copyFields(addDefinition.getMetadata().getFields());
+            }
+        }
+        return definition;
+    }
+
+    /**
+     * getRemovedMenuDefinitions
+     *
+     * @return removed menu definitions tracking collection
+     */
+    private List getRemovedMenuDefinitions()
+    {
+        if (removedMenuDefinitions == null)
+        {
+            removedMenuDefinitions = new ArrayList();
+        }
+        return removedMenuDefinitions;
+    }
+
+    /* (non-Javadoc)
+     * @see java.util.List#add(int,java.lang.Object)
+     */
+    public synchronized void add(int index, Object element)
+    {
+        // implement for modifiable AbstractList:
+        // validate index
+        if ((index < 0) || (index > page.accessMenus().size()))
+        {
+            throw new IndexOutOfBoundsException("Unable to add to list at index: " + index);
+        }
+        // verify menu definition
+        PageMenuDefinitionImpl definition = validateDefinitionForAdd((PageMenuDefinitionImpl)element);
+        // add to underlying ordered list
+        definition.setInverseTopLevelRelationship(page);
+        page.accessMenus().add(index, definition);
+    }
+
+    /* (non-Javadoc)
+     * @see java.util.List#get(int)
+     */
+    public synchronized Object get(int index)
+    {
+        // implement for modifiable AbstractList
+        return page.accessMenus().get(index);
+    }
+
+    /* (non-Javadoc)
+     * @see java.util.List#remove(int)
+     */
+    public synchronized Object remove(int index)
+    {
+        // implement for modifiable AbstractList:
+        // save removed element 
+        PageMenuDefinitionImpl removed = (PageMenuDefinitionImpl)page.accessMenus().remove(index);
+        if (removed != null)
+        {
+            removed.setInverseTopLevelRelationship(null);
+            getRemovedMenuDefinitions().add(removed);
+        }
+        return removed;
+    }
+
+    /* (non-Javadoc)
+     * @see java.util.List#set(int,java.lang.Object)
+     */
+    public synchronized Object set(int index, Object element)
+    {
+        // implement for modifiable AbstractList:
+        // verify menu definition
+        PageMenuDefinitionImpl newDefinition = validateDefinitionForAdd((PageMenuDefinitionImpl)element);
+        // set in underlying ordered list
+        newDefinition.setInverseTopLevelRelationship(page);
+        PageMenuDefinitionImpl definition = (PageMenuDefinitionImpl)page.accessMenus().set(index, newDefinition);
+        definition.setInverseTopLevelRelationship(null);
+        // save replaced element
+        getRemovedMenuDefinitions().add(definition);
+        // return menu definition
+        return definition;
+    }
+
+    /* (non-Javadoc)
+     * @see java.util.List#size()
+     */
+    public synchronized int size()
+    {
+        // implement for modifiable AbstractList
+        return page.accessMenus().size();
+    }
+}



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