You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@wookie.apache.org by sc...@apache.org on 2010/06/16 16:16:40 UTC

svn commit: r955236 [6/10] - in /incubator/wookie/branches/pluggablepersistence: ./ WebContent/WEB-INF/ WebContent/admin/ WebContent/webmenu/ ant/ etc/ddl-schema/ etc/tomcat/ etc/tomcat/conf/ parser/java/src/org/apache/wookie/w3c/util/ scripts/ scripts...

Added: incubator/wookie/branches/pluggablepersistence/src/org/apache/wookie/beans/jcr/impl/WidgetInstanceImpl.java
URL: http://svn.apache.org/viewvc/incubator/wookie/branches/pluggablepersistence/src/org/apache/wookie/beans/jcr/impl/WidgetInstanceImpl.java?rev=955236&view=auto
==============================================================================
--- incubator/wookie/branches/pluggablepersistence/src/org/apache/wookie/beans/jcr/impl/WidgetInstanceImpl.java (added)
+++ incubator/wookie/branches/pluggablepersistence/src/org/apache/wookie/beans/jcr/impl/WidgetInstanceImpl.java Wed Jun 16 14:16:36 2010
@@ -0,0 +1,485 @@
+/*
+ *  Licensed 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.wookie.beans.jcr.impl;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.apache.jackrabbit.ocm.manager.beanconverter.impl.ReferenceBeanConverterImpl;
+import org.apache.jackrabbit.ocm.mapper.impl.annotation.Bean;
+import org.apache.jackrabbit.ocm.mapper.impl.annotation.Field;
+import org.apache.jackrabbit.ocm.mapper.impl.annotation.Node;
+
+import org.apache.wookie.beans.IPreference;
+import org.apache.wookie.beans.ISharedData;
+import org.apache.wookie.beans.IToken;
+import org.apache.wookie.beans.IWidget;
+import org.apache.wookie.beans.IWidgetInstance;
+import org.apache.wookie.beans.jcr.IPathBean;
+import org.apache.wookie.beans.jcr.IUuidBean;
+import org.apache.wookie.beans.jcr.IdCollection;
+import org.apache.wookie.beans.jcr.JCRPersistenceManager;
+
+/**
+ * WidgetInstanceImpl - JCR OCM IWidgetInstance implementation.
+ * 
+ * @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
+ * @version $Id$
+ */
+@Node(jcrType="wookie:widgetInstance", jcrMixinTypes="mix:referenceable", discriminator=false)
+public class WidgetInstanceImpl implements IWidgetInstance, IPathBean, IUuidBean
+{
+    @Field(path=true)
+    private String path;
+    
+    @Field(uuid=true)
+    private String uuid;
+    
+    @Field(jcrName="wookie:apiKey")
+    private String apiKey;
+
+    @Field(jcrName="wookie:userId")
+    private String userId;
+
+    @Field(jcrName="wookie:sharedDataKey")
+    private String sharedDataKey;
+
+    @Field(jcrName="wookie:nonce")
+    private String nonce;
+
+    @Field(jcrName="wookie:idKey")
+    private String idKey;
+
+    @Field(jcrName="wookie:opensocialToken")
+    private String opensocialToken;
+    
+    @Field(jcrName="wookie:updated")
+    private Boolean updated;
+    
+    @Field(jcrName="wookie:shown")
+    private Boolean shown;
+    
+    @Field(jcrName="wookie:hidden")
+    private Boolean hidden;
+    
+    @Field(jcrName="wookie:locked")
+    private Boolean locked;
+    
+    @Field(jcrName="wookie:lang")
+    private String lang;
+    
+    @Bean(jcrName="wookie:widget", converter=ReferenceBeanConverterImpl.class)
+    private WidgetImpl widgetImpl;
+
+    @org.apache.jackrabbit.ocm.mapper.impl.annotation.Collection(jcrName="wookie:preferences", elementClassName=PreferenceImpl.class)    
+    private Collection<PreferenceImpl> preferenceImpls;
+
+    @org.apache.jackrabbit.ocm.mapper.impl.annotation.Collection(jcrName="wookie:tokens", elementClassName=TokenImpl.class)    
+    private Collection<TokenImpl> tokenImpls;
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IWidgetInstance#getApiKey()
+     */
+    public String getApiKey()
+    {
+        return apiKey;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IWidgetInstance#setApiKey(java.lang.String)
+     */
+    public void setApiKey(String apiKey)
+    {
+        this.apiKey = apiKey;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IBean#getId()
+     */
+    public Object getId()
+    {
+        return path;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IWidgetInstance#getIdKey()
+     */
+    public String getIdKey()
+    {
+        return idKey;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IWidgetInstance#setIdKey(java.lang.String)
+     */
+    public void setIdKey(String idKey)
+    {
+        this.idKey = idKey;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IWidgetInstance#getLang()
+     */
+    public String getLang()
+    {
+        return lang;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IWidgetInstance#setLang(java.lang.String)
+     */
+    public void setLang(String lang)
+    {
+        this.lang = lang;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.jcr.IPathBean#getNodePath()
+     */
+    public String getNodePath()
+    {
+        return path;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.jcr.IPathBean#setNodePath(java.lang.String)
+     */
+    public String setNodePath(String nodeRootPath)
+    {
+        if (path == null)
+        {
+            path = nodeRootPath+"/"+JCRPersistenceManager.escapeJCRName(userId)+"/"+JCRPersistenceManager.escapeJCRName(apiKey)+"/"+JCRPersistenceManager.escapeJCRName(sharedDataKey)+"/"+JCRPersistenceManager.escapeJCRName(widgetImpl.getGuid());
+        }
+        return path;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IWidgetInstance#getNonce()
+     */
+    public String getNonce()
+    {
+        return nonce;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IWidgetInstance#setNonce(java.lang.String)
+     */
+    public void setNonce(String nonce)
+    {
+        this.nonce = nonce;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IWidgetInstance#getOpensocialToken()
+     */
+    public String getOpensocialToken()
+    {
+        return opensocialToken;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IWidgetInstance#setOpensocialToken(java.lang.String)
+     */
+    public void setOpensocialToken(String opensocialToken)
+    {
+        this.opensocialToken = opensocialToken;
+    }
+
+    /**
+     * Get raw persistent JCR absolute node path.
+     * 
+     * @return absolute path
+     */
+    public String getPath()
+    {
+        return path;
+    }
+
+    /**
+     * Set raw persistent JCR absolute node path.
+     * 
+     * @param path absolute path
+     */
+    public void setPath(String path)
+    {
+        this.path = path;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IWidgetInstance#getPreferences()
+     */
+    public Collection<IPreference> getPreferences()
+    {
+        if (preferenceImpls == null)
+        {
+            preferenceImpls = new ArrayList<PreferenceImpl>();
+        }
+        return new IdCollection<PreferenceImpl,IPreference>(preferenceImpls);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IWidgetInstance#setPreferences(java.util.Collection)
+     */
+    public void setPreferences(Collection<IPreference> preferences)
+    {
+        getPreferences().clear();
+        if (preferences != null)
+        {
+            for (IPreference preference : preferences)
+            {
+                getPreferences().add((PreferenceImpl)preference);
+            }
+        }
+    }
+
+    /**
+     * Get preference implementations collection.
+     * 
+     * @return preference implementations collection
+     */
+    public Collection<PreferenceImpl> getPreferenceImpls()
+    {
+        return preferenceImpls;
+    }
+
+    /**
+     * Set preference implementations collection.
+     * 
+     * @param preferenceImpls preference implementations collection
+     */
+    public void setPreferenceImpls(Collection<PreferenceImpl> preferenceImpls)
+    {
+        this.preferenceImpls = preferenceImpls;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IWidgetInstance#getSharedDataKey()
+     */
+    public String getSharedDataKey()
+    {
+        return sharedDataKey;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IWidgetInstance#setSharedDataKey(java.lang.String)
+     */
+    public void setSharedDataKey(String sharedDataKey)
+    {
+        this.sharedDataKey = sharedDataKey;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IWidgetInstance#getTokens()
+     */
+    public Collection<IToken> getTokens()
+    {
+        if (tokenImpls == null)
+        {
+            tokenImpls = new ArrayList<TokenImpl>();
+        }
+        return new IdCollection<TokenImpl,IToken>(tokenImpls);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IWidgetInstance#setTokens(java.util.Collection)
+     */
+    public void setTokens(Collection<IToken> tokens)
+    {
+        getTokens().clear();
+        if (tokens != null)
+        {
+            for (IToken token : tokens)
+            {
+                getTokens().add((TokenImpl)token);
+            }
+        }
+    }
+
+    /**
+     * Get token implementations collection.
+     * 
+     * @return token implementations collection
+     */
+    public Collection<TokenImpl> getTokenImpls()
+    {
+        return tokenImpls;
+    }
+
+    /**
+     * Set token implementations collection.
+     * 
+     * @param tokenImpls token implementations collection
+     */
+    public void setTokenImpls(Collection<TokenImpl> tokenImpls)
+    {
+        this.tokenImpls = tokenImpls;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IWidgetInstance#getUserId()
+     */
+    public String getUserId()
+    {
+        return userId;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IWidgetInstance#setUserId(java.lang.String)
+     */
+    public void setUserId(String userId)
+    {
+        this.userId = userId;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IWidgetInstance#getWidget()
+     */
+    public IWidget getWidget()
+    {
+        return widgetImpl;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IWidgetInstance#setWidget(org.apache.wookie.beans.IWidget)
+     */
+    public void setWidget(IWidget widget)
+    {
+        this.widgetImpl = (WidgetImpl)widget;
+    }
+    
+    /**
+     * Get widget implementation.
+     * 
+     * @return widget implementation
+     */
+    public WidgetImpl getWidgetImpl()
+    {
+        return widgetImpl;
+    }
+
+    /**
+     * Set widget implementation.
+     * 
+     * @return widgetImpl widget implementation
+     */
+    public void setWidgetImpl(WidgetImpl widgetImpl)
+    {
+        this.widgetImpl = widgetImpl;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IWidgetInstance#isHidden()
+     */
+    public boolean isHidden()
+    {
+        return ((hidden != null) ? hidden.booleanValue() : false);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IWidgetInstance#setHidden(boolean)
+     */
+    public void setHidden(boolean hidden)
+    {
+        this.hidden = (hidden ? Boolean.TRUE : Boolean.FALSE);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IWidgetInstance#isLocked()
+     */
+    public boolean isLocked()
+    {
+        return ((locked != null) ? locked.booleanValue() : false);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IWidgetInstance#setLocked(boolean)
+     */
+    public void setLocked(boolean locked)
+    {
+        this.locked = (locked ? Boolean.TRUE : Boolean.FALSE);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IWidgetInstance#isShown()
+     */
+    public boolean isShown()
+    {
+        return ((shown != null) ? shown.booleanValue() : false);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IWidgetInstance#setShown(boolean)
+     */
+    public void setShown(boolean shown)
+    {
+        this.shown = (shown ? Boolean.TRUE : Boolean.FALSE);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IWidgetInstance#isUpdated()
+     */
+    public boolean isUpdated()
+    {
+        return ((updated != null) ? updated.booleanValue() : false);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IWidgetInstance#setUpdated(boolean)
+     */
+    public void setUpdated(boolean updated)
+    {
+        this.updated = (updated ? Boolean.TRUE : Boolean.FALSE);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.jcr.IUuidBean#getUuid()
+     */
+    public String getUuid()
+    {
+        return uuid;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.jcr.IUuidBean#setUuid(java.lang.String)
+     */
+    public void setUuid(String uuid)
+    {
+        this.uuid = uuid;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IWidgetInstance#getPreference(java.lang.String)
+     */
+    public IPreference getPreference(String key)
+    {
+        return Utilities.getPreference(this, key);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IWidgetInstance#getSharedData()
+     */
+    public ISharedData [] getSharedData()
+    {
+        return Utilities.getSharedData(this);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IWidgetInstance#getSharedData(java.lang.String)
+     */
+    public ISharedData getSharedData(String name)
+    {
+        return Utilities.getSharedData(this, name);
+    }
+}

Added: incubator/wookie/branches/pluggablepersistence/src/org/apache/wookie/beans/jcr/impl/WidgetServiceImpl.java
URL: http://svn.apache.org/viewvc/incubator/wookie/branches/pluggablepersistence/src/org/apache/wookie/beans/jcr/impl/WidgetServiceImpl.java?rev=955236&view=auto
==============================================================================
--- incubator/wookie/branches/pluggablepersistence/src/org/apache/wookie/beans/jcr/impl/WidgetServiceImpl.java (added)
+++ incubator/wookie/branches/pluggablepersistence/src/org/apache/wookie/beans/jcr/impl/WidgetServiceImpl.java Wed Jun 16 14:16:36 2010
@@ -0,0 +1,102 @@
+/*
+ *  Licensed 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.wookie.beans.jcr.impl;
+
+import org.apache.jackrabbit.ocm.mapper.impl.annotation.Field;
+import org.apache.jackrabbit.ocm.mapper.impl.annotation.Node;
+
+import org.apache.wookie.beans.IWidgetService;
+import org.apache.wookie.beans.jcr.IPathBean;
+import org.apache.wookie.beans.jcr.JCRPersistenceManager;
+
+/**
+ * WidgetServiceImpl - JCR OCM IWidgetService implementation.
+ * 
+ * @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
+ * @version $Id$
+ */
+@Node(jcrType="wookie:widgetService", discriminator=false)
+public class WidgetServiceImpl implements IWidgetService, IPathBean
+{
+    @Field(path=true)
+    private String path;
+    
+    @Field(jcrName="wookie:serviceName")
+    private String serviceName;
+    
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IBean#getId()
+     */
+    public Object getId()
+    {
+        return path;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.jcr.IPathBean#getNodePath()
+     */
+    public String getNodePath()
+    {
+        return path;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.jcr.IPathBean#setNodePath(java.lang.String)
+     */
+    public String setNodePath(String nodeRootPath)
+    {
+        if (path == null)
+        {
+            path = nodeRootPath+"/"+JCRPersistenceManager.escapeJCRName(serviceName);
+        }
+        return path;
+    }
+
+    /**
+     * Get raw persistent JCR absolute node path.
+     * 
+     * @return absolute path
+     */
+    public String getPath()
+    {
+        return path;
+    }
+
+    /**
+     * Set raw persistent JCR absolute node path.
+     * 
+     * @param path absolute path
+     */
+    public void setPath(String path)
+    {
+        this.path = path;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IWidgetService#getServiceName()
+     */
+    public String getServiceName()
+    {
+        return serviceName;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IWidgetService#setServiceName(java.lang.String)
+     */
+    public void setServiceName(String serviceName)
+    {
+        this.serviceName = serviceName;
+    }
+}

Added: incubator/wookie/branches/pluggablepersistence/src/org/apache/wookie/beans/jcr/impl/WidgetTypeImpl.java
URL: http://svn.apache.org/viewvc/incubator/wookie/branches/pluggablepersistence/src/org/apache/wookie/beans/jcr/impl/WidgetTypeImpl.java?rev=955236&view=auto
==============================================================================
--- incubator/wookie/branches/pluggablepersistence/src/org/apache/wookie/beans/jcr/impl/WidgetTypeImpl.java (added)
+++ incubator/wookie/branches/pluggablepersistence/src/org/apache/wookie/beans/jcr/impl/WidgetTypeImpl.java Wed Jun 16 14:16:36 2010
@@ -0,0 +1,69 @@
+/*
+ *  Licensed 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.wookie.beans.jcr.impl;
+
+import org.apache.jackrabbit.ocm.mapper.impl.annotation.Field;
+import org.apache.jackrabbit.ocm.mapper.impl.annotation.Node;
+
+import org.apache.wookie.beans.IWidgetType;
+import org.apache.wookie.beans.jcr.IIdElement;
+
+/**
+ * WidgetTypeImpl - JCR OCM IWidgetType implementation.
+ * 
+ * @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
+ * @version $Id$
+ */
+@Node(jcrType="wookie:widgetType", discriminator=false)
+public class WidgetTypeImpl implements IWidgetType, IIdElement
+{
+    @Field(id=true, jcrName="wookie:elementId")
+    private long elementId = -1;
+    
+    @Field(jcrName="wookie:widgetContext")
+    private String widgetContext;
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.jcr.IIdElement#getElementId()
+     */
+    public long getElementId()
+    {
+        return elementId;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.jcr.IIdElement#setElementId(long)
+     */
+    public void setElementId(long elementId)
+    {
+        this.elementId = elementId;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IWidgetType#getWidgetContext()
+     */
+    public String getWidgetContext()
+    {
+        return widgetContext;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IWidgetType#setWidgetContext(java.lang.String)
+     */
+    public void setWidgetContext(String widgetContext)
+    {
+        this.widgetContext = widgetContext;
+    }
+}

Added: incubator/wookie/branches/pluggablepersistence/src/org/apache/wookie/beans/jcr/wookie-schema.cnd
URL: http://svn.apache.org/viewvc/incubator/wookie/branches/pluggablepersistence/src/org/apache/wookie/beans/jcr/wookie-schema.cnd?rev=955236&view=auto
==============================================================================
--- incubator/wookie/branches/pluggablepersistence/src/org/apache/wookie/beans/jcr/wookie-schema.cnd (added)
+++ incubator/wookie/branches/pluggablepersistence/src/org/apache/wookie/beans/jcr/wookie-schema.cnd Wed Jun 16 14:16:36 2010
@@ -0,0 +1,171 @@
+/*
+ *  Licensed 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.
+ */
+
+<jcr='http://www.jcp.org/jcr/1.0'>
+<nt='http://www.jcp.org/jcr/nt/1.0'>
+<mix='http://www.jcp.org/jcr/mix/1.0'>
+<wookie='http://www.apache.org/wookie/jcr/nt/0.1'>
+
+[wookie:widgetIcon] > nt:base
+- wookie:elementId (long)
+- wookie:src (string)
+- wookie:height (long)
+- wookie:width (long)
+- wookie:lang (string)
+
+[wookie:license] > nt:base
+- wookie:elementId (long)
+- wookie:href (string)
+- wookie:text (string)
+- wookie:dir (string)
+- wookie:lang (string)
+
+[wookie:name] > nt:base
+- wookie:elementId (long)
+- wookie:name (string)
+- wookie:shortName (string)
+- wookie:dir (string)
+- wookie:lang (string)
+
+[wookie:description] > nt:base
+- wookie:elementId (long)
+- wookie:content (string)
+- wookie:dir (string)
+- wookie:lang (string)
+
+[wookie:startFile] > nt:base
+- wookie:elementId (long)
+- wookie:url (string)
+- wookie:charset (string)
+- wookie:lang (string)
+
+[wookie:preferenceDefault] > nt:base
+- wookie:elementId (long)
+- wookie:preference (string) mandatory
+- wookie:value (string) mandatory
+- wookie:readOnly (boolean)
+
+[wookie:sharedData] > nt:base
+- wookie:elementId (long)
+- wookie:sharedDataKey (string)
+- wookie:dkey (string)
+- wookie:dvalue (string)
+
+[wookie:widgetType] > nt:base
+- wookie:elementId (long)
+- wookie:widgetContext (string)
+
+[wookie:param] > nt:base
+- wookie:elementId (long)
+- wookie:parameterName (string) mandatory
+- wookie:parameterValue (string) mandatory
+
+[wookie:feature] > nt:base
+- wookie:elementId (long)
+- wookie:featureName (string) mandatory
+- wookie:required (boolean)
++ wookie:parameters (nt:unstructured) = nt:unstructured
+
+[wookie:widget] > nt:base, mix:referenceable
+- wookie:height (long)
+- wookie:width (long)
+- wookie:guid (string) mandatory
+- wookie:widgetAuthor (string)
+- wookie:widgetAuthorEmail (string)
+- wookie:widgetAuthorHref (string)
+- wookie:widgetVersion (string)
++ wookie:widgetTypes (nt:unstructured) = nt:unstructured
++ wookie:accessRequests (nt:unstructured) = nt:unstructured
++ wookie:features (nt:unstructured) = nt:unstructured
++ wookie:widgetIcons (nt:unstructured) = nt:unstructured
++ wookie:licenses (nt:unstructured) = nt:unstructured
++ wookie:names (nt:unstructured) = nt:unstructured
++ wookie:descriptions (nt:unstructured) = nt:unstructured
++ wookie:startFiles (nt:unstructured) = nt:unstructured
++ wookie:preferenceDefaults (nt:unstructured) = nt:unstructured
++ wookie:sharedData (nt:unstructured) = nt:unstructured
+
+[wookie:accessRequest] > nt:base
+- wookie:elementId (long)
+- wookie:origin (string)
+- wookie:subdomains (boolean)
+- wookie:granted (boolean)
+- wookie:widget (reference) mandatory
+
+[wookie:widgetDefault] > nt:base
+- wookie:widgetContext (string) mandatory
+- wookie:widget (reference) mandatory
+
+[wookie:participant] > nt:base
+- wookie:participantId (string) mandatory
+- wookie:participantDisplayName (string) mandatory
+- wookie:participantThumbnailUrl (string)
+- wookie:sharedDataKey (string) mandatory
+- wookie:widget (reference) mandatory
+
+[wookie:preference] > nt:base
+- wookie:elementId (long)
+- wookie:dkey (string)
+- wookie:dvalue (string)
+- wookie:readOnly (boolean)
+
+[wookie:token] > nt:base
+- wookie:elementId (long)
+- wookie:requestUrl (string) mandatory
+- wookie:accessUrl (string) mandatory
+- wookie:authzUrl (string) mandatory
+- wookie:requestToken (string) mandatory
+- wookie:accessToken (string) mandatory
+- wookie:tokenSecret (string) mandatory
+
+[wookie:widgetInstance] > nt:base, mix:referenceable
+- wookie:apiKey (string) mandatory
+- wookie:userId (string) mandatory
+- wookie:sharedDataKey (string)
+- wookie:nonce (string)
+- wookie:idKey (string) mandatory
+- wookie:opensocialToken (string) mandatory
+- wookie:widget (reference) mandatory
+- wookie:updated (boolean)
+- wookie:shown (boolean)
+- wookie:hidden (boolean)
+- wookie:locked (boolean)
+- wookie:lang (string)
++ wookie:preferences (nt:unstructured) = nt:unstructured
++ wookie:tokens (nt:unstructured) = nt:unstructured
+
+[wookie:whitelist] > nt:base
+- wookie:fUrl (string) mandatory
+
+[wookie:apiKey] > nt:base
+- wookie:value (string) mandatory
+- wookie:email (string) mandatory
+
+[wookie:post] > nt:base, mix:referenceable
+- wookie:elementId (long)
+- wookie:userId (string) mandatory
+- wookie:title (string) mandatory
+- wookie:content (string)
+- wookie:publishDate (date) mandatory
+- wookie:updateDate (date)
+- wookie:sharedDataKey (string) mandatory
+- wookie:parent (string)
+- wookie:posts (reference) multiple
+
+[wookie:serverFeature] > nt:base
+- wookie:featureName (string) mandatory
+- wookie:className (string) mandatory
+
+[wookie:widgetService] > nt:base
+- wookie:serviceName (string) mandatory

Added: incubator/wookie/branches/pluggablepersistence/src/org/apache/wookie/beans/jpa/IInverseRelationship.java
URL: http://svn.apache.org/viewvc/incubator/wookie/branches/pluggablepersistence/src/org/apache/wookie/beans/jpa/IInverseRelationship.java?rev=955236&view=auto
==============================================================================
--- incubator/wookie/branches/pluggablepersistence/src/org/apache/wookie/beans/jpa/IInverseRelationship.java (added)
+++ incubator/wookie/branches/pluggablepersistence/src/org/apache/wookie/beans/jpa/IInverseRelationship.java Wed Jun 16 14:16:36 2010
@@ -0,0 +1,31 @@
+/*
+ *  Licensed 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.wookie.beans.jpa;
+
+/**
+ * IInverseRelationship - interface to manage inverse relationships.
+ * 
+ * @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
+ * @version $Id$
+ */
+public interface IInverseRelationship<O>
+{
+    /**
+     * Update inverse relationship.
+     * 
+     * @param owningObject owning object
+     */
+    void updateInverseRelationship(O owningObject);
+}

Added: incubator/wookie/branches/pluggablepersistence/src/org/apache/wookie/beans/jpa/InverseRelationshipCollection.java
URL: http://svn.apache.org/viewvc/incubator/wookie/branches/pluggablepersistence/src/org/apache/wookie/beans/jpa/InverseRelationshipCollection.java?rev=955236&view=auto
==============================================================================
--- incubator/wookie/branches/pluggablepersistence/src/org/apache/wookie/beans/jpa/InverseRelationshipCollection.java (added)
+++ incubator/wookie/branches/pluggablepersistence/src/org/apache/wookie/beans/jpa/InverseRelationshipCollection.java Wed Jun 16 14:16:36 2010
@@ -0,0 +1,118 @@
+/*
+ *  Licensed 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.wookie.beans.jpa;
+
+import java.util.AbstractCollection;
+import java.util.Collection;
+import java.util.Iterator;
+
+/**
+ * InverseRelationshipCollection - collection that manages inverse relationships.
+ * 
+ * @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
+ * @version $Id$
+ */
+public class InverseRelationshipCollection<O,I extends IInverseRelationship<O>,M> extends AbstractCollection<M>
+{
+    private O owningObject;
+    private Collection<I> inverseCollection;
+
+    /**
+     * Construct managing collection.
+     * 
+     * @param owningObject owning object
+     * @param inverseCollection managed inverse collection
+     */
+    public InverseRelationshipCollection(O owningObject, Collection<I> inverseCollection)
+    {
+        super();
+        this.owningObject = owningObject;
+        this.inverseCollection = inverseCollection;
+    }
+
+    /* (non-Javadoc)
+     * @see java.util.AbstractCollection#add(java.lang.Object)
+     */
+    @SuppressWarnings("unchecked")
+    public boolean add(M member)
+    {
+        I inverse = (I)member;
+        inverse.updateInverseRelationship(owningObject);
+        return inverseCollection.add(inverse);
+    }
+
+    /* (non-Javadoc)
+     * @see java.util.AbstractCollection#iterator()
+     */
+    public Iterator<M> iterator()
+    {
+        return new Iterator<M>()
+        {
+            Iterator<I> inverseIter = inverseCollection.iterator();
+            I lastInverse = null;
+            
+            /* (non-Javadoc)
+             * @see java.util.Iterator#hasNext()
+             */
+            public boolean hasNext()
+            {
+                return inverseIter.hasNext();
+            }
+
+            /* (non-Javadoc)
+             * @see java.util.Iterator#next()
+             */
+            @SuppressWarnings("unchecked")
+            public M next()
+            {
+                lastInverse = inverseIter.next();
+                M member = (M)lastInverse;
+                return member;
+            }
+
+            /* (non-Javadoc)
+             * @see java.util.Iterator#remove()
+             */
+            public void remove()
+            {
+                inverseIter.remove();
+                lastInverse.updateInverseRelationship(null);
+            }
+        };
+    }
+
+    /* (non-Javadoc)
+     * @see java.util.AbstractCollection#remove(java.lang.Object)
+     */
+    @SuppressWarnings("unchecked")
+    public boolean remove(Object member)
+    {
+        I inverse = (I)member;
+        if (inverseCollection.remove(inverse))
+        {
+            inverse.updateInverseRelationship(null);
+            return true;
+        }
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see java.util.AbstractCollection#size()
+     */
+    public int size()
+    {
+        return inverseCollection.size();
+    }  
+}

Added: incubator/wookie/branches/pluggablepersistence/src/org/apache/wookie/beans/jpa/JPAPersistenceManager.java
URL: http://svn.apache.org/viewvc/incubator/wookie/branches/pluggablepersistence/src/org/apache/wookie/beans/jpa/JPAPersistenceManager.java?rev=955236&view=auto
==============================================================================
--- incubator/wookie/branches/pluggablepersistence/src/org/apache/wookie/beans/jpa/JPAPersistenceManager.java (added)
+++ incubator/wookie/branches/pluggablepersistence/src/org/apache/wookie/beans/jpa/JPAPersistenceManager.java Wed Jun 16 14:16:36 2010
@@ -0,0 +1,1052 @@
+/*
+ *  Licensed 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.wookie.beans.jpa;
+
+import java.io.InputStream;
+import java.lang.reflect.Array;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.EntityTransaction;
+import javax.persistence.NoResultException;
+import javax.persistence.Persistence;
+import javax.persistence.Query;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+import javax.sql.DataSource;
+
+import org.apache.commons.configuration.Configuration;
+import org.apache.openjpa.persistence.Extent;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+import org.apache.openjpa.persistence.QueryResultCache;
+import org.apache.openjpa.persistence.StoreCache;
+import org.apache.wookie.beans.IAccessRequest;
+import org.apache.wookie.beans.IApiKey;
+import org.apache.wookie.beans.IBean;
+import org.apache.wookie.beans.IDescription;
+import org.apache.wookie.beans.IFeature;
+import org.apache.wookie.beans.ILicense;
+import org.apache.wookie.beans.IName;
+import org.apache.wookie.beans.IParam;
+import org.apache.wookie.beans.IParticipant;
+import org.apache.wookie.beans.IPost;
+import org.apache.wookie.beans.IPreference;
+import org.apache.wookie.beans.IPreferenceDefault;
+import org.apache.wookie.beans.IServerFeature;
+import org.apache.wookie.beans.ISharedData;
+import org.apache.wookie.beans.IStartFile;
+import org.apache.wookie.beans.IToken;
+import org.apache.wookie.beans.IWhitelist;
+import org.apache.wookie.beans.IWidget;
+import org.apache.wookie.beans.IWidgetDefault;
+import org.apache.wookie.beans.IWidgetIcon;
+import org.apache.wookie.beans.IWidgetInstance;
+import org.apache.wookie.beans.IWidgetService;
+import org.apache.wookie.beans.IWidgetType;
+import org.apache.wookie.beans.jpa.impl.AccessRequestImpl;
+import org.apache.wookie.beans.jpa.impl.ApiKeyImpl;
+import org.apache.wookie.beans.jpa.impl.DescriptionImpl;
+import org.apache.wookie.beans.jpa.impl.FeatureImpl;
+import org.apache.wookie.beans.jpa.impl.LicenseImpl;
+import org.apache.wookie.beans.jpa.impl.NameImpl;
+import org.apache.wookie.beans.jpa.impl.ParamImpl;
+import org.apache.wookie.beans.jpa.impl.ParticipantImpl;
+import org.apache.wookie.beans.jpa.impl.PostImpl;
+import org.apache.wookie.beans.jpa.impl.PreferenceDefaultImpl;
+import org.apache.wookie.beans.jpa.impl.PreferenceImpl;
+import org.apache.wookie.beans.jpa.impl.ServerFeatureImpl;
+import org.apache.wookie.beans.jpa.impl.SharedDataImpl;
+import org.apache.wookie.beans.jpa.impl.StartFileImpl;
+import org.apache.wookie.beans.jpa.impl.TokenImpl;
+import org.apache.wookie.beans.jpa.impl.WhitelistImpl;
+import org.apache.wookie.beans.jpa.impl.WidgetDefaultImpl;
+import org.apache.wookie.beans.jpa.impl.WidgetIconImpl;
+import org.apache.wookie.beans.jpa.impl.WidgetImpl;
+import org.apache.wookie.beans.jpa.impl.WidgetInstanceImpl;
+import org.apache.wookie.beans.jpa.impl.WidgetServiceImpl;
+import org.apache.wookie.beans.jpa.impl.WidgetTypeImpl;
+import org.apache.wookie.beans.util.IPersistenceManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * JPAPersistenceManager - JPA IPersistenceManager implementation.
+ * 
+ * @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
+ * @version $Id$
+ */
+public class JPAPersistenceManager implements IPersistenceManager
+{
+    private static final Logger logger = LoggerFactory.getLogger(JPAPersistenceManager.class);
+    
+    public static final String WIDGET_DATABASE_JNDI_DATASOURCE_NAME = "jdbc/widgetdb";
+    public static final String WIDGET_DATABASE_JNDI_DATASOURCE_FULL_NAME = "java:comp/env/"+WIDGET_DATABASE_JNDI_DATASOURCE_NAME;
+
+    public static final String PERSISTENCE_MANAGER_CACHE_SIZE_PROPERTY_NAME = "widget.persistence.manager.cachesize";
+    public static final String PERSISTENCE_MANAGER_DB_TYPE_PROPERTY_NAME = "widget.persistence.manager.dbtype";
+    
+    private static final Map<Class<?>,Class<?>> INTERFACE_TO_CLASS_MAP = new HashMap<Class<?>,Class<?>>();
+    private static final Map<Class<? extends IBean>,Class<? extends IBean>> BEAN_INTERFACE_TO_CLASS_MAP = new HashMap<Class<? extends IBean>,Class<? extends IBean>>();
+    private static final Map<Class<? extends IBean>,Class<?>> BEAN_INTERFACE_TO_ID_FIELD_TYPE_MAP = new HashMap<Class<? extends IBean>,Class<?>>();
+    private static final Map<String,String> DB_TYPE_TO_JPA_DICTIONARY_MAP = new HashMap<String,String>();
+    static
+    {
+        INTERFACE_TO_CLASS_MAP.put(IAccessRequest.class, AccessRequestImpl.class);
+        INTERFACE_TO_CLASS_MAP.put(IApiKey.class, ApiKeyImpl.class);
+        INTERFACE_TO_CLASS_MAP.put(IDescription.class, DescriptionImpl.class);
+        INTERFACE_TO_CLASS_MAP.put(IFeature.class, FeatureImpl.class);
+        INTERFACE_TO_CLASS_MAP.put(ILicense.class, LicenseImpl.class);
+        INTERFACE_TO_CLASS_MAP.put(IName.class, NameImpl.class);
+        INTERFACE_TO_CLASS_MAP.put(IParam.class, ParamImpl.class);
+        INTERFACE_TO_CLASS_MAP.put(IParticipant.class, ParticipantImpl.class);
+        INTERFACE_TO_CLASS_MAP.put(IPost.class, PostImpl.class);
+        INTERFACE_TO_CLASS_MAP.put(IPreference.class, PreferenceImpl.class);
+        INTERFACE_TO_CLASS_MAP.put(IPreferenceDefault.class, PreferenceDefaultImpl.class);
+        INTERFACE_TO_CLASS_MAP.put(IServerFeature.class, ServerFeatureImpl.class);
+        INTERFACE_TO_CLASS_MAP.put(ISharedData.class, SharedDataImpl.class);
+        INTERFACE_TO_CLASS_MAP.put(IStartFile.class, StartFileImpl.class);
+        INTERFACE_TO_CLASS_MAP.put(IToken.class, TokenImpl.class);
+        INTERFACE_TO_CLASS_MAP.put(IWhitelist.class, WhitelistImpl.class);
+        INTERFACE_TO_CLASS_MAP.put(IWidget.class, WidgetImpl.class);
+        INTERFACE_TO_CLASS_MAP.put(IWidgetDefault.class, WidgetDefaultImpl.class);
+        INTERFACE_TO_CLASS_MAP.put(IWidgetIcon.class, WidgetIconImpl.class);
+        INTERFACE_TO_CLASS_MAP.put(IWidgetInstance.class, WidgetInstanceImpl.class);
+        INTERFACE_TO_CLASS_MAP.put(IWidgetService.class, WidgetServiceImpl.class);
+        INTERFACE_TO_CLASS_MAP.put(IWidgetType.class, WidgetTypeImpl.class);
+
+        BEAN_INTERFACE_TO_CLASS_MAP.put(IAccessRequest.class, AccessRequestImpl.class);
+        BEAN_INTERFACE_TO_CLASS_MAP.put(IApiKey.class, ApiKeyImpl.class);
+        BEAN_INTERFACE_TO_CLASS_MAP.put(IParticipant.class, ParticipantImpl.class);
+        BEAN_INTERFACE_TO_CLASS_MAP.put(IPost.class, PostImpl.class);
+        BEAN_INTERFACE_TO_CLASS_MAP.put(IServerFeature.class, ServerFeatureImpl.class);
+        BEAN_INTERFACE_TO_CLASS_MAP.put(IWhitelist.class, WhitelistImpl.class);
+        BEAN_INTERFACE_TO_CLASS_MAP.put(IWidget.class, WidgetImpl.class);
+        BEAN_INTERFACE_TO_CLASS_MAP.put(IWidgetDefault.class, WidgetDefaultImpl.class);
+        BEAN_INTERFACE_TO_CLASS_MAP.put(IWidgetInstance.class, WidgetInstanceImpl.class);
+        BEAN_INTERFACE_TO_CLASS_MAP.put(IWidgetService.class, WidgetServiceImpl.class);
+
+        BEAN_INTERFACE_TO_ID_FIELD_TYPE_MAP.put(IAccessRequest.class, Integer.class);
+        BEAN_INTERFACE_TO_ID_FIELD_TYPE_MAP.put(IApiKey.class, Integer.class);
+        BEAN_INTERFACE_TO_ID_FIELD_TYPE_MAP.put(IParticipant.class, Integer.class);
+        BEAN_INTERFACE_TO_ID_FIELD_TYPE_MAP.put(IPost.class, Integer.class);
+        BEAN_INTERFACE_TO_ID_FIELD_TYPE_MAP.put(IServerFeature.class, Integer.class);
+        BEAN_INTERFACE_TO_ID_FIELD_TYPE_MAP.put(IWhitelist.class, Integer.class);
+        BEAN_INTERFACE_TO_ID_FIELD_TYPE_MAP.put(IWidget.class, Integer.class);
+        BEAN_INTERFACE_TO_ID_FIELD_TYPE_MAP.put(IWidgetDefault.class, String.class);
+        BEAN_INTERFACE_TO_ID_FIELD_TYPE_MAP.put(IWidgetInstance.class, Integer.class);
+        BEAN_INTERFACE_TO_ID_FIELD_TYPE_MAP.put(IWidgetService.class, Integer.class);
+        
+        DB_TYPE_TO_JPA_DICTIONARY_MAP.put("db2", "db2");
+        DB_TYPE_TO_JPA_DICTIONARY_MAP.put("derby", "derby");
+        DB_TYPE_TO_JPA_DICTIONARY_MAP.put("hsqldb", "hsql");
+        DB_TYPE_TO_JPA_DICTIONARY_MAP.put("mssql", "sqlserver");
+        DB_TYPE_TO_JPA_DICTIONARY_MAP.put("mysql", "mysql");
+        DB_TYPE_TO_JPA_DICTIONARY_MAP.put("mysql5", "mysql");
+        DB_TYPE_TO_JPA_DICTIONARY_MAP.put("oracle", "oracle");
+        DB_TYPE_TO_JPA_DICTIONARY_MAP.put("oracle9", "oracle");
+        DB_TYPE_TO_JPA_DICTIONARY_MAP.put("oracle10", "oracle");
+        DB_TYPE_TO_JPA_DICTIONARY_MAP.put("postgresql", "postgres");
+        DB_TYPE_TO_JPA_DICTIONARY_MAP.put("sybase", "sybase");
+    }
+
+    private static String cacheSize;
+    private static String dbType;
+    private static String dictionaryType;
+    private static OpenJPAEntityManagerFactory entityManagerFactory;
+    
+    /**
+     * Initialize implementation with configuration.
+     * 
+     * @param configuration configuration properties
+     * @param initializeStore truncate and initialize persistent store
+     */
+    public static void initialize(Configuration configuration, boolean initializeStore)
+    {
+        try
+        {
+            // configuration
+            cacheSize = configuration.getString(PERSISTENCE_MANAGER_CACHE_SIZE_PROPERTY_NAME);
+            dbType = configuration.getString(PERSISTENCE_MANAGER_DB_TYPE_PROPERTY_NAME);
+            dictionaryType = ((dbType != null) ? DB_TYPE_TO_JPA_DICTIONARY_MAP.get(dbType) : null);
+            if ((dbType != null) && (dictionaryType == null)) 
+            {
+                throw new IllegalArgumentException("Unsupported database type: "+dbType);
+            }
+
+            // initialize persistent store
+            if (initializeStore && (dbType != null))
+            {
+                // get datasource connection
+                Context initialContext = new InitialContext();
+                DataSource dataSource = (DataSource)initialContext.lookup(WIDGET_DATABASE_JNDI_DATASOURCE_FULL_NAME);
+                Connection connection = dataSource.getConnection();
+                connection.setAutoCommit(true);
+
+                // execute initialization scripts
+                String sqlScriptResource = dbType+"-wookie-schema.sql";
+                InputStream sqlStream = JPAPersistenceManager.class.getResourceAsStream(sqlScriptResource);
+                if (sqlStream == null)
+                {
+                    throw new IllegalArgumentException("Unsupported persistent store initialization script: "+sqlScriptResource);                    
+                }
+                SQLScriptReader reader = new SQLScriptReader(sqlStream);
+                int statementCount = 0;
+                int statementErrorCount = 0;
+                for (;;)
+                {
+                    String scriptStatement = reader.readSQLStatement();
+                    if (scriptStatement != null)
+                    {
+                        Statement statement = connection.createStatement();
+                        statementCount++;
+                        try
+                        {
+                            statement.execute(scriptStatement);
+                        }
+                        catch (SQLException sqle)
+                        {
+                            statementErrorCount++;
+                        }
+                    }
+                    else
+                    {
+                        break;
+                    }
+                }
+                logger.info("Persistent store initialized from "+sqlScriptResource+", ("+statementCount+" statements, "+statementErrorCount+" errors)");
+                    
+                // close datasource connection
+                connection.close();
+            }
+            
+            // initialize entity manager factory
+            Properties persistenceProperties = new Properties();
+            InputStream propertiesStream = JPAPersistenceManager.class.getResourceAsStream("persistence.properties");
+            if (propertiesStream == null)
+            {
+                throw new IllegalArgumentException("Unable to load configuration: persistence.properties");
+            }            
+            persistenceProperties.load(propertiesStream);
+            if (cacheSize != null)
+            {
+                int dataCacheSize = Integer.parseInt(cacheSize);
+                persistenceProperties.setProperty("openjpa.DataCache", "true(CacheSize="+dataCacheSize+",SoftReferenceSize=0)");                
+                int queryCacheSize = Integer.parseInt(cacheSize)/10;
+                persistenceProperties.setProperty("openjpa.QueryCache", "CacheSize="+queryCacheSize+",SoftReferenceSize=0");                
+            }
+            if (dictionaryType != null)
+            {
+                persistenceProperties.setProperty("openjpa.jdbc.DBDictionary", dictionaryType);
+            }
+            EntityManagerFactory factory = Persistence.createEntityManagerFactory("wookie", persistenceProperties);
+            entityManagerFactory = OpenJPAPersistence.cast(factory);
+
+            logger.info("Initialized");
+        }
+        catch (Exception e)
+        {
+            throw new RuntimeException("Unable to initialize: "+e, e);
+        }
+    }
+
+    /**
+     * Terminate implementation.
+     */
+    public static void terminate()
+    {
+        try
+        {
+            // evict all caches
+            StoreCache cache = entityManagerFactory.getStoreCache();
+            cache.evictAll();
+            QueryResultCache queryCache = entityManagerFactory.getQueryResultCache();
+            queryCache.evictAll();
+            
+            // close entity manager factory
+            entityManagerFactory.close();
+            entityManagerFactory = null;
+            
+            logger.info("Terminated");
+        }
+        catch (Exception e)
+        {            
+            throw new RuntimeException("Unable to terminate: "+e, e);
+        }
+    }
+
+    private EntityManager entityManager;
+    
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.util.IPersistenceManager#begin()
+     */
+    public void begin()
+    {
+        // validate entity manager transaction
+        if (entityManager != null)
+        {
+            throw new IllegalStateException("Transaction already initiated");
+        }
+
+        // create entity manager and start transaction
+        entityManager = entityManagerFactory.createEntityManager();
+        EntityTransaction transaction = entityManager.getTransaction();
+        if (!transaction.isActive())
+        {
+            transaction.begin();
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.util.IPersistenceManager#close()
+     */
+    public void close()
+    {
+        // validate entity manager transaction
+        if (entityManager == null)
+        {
+            throw new IllegalStateException("Transaction not initiated or already closed");
+        }        
+
+        // rollback transaction and close entity manager
+        EntityTransaction transaction = entityManager.getTransaction();
+        if (transaction.isActive())
+        {
+            transaction.rollback();
+        }
+        entityManager.clear();
+        entityManager.close();
+        entityManager = null;            
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.util.IPersistenceManager#commit()
+     */
+    public void commit()
+    {
+        // validate entity manager transaction
+        if (entityManager == null)
+        {
+            throw new IllegalStateException("Transaction not initiated or already closed");
+        }        
+
+        // commit transaction
+        EntityTransaction transaction = entityManager.getTransaction();
+        if (transaction.isActive())
+        {
+            transaction.commit();
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.util.IPersistenceManager#delete(org.apache.wookie.beans.IBean)
+     */
+    public boolean delete(IBean bean)
+    {
+        // validate entity manager transaction
+        if (entityManager == null)
+        {
+            throw new IllegalStateException("Transaction not initiated or already closed");
+        }        
+
+        // remove bean
+        try
+        {
+            entityManager.remove(bean);
+            return true;
+        }
+        catch (Exception e)
+        {
+            logger.error("Unexpected exception: "+e, e);
+            return false;
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.util.IPersistenceManager#delete(org.apache.wookie.beans.IBean[])
+     */
+    public boolean delete(IBean[] beans)
+    {
+        // validate entity manager transaction
+        if (entityManager == null)
+        {
+            throw new IllegalStateException("Transaction not initiated or already closed");
+        }        
+
+        // remove beans
+        try
+        {
+            for (IBean bean : beans)
+            {
+                entityManager.remove(bean);
+            }
+            return true;
+        }
+        catch (Exception e)
+        {
+            logger.error("Unexpected exception: "+e, e);
+            return false;
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.util.IPersistenceManager#findAll(java.lang.Class)
+     */
+    @SuppressWarnings("unchecked")
+    public <T extends IBean> T [] findAll(Class<T> beansInterface)
+    {
+        // validate entity manager transaction
+        if (entityManager == null)
+        {
+            throw new IllegalStateException("Transaction not initiated or already closed");
+        }        
+
+        // validate bean interface
+        Class<? extends IBean> beanClass = BEAN_INTERFACE_TO_CLASS_MAP.get(beansInterface);
+        if (beanClass == null)
+        {
+            throw new IllegalArgumentException("Invalid bean interface specified");            
+        }
+
+        // get persistent bean extent
+        try
+        {
+            OpenJPAEntityManager manager = OpenJPAPersistence.cast(entityManager);
+            Extent<? extends IBean> beansExtent = manager.createExtent(beanClass, true);
+            List<? extends IBean> beansExtentList = beansExtent.list();
+            if ((beansExtentList != null) && !beansExtentList.isEmpty())
+            {
+                return beansExtentList.toArray((T [])Array.newInstance(beansInterface, beansExtentList.size()));
+            }
+        }
+        catch (Exception e)
+        {
+            logger.error("Unexpected exception: "+e, e);
+        }
+        return (T [])Array.newInstance(beansInterface, 0);
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.util.IPersistenceManager#findApplicableAccessRequests(org.apache.wookie.beans.IWidget)
+     */
+    @SuppressWarnings("unchecked")
+    public IAccessRequest [] findApplicableAccessRequests(IWidget widget)
+    {
+        // validate entity manager transaction
+        if (entityManager == null)
+        {
+            throw new IllegalStateException("Transaction not initiated or already closed");
+        }        
+
+        // get applicable access requests for widget using custom query
+        if (widget != null)
+        {
+            try
+            {
+                Query query = entityManager.createNamedQuery("ACCESS_REQUESTS");
+                query.setParameter("widget", widget);
+                List<IParticipant> accessRequestsList = query.getResultList();
+                if ((accessRequestsList != null) && !accessRequestsList.isEmpty())
+                {
+                    return accessRequestsList.toArray(new IAccessRequest[accessRequestsList.size()]);
+                }
+            }
+            catch (Exception e)
+            {
+                logger.error("Unexpected exception: "+e, e);
+            }
+        }
+        return new IAccessRequest[0];
+        
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.util.IPersistenceManager#findById(java.lang.Class, java.lang.Object)
+     */
+    @SuppressWarnings("unchecked")
+    public <T extends IBean> T findById(Class<T> beanInterface, Object id)
+    {
+        // validate entity manager transaction
+        if (entityManager == null)
+        {
+            throw new IllegalStateException("Transaction not initiated or already closed");
+        }        
+
+        // validate bean interface
+        Class<? extends IBean> beanClass = BEAN_INTERFACE_TO_CLASS_MAP.get(beanInterface);
+        Class<?> idFieldType = BEAN_INTERFACE_TO_ID_FIELD_TYPE_MAP.get(beanInterface);
+        if ((beanClass == null) || (idFieldType == null))
+        {
+            throw new IllegalArgumentException("Invalid bean interface specified");            
+        }
+
+        // get persistent bean by primary key
+        try
+        {
+            if (id != null)
+            {
+                if ((idFieldType == Integer.class) && !(id instanceof Integer))
+                {
+                    try
+                    {
+                        id = new Integer(id.toString());
+                    }
+                    catch (NumberFormatException nfe)
+                    {
+                        return null;
+                    }
+                }
+                else if ((idFieldType == String.class) && !(id instanceof String))
+                {
+                    id = id.toString();
+                }
+            }
+            return (T)entityManager.find(beanClass, id);
+        }
+        catch (Exception e)
+        {
+            logger.error("Unexpected exception: "+e, e);
+            return null;
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.util.IPersistenceManager#findByValue(java.lang.Class, java.lang.String, java.lang.Object, java.lang.String, boolean)
+     */
+    @SuppressWarnings("unchecked")
+    public <T extends IBean> T [] findByValue(Class<T> beansInterface, String name, Object value, String orderBy, boolean ascending)
+    {
+        // validate entity manager transaction
+        if (entityManager == null)
+        {
+            throw new IllegalStateException("Transaction not initiated or already closed");
+        }        
+
+        // validate bean interface
+        Class<? extends IBean> beanClass = BEAN_INTERFACE_TO_CLASS_MAP.get(beansInterface);
+        if (beanClass == null)
+        {
+            throw new IllegalArgumentException("Invalid bean interface specified");            
+        }
+
+        // get persistent beans by criteria
+        try
+        {
+            // construct query criteria
+            CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
+            CriteriaQuery<? extends IBean> criteriaQuery = criteriaBuilder.createQuery(beanClass);
+            Root<? extends IBean> beanRoot = criteriaQuery.from(beanClass);
+            if (name != null)
+            {
+                criteriaQuery.where((value != null) ? criteriaBuilder.equal(beanRoot.get(name), value) : criteriaBuilder.isNull(beanRoot.get(name)));
+            }
+            if (orderBy != null)
+            {
+                criteriaQuery.orderBy(ascending ? criteriaBuilder.asc(beanRoot.get(orderBy)) : criteriaBuilder.desc(beanRoot.get(orderBy)));
+            }
+            
+            // invoke query
+            Query query = entityManager.createQuery(criteriaQuery);
+            List<? extends IBean> beansList = query.getResultList();
+            if ((beansList != null) && !beansList.isEmpty())
+            {
+                return beansList.toArray((T [])Array.newInstance(beansInterface, beansList.size()));
+            }
+        }
+        catch (Exception e)
+        {
+            logger.error("Unexpected exception: "+e, e);
+        }
+        return (T [])Array.newInstance(beansInterface, 0);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.util.IPersistenceManager#findByValue(java.lang.Class, java.lang.String, java.lang.Object)
+     */
+    public <T extends IBean> T [] findByValue(Class<T> beansInterface, String name, Object value)
+    {
+        return findByValue(beansInterface, name, value, null, true);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.util.IPersistenceManager#findByValues(java.lang.Class, java.util.Map, java.lang.String, boolean)
+     */
+    @SuppressWarnings("unchecked")
+    public <T extends IBean> T [] findByValues(Class<T> beansInterface, Map<String, Object> values, String orderBy, boolean ascending)
+    {
+        // validate entity manager transaction
+        if (entityManager == null)
+        {
+            throw new IllegalStateException("Transaction not initiated or already closed");
+        }        
+
+        // validate bean interface
+        Class<? extends IBean> beanClass = BEAN_INTERFACE_TO_CLASS_MAP.get(beansInterface);
+        if (beanClass == null)
+        {
+            throw new IllegalArgumentException("Invalid bean interface specified");            
+        }
+
+        // get persistent beans by criteria
+        try
+        {
+            // construct query criteria
+            CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
+            CriteriaQuery<? extends IBean> criteriaQuery = criteriaBuilder.createQuery(beanClass);
+            Root<? extends IBean> beanRoot = criteriaQuery.from(beanClass);
+            if ((values != null) && !values.isEmpty())
+            {
+                Predicate predicate = null;
+                for (Map.Entry<String,Object> value : values.entrySet())
+                {
+                    Predicate valuePredicate = ((value.getValue() != null) ? criteriaBuilder.equal(beanRoot.get(value.getKey()), value.getValue()) : criteriaBuilder.isNull(beanRoot.get(value.getKey())));
+                    predicate = ((predicate != null) ? criteriaBuilder.and(predicate, valuePredicate) : valuePredicate);
+                }
+                criteriaQuery.where(predicate);
+            }
+            if (orderBy != null)
+            {
+                criteriaQuery.orderBy(ascending ? criteriaBuilder.asc(beanRoot.get(orderBy)) : criteriaBuilder.desc(beanRoot.get(orderBy)));
+            }
+            
+            // invoke query
+            Query query = entityManager.createQuery(criteriaQuery);
+            List<? extends IBean> beansList = query.getResultList();
+            if ((beansList != null) && !beansList.isEmpty())
+            {
+                return beansList.toArray((T [])Array.newInstance(beansInterface, beansList.size()));
+            }
+        }
+        catch (Exception e)
+        {
+            logger.error("Unexpected exception: "+e, e);
+        }
+        return (T [])Array.newInstance(beansInterface, 0);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.util.IPersistenceManager#findByValues(java.lang.Class, java.util.Map)
+     */
+    public <T extends IBean> T [] findByValues(Class<T> beansInterface, Map<String, Object> values)
+    {
+        return findByValues(beansInterface, values, null, true);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.util.IPersistenceManager#findParticipants(org.apache.wookie.beans.IWidgetInstance)
+     */
+    @SuppressWarnings("unchecked")
+    public IParticipant[] findParticipants(IWidgetInstance widgetInstance)
+    {
+        // validate entity manager transaction
+        if (entityManager == null)
+        {
+            throw new IllegalStateException("Transaction not initiated or already closed");
+        }        
+
+        // get participants for widget instance using custom query
+        if (widgetInstance != null)
+        {
+            try
+            {
+                String sharedDataKey = widgetInstance.getSharedDataKey();
+                IWidget widget = widgetInstance.getWidget();
+                Query query = entityManager.createNamedQuery("PARTICIPANTS");
+                query.setParameter("sharedDataKey", sharedDataKey);
+                query.setParameter("widget", widget);
+                List<IParticipant> participantsList = query.getResultList();
+                if ((participantsList != null) && !participantsList.isEmpty())
+                {
+                    return participantsList.toArray(new IParticipant[participantsList.size()]);
+                }
+            }
+            catch (Exception e)
+            {
+                logger.error("Unexpected exception: "+e, e);
+            }
+        }
+        return new IParticipant[0];
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.util.IPersistenceManager#findParticipantViewer(org.apache.wookie.beans.IWidgetInstance)
+     */
+    public IParticipant findParticipantViewer(IWidgetInstance widgetInstance)
+    {
+        // validate entity manager transaction
+        if (entityManager == null)
+        {
+            throw new IllegalStateException("Transaction not initiated or already closed");
+        }        
+
+        // get participant viewer for widget instance using custom query
+        if (widgetInstance != null)
+        {
+            try
+            {
+                String sharedDataKey = widgetInstance.getSharedDataKey();
+                IWidget widget = widgetInstance.getWidget();
+                String userId = widgetInstance.getUserId();
+                Query query = entityManager.createNamedQuery("PARTICIPANT_VIEWER");
+                query.setParameter("sharedDataKey", sharedDataKey);
+                query.setParameter("widget", widget);
+                query.setParameter("userId", userId);
+                return (IParticipant)query.getSingleResult();
+            }
+            catch (NoResultException nre)
+            {
+            }
+            catch (Exception e)
+            {
+                logger.error("Unexpected exception: "+e, e);
+            }
+        }
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.util.IPersistenceManager#findServerFeatureByName(java.lang.String)
+     */
+    public IServerFeature findServerFeatureByName(String name)
+    {
+        // validate entity manager transaction
+        if (entityManager == null)
+        {
+            throw new IllegalStateException("Transaction not initiated or already closed");
+        }        
+
+        // get server feature by name using custom query
+        if (name != null)
+        {
+            try
+            {
+                Query query = entityManager.createNamedQuery("SERVER_FEATURE");
+                query.setParameter("featureName", name);
+                return (IServerFeature)query.getSingleResult();
+            }
+            catch (NoResultException nre)
+            {
+            }
+            catch (Exception e)
+            {
+                logger.error("Unexpected exception: "+e, e);
+            }
+        }
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.util.IPersistenceManager#findServerFeatureNames()
+     */
+    @SuppressWarnings("unchecked")
+    public String[] findServerFeatureNames()
+    {
+        // validate entity manager transaction
+        if (entityManager == null)
+        {
+            throw new IllegalStateException("Transaction not initiated or already closed");
+        }        
+
+        // get server feature names using custom query
+        try
+        {
+            Query query = entityManager.createNamedQuery("SERVER_FEATURE_NAMES");
+            List<String> namesList = query.getResultList();
+            if ((namesList != null) && !namesList.isEmpty())
+            {
+                return namesList.toArray(new String[namesList.size()]);
+            }
+        }
+        catch (Exception e)
+        {
+            logger.error("Unexpected exception: "+e, e);
+        }
+        return new String[0];
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.util.IPersistenceManager#findWidgetByGuid(java.lang.String)
+     */
+    public IWidget findWidgetByGuid(String guid)
+    {
+        // validate entity manager transaction
+        if (entityManager == null)
+        {
+            throw new IllegalStateException("Transaction not initiated or already closed");
+        }        
+
+        // get widget by GUID using custom query
+        if (guid != null)
+        {
+            try
+            {
+                Query query = entityManager.createNamedQuery("WIDGET");
+                query.setParameter("guid", guid);
+                return (IWidget)query.getSingleResult();
+            }
+            catch (NoResultException nre)
+            {
+            }
+            catch (Exception e)
+            {
+                logger.error("Unexpected exception: "+e, e);
+            }
+        }
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.util.IPersistenceManager#findWidgetDefaultByType(java.lang.String)
+     */
+    public IWidget findWidgetDefaultByType(String widgetContext)
+    {
+        // validate entity manager transaction
+        if (entityManager == null)
+        {
+            throw new IllegalStateException("Transaction not initiated or already closed");
+        }        
+
+        // get default widget by type using custom query
+        if (widgetContext != null)
+        {
+            try
+            {
+                Query query = entityManager.createNamedQuery("DEFAULT_WIDGET");
+                query.setParameter("widgetContext", widgetContext);
+                return (IWidget)query.getSingleResult();
+            }
+            catch (NoResultException nre)
+            {
+            }
+            catch (Exception e)
+            {
+                logger.error("Unexpected exception: "+e, e);
+            }
+        }
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.util.IPersistenceManager#findWidgetInstance(java.lang.String, java.lang.String, java.lang.String, java.lang.String)
+     */
+    public IWidgetInstance findWidgetInstance(String apiKey, String userId, String sharedDataKey, String serviceContext)
+    {
+        // validate entity manager transaction
+        if (entityManager == null)
+        {
+            throw new IllegalStateException("Transaction not initiated or already closed");
+        }        
+
+        // get widget instance using custom query
+        if ((apiKey != null) && (userId != null) && (sharedDataKey != null) && (serviceContext != null))
+        {
+            try
+            {
+                Query query = entityManager.createNamedQuery("WIDGET_INSTANCE");
+                query.setParameter("apiKey", apiKey);
+                query.setParameter("userId", userId);
+                query.setParameter("sharedDataKey", sharedDataKey);
+                query.setParameter("widgetContext", serviceContext);
+                return (IWidgetInstance)query.getSingleResult();
+            }
+            catch (NoResultException nre)
+            {
+            }
+            catch (Exception e)
+            {
+                logger.error("Unexpected exception: "+e, e);
+            }
+        }
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.util.IPersistenceManager#findWidgetInstanceByGuid(java.lang.String, java.lang.String, java.lang.String, java.lang.String)
+     */
+    public IWidgetInstance findWidgetInstanceByGuid(String apiKey, String userId, String sharedDataKey, String widgetGuid)
+    {
+        // validate entity manager transaction
+        if (entityManager == null)
+        {
+            throw new IllegalStateException("Transaction not initiated or already closed");
+        }        
+
+        // get widget instance using custom query
+        if ((apiKey != null) && (userId != null) && (sharedDataKey != null) && (widgetGuid != null))
+        {
+            try
+            {
+                Query query = entityManager.createNamedQuery("WIDGET_INSTANCE_GUID");
+                query.setParameter("apiKey", apiKey);
+                query.setParameter("userId", userId);
+                query.setParameter("sharedDataKey", sharedDataKey);
+                query.setParameter("guid", widgetGuid);
+                return (IWidgetInstance)query.getSingleResult();
+            }
+            catch (NoResultException nre)
+            {
+            }
+            catch (Exception e)
+            {
+                logger.error("Unexpected exception: "+e, e);
+            }
+        }
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.util.IPersistenceManager#findWidgetInstanceByIdKey(java.lang.String)
+     */
+    public IWidgetInstance findWidgetInstanceByIdKey(String idKey)
+    {
+        // validate entity manager transaction
+        if (entityManager == null)
+        {
+            throw new IllegalStateException("Transaction not initiated or already closed");
+        }        
+
+        // get widget instance using custom query
+        if (idKey != null)
+        {
+            try
+            {
+                Query query = entityManager.createNamedQuery("WIDGET_INSTANCE_ID");
+                query.setParameter("idKey", idKey);
+                return (IWidgetInstance)query.getSingleResult();
+            }
+            catch (NoResultException nre)
+            {
+            }
+            catch (Exception e)
+            {
+                logger.error("Unexpected exception: "+e, e);
+            }
+        }
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.util.IPersistenceManager#findWidgetsByType(java.lang.String)
+     */
+    @SuppressWarnings("unchecked")
+    public IWidget[] findWidgetsByType(String widgetContext)
+    {
+        // validate entity manager transaction
+        if (entityManager == null)
+        {
+            throw new IllegalStateException("Transaction not initiated or already closed");
+        }        
+
+        // get widgets by type using custom query
+        if (widgetContext != null)
+        {
+            try
+            {
+                Query query = entityManager.createNamedQuery("WIDGETS");
+                query.setParameter("widgetContext", widgetContext);
+                List<IWidget> widgetsList = query.getResultList();
+                if ((widgetsList != null) && !widgetsList.isEmpty())
+                {
+                    return widgetsList.toArray(new IWidget[widgetsList.size()]);
+                }
+            }
+            catch (Exception e)
+            {
+                logger.error("Unexpected exception: "+e, e);
+            }
+        }
+        return new IWidget[0];
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.util.IPersistenceManager#newInstance(java.lang.Class)
+     */
+    @SuppressWarnings("unchecked")
+    public <T> T newInstance(Class<T> instanceInterface)
+    {
+        // validate instance interface
+        Class<?> instanceClass = INTERFACE_TO_CLASS_MAP.get(instanceInterface);
+        if (instanceClass == null)
+        {
+            throw new IllegalArgumentException("Invalid instance interface specified");            
+        }
+
+        // create new instance of persistent class
+        try
+        {
+            return (T)instanceClass.newInstance();
+        }
+        catch (Exception e)
+        {
+            logger.error("Unexpected exception: "+e, e);
+            return null;
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.util.IPersistenceManager#rollback()
+     */
+    public void rollback()
+    {
+        // validate entity manager transaction
+        if (entityManager == null)
+        {
+            throw new IllegalStateException("Transaction not initiated or already closed");
+        }        
+
+        // commit transaction
+        EntityTransaction transaction = entityManager.getTransaction();
+        if (transaction.isActive())
+        {
+            transaction.rollback();
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.util.IPersistenceManager#save(org.apache.wookie.beans.IBean)
+     */
+    public boolean save(IBean bean)
+    {
+        // validate entity manager transaction
+        if (entityManager == null)
+        {
+            throw new IllegalStateException("Transaction not initiated or already closed");
+        }        
+
+        // persist new or update existing bean
+        try
+        {
+            entityManager.persist(bean);
+            return true;
+        }
+        catch (Exception e)
+        {
+            logger.error("Unexpected exception: "+e, e);
+            return false;
+        }
+    }
+}

Added: incubator/wookie/branches/pluggablepersistence/src/org/apache/wookie/beans/jpa/SQLScriptReader.java
URL: http://svn.apache.org/viewvc/incubator/wookie/branches/pluggablepersistence/src/org/apache/wookie/beans/jpa/SQLScriptReader.java?rev=955236&view=auto
==============================================================================
--- incubator/wookie/branches/pluggablepersistence/src/org/apache/wookie/beans/jpa/SQLScriptReader.java (added)
+++ incubator/wookie/branches/pluggablepersistence/src/org/apache/wookie/beans/jpa/SQLScriptReader.java Wed Jun 16 14:16:36 2010
@@ -0,0 +1,118 @@
+/*
+ *  Licensed 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.wookie.beans.jpa;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+/**
+ * SQLScriptReader - SQL script file reader.
+ * 
+ * @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
+ * @version $Id$
+ */
+public class SQLScriptReader
+{
+    private static final String EOL = System.getProperty("line.separator");
+    
+    private BufferedReader reader;
+    
+    /**
+     * Construct reader for SQL script stream.
+     * 
+     * @param scriptStream script stream
+     * @throws FileNotFoundException
+     */
+    public SQLScriptReader(InputStream scriptStream) throws FileNotFoundException
+    {
+        this.reader = new BufferedReader(new InputStreamReader(scriptStream));
+    }
+    
+    /**
+     * Construct reader for SQL script file.
+     * 
+     * @param scriptFile script file
+     * @throws FileNotFoundException
+     */
+    public SQLScriptReader(File scriptFile) throws FileNotFoundException
+    {
+        this.reader = new BufferedReader(new FileReader(scriptFile));
+    }
+    
+    /**
+     * Read next SQL statement from script file.
+     * 
+     * @return read SQL statement
+     * @throws IOException
+     */
+    public String readSQLStatement() throws IOException
+    {
+        StringBuilder sqlStatement = new StringBuilder();
+        boolean comment = false;
+        for (;;)
+        {
+            String line = reader.readLine();
+            if (line != null)
+            {
+                line = line.trim();
+                if (comment)
+                {
+                    comment = !line.endsWith("*/");
+                }
+                else
+                {
+                    comment = line.startsWith("/*");
+                    if (!comment && !line.startsWith("--") && !line.startsWith("//") && !line.startsWith("#") && (line.length() > 0))
+                    {
+                        if (sqlStatement.length() > 0)
+                        {
+                            sqlStatement.append(EOL);
+                        }
+                        if (line.endsWith(";"))
+                        {
+                            sqlStatement.append(line.substring(0, line.length()-1));
+                            break;
+                        }
+                        else
+                        {
+                            sqlStatement.append(line);
+                        }
+                    }
+                }
+            }
+            else
+            {
+                sqlStatement.setLength(0);
+                break;
+            }
+        }
+        return ((sqlStatement.length() > 0) ? sqlStatement.toString() : null);
+    }
+
+    /**
+     * Close reader.
+     * 
+     * @throws IOException
+     */
+    public void close() throws IOException
+    {
+        reader.close();
+    }
+}

Added: incubator/wookie/branches/pluggablepersistence/src/org/apache/wookie/beans/jpa/impl/AccessRequestImpl.java
URL: http://svn.apache.org/viewvc/incubator/wookie/branches/pluggablepersistence/src/org/apache/wookie/beans/jpa/impl/AccessRequestImpl.java?rev=955236&view=auto
==============================================================================
--- incubator/wookie/branches/pluggablepersistence/src/org/apache/wookie/beans/jpa/impl/AccessRequestImpl.java (added)
+++ incubator/wookie/branches/pluggablepersistence/src/org/apache/wookie/beans/jpa/impl/AccessRequestImpl.java Wed Jun 16 14:16:36 2010
@@ -0,0 +1,159 @@
+/*
+ *  Licensed 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.wookie.beans.jpa.impl;
+
+import java.net.URI;
+
+import javax.persistence.Basic;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
+import javax.persistence.Table;
+import javax.persistence.Version;
+
+import org.apache.openjpa.persistence.ExternalValues;
+import org.apache.openjpa.persistence.Type;
+
+import org.apache.wookie.beans.IAccessRequest;
+import org.apache.wookie.beans.IWidget;
+
+/**
+ * AccessRequestImpl - JPA IAccessRequest implementation.
+ * 
+ * @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
+ * @version $Id$
+ */
+@Entity(name="AccessRequest")
+@Table(name="AccessRequest")
+@NamedQueries({@NamedQuery(name="ACCESS_REQUESTS", query="SELECT ar FROM AccessRequest ar WHERE ar.widget = :widget AND ar.granted = TRUE")})
+public class AccessRequestImpl implements IAccessRequest
+{
+    @Id
+    @GeneratedValue(strategy=GenerationType.AUTO)
+    @Column(name="id", nullable=false)
+    private int id;
+
+    @Version
+    @Column(name="jpa_version")
+    @SuppressWarnings("unused")
+    private int jpaVersion;
+
+    @Basic
+    @Column(name="origin")
+    private String origin;
+
+    @Basic
+    @Column(name="subdomains")
+    @ExternalValues({"true=t","false=f","null="})
+    @Type(String.class)
+    private Boolean subdomains;
+
+    @Basic
+    @Column(name="granted")
+    @ExternalValues({"true=t","false=f","null="})
+    @Type(String.class)
+    private Boolean granted;
+
+    @ManyToOne(fetch=FetchType.LAZY, optional=false)
+    @JoinColumn(name="widget_id", referencedColumnName="id", nullable=false)
+    private WidgetImpl widget;
+    
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IBean#getId()
+     */
+    public Object getId()
+    {
+        return id;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IAccessRequest#getOrigin()
+     */
+    public String getOrigin()
+    {
+        return origin;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IAccessRequest#setOrigin(java.lang.String)
+     */
+    public void setOrigin(String origin)
+    {
+        this.origin = origin;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IAccessRequest#isGranted()
+     */
+    public boolean isGranted()
+    {
+        return ((granted != null) ? granted.booleanValue() : false);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IAccessRequest#setGranted(boolean)
+     */
+    public void setGranted(boolean granted)
+    {
+        this.granted = (granted ? Boolean.TRUE : Boolean.FALSE);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IAccessRequest#isSubdomains()
+     */
+    public boolean isSubdomains()
+    {
+        return ((subdomains != null) ? subdomains.booleanValue() : false);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IAccessRequest#setSubdomains(boolean)
+     */
+    public void setSubdomains(boolean subdomains)
+    {
+        this.subdomains = (subdomains ? Boolean.TRUE : Boolean.FALSE);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IAccessRequest#getWidget()
+     */
+    public IWidget getWidget()
+    {
+        return widget;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IAccessRequest#setWidget(org.apache.wookie.beans.IWidget)
+     */
+    public void setWidget(IWidget widget)
+    {
+        this.widget = (WidgetImpl)widget;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IAccessRequest#isAllowed(java.net.URI)
+     */
+    public boolean isAllowed(URI requestedUri)
+    {
+        return Utilities.isAllowed(this, requestedUri);
+    }
+}

Added: incubator/wookie/branches/pluggablepersistence/src/org/apache/wookie/beans/jpa/impl/ApiKeyImpl.java
URL: http://svn.apache.org/viewvc/incubator/wookie/branches/pluggablepersistence/src/org/apache/wookie/beans/jpa/impl/ApiKeyImpl.java?rev=955236&view=auto
==============================================================================
--- incubator/wookie/branches/pluggablepersistence/src/org/apache/wookie/beans/jpa/impl/ApiKeyImpl.java (added)
+++ incubator/wookie/branches/pluggablepersistence/src/org/apache/wookie/beans/jpa/impl/ApiKeyImpl.java Wed Jun 16 14:16:36 2010
@@ -0,0 +1,95 @@
+/*
+ *  Licensed 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.wookie.beans.jpa.impl;
+
+import javax.persistence.Basic;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.persistence.Version;
+
+import org.apache.wookie.beans.IApiKey;
+
+/**
+ * ApiKeyImpl - JPA IApiKey implementation.
+ * 
+ * @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
+ * @version $Id$
+ */
+@Entity(name="ApiKey")
+@Table(name="ApiKey")
+public class ApiKeyImpl implements IApiKey
+{
+    @Id
+    @GeneratedValue(strategy=GenerationType.AUTO)
+    @Column(name="id", nullable=false)
+    private int id;
+
+    @Version
+    @Column(name="jpa_version")
+    @SuppressWarnings("unused")
+    private int jpaVersion;
+
+    @Basic(optional=false)
+    @Column(name="value", nullable=false)
+    private String value;
+
+    @Basic(optional=false)
+    @Column(name="email", nullable=false)
+    private String email;
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IApiKey#getEmail()
+     */
+    public String getEmail()
+    {
+        return email;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IApiKey#setEmail(java.lang.String)
+     */
+    public void setEmail(String email)
+    {
+        this.email = email;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IBean#getId()
+     */
+    public Object getId()
+    {
+        return id;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IApiKey#getValue()
+     */
+    public String getValue()
+    {
+        return value;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IApiKey#setValue(java.lang.String)
+     */
+    public void setValue(String value)
+    {
+        this.value = value;
+    }
+}

Added: incubator/wookie/branches/pluggablepersistence/src/org/apache/wookie/beans/jpa/impl/DescriptionImpl.java
URL: http://svn.apache.org/viewvc/incubator/wookie/branches/pluggablepersistence/src/org/apache/wookie/beans/jpa/impl/DescriptionImpl.java?rev=955236&view=auto
==============================================================================
--- incubator/wookie/branches/pluggablepersistence/src/org/apache/wookie/beans/jpa/impl/DescriptionImpl.java (added)
+++ incubator/wookie/branches/pluggablepersistence/src/org/apache/wookie/beans/jpa/impl/DescriptionImpl.java Wed Jun 16 14:16:36 2010
@@ -0,0 +1,85 @@
+/*
+ *  Licensed 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.wookie.beans.jpa.impl;
+
+import javax.persistence.Basic;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import javax.persistence.Version;
+
+import org.apache.wookie.beans.IDescription;
+import org.apache.wookie.beans.jpa.IInverseRelationship;
+
+/**
+ * DescriptionImpl - JPA IDescription implementation.
+ * 
+ * @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
+ * @version $Id$
+ */
+@Entity(name="Description")
+@Table(name="Description")
+public class DescriptionImpl extends LocalizedBeanImpl implements IDescription, IInverseRelationship<WidgetImpl>
+{
+    @Id
+    @GeneratedValue(strategy=GenerationType.AUTO)
+    @Column(name="id", nullable=false)
+    @SuppressWarnings("unused")
+    private int id;
+
+    @Version
+    @Column(name="jpa_version")
+    @SuppressWarnings("unused")
+    private int jpaVersion;
+
+    @Basic
+    @Column(name="content")
+    private String content;
+
+    @ManyToOne(fetch=FetchType.LAZY)
+    @JoinColumn(name="widget_id", referencedColumnName="id")
+    @SuppressWarnings("unused")
+    private WidgetImpl widget;
+    
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.util.IInverseRelationship#updateInverseRelationship(java.lang.Object)
+     */
+    public void updateInverseRelationship(WidgetImpl owningObject)
+    {
+        widget = owningObject;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IDescription#getContent()
+     */
+    public String getContent()
+    {
+        return content;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.beans.IDescription#setContent(java.lang.String)
+     */
+    public void setContent(String text)
+    {
+        this.content = text;
+    }
+}