[jboss-svn-commits] JBoss Portal SVN: r5217 - in trunk: . cms cms/jackrabbit-customization cms/jackrabbit-customization/lib cms/jackrabbit-customization/src cms/jackrabbit-customization/src/org cms/jackrabbit-customization/src/org/apache cms/jackrabbit-customization/src/org/apache/jackrabbit cms/jackrabbit-customization/src/org/apache/jackrabbit/core cms/jackrabbit-customization/src/org/apache/jackrabbit/core/state cms/src/main/org/jboss/portal/cms/hibernate/state cms/src/main/org/jboss/portal/cms/impl/jcr/command cms/src/main/org/jboss/portal/cms/impl/jcr/jackrabbit core core/src/resources/portal-cms-sar/META-INF core/src/resources/portal-cms-sar/conf/hibernate/cms
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Mon Sep 18 00:24:04 EDT 2006
Author: sohil.shah at jboss.com
Date: 2006-09-18 00:21:11 -0400 (Mon, 18 Sep 2006)
New Revision: 5217
Added:
trunk/cms/jackrabbit-customization/
trunk/cms/jackrabbit-customization/lib/
trunk/cms/jackrabbit-customization/lib/jackrabbit-core-1.0.1.jar
trunk/cms/jackrabbit-customization/lib/jboss-cache.jar
trunk/cms/jackrabbit-customization/lib/jgroups.jar
trunk/cms/jackrabbit-customization/src/
trunk/cms/jackrabbit-customization/src/org/
trunk/cms/jackrabbit-customization/src/org/apache/
trunk/cms/jackrabbit-customization/src/org/apache/jackrabbit/
trunk/cms/jackrabbit-customization/src/org/apache/jackrabbit/core/
trunk/cms/jackrabbit-customization/src/org/apache/jackrabbit/core/state/
trunk/cms/jackrabbit-customization/src/org/apache/jackrabbit/core/state/ItemStateReferenceCache.java
trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/Base.java
trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/JBossCachePersistenceManager.java
trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/PortalCMSCacheLoader.java
trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/Tools.java
trunk/cms/src/main/org/jboss/portal/cms/impl/jcr/jackrabbit/ClusteredCacheListener.java
Modified:
trunk/
trunk/cms/
trunk/cms/build.xml
trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/HibernatePersistenceManager.java
trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/VersionNode.java
trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/VersionProp.java
trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/VersionRefs.java
trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/WSPNode.java
trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/WSPProp.java
trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/WSPRefs.java
trunk/cms/src/main/org/jboss/portal/cms/impl/jcr/command/ContentGetVersionsCommand.java
trunk/core/build.xml
trunk/core/src/resources/portal-cms-sar/META-INF/
trunk/core/src/resources/portal-cms-sar/META-INF/jboss-service.xml
trunk/core/src/resources/portal-cms-sar/conf/hibernate/cms/domain.hbm.xml
trunk/core/src/resources/portal-cms-sar/conf/hibernate/cms/hibernate.cfg.xml
Log:
first iteration of CMS performance enhancements - Includes a JBossCache based PersistenceManager and clustered caching of JackRabbit's internal caching mechanism
Property changes on: trunk
___________________________________________________________________
Name: svn:ignore
+ .project
.classpath
thirdparty
eclipseBin
Property changes on: trunk/cms
___________________________________________________________________
Name: svn:ignore
- output
bin
bin
+ output
bin
bin
*.log
Modified: trunk/cms/build.xml
===================================================================
--- trunk/cms/build.xml 2006-09-17 15:27:03 UTC (rev 5216)
+++ trunk/cms/build.xml 2006-09-18 04:21:11 UTC (rev 5217)
@@ -84,6 +84,8 @@
<path refid="sun.jaf.classpath"/>
<path refid="xdoclet.xdoclet.classpath"/>
<path refid="jcr.jcr.classpath"/>
+ <!-- cms optimization integration -->
+ <path refid="jgroups.jgroups.classpath"/>
</path>
@@ -161,7 +163,22 @@
<fileset dir="${jcr.jcr.root}/lib" includes="jcr-1.0.jar"/>
<fileset dir="${apache.collections.root}/lib" includes="commons-collections.jar"/>
<fileset dir="${apache.lucene.root}/lib" includes="lucene.jar"/>
- <fileset dir="${jackrabbit.jackrabbit.lib}" includes="jackrabbit-core-1.0.jar"/>
+
+ <!-- cms optimization integration - this contains a clustered cache enabled version
+ of jackrabbit customization of jackrabbit-core-1.0.1 codebase
+ For details regarding this customization see: cms/jackrabbit-customization
+ also needed are jboss-cache.jar and jgroups.jar to support this customization
+ 1.4.0SP1
+
+ TODO: This is fine for this iteration. Eventually we need to integrate these libraries
+ for bundling in the thirdparty mechanism. This will follow in the next iteration
+ -->
+ <!--fileset dir="${jackrabbit.jackrabbit.lib}" includes="jackrabbit-core-1.0.jar"/-->
+ <fileset dir="../cms/jackrabbit-customization/lib" includes="jackrabbit-core-1.0.1.jar"/>
+ <fileset dir="../cms/jackrabbit-customization/lib" includes="jboss-cache.jar"/>
+ <fileset dir="../cms/jackrabbit-customization/lib" includes="jgroups.jar"/>
+
+
<fileset dir="${slf4j.slf4j.lib}" includes="slf4j-log4j12.jar"/>
</jar>
Added: trunk/cms/jackrabbit-customization/lib/jackrabbit-core-1.0.1.jar
===================================================================
(Binary files differ)
Property changes on: trunk/cms/jackrabbit-customization/lib/jackrabbit-core-1.0.1.jar
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/cms/jackrabbit-customization/lib/jboss-cache.jar
===================================================================
(Binary files differ)
Property changes on: trunk/cms/jackrabbit-customization/lib/jboss-cache.jar
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/cms/jackrabbit-customization/lib/jgroups.jar
===================================================================
(Binary files differ)
Property changes on: trunk/cms/jackrabbit-customization/lib/jgroups.jar
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/cms/jackrabbit-customization/src/org/apache/jackrabbit/core/state/ItemStateReferenceCache.java
===================================================================
--- trunk/cms/jackrabbit-customization/src/org/apache/jackrabbit/core/state/ItemStateReferenceCache.java 2006-09-17 15:27:03 UTC (rev 5216)
+++ trunk/cms/jackrabbit-customization/src/org/apache/jackrabbit/core/state/ItemStateReferenceCache.java 2006-09-18 04:21:11 UTC (rev 5217)
@@ -0,0 +1,308 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. 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.jackrabbit.core.state;
+
+import org.apache.jackrabbit.core.ItemId;
+import org.apache.jackrabbit.core.util.Dumpable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Set;
+import java.util.Collections;
+import java.util.Collection;
+import java.io.PrintStream;
+
+//clustered caching code
+import java.io.InputStream;
+import javax.management.MBeanServer;
+import org.jboss.cache.*;
+import org.jboss.mx.util.MBeanProxyExt;
+import org.jboss.mx.util.MBeanServerLocator;
+import org.jboss.portal.cms.impl.jcr.jackrabbit.ClusteredCacheListener;
+
+/**
+ * <code>ItemStateReferenceCache</code> internally consists of 2 components:
+ * <ul>
+ * <li>an <code>ItemStateReferenceMap<code> serving as the primary (or main)
+ * cache; it holds weak references to <code>ItemState</code> instances. This
+ * <code>ItemStateCache</code> implementation directly represents the
+ * contents of the primary cache, i.e. {@link #isCached(ItemId)},
+ * {@link #retrieve(ItemId)}}, {@link #size()} etc. only refer to the contents
+ * of the primary cache.</li>
+ * <li>an <code>ItemStateCache</code> implementing a custom eviction policy and
+ * serving as the secondary (or auxiliary) cache; entries that are automatically
+ * flusehd from this secondary cache through its eviction policy (LRU, etc.)
+ * will be indirectly flushed from the primary (reference) cache by the garbage
+ * collector if they are thus rendered weakly reachable.
+ * </li>
+ * </ul>
+ */
+public class ItemStateReferenceCache implements ItemStateCache, Dumpable {
+
+ /** Logger instance */
+ private static Logger log = LoggerFactory.getLogger(LRUItemStateCache.class);
+
+ /**
+ * primary cache storing weak references to <code>ItemState</code>
+ * instances.
+ */
+ private final ItemStateReferenceMap refs;
+ /**
+ * secondary cache that automatically flushes entries based on some
+ * eviction policy; entries flushed from the secondary cache will be
+ * indirectly flushed from the primary (reference) cache by the garbage
+ * collector if they thus are rendered weakly reachable.
+ */
+ private final ItemStateCache cache;
+
+ /**
+ * clustered caching code - integrating a clustered invalidating jbosscache
+ *
+ */
+ private static TreeCache treeCache = null;
+ private static boolean standalone = false;
+
+
+ /**
+ * Creates a new <code>ItemStateReferenceCache</code> that uses a
+ * <code>LRUItemStateCache</code> instance as internal secondary
+ * cache.
+ */
+ public ItemStateReferenceCache() {
+ this(new LRUItemStateCache());
+ }
+
+ /**
+ * Creates a new <code>ItemStateReferenceCache</code> that uses the
+ * specified <code>ItemStateCache</code> instance as internal secondary
+ * cache.
+ *
+ * @param cache secondary cache implementing a custom eviction policy
+ */
+ public ItemStateReferenceCache(ItemStateCache cache) {
+ this.cache = cache;
+ refs = new ItemStateReferenceMap();
+
+ //clustered caching code - initialize the treecache and start it
+ if(treeCache == null)
+ {
+ setUpClustedCache();
+ }
+ }
+
+ //-------------------------------------------------------< ItemStateCache >
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isCached(ItemId id) {
+
+ // check primary cache
+ return refs.contains(id);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ItemState retrieve(ItemId id) {
+
+ // fake call to update stats of secondary cache
+ cache.retrieve(id);
+
+ // retrieve from primary cache
+ return (ItemState) refs.get(id);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void cache(ItemState state) {
+
+ ItemId id = state.getId();
+ if (refs.contains(id)) {
+ log.warn("overwriting cached entry " + id);
+ }
+ // fake call to update stats of secondary cache
+ cache.cache(state);
+ // store weak reference in primary cache
+ refs.put(state);
+
+ //clustered-caching code
+ //hook into the clustered cache for sending invalidation notifications in a clustered environment
+ handleClusteredCaching(state);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void evict(ItemId id) {
+ // fake call to update stats of secondary cache
+ cache.evict(id);
+ // remove from primary cache
+ refs.remove(id);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void evictAll() {
+ // fake call to update stats of secondary cache
+ cache.evictAll();
+ // remove all weak references from primary cache
+ refs.clear();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isEmpty() {
+
+ // check primary cache
+ return refs.isEmpty();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int size() {
+ // size of primary cache
+ return refs.size();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Set keySet() {
+ // keys of primary cache
+ return Collections.unmodifiableSet(refs.keySet());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Collection values() {
+ // values of primary cache
+ return Collections.unmodifiableCollection(refs.values());
+ }
+
+ //-------------------------------------------------------------< Dumpable >
+ /**
+ * {@inheritDoc}
+ */
+ public void dump(PrintStream ps) {
+ ps.println("ItemStateReferenceCache (" + this + ")");
+ ps.println();
+ ps.print("[refs] ");
+ refs.dump(ps);
+ }
+
+ //-----clustered caching code integrated for jboss portal cms clustering-------------------------------------------------------------------------
+ /**
+ * clustered-caching code
+ * hook into the clustered cache for sending invalidation notifications in a clustered environment
+ */
+ private void handleClusteredCaching(ItemState state)
+ {
+ if(treeCache != null && !standalone)
+ {
+ try
+ {
+ //cache the itemid of the itemstate being saved in cache
+ String node = "/"+ClusteredCacheListener.parseNodeName(state.getId().toString());
+
+ treeCache.put(node,
+ state.getId().toString(),
+ "sendCacheInvalidation");
+ log.debug("Placing "+node+" into the clustered cache..");
+
+ ClusteredCacheListener.storeCacheItem(node,state.getId(),this);
+ }
+ catch(Exception e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ /**
+ * clustered caching code - initialize the treecache and start it
+ *
+ * it looks for an MBEAN in case of a managed environment like JBoss or instantiates from a configuration
+ * file in standalone mode
+ *
+ * This is synchronized so that only one thread is allowed to setup the static TreeCache
+ *
+ */
+ private static synchronized void setUpClustedCache()
+ {
+ log.info("Starting the JackRabbit In-Memory Invalidation Cache. This is helpful in a clustered environment.");
+ InputStream is = null;
+ try
+ {
+ try
+ {
+ MBeanServer server=MBeanServerLocator.locateJBoss();
+ TreeCacheMBean treeCacheMBean = (TreeCacheMBean)MBeanProxyExt.create(TreeCacheMBean.class,"jackrabbit.inmemory.cache:service=TreeCache",server);
+ treeCache = treeCacheMBean.getInstance();
+ treeCache.addTreeCacheListener(new ClusteredCacheListener());
+ return;
+ }
+ catch(Exception e)
+ {
+ treeCache = null;
+ }
+
+ //if nothing found in the environment...chances are running in a non-managed environment
+ if(treeCache == null)
+ {
+ treeCache = new TreeCache();
+
+ //configure the cache
+ PropertyConfigurator configurator = new PropertyConfigurator();
+ is = ItemStateReferenceCache.class.getClassLoader().getResourceAsStream("cluster-cache.xml");
+ configurator.configure(treeCache,is);
+
+ treeCache.addTreeCacheListener(new ClusteredCacheListener());
+ treeCache.createService();
+ treeCache.startService();
+ }
+ }
+ catch(Exception e)
+ {
+ treeCache = null;
+ if(!standalone)
+ {
+ log.info("----------------------------------------------------------------------------------------");
+ log.info("JackRabbit In-Memory cache running in standalone mode. No cluster configuration detected");
+ log.info("----------------------------------------------------------------------------------------");
+ standalone = true;
+ }
+ }
+ finally
+ {
+ if(is != null)
+ {
+ try{is.close();}catch(Exception e){}
+ }
+
+ if(treeCache != null)
+ {
+ log.info("-------------------------------------------------------------------------------------------------");
+ log.info("The JackRabbit In-Memory Clustered Cache successfully started....("+treeCache.getClusterName()+")");
+ log.info("-------------------------------------------------------------------------------------------------");
+ }
+ }
+ }
+}
Added: trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/Base.java
===================================================================
--- trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/Base.java 2006-09-17 15:27:03 UTC (rev 5216)
+++ trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/Base.java 2006-09-18 04:21:11 UTC (rev 5217)
@@ -0,0 +1,85 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.portal.cms.hibernate.state;
+
+import java.io.Serializable;
+
+/*
+ * Created on Aug 31, 2006
+ *
+ * @author <a href="mailto:sohil.shah at jboss.com">Sohil Shah</a>
+ */
+public abstract class Base implements Serializable
+{
+ /**
+ *
+ */
+ private boolean persistCacheItem = true; //true by default...all items when placed in cache must be persisted to database by cacheloader by default
+ private Integer key = null;
+
+ /**
+ *
+ *
+ */
+ public Base()
+ {
+
+ }
+
+ //------cacheItem Persistence related methods------------------------------------------------------------------------------------------------------
+ /**
+ *
+ *
+ */
+ public void disableCacheItemPersistence()
+ {
+ this.persistCacheItem = false;
+ }
+
+ /**
+ *
+ *
+ */
+ public boolean isPersistCacheItem()
+ {
+ return this.persistCacheItem;
+ }
+
+ /**
+ *
+ *
+ */
+ public void resetCacheItemPersistence()
+ {
+ this.persistCacheItem = true;
+ }
+ //-----------data access related methods-------------------------------------------------------------------------------------------------------------
+ public Integer getKey()
+ {
+ return key;
+ }
+
+ public void setKey(Integer key)
+ {
+ this.key = key;
+ }
+}
Modified: trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/HibernatePersistenceManager.java
===================================================================
--- trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/HibernatePersistenceManager.java 2006-09-17 15:27:03 UTC (rev 5216)
+++ trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/HibernatePersistenceManager.java 2006-09-18 04:21:11 UTC (rev 5217)
@@ -58,7 +58,7 @@
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.jboss.portal.cms.hibernate.HibernateStoreConstants;
-import org.jboss.portal.cms.util.HibernateUtil;
+//import org.jboss.portal.cms.util.HibernateUtil;
import org.jboss.portal.common.util.Tools;
import org.jboss.portal.jems.hibernate.CacheableBlobUserType;
import org.jboss.portal.jems.hibernate.ByteArrayBlob;
@@ -155,7 +155,9 @@
throw new IllegalStateException("already initialized");
}
- hibernateSessionFactory = HibernateUtil.getSessionFactory(jndiName);
+ //hibernateSessionFactory = HibernateUtil.getSessionFactory(jndiName);
+ org.jboss.portal.cms.hibernate.state.Tools.init(jndiName);
+ hibernateSessionFactory = org.jboss.portal.cms.hibernate.state.Tools.getSessionFactory();
nodeBinValSelect = "from " + schemaObjectPrefix + "BinVal where BINVAL_ID = ?";
@@ -388,8 +390,12 @@
List rs = session.createQuery(nodeStateSelectData).setString(0, id.toString()).list();
Iterator iter = rs.iterator();
- java.sql.Blob blob = (java.sql.Blob) iter.next();
- in = blob.getBinaryStream();
+
+ //java.sql.Blob blob = (java.sql.Blob) iter.next();
+ //in = blob.getBinaryStream();
+ byte[] data = (byte[])iter.next();
+ in = new java.io.ByteArrayInputStream(data);
+
NodeState state = createNew(id);
Serializer.deserialize(state, in);
Tools.safeClose(in);
@@ -428,8 +434,13 @@
{
List rs = session.createQuery(propertyStateSelectData).setCacheable(true).setString(0, id.toString()).list();
Iterator iter = rs.iterator();
- java.sql.Blob blob = (java.sql.Blob) iter.next();
- in = blob.getBinaryStream();
+
+ //java.sql.Blob blob = (java.sql.Blob) iter.next();
+ //in = blob.getBinaryStream();
+ byte[] data = (byte[])iter.next();
+ in = new java.io.ByteArrayInputStream(data);
+
+
PropertyState state = createNew(id);
Serializer.deserialize(state, in, blobStore);
Tools.safeClose(in);
@@ -474,8 +485,9 @@
{
throw new NoSuchItemStateException(targetId.toString());
}
- java.sql.Blob blob = (java.sql.Blob) iter.next();
- in = blob.getBinaryStream();
+ byte[] data = (byte[]) iter.next();
+ in = new java.io.ByteArrayInputStream(data);
+
NodeReferences refs = new NodeReferences(targetId);
Serializer.deserialize(refs, in);
Tools.safeClose(in);
@@ -515,13 +527,13 @@
Serializer.serialize(state, out);
if (schemaObjectPrefix.equalsIgnoreCase(HibernateStoreConstants.versionPrefix))
{
- VersionNode versionNode = new VersionNode(state.getId().toString(), createBlob(out.toByteArray()));
+ VersionNode versionNode = new VersionNode(state.getId().toString(),out.toByteArray());
session.save(versionNode);
}
else if (schemaObjectPrefix.equalsIgnoreCase(HibernateStoreConstants.wspPrefix))
{
- WSPNode wspNode = new WSPNode(state.getId().toString(), createBlob(out.toByteArray()));
+ WSPNode wspNode = new WSPNode(state.getId().toString(),out.toByteArray());
session.save(wspNode);
}
}
@@ -568,14 +580,14 @@
if (schemaObjectPrefix.equalsIgnoreCase(HibernateStoreConstants.versionPrefix))
{
- VersionRefs versionRefs = new VersionRefs(refs.getTargetId().toString(), createBlob(out
- .toByteArray()));
+ VersionRefs versionRefs = new VersionRefs(refs.getTargetId().toString(),out
+ .toByteArray());
session.save(versionRefs);
}
else if (schemaObjectPrefix.equalsIgnoreCase(HibernateStoreConstants.wspPrefix))
{
- WSPRefs wspRefs = new WSPRefs(refs.getTargetId().toString(), createBlob(out.toByteArray()));
+ WSPRefs wspRefs = new WSPRefs(refs.getTargetId().toString(),out.toByteArray());
session.save(wspRefs);
}
}
@@ -625,12 +637,12 @@
if (schemaObjectPrefix.equalsIgnoreCase(HibernateStoreConstants.versionPrefix))
{
- VersionProp versionProp = new VersionProp(state.getId().toString(), createBlob(out.toByteArray()));
+ VersionProp versionProp = new VersionProp(state.getId().toString(),out.toByteArray());
session.save(versionProp);
}
else if (schemaObjectPrefix.equalsIgnoreCase(HibernateStoreConstants.wspPrefix))
{
- WSPProp wspProp = new WSPProp(state.getId().toString(), createBlob(out.toByteArray()));
+ WSPProp wspProp = new WSPProp(state.getId().toString(),out.toByteArray());
session.save(wspProp);
}
}
@@ -678,7 +690,7 @@
{
throw new Exception("No such Node: " + state.getId());
}
- versionNode.setData(createBlob(out.toByteArray()));
+ versionNode.setData(out.toByteArray());
}
else if (schemaObjectPrefix.equalsIgnoreCase(HibernateStoreConstants.wspPrefix))
{
@@ -688,7 +700,7 @@
{
throw new Exception("No such Node: " + state.getId());
}
- wspNode.setData(createBlob(out.toByteArray()));
+ wspNode.setData(out.toByteArray());
}
}
catch (Exception e)
@@ -735,7 +747,7 @@
{
throw new Exception("No such Property: " + state.getId());
}
- versionProp.setData(createBlob(out.toByteArray()));
+ versionProp.setData(out.toByteArray());
}
else if (schemaObjectPrefix.equalsIgnoreCase(HibernateStoreConstants.wspPrefix))
{
@@ -745,7 +757,7 @@
{
throw new Exception("No such Property: " + state.getId());
}
- wspProp.setData(createBlob(out.toByteArray()));
+ wspProp.setData(out.toByteArray());
}
}
catch (Exception e)
Added: trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/JBossCachePersistenceManager.java
===================================================================
--- trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/JBossCachePersistenceManager.java 2006-09-17 15:27:03 UTC (rev 5216)
+++ trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/JBossCachePersistenceManager.java 2006-09-18 04:21:11 UTC (rev 5217)
@@ -0,0 +1,1484 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.portal.cms.hibernate.state;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.InputStream;
+import java.io.ByteArrayInputStream;
+import java.sql.Blob;
+import java.sql.SQLException;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.jcr.PropertyType;
+import javax.management.MBeanServer;
+
+import org.apache.jackrabbit.core.NodeId;
+import org.apache.jackrabbit.core.PropertyId;
+import org.apache.jackrabbit.core.fs.FileSystem;
+import org.apache.jackrabbit.core.fs.local.LocalFileSystem;
+import org.apache.jackrabbit.core.state.ChangeLog;
+import org.apache.jackrabbit.core.state.ItemState;
+import org.apache.jackrabbit.core.state.ItemStateException;
+import org.apache.jackrabbit.core.state.NoSuchItemStateException;
+import org.apache.jackrabbit.core.state.NodeReferences;
+import org.apache.jackrabbit.core.state.NodeReferencesId;
+import org.apache.jackrabbit.core.state.NodeState;
+import org.apache.jackrabbit.core.state.PMContext;
+import org.apache.jackrabbit.core.state.PersistenceManager;
+import org.apache.jackrabbit.core.state.PropertyState;
+import org.apache.jackrabbit.core.state.util.BLOBStore;
+import org.apache.jackrabbit.core.state.util.FileSystemBLOBStore;
+import org.apache.jackrabbit.core.state.util.Serializer;
+import org.apache.jackrabbit.core.value.BLOBFileValue;
+import org.apache.jackrabbit.core.value.InternalValue;
+import org.apache.log4j.Logger;
+
+import org.jboss.portal.cms.hibernate.HibernateStoreConstants;
+
+import org.jboss.cache.TreeCacheMBean;
+import org.jboss.cache.CacheException;
+import org.jboss.mx.util.MBeanProxyExt;
+import org.jboss.mx.util.MBeanServerLocator;
+
+import org.hibernate.Hibernate;
+import org.hibernate.HibernateException;
+import org.hibernate.Query;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+
+/*
+ * Created on Aug 28, 2006
+ *
+ * @author <a href="mailto:sohil.shah at jboss.com">Sohil Shah</a>
+ */
+public class JBossCachePersistenceManager implements PersistenceManager
+{
+ /**
+ * Logger instance
+ */
+ private static Logger log = Logger.getLogger(JBossCachePersistenceManager.class);
+
+ protected static final String SCHEMA_OBJECT_PREFIX_VARIABLE = "${schemaObjectPrefix}";
+
+ protected boolean initialized;
+
+ protected String jndiName;
+
+ protected String schemaObjectPrefix;
+
+ protected boolean externalBLOBs;
+
+ // initial size of buffer used to serialize objects
+ protected static final int INITIAL_BUFFER_SIZE = 1024;
+
+ // shared statements for NodeState management
+ protected String nodeStateSelect;
+
+ protected String nodeStateSelectData;
+
+ protected String nodeStateSelectExist;
+
+ // shared statements for PropertyState management
+ protected String propertyStateSelect;
+
+ protected String propertyStateSelectData;
+
+ protected String propertyStateSelectExist;
+
+ // shared statements for NodeReference management
+ protected String nodeReferenceSelect;
+
+ protected String nodeReferenceSelectData;
+
+ protected String nodeReferenceSelectExist;
+
+ // shared statements for BLOB management
+ // (if <code>externalBLOBs==false</code>)
+ protected String blobSelect;
+
+ protected String blobSelectData;
+
+ protected String blobSelectExist;
+
+ protected String nodeBinValSelect;
+
+ /**
+ * file system where BLOB data is stored
+ * (if <code>externalBLOBs==true</code>)
+ */
+ protected FileSystem blobFS;
+
+ /**
+ * BLOBStore that manages BLOB data in the file system
+ * (if <code>externalBLOBs==true</code>)
+ */
+ protected BLOBStore blobStore;
+
+ /**
+ *
+ */
+ private static TreeCacheMBean pmCache = null;
+ private static boolean preloaded = false;
+
+ /**
+ * Creates a new <code>SimpleDbPersistenceManager</code> instance.
+ */
+ public JBossCachePersistenceManager()
+ {
+ schemaObjectPrefix = "";
+ externalBLOBs = true;
+ initialized = false;
+ }
+
+
+ /*
+ *
+ */
+ public void init(PMContext context) throws Exception
+ {
+ if (initialized)
+ {
+ throw new IllegalStateException("already initialized");
+ }
+
+ nodeBinValSelect = "from " + schemaObjectPrefix + "BinVal where BINVAL_ID = ?";
+
+ nodeStateSelect = "from " + schemaObjectPrefix + "Node where NODE_ID = ?";
+ nodeStateSelectData = "select data from " + schemaObjectPrefix + "Node where NODE_ID = ?";
+ nodeStateSelectExist = "select 1 from " + schemaObjectPrefix + "Node where NODE_ID = ?";
+
+ propertyStateSelect = "from " + schemaObjectPrefix + "Prop where PROP_ID = ?";
+ propertyStateSelectData = "select data from " + schemaObjectPrefix + "Prop where PROP_ID = ?";
+ propertyStateSelectExist = "select 1 from " + schemaObjectPrefix + "Prop where PROP_ID = ?";
+
+ nodeReferenceSelect = "from " + schemaObjectPrefix + "Refs where NODE_ID = ?";
+ nodeReferenceSelectData = "select data from " + schemaObjectPrefix + "Refs where NODE_ID = ?";
+ nodeReferenceSelectExist = "select 1 from " + schemaObjectPrefix + "Refs where NODE_ID = ?";
+
+
+ if (externalBLOBs)
+ {
+ /**
+ * store BLOBs in local file system in a sub directory
+ * of the workspace home directory
+ */
+ LocalFileSystem blobFS = new LocalFileSystem();
+ blobFS.setRoot(new File(context.getHomeDir(), "blobs"));
+ blobFS.init();
+ this.blobFS = blobFS;
+ blobStore = new FileSystemBLOBStore(blobFS);
+ }
+ else
+ {
+ /**
+ * store BLOBs in db
+ */
+ blobStore = new DbBLOBStore();
+
+ blobSelect = "from " + schemaObjectPrefix + "BinVal where BINVAL_ID = ?";
+ blobSelectData = "select data from " + schemaObjectPrefix + "BinVal where BINVAL_ID = ?";
+ blobSelectExist = "select 1 from " + schemaObjectPrefix + "BinVal where BINVAL_ID = ?";
+ }
+
+ initialized = true;
+
+ try
+ {
+ Tools.init(this.jndiName);
+ if(JBossCachePersistenceManager.pmCache == null)
+ {
+ MBeanServer server=MBeanServerLocator.locateJBoss();
+ JBossCachePersistenceManager.pmCache = (TreeCacheMBean)MBeanProxyExt.create(TreeCacheMBean.class,"cms.pm.cache:service=TreeCache",server);
+ }
+
+ //pre-load the cache with property nodes
+ if(!JBossCachePersistenceManager.preloaded)
+ {
+ JBossCachePersistenceManager.loadProperties();
+ log.info("-------------------------------------------------");
+ log.info("JBossCachePersistenceManager is fully loaded.....");
+ log.info("-------------------------------------------------");
+ }
+ }
+ catch(Exception e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ *
+ *
+ */
+ private static synchronized void loadProperties() throws Exception
+ {
+ if(JBossCachePersistenceManager.preloaded)
+ {
+ return;
+ }
+
+ log.info("Pre-loading the PersistenceManager Cache in the background (started).......");
+
+ CacheLoader wspProp = new CacheLoader(CacheLoader.wspProp,PortalCMSCacheLoader.WSP_PROP_NODE);
+ Thread wspPropLoader = new Thread(wspProp);
+ CacheLoader versionProp = new CacheLoader(CacheLoader.versionProp,PortalCMSCacheLoader.VERSION_PROP_NODE);
+ Thread versionPropLoader = new Thread(versionProp);
+ CacheLoader wspNode = new CacheLoader(CacheLoader.wspNode,PortalCMSCacheLoader.WSP_NODE_NODE);
+ Thread wspNodeLoader = new Thread(wspNode);
+ CacheLoader versionNode = new CacheLoader(CacheLoader.versionNode,PortalCMSCacheLoader.VERSION_NODE_NODE);
+ Thread versionNodeLoader = new Thread(versionNode);
+ CacheLoader wspRef = new CacheLoader(CacheLoader.wspRef,PortalCMSCacheLoader.WSP_REF_NODE);
+ Thread wspRefLoader = new Thread(wspRef);
+ CacheLoader versionRef = new CacheLoader(CacheLoader.versionRef,PortalCMSCacheLoader.VERSION_REF_NODE);
+ Thread versionRefLoader = new Thread(versionRef);
+
+ wspPropLoader.start();
+ versionPropLoader.start();
+ wspNodeLoader.start();
+ versionNodeLoader.start();
+ wspRefLoader.start();
+ versionRefLoader.start();
+
+ //hang out here till the cache loader threads have pre-loaded the busy nodes
+ //of the CMS...don't allow the usage of CMS till this operation is completed.
+ while(
+ !wspProp.done ||
+ !versionProp.done ||
+ !wspNode.done ||
+ !versionNode.done ||
+ !wspRef.done ||
+ !versionRef.done
+ )
+ {
+ Thread.currentThread().sleep((long)2000);
+ }
+
+ JBossCachePersistenceManager.preloaded = true;
+ }
+
+ private static class CacheLoader implements Runnable
+ {
+ /**
+ *
+ */
+ private static final String wspProp = "from org.jboss.portal.cms.hibernate.state.WSPProp";
+ private static final String versionProp = "from org.jboss.portal.cms.hibernate.state.VersionProp";
+ private static final String wspNode = "from org.jboss.portal.cms.hibernate.state.WSPNode";
+ private static final String versionNode = "from org.jboss.portal.cms.hibernate.state.VersionNode";
+ private static final String wspRef = "from org.jboss.portal.cms.hibernate.state.WSPRefs";
+ private static final String versionRef = "from org.jboss.portal.cms.hibernate.state.VersionRefs";
+
+
+ /**
+ *
+ */
+ private String nodeQuery = null;
+ private String nodePrefix = null;
+ private boolean done = false;
+
+ private CacheLoader(String nodeQuery,String nodePrefix)
+ {
+ this.nodeQuery = nodeQuery;
+ this.nodePrefix = nodePrefix;
+ }
+
+ public void run()
+ {
+ Session session = null;
+ try
+ {
+ session = Tools.getOpenSession();
+ List rs = session.createQuery(this.nodeQuery).list();
+ if(rs != null)
+ {
+ for(Iterator itr=rs.iterator();itr.hasNext();)
+ {
+ Base cour = (Base)itr.next();
+ cour.disableCacheItemPersistence();
+
+ if(cour instanceof WSPProp)
+ {
+ String node = this.nodePrefix + "/" + PortalCMSCacheLoader.parseNodeName(((WSPProp)cour).getPropId());
+ pmCache.put(node,((WSPProp)cour).getPropId(),cour);
+ }
+ else if(cour instanceof VersionProp)
+ {
+ String node = this.nodePrefix + "/" + PortalCMSCacheLoader.parseNodeName(((VersionProp)cour).getPropId());
+ pmCache.put(node,((VersionProp)cour).getPropId(),cour);
+ }
+ else if(cour instanceof WSPNode)
+ {
+ String node = this.nodePrefix + "/" + PortalCMSCacheLoader.parseNodeName(((WSPNode)cour).getNodeId());
+ pmCache.put(node,((WSPNode)cour).getNodeId(),cour);
+ }
+ else if(cour instanceof VersionNode)
+ {
+ String node = this.nodePrefix + "/" + PortalCMSCacheLoader.parseNodeName(((VersionNode)cour).getNodeId());
+ pmCache.put(node,((VersionNode)cour).getNodeId(),cour);
+ }
+ else if(cour instanceof WSPRefs)
+ {
+ String node = this.nodePrefix + "/" + PortalCMSCacheLoader.parseNodeName(((WSPRefs)cour).getRefId());
+ pmCache.put(node,((WSPRefs)cour).getRefId(),cour);
+ }
+ else if(cour instanceof VersionRefs)
+ {
+ String node = this.nodePrefix + "/" + PortalCMSCacheLoader.parseNodeName(((VersionRefs)cour).getRefId());
+ pmCache.put(node,((VersionRefs)cour).getRefId(),cour);
+ }
+ }
+ }
+ log.info("Pre-loading the PersistenceManager Cache for"+this.nodePrefix+" (finished).......");
+ }
+ catch(CacheException ce)
+ {
+ throw new RuntimeException(ce);
+ }
+ finally
+ {
+ Tools.closeSession(session);
+ this.done = true;
+ }
+ }
+ }
+
+ //----------actions for node entities-------------------------------------------------------------------------------------------------------------
+ /*
+ *
+ */
+ public boolean exists(NodeId node) throws ItemStateException
+ {
+ try
+ {
+ boolean exists = false;
+ String nodeId = node.toString();
+ if(this.schemaObjectPrefix.equalsIgnoreCase(HibernateStoreConstants.wspPrefix))
+ {
+ Object o = this.pmCache.get(PortalCMSCacheLoader.WSP_NODE_NODE+"/"+PortalCMSCacheLoader.parseNodeName(nodeId),nodeId);
+ if(o != null)
+ {
+ if(o instanceof WSPNode)
+ {
+ exists = true;
+ }
+ }
+ else
+ {
+ this.pmCache.put(PortalCMSCacheLoader.WSP_NODE_NODE+"/"+PortalCMSCacheLoader.parseNodeName(nodeId),nodeId,new Boolean(false));
+ }
+ }
+ else if(this.schemaObjectPrefix.equalsIgnoreCase(HibernateStoreConstants.versionPrefix))
+ {
+ Object o = this.pmCache.get(PortalCMSCacheLoader.VERSION_NODE_NODE+"/"+PortalCMSCacheLoader.parseNodeName(nodeId),nodeId);
+ if(o != null)
+ {
+ if(o instanceof VersionNode)
+ {
+ exists = true;
+ }
+ }
+ else
+ {
+ this.pmCache.put(PortalCMSCacheLoader.VERSION_NODE_NODE+"/"+PortalCMSCacheLoader.parseNodeName(nodeId),nodeId,new Boolean(false));
+ }
+ }
+ return exists;
+ }
+ catch(CacheException ce)
+ {
+ throw new RuntimeException(ce);
+ }
+ }
+
+ /*
+ *
+ */
+ public NodeState load(NodeId node) throws NoSuchItemStateException,ItemStateException
+ {
+ try
+ {
+ NodeState nodeState = null;
+ String nodeId = node.toString();
+
+ //get the nodeData
+ byte[] nodeData = null;
+ if(this.schemaObjectPrefix.equalsIgnoreCase(HibernateStoreConstants.wspPrefix))
+ {
+ Object o = this.pmCache.get(PortalCMSCacheLoader.WSP_NODE_NODE+"/"+PortalCMSCacheLoader.parseNodeName(nodeId),nodeId);
+ nodeData = ((WSPNode)o).getData();
+ }
+ else if(this.schemaObjectPrefix.equalsIgnoreCase(HibernateStoreConstants.versionPrefix))
+ {
+ Object o = this.pmCache.get(PortalCMSCacheLoader.VERSION_NODE_NODE+"/"+PortalCMSCacheLoader.parseNodeName(nodeId),nodeId);
+ nodeData = ((VersionNode)o).getData();
+ }
+
+ //parse propertyData into propertyState
+ if(nodeData!=null)
+ {
+ Session session = null;
+ Transaction tx = null;
+ boolean success = false;
+ try
+ {
+ session = Tools.getOpenSession();
+ tx = session.beginTransaction();
+
+ InputStream in = new ByteArrayInputStream(nodeData);
+
+ //setup the propertyState
+ nodeState = createNew(node);
+ Serializer.deserialize(nodeState,in);
+ org.jboss.portal.common.util.Tools.safeClose(in);
+
+ tx.commit();
+ success = true;
+ }
+ catch(Exception e)
+ {
+ if (e instanceof NoSuchItemStateException)
+ {
+ throw (NoSuchItemStateException) e;
+ }
+ String msg = "failed to read node state from cache: " + node.toString();
+ log.error(msg, e);
+ throw new ItemStateException(msg, e);
+ }
+ finally
+ {
+ if(!success)
+ {
+ tx.rollback();
+ }
+ Tools.closeSession(session);
+ }
+ }
+
+ return nodeState;
+ }
+ catch(CacheException ce)
+ {
+ throw new RuntimeException(ce);
+ }
+ }
+
+ /**
+ *
+ *
+ */
+ private void store(NodeState state) throws ItemStateException
+ {
+ if (!initialized)
+ {
+ throw new IllegalStateException("not initialized");
+ }
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream(INITIAL_BUFFER_SIZE);
+ try
+ {
+ Serializer.serialize(state, out);
+ if (schemaObjectPrefix.equalsIgnoreCase(HibernateStoreConstants.versionPrefix))
+ {
+ VersionNode versionNode = new VersionNode(state.getId().toString(), out.toByteArray());
+
+ //place this in the cache
+ versionNode.resetCacheItemPersistence();
+ String cacheNode = PortalCMSCacheLoader.VERSION_NODE_NODE + "/" + PortalCMSCacheLoader.parseNodeName(versionNode.getNodeId());
+ pmCache.put(cacheNode,versionNode.getNodeId(),versionNode);
+ }
+ else if (schemaObjectPrefix.equalsIgnoreCase(HibernateStoreConstants.wspPrefix))
+ {
+
+ WSPNode wspNode = new WSPNode(state.getId().toString(), out.toByteArray());
+
+ //place this in the cache
+ wspNode.resetCacheItemPersistence();
+ String cacheNode = PortalCMSCacheLoader.WSP_NODE_NODE + "/" + PortalCMSCacheLoader.parseNodeName(wspNode.getNodeId());
+ pmCache.put(cacheNode,wspNode.getNodeId(),wspNode);
+ }
+ }
+ catch (Exception e)
+ {
+ String msg = "failed to write node state: " + state.getId();
+ log.error(msg, e);
+ throw new ItemStateException(msg, e);
+ }
+ finally
+ {
+ try
+ {
+ out.close();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ *
+ *
+ */
+ private void update(NodeState state) throws ItemStateException
+ {
+ if (!initialized)
+ {
+ throw new IllegalStateException("not initialized");
+ }
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream(INITIAL_BUFFER_SIZE);
+ try
+ {
+ Serializer.serialize(state, out);
+ String id = state.getId().toString();
+ String cacheNodeName = PortalCMSCacheLoader.parseNodeName(id);
+ if (schemaObjectPrefix.equalsIgnoreCase(HibernateStoreConstants.versionPrefix))
+ {
+ VersionNode versionNode = (VersionNode)pmCache.get(PortalCMSCacheLoader.VERSION_NODE_NODE+"/"+cacheNodeName,id);
+ if (versionNode == null)
+ {
+ throw new Exception("No such Node: " + state.getId());
+ }
+ versionNode.setData(out.toByteArray());
+ versionNode.resetCacheItemPersistence();
+ pmCache.put(PortalCMSCacheLoader.VERSION_NODE_NODE+"/"+cacheNodeName,id,versionNode);
+ }
+ else if (schemaObjectPrefix.equalsIgnoreCase(HibernateStoreConstants.wspPrefix))
+ {
+ WSPNode wspNode = (WSPNode)pmCache.get(PortalCMSCacheLoader.WSP_NODE_NODE+"/"+cacheNodeName,id);
+ if (wspNode == null)
+ {
+ throw new Exception("No such Node: " + state.getId());
+ }
+ wspNode.setData(out.toByteArray());
+ wspNode.resetCacheItemPersistence();
+ pmCache.put(PortalCMSCacheLoader.WSP_NODE_NODE+"/"+cacheNodeName,id,wspNode);
+ }
+ }
+ catch (Exception e)
+ {
+ String msg = "failed to write node state: " + state.getId();
+ log.error(msg, e);
+ throw new ItemStateException(msg, e);
+ }
+ finally
+ {
+ try
+ {
+ out.close();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ * This is called by store(Changelog) this should not be called anywhere else
+ */
+ private void destroy(NodeState state) throws ItemStateException
+ {
+ if (!initialized)
+ {
+ throw new IllegalStateException("not initialized");
+ }
+
+ String id = state.getId().toString();
+ String cacheNodeName = PortalCMSCacheLoader.parseNodeName(id);
+ try
+ {
+ if (schemaObjectPrefix.equalsIgnoreCase(HibernateStoreConstants.versionPrefix))
+ {
+ pmCache.remove(PortalCMSCacheLoader.VERSION_NODE_NODE+"/"+cacheNodeName,id);
+ }
+ else if(schemaObjectPrefix.equalsIgnoreCase(HibernateStoreConstants.wspPrefix))
+ {
+ pmCache.remove(PortalCMSCacheLoader.WSP_NODE_NODE+"/"+cacheNodeName,id);
+ }
+ }
+ catch (Exception e)
+ {
+ String msg = "failed to delete node state: " + state.getId();
+ log.error(msg, e);
+ throw new ItemStateException(msg, e);
+ }
+ }
+
+ //----------actions for property entities-------------------------------------------------------------------------------------------------------------
+ /*
+ *
+ */
+ public boolean exists(PropertyId property) throws ItemStateException
+ {
+ try
+ {
+ boolean exists = false;
+ String propId = property.toString();
+ if(this.schemaObjectPrefix.equalsIgnoreCase(HibernateStoreConstants.wspPrefix))
+ {
+ Object o = this.pmCache.get(PortalCMSCacheLoader.WSP_PROP_NODE+"/"+PortalCMSCacheLoader.parseNodeName(propId),propId);
+ if(o != null)
+ {
+ if(o instanceof WSPProp)
+ {
+ exists = true;
+ }
+ }
+ else
+ {
+ this.pmCache.put(PortalCMSCacheLoader.WSP_PROP_NODE+"/"+PortalCMSCacheLoader.parseNodeName(propId),propId,new Boolean(false));
+ }
+ }
+ else if(this.schemaObjectPrefix.equalsIgnoreCase(HibernateStoreConstants.versionPrefix))
+ {
+ Object o = this.pmCache.get(PortalCMSCacheLoader.VERSION_PROP_NODE+"/"+PortalCMSCacheLoader.parseNodeName(propId),propId);
+ if(o != null)
+ {
+ if(o instanceof VersionProp)
+ {
+ exists = true;
+ }
+ }
+ else
+ {
+ this.pmCache.put(PortalCMSCacheLoader.VERSION_PROP_NODE+"/"+PortalCMSCacheLoader.parseNodeName(propId),propId,new Boolean(false));
+ }
+ }
+ return exists;
+ }
+ catch(CacheException ce)
+ {
+ throw new RuntimeException(ce);
+ }
+ }
+
+ /*
+ *
+ */
+ public PropertyState load(PropertyId property) throws NoSuchItemStateException,ItemStateException
+ {
+ try
+ {
+ PropertyState propertyState = null;
+ String propId = property.toString();
+
+ //get the propertyData
+ byte[] propertyData = null;
+ if(this.schemaObjectPrefix.equalsIgnoreCase(HibernateStoreConstants.wspPrefix))
+ {
+ Object o = this.pmCache.get(PortalCMSCacheLoader.WSP_PROP_NODE+"/"+PortalCMSCacheLoader.parseNodeName(propId),propId);
+ propertyData = ((WSPProp)o).getData();
+ }
+ else if(this.schemaObjectPrefix.equalsIgnoreCase(HibernateStoreConstants.versionPrefix))
+ {
+ Object o = this.pmCache.get(PortalCMSCacheLoader.VERSION_PROP_NODE+"/"+PortalCMSCacheLoader.parseNodeName(propId),propId);
+ propertyData = ((VersionProp)o).getData();
+ }
+
+ //parse propertyData into propertyState
+ if(propertyData!=null)
+ {
+ Session session = null;
+ Transaction tx = null;
+ boolean success = false;
+ try
+ {
+ session = Tools.getOpenSession();
+ tx = session.beginTransaction();
+
+ InputStream in = new ByteArrayInputStream(propertyData);
+
+ //setup the propertyState
+ propertyState = createNew(property);
+ Serializer.deserialize(propertyState,in,blobStore);
+ org.jboss.portal.common.util.Tools.safeClose(in);
+
+ tx.commit();
+ success = true;
+ }
+ catch(Exception e)
+ {
+ if (e instanceof NoSuchItemStateException)
+ {
+ throw (NoSuchItemStateException) e;
+ }
+ String msg = "failed to read property state from cache: " + property.toString();
+ log.error(msg, e);
+ throw new ItemStateException(msg, e);
+ }
+ finally
+ {
+ if(!success)
+ {
+ tx.rollback();
+ }
+ Tools.closeSession(session);
+ }
+ }
+
+ return propertyState;
+ }
+ catch(CacheException ce)
+ {
+ throw new RuntimeException(ce);
+ }
+ }
+
+ /**
+ *
+ */
+ private void store(PropertyState state) throws ItemStateException
+ {
+ if (!initialized)
+ {
+ throw new IllegalStateException("not initialized");
+ }
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream(INITIAL_BUFFER_SIZE);
+ try
+ {
+ Serializer.serialize(state,out,blobStore);
+ if (schemaObjectPrefix.equalsIgnoreCase(HibernateStoreConstants.versionPrefix))
+ {
+ VersionProp versionProp = new VersionProp(state.getId().toString(), out.toByteArray());
+
+ //place this in the cache
+ versionProp.resetCacheItemPersistence();
+ String cacheNode = PortalCMSCacheLoader.VERSION_PROP_NODE + "/" + PortalCMSCacheLoader.parseNodeName(versionProp.getPropId());
+ pmCache.put(cacheNode,versionProp.getPropId(),versionProp);
+ }
+ else if (schemaObjectPrefix.equalsIgnoreCase(HibernateStoreConstants.wspPrefix))
+ {
+
+ WSPProp wspProp = new WSPProp(state.getId().toString(), out.toByteArray());
+
+ //place this in the cache
+ wspProp.resetCacheItemPersistence();
+ String cacheNode = PortalCMSCacheLoader.WSP_PROP_NODE + "/" + PortalCMSCacheLoader.parseNodeName(wspProp.getPropId());
+ pmCache.put(cacheNode,wspProp.getPropId(),wspProp);
+ }
+ }
+ catch (Exception e)
+ {
+ String msg = "failed to write property state: " + state.getId();
+ log.error(msg, e);
+ throw new ItemStateException(msg, e);
+ }
+ finally
+ {
+ try
+ {
+ out.close();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ *
+ *
+ */
+ private void update(PropertyState state) throws ItemStateException
+ {
+ if (!initialized)
+ {
+ throw new IllegalStateException("not initialized");
+ }
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream(INITIAL_BUFFER_SIZE);
+ try
+ {
+ Serializer.serialize(state, out, blobStore);
+ String id = state.getId().toString();
+ String cacheNodeName = PortalCMSCacheLoader.parseNodeName(id);
+ if (schemaObjectPrefix.equalsIgnoreCase(HibernateStoreConstants.versionPrefix))
+ {
+ VersionProp versionProp = (VersionProp)pmCache.get(PortalCMSCacheLoader.VERSION_PROP_NODE+"/"+cacheNodeName,id);
+ if (versionProp == null)
+ {
+ throw new Exception("No such Property: " + state.getId());
+ }
+ versionProp.setData(out.toByteArray());
+ versionProp.resetCacheItemPersistence();
+ pmCache.put(PortalCMSCacheLoader.VERSION_PROP_NODE+"/"+cacheNodeName,id,versionProp);
+ }
+ else if (schemaObjectPrefix.equalsIgnoreCase(HibernateStoreConstants.wspPrefix))
+ {
+ WSPProp wspProp = (WSPProp)pmCache.get(PortalCMSCacheLoader.WSP_PROP_NODE+"/"+cacheNodeName,id);
+ if (wspProp == null)
+ {
+ throw new Exception("No such Property: " + state.getId());
+ }
+ wspProp.setData(out.toByteArray());
+ wspProp.resetCacheItemPersistence();
+ pmCache.put(PortalCMSCacheLoader.WSP_PROP_NODE+"/"+cacheNodeName,id,wspProp);
+ }
+ }
+ catch (Exception e)
+ {
+ String msg = "failed to write property state: " + state.getId();
+ log.error(msg, e);
+ throw new ItemStateException(msg, e);
+ }
+ finally
+ {
+ try
+ {
+ out.close();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ * This is called by store(Changelog) this should not be called anywhere else
+ */
+ private void destroy(PropertyState state) throws ItemStateException
+ {
+ if (!initialized)
+ {
+ throw new IllegalStateException("not initialized");
+ }
+
+ // make sure binary values (BLOBs) are properly removed
+ InternalValue[] values = state.getValues();
+ if (values != null)
+ {
+ for (int i = 0; i < values.length; i++)
+ {
+ InternalValue val = values[i];
+ if (val != null)
+ {
+ if (val.getType() == PropertyType.BINARY)
+ {
+ BLOBFileValue blobVal = (BLOBFileValue) val.internalValue();
+ // delete internal resource representation of BLOB value
+ blobVal.delete(true);
+ // also remove from BLOBStore
+ String blobId = blobStore.createId((PropertyId) state.getId(), i);
+ try
+ {
+ blobStore.remove(blobId);
+ }
+ catch (Exception e)
+ {
+ log.warn("failed to remove from BLOBStore: " + blobId, e);
+ }
+ }
+ }
+ }
+ }
+
+ //remove the property node
+ String id = state.getId().toString();
+ String cacheNodeName = PortalCMSCacheLoader.parseNodeName(id);
+ try
+ {
+ if (schemaObjectPrefix.equalsIgnoreCase(HibernateStoreConstants.versionPrefix))
+ {
+ pmCache.remove(PortalCMSCacheLoader.VERSION_PROP_NODE+"/"+cacheNodeName,id);
+ }
+ else if(schemaObjectPrefix.equalsIgnoreCase(HibernateStoreConstants.wspPrefix))
+ {
+ pmCache.remove(PortalCMSCacheLoader.WSP_PROP_NODE+"/"+cacheNodeName,id);
+ }
+ }
+ catch (Exception e)
+ {
+ String msg = "failed to delete property state: " + state.getId();
+ log.error(msg, e);
+ throw new ItemStateException(msg, e);
+ }
+ }
+ //----------actions for nodereferences entities-------------------------------------------------------------------------------------------------------------
+ /**
+ *
+ */
+ public boolean exists(NodeReferencesId targetId) throws ItemStateException
+ {
+ try
+ {
+ boolean exists = false;
+ String nodeId = targetId.toString();
+ if(this.schemaObjectPrefix.equalsIgnoreCase(HibernateStoreConstants.wspPrefix))
+ {
+ Object o = this.pmCache.get(PortalCMSCacheLoader.WSP_REF_NODE+"/"+PortalCMSCacheLoader.parseNodeName(nodeId),nodeId);
+ if(o != null)
+ {
+ if(o instanceof WSPRefs)
+ {
+ exists = true;
+ }
+ }
+ else
+ {
+ this.pmCache.put(PortalCMSCacheLoader.WSP_REF_NODE+"/"+PortalCMSCacheLoader.parseNodeName(nodeId),nodeId,new Boolean(false));
+ }
+ }
+ else if(this.schemaObjectPrefix.equalsIgnoreCase(HibernateStoreConstants.versionPrefix))
+ {
+ Object o = this.pmCache.get(PortalCMSCacheLoader.VERSION_REF_NODE+"/"+PortalCMSCacheLoader.parseNodeName(nodeId),nodeId);
+ if(o != null)
+ {
+ if(o instanceof VersionRefs)
+ {
+ exists = true;
+ }
+ }
+ else
+ {
+ this.pmCache.put(PortalCMSCacheLoader.VERSION_REF_NODE+"/"+PortalCMSCacheLoader.parseNodeName(nodeId),nodeId,new Boolean(false));
+ }
+ }
+ return exists;
+ }
+ catch(CacheException ce)
+ {
+ throw new RuntimeException(ce);
+ }
+ }
+
+ /**
+ *
+ */
+ public NodeReferences load(NodeReferencesId targetId) throws NoSuchItemStateException, ItemStateException
+ {
+ try
+ {
+ NodeReferences refs = null;
+ String nodeId = targetId.toString();
+
+ //get the nodeData
+ byte[] nodeData = null;
+ if(this.schemaObjectPrefix.equalsIgnoreCase(HibernateStoreConstants.wspPrefix))
+ {
+ Object o = this.pmCache.get(PortalCMSCacheLoader.WSP_REF_NODE+"/"+PortalCMSCacheLoader.parseNodeName(nodeId),nodeId);
+ nodeData = ((WSPRefs)o).getData();
+ }
+ else if(this.schemaObjectPrefix.equalsIgnoreCase(HibernateStoreConstants.versionPrefix))
+ {
+ Object o = this.pmCache.get(PortalCMSCacheLoader.VERSION_REF_NODE+"/"+PortalCMSCacheLoader.parseNodeName(nodeId),nodeId);
+ nodeData = ((VersionRefs)o).getData();
+ }
+
+ //parse propertyData into propertyState
+ if(nodeData!=null)
+ {
+ Session session = null;
+ Transaction tx = null;
+ boolean success = false;
+ try
+ {
+ session = Tools.getOpenSession();
+ tx = session.beginTransaction();
+
+ InputStream in = new ByteArrayInputStream(nodeData);
+
+ //setup the propertyState
+ refs = new NodeReferences(targetId);
+ Serializer.deserialize(refs,in);
+ org.jboss.portal.common.util.Tools.safeClose(in);
+
+ tx.commit();
+ success = true;
+ }
+ catch(Exception e)
+ {
+ if (e instanceof NoSuchItemStateException)
+ {
+ throw (NoSuchItemStateException) e;
+ }
+ String msg = "failed to read reference from cache: " + targetId.toString();
+ log.error(msg, e);
+ throw new ItemStateException(msg, e);
+ }
+ finally
+ {
+ if(!success)
+ {
+ tx.rollback();
+ }
+ Tools.closeSession(session);
+ }
+ }
+
+ return refs;
+ }
+ catch(CacheException ce)
+ {
+ throw new RuntimeException(ce);
+ }
+ }
+
+ /**
+ *
+ *
+ */
+ private void store(NodeReferences refs) throws ItemStateException
+ {
+ if (!initialized)
+ {
+ throw new IllegalStateException("not initialized");
+ }
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream(INITIAL_BUFFER_SIZE);
+ try
+ {
+ Serializer.serialize(refs,out);
+ if (schemaObjectPrefix.equalsIgnoreCase(HibernateStoreConstants.versionPrefix))
+ {
+ VersionRefs versionRefs = new VersionRefs(refs.getId().toString(), out.toByteArray());
+
+ //place this in the cache
+ versionRefs.resetCacheItemPersistence();
+ String cacheNode = PortalCMSCacheLoader.VERSION_REF_NODE + "/" + PortalCMSCacheLoader.parseNodeName(versionRefs.getRefId());
+ pmCache.put(cacheNode,versionRefs.getRefId(),versionRefs);
+ }
+ else if (schemaObjectPrefix.equalsIgnoreCase(HibernateStoreConstants.wspPrefix))
+ {
+
+ WSPRefs wspRefs = new WSPRefs(refs.getId().toString(), out.toByteArray());
+
+ //place this in the cache
+ wspRefs.resetCacheItemPersistence();
+ String cacheNode = PortalCMSCacheLoader.WSP_REF_NODE + "/" + PortalCMSCacheLoader.parseNodeName(wspRefs.getRefId());
+ pmCache.put(cacheNode,wspRefs.getRefId(),wspRefs);
+ }
+ }
+ catch (Exception e)
+ {
+ String msg = "failed to write reference state: " + refs.getId();
+ log.error(msg, e);
+ throw new ItemStateException(msg, e);
+ }
+ finally
+ {
+ try
+ {
+ out.close();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ *
+ */
+ private void destroy(NodeReferences refs) throws ItemStateException
+ {
+ if (!initialized)
+ {
+ throw new IllegalStateException("not initialized");
+ }
+
+ String id = refs.getId().toString();
+ String cacheNodeName = PortalCMSCacheLoader.parseNodeName(id);
+ try
+ {
+ if (schemaObjectPrefix.equalsIgnoreCase(HibernateStoreConstants.versionPrefix))
+ {
+ pmCache.remove(PortalCMSCacheLoader.VERSION_REF_NODE+"/"+cacheNodeName,id);
+ }
+ else if(schemaObjectPrefix.equalsIgnoreCase(HibernateStoreConstants.wspPrefix))
+ {
+ pmCache.remove(PortalCMSCacheLoader.WSP_REF_NODE+"/"+cacheNodeName,id);
+ }
+ }
+ catch (Exception e)
+ {
+ String msg = "failed to delete reference state: " + refs.getId();
+ log.error(msg, e);
+ throw new ItemStateException(msg, e);
+ }
+ }
+ //---------------------------------------------------< PersistenceManager >
+ public String getJNDIName()
+ {
+ return jndiName;
+ }
+
+ public void setJNDIName(String JNDIName)
+ {
+ this.jndiName = JNDIName;
+ }
+
+ public String getSchemaObjectPrefix()
+ {
+ return schemaObjectPrefix;
+ }
+
+ public void setSchemaObjectPrefix(String schemaObjectPrefix)
+ {
+ this.schemaObjectPrefix = schemaObjectPrefix;//.toUpperCase();
+ }
+
+ public boolean isExternalBLOBs()
+ {
+ return externalBLOBs;
+ }
+
+ public void setExternalBLOBs(boolean externalBLOBs)
+ {
+ this.externalBLOBs = externalBLOBs;
+ }
+
+ public void setExternalBLOBs(String externalBLOBs)
+ {
+ this.externalBLOBs = Boolean.valueOf(externalBLOBs).booleanValue();
+ }
+ //---------------------------------------------------< PersistenceManager >
+ /**
+ *
+ */
+ public void close() throws Exception
+ {
+ if (!initialized)
+ {
+ throw new IllegalStateException("not initialized");
+ }
+
+ try
+ {
+ if (externalBLOBs)
+ {
+ //close BLOB file system
+ blobFS.close();
+ blobFS = null;
+ }
+ blobStore = null;
+ }
+ finally
+ {
+ initialized = false;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public NodeState createNew(NodeId id)
+ {
+ return new NodeState(id, null, null, NodeState.STATUS_NEW, false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public PropertyState createNew(PropertyId id)
+ {
+ return new PropertyState(id, PropertyState.STATUS_NEW, false);
+ }
+
+ /**
+ *
+ */
+ public void store(ChangeLog changeLog) throws ItemStateException
+ {
+ Session session = null;
+ Transaction tx = null;
+ try
+ {
+ session = Tools.getOpenSession();
+ tx = session.beginTransaction();
+ storeHB(changeLog);
+ tx.commit();
+ }
+ catch (ItemStateException e)
+ {
+ tx.rollback();
+ throw e;
+ }
+ finally
+ {
+ Tools.closeSession(session);
+ }
+ }
+
+ private Blob createBlob(byte[] bytes)
+ {
+ return Hibernate.createBlob(bytes);
+ //return new ByteArrayBlob(bytes);
+ }
+
+ public void storeHB(ChangeLog changeLog) throws ItemStateException
+ {
+ Iterator iter = changeLog.deletedStates();
+ while (iter.hasNext())
+ {
+ ItemState state = (ItemState) iter.next();
+ if (state.isNode())
+ {
+ destroy((NodeState) state);
+ }
+ else
+ {
+ destroy((PropertyState) state);
+ }
+ }
+ iter = changeLog.addedStates();
+ while (iter.hasNext())
+ {
+ ItemState state = (ItemState) iter.next();
+ if (state.isNode())
+ {
+ store((NodeState) state);
+ }
+ else
+ {
+ store((PropertyState) state);
+ }
+ }
+ iter = changeLog.modifiedStates();
+ while (iter.hasNext())
+ {
+ ItemState state = (ItemState) iter.next();
+ if (state.isNode())
+ {
+ update((NodeState) state);
+ }
+ else
+ {
+ update((PropertyState) state);
+ }
+ }
+ iter = changeLog.modifiedRefs();
+ while (iter.hasNext())
+ {
+ NodeReferences refs = (NodeReferences) iter.next();
+ if (refs.hasReferences())
+ {
+ store(refs);
+ }
+ else
+ {
+ if (exists(refs.getId()))
+ {
+ destroy(refs);
+ }
+ }
+ }
+ }
+
+ /**
+ *
+ */
+ protected boolean exists(String blobid) throws ItemStateException
+ {
+ return exists(blobSelectExist, blobid);
+ }
+
+ /**
+ *
+ *
+ */
+ private boolean exists(String query, String id) throws ItemStateException
+ {
+ if (!initialized)
+ {
+ throw new IllegalStateException("not initialized");
+ }
+
+ Session session = Tools.getOpenSession();
+ try
+ {
+ List rs = session.createQuery(query).setCacheable(true).setString(0, id).list();
+ Iterator iter = rs.iterator();
+ return iter.hasNext();
+ }
+ catch (Exception e)
+ {
+ String msg = "failed to check existence of node state: " + id;
+ log.error(msg, e);
+ throw new ItemStateException(msg, e);
+ }
+ finally
+ {
+ Tools.closeSession(session);
+ }
+
+ }
+ //-------------------------------------------------< misc. helper methods >
+ protected void logException(String message, SQLException se)
+ {
+ if (message != null)
+ {
+ log.error(message);
+ }
+ log.error(" reason: " + se.getMessage());
+ log.error("state/code: " + se.getSQLState() + "/" + se.getErrorCode());
+ log.debug(" dump:", se);
+ }
+ //--------------------------------------------------------< inner classes >
+ class DbBLOBStore implements BLOBStore
+ {
+
+ /**
+ *
+ */
+ public String createId(PropertyId id, int index)
+ {
+ // the blobId is a simple string concatenation of id plus index
+ StringBuffer sb = new StringBuffer();
+ sb.append(id.toString());
+ sb.append('[');
+ sb.append(index);
+ sb.append(']');
+ return sb.toString();
+ }
+
+ /**
+ *
+ */
+ public InputStream get(String blobId) throws Exception
+ {
+ Session session = Tools.getCurrentSession();
+ try
+ {
+ List rs = session.createQuery(blobSelectData).setCacheable(true).setString(0, blobId).list();
+ Iterator iter = rs.iterator();
+ java.sql.Blob blob = (java.sql.Blob) iter.next();
+ InputStream is = blob.getBinaryStream();
+ return is;
+ }
+ catch (Exception e)
+ {
+ if (e instanceof NoSuchItemStateException)
+ {
+ throw (NoSuchItemStateException) e;
+ }
+ String msg = "failed to read binary data: " + blobId;
+ log.error(msg, e);
+ throw new ItemStateException(msg, e);
+ }
+ }
+
+ /**
+ *
+ */
+ public void put(String blobId, InputStream in, long size) throws Exception
+ {
+ boolean update = exists(blobId);
+
+ Session session = Tools.getCurrentSession();
+
+ if (update)
+ {
+ try
+ {
+
+ Query query = session.createQuery(blobSelect).setCacheable(true);
+ if (schemaObjectPrefix.equalsIgnoreCase(HibernateStoreConstants.versionPrefix))
+ {
+ query.setString(0, blobId);
+ VersionBinVal versionNode = (VersionBinVal) query.uniqueResult();
+ if (versionNode == null)
+ {
+ throw new Exception("No such Node: " + blobId);
+ }
+ versionNode.setId(blobId);
+ versionNode.setData(Hibernate.createBlob(in));
+ }
+ else if (schemaObjectPrefix.equalsIgnoreCase(HibernateStoreConstants.wspPrefix))
+ {
+ query.setString(0, blobId);
+ WSPBinVal wspNode = (WSPBinVal) query.uniqueResult();
+ if (wspNode == null)
+ {
+ throw new Exception("No such Node: " + blobId);
+ }
+ wspNode.setId(blobId);
+ wspNode.setData(Hibernate.createBlob(in));
+ }
+ }
+ catch (Exception e)
+ {
+ String msg = "failed to write node state: " + blobId;
+ log.error(msg, e);
+ throw new ItemStateException(msg, e);
+ }
+ }
+ else
+ // insert
+ {
+ try
+ {
+
+ if (schemaObjectPrefix.equalsIgnoreCase(HibernateStoreConstants.versionPrefix))
+ {
+ VersionBinVal versionNode = new VersionBinVal(blobId, Hibernate.createBlob(in));
+ session.save(versionNode);
+ }
+ else if (schemaObjectPrefix.equalsIgnoreCase(HibernateStoreConstants.wspPrefix))
+ {
+ WSPBinVal wspNode = new WSPBinVal(blobId, Hibernate.createBlob(in));
+ session.save(wspNode);
+ }
+ }
+ catch (Exception e)
+ {
+ String msg = "failed to write node state: " + blobId;
+ log.error(msg, e);
+ throw new ItemStateException(msg, e);
+ }
+ }
+ }
+
+ /**
+ *
+ */
+ // public synchronized boolean remove(String blobId) throws Exception
+ public boolean remove(String blobId) throws Exception
+ {
+ Session session = Tools.getCurrentSession();
+ try
+ {
+ Query query = session.createQuery(nodeBinValSelect).setCacheable(true).setString(0, blobId);
+ Object result = query.uniqueResult();
+ if (result != null)
+ {
+ session.delete(result);
+ }
+ return true;
+ }
+ catch (Exception e)
+ {
+ String msg = "failed to delete binval: " + blobId;
+ log.error(msg, e);
+ throw new ItemStateException(msg, e);
+ }
+ }
+ }
+}
Added: trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/PortalCMSCacheLoader.java
===================================================================
--- trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/PortalCMSCacheLoader.java 2006-09-17 15:27:03 UTC (rev 5216)
+++ trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/PortalCMSCacheLoader.java 2006-09-18 04:21:11 UTC (rev 5217)
@@ -0,0 +1,845 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.portal.cms.hibernate.state;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Collections;
+
+import org.jboss.cache.Fqn;
+import org.jboss.cache.TreeCache;
+import org.jboss.cache.loader.CacheLoader;
+import org.jboss.cache.Modification;
+
+import org.jboss.portal.cms.hibernate.state.Base;
+import org.jboss.portal.cms.hibernate.state.WSPProp;
+import org.jboss.portal.cms.hibernate.state.VersionProp;
+import org.jboss.portal.cms.hibernate.state.WSPNode;
+import org.jboss.portal.cms.hibernate.state.VersionNode;
+
+import org.apache.log4j.Logger;
+import org.hibernate.Session;
+
+
+/*
+ * Created on Aug 29, 2006
+ *
+ * @author <a href="mailto:sohil.shah at jboss.com">Sohil Shah</a>
+ */
+public class PortalCMSCacheLoader implements CacheLoader
+{
+ /**
+ * Logger instance
+ */
+ private static Logger log = Logger.getLogger(PortalCMSCacheLoader.class);
+
+ /**
+ *
+ */
+ private static final String loadWSPProps = "from org.jboss.portal.cms.hibernate.state.WSPProp";
+ private static final String loadWSPPropChildren = "select property.propId from org.jboss.portal.cms.hibernate.state.WSPProp property";
+ private static final String loadWSPProp = "from org.jboss.portal.cms.hibernate.state.WSPProp property where property.propId=?";
+ private static final String loadVersionProps = "from org.jboss.portal.cms.hibernate.state.VersionProp";
+ private static final String loadVersionPropChildren = "select property.propId from org.jboss.portal.cms.hibernate.state.VersionProp property";
+ private static final String loadVersionProp = "from org.jboss.portal.cms.hibernate.state.VersionProp property where property.propId=?";
+
+ /**
+ *
+ */
+ private static final String loadWSPNodes = "from org.jboss.portal.cms.hibernate.state.WSPNode";
+ private static final String loadWSPNodeChildren = "select node.nodeId from org.jboss.portal.cms.hibernate.state.WSPNode node";
+ private static final String loadWSPNode = "from org.jboss.portal.cms.hibernate.state.WSPNode node where node.nodeId=?";
+ private static final String loadVersionNodes = "from org.jboss.portal.cms.hibernate.state.VersionNode";
+ private static final String loadVersionNodeChildren = "select node.nodeId from org.jboss.portal.cms.hibernate.state.VersionNode node";
+ private static final String loadVersionNode = "from org.jboss.portal.cms.hibernate.state.VersionNode node where node.nodeId=?";
+
+ /**
+ *
+ */
+ private static final String loadWSPRefs = "from org.jboss.portal.cms.hibernate.state.WSPRefs";
+ private static final String loadWSPRefsChildren = "select ref.refId from org.jboss.portal.cms.hibernate.state.WSPRefs ref";
+ private static final String loadWSPRef = "from org.jboss.portal.cms.hibernate.state.WSPRefs ref where ref.refId=?";
+ private static final String loadVersionRefs = "from org.jboss.portal.cms.hibernate.state.VersionRefs";
+ private static final String loadVersionRefsChildren = "select ref.refId from org.jboss.portal.cms.hibernate.state.VersionRefs ref";
+ private static final String loadVersionRef = "from org.jboss.portal.cms.hibernate.state.VersionRefs ref where ref.refId=?";
+
+
+ /**
+ *
+ */
+ public static final String WSP_PROP_NODE = "/wsp_prop";
+ public static final String VERSION_PROP_NODE = "/version_prop";
+ public static final String WSP_NODE_NODE = "/wsp_node";
+ public static final String VERSION_NODE_NODE = "/version_node";
+ public static final String WSP_REF_NODE = "/wsp_ref";
+ public static final String VERSION_REF_NODE = "/version_ref";
+
+ /**
+ * map of propertyId-nodeName map
+ */
+ private static Map nodeNames = Collections.synchronizedMap(new HashMap());
+
+ /**
+ *
+ */
+ private TreeCache cache = null;
+
+
+ /**
+ *
+ */
+ public void setConfig(Properties properties)
+ {
+ }
+
+ /**
+ *
+ */
+ public void setCache(TreeCache cache)
+ {
+ this.cache = cache;
+ }
+
+ /**
+ *
+ */
+ public Set getChildrenNames(Fqn fqn) throws Exception
+ {
+ Set children = null;
+
+ if(fqn.toString().equals("/"))
+ {
+ children = new HashSet();
+ children.add(WSP_PROP_NODE.substring(1));
+ children.add(VERSION_PROP_NODE.substring(1));
+ children.add(WSP_NODE_NODE.substring(1));
+ children.add(VERSION_NODE_NODE.substring(1));
+ }
+ else if(fqn.toString().equals(WSP_PROP_NODE))
+ {
+ children = this.getChildrenNames(loadWSPPropChildren);
+ }
+ else if(fqn.toString().equals(VERSION_PROP_NODE))
+ {
+ children = this.getChildrenNames(loadVersionPropChildren);
+ }
+ else if(fqn.toString().equals(WSP_NODE_NODE))
+ {
+ children = this.getChildrenNames(loadWSPNodeChildren);
+ }
+ else if(fqn.toString().equals(VERSION_NODE_NODE))
+ {
+ children = this.getChildrenNames(loadVersionNodeChildren);
+ }
+ else if(fqn.toString().equals(WSP_REF_NODE))
+ {
+ children = this.getChildrenNames(loadWSPRefsChildren);
+ }
+ else if(fqn.toString().equals(VERSION_REF_NODE))
+ {
+ children = this.getChildrenNames(loadVersionRefsChildren);
+ }
+
+ if(children!=null)
+ {
+ children = Collections.unmodifiableSet(children);
+ }
+
+ return children;
+ }
+
+ /**
+ *
+ */
+ public boolean exists(Fqn fqn) throws Exception
+ {
+ boolean exists = false;
+
+ //node calculation
+ String node = fqn.toString();
+ String nodeName = "";
+ int lastIndex = node.lastIndexOf('/');
+ if(lastIndex>0)
+ {
+ nodeName = node.substring(lastIndex+1);
+ }
+ String query = null;
+
+ if(
+ node.equals("/")
+ )
+ {
+ exists = true;
+ return exists;
+ }
+ else if(node.startsWith(WSP_PROP_NODE))
+ {
+ query = loadWSPProp;
+ }
+ else if(node.startsWith(VERSION_PROP_NODE))
+ {
+ query = loadVersionProp;
+ }
+ else if(node.startsWith(WSP_NODE_NODE))
+ {
+ query = loadWSPNode;
+ }
+ else if(node.startsWith(VERSION_NODE_NODE))
+ {
+ query = loadVersionNode;
+ }
+ else if(node.startsWith(WSP_REF_NODE))
+ {
+ query = loadWSPRef;
+ }
+ else if(node.startsWith(VERSION_REF_NODE))
+ {
+ query = loadVersionRef;
+ }
+
+ if(query!=null && query.trim().length()>0)
+ {
+ String id = PortalCMSCacheLoader.lookupNodeId(nodeName);
+ if(id!=null && id.trim().length()>0)
+ {
+ Object nodeValue = this.loadNode(query,id);
+ if(nodeValue!=null)
+ {
+ exists = true;
+ }
+ }
+ }
+
+ return exists;
+ }
+
+ /**
+ *
+ */
+ public Map get(Fqn fqn) throws Exception
+ {
+ Map map = null;
+
+ //node calculation
+ String node = fqn.toString();
+ String nodeName = "";
+ int lastIndex = node.lastIndexOf('/');
+ if(lastIndex>0)
+ {
+ nodeName = node.substring(lastIndex+1);
+ }
+ String query = null;
+
+ if(node.startsWith(WSP_PROP_NODE))
+ {
+ query = loadWSPProp;
+ }
+ else if(node.startsWith(VERSION_PROP_NODE))
+ {
+ query = loadVersionProp;
+ }
+ else if(node.startsWith(WSP_NODE_NODE))
+ {
+ query = loadWSPNode;
+ }
+ else if(node.startsWith(VERSION_NODE_NODE))
+ {
+ query = loadVersionNode;
+ }
+ else if(node.startsWith(WSP_REF_NODE))
+ {
+ query = loadWSPRef;
+ }
+ else if(node.startsWith(VERSION_REF_NODE))
+ {
+ query = loadVersionRef;
+ }
+
+ if(query != null && query.trim().length()>0)
+ {
+ String id = PortalCMSCacheLoader.lookupNodeId(nodeName);
+ if(id !=null && id.trim().length()>0)
+ {
+ Object nodeValue = this.loadNode(query,id);
+ if(nodeValue!=null)
+ {
+ map = new HashMap();
+ map.put(id,nodeValue);
+ }
+ }
+ }
+
+ return map;
+ }
+
+ /**
+ * semantically, if the fqn node does not exist, the entire node needs to be created..
+ * In this cacheLoader's case, the node not existing in the database is not an option.
+ * that scenario never happens
+ *
+ * returns the oldValue if its found or a new value is created
+ */
+ public Object put(Fqn fqn,Object key,Object value) throws Exception
+ {
+ Object oldValue = null;
+ String node = fqn.toString();
+
+ if(node.startsWith(WSP_PROP_NODE) && value instanceof WSPProp)
+ {
+ if(((Base)value).isPersistCacheItem())
+ {
+ oldValue = this.saveWSPPropNodeEntry((WSPProp)value);
+ }
+ ((Base)value).resetCacheItemPersistence();
+ }
+ else if(node.startsWith(VERSION_PROP_NODE) && value instanceof VersionProp)
+ {
+ if(((Base)value).isPersistCacheItem())
+ {
+ oldValue = this.saveVersionPropNodeEntry((VersionProp)value);
+ }
+ ((Base)value).resetCacheItemPersistence();
+ }
+ else if(node.startsWith(WSP_NODE_NODE) && value instanceof WSPNode)
+ {
+ if(((Base)value).isPersistCacheItem())
+ {
+ oldValue = this.saveWSPNodeNodeEntry((WSPNode)value);
+ }
+ ((Base)value).resetCacheItemPersistence();
+ }
+ else if(node.startsWith(VERSION_NODE_NODE) && value instanceof VersionNode)
+ {
+ if(((Base)value).isPersistCacheItem())
+ {
+ oldValue = this.saveVersionNodeNodeEntry((VersionNode)value);
+ }
+ ((Base)value).resetCacheItemPersistence();
+ }
+ else if(node.startsWith(WSP_REF_NODE) && value instanceof WSPRefs)
+ {
+ if(((Base)value).isPersistCacheItem())
+ {
+ oldValue = this.saveWSPRefNodeEntry((WSPRefs)value);
+ }
+ ((Base)value).resetCacheItemPersistence();
+ }
+ else if(node.startsWith(VERSION_REF_NODE) && value instanceof VersionRefs)
+ {
+ if(((Base)value).isPersistCacheItem())
+ {
+ oldValue = this.saveVersionRefNodeEntry((VersionRefs)value);
+ }
+ ((Base)value).resetCacheItemPersistence();
+ }
+
+ return oldValue;
+ }
+
+ /**
+ *
+ */
+ public void put(Fqn fqn,Map attributes) throws Exception
+ {
+ if(attributes!=null)
+ {
+ Set keys = attributes.keySet();
+ for(Iterator itr=keys.iterator();itr.hasNext();)
+ {
+ Object key = itr.next();
+ Object value = attributes.get(key);
+ this.put(fqn,key,value);
+ }
+ }
+ }
+
+ /**
+ *
+ */
+ public void put(List modifications) throws Exception
+ {
+ if(modifications!=null)
+ {
+ for(int i = 0; i < modifications.size(); ++i)
+ {
+ Modification m = (Modification) modifications.get(i);
+ switch(m.getType())
+ {
+ case Modification.PUT_DATA:
+ put(m.getFqn(),m.getData());
+ break;
+ case Modification.PUT_DATA_ERASE:
+ put(m.getFqn(), m.getData());
+ break;
+ case Modification.PUT_KEY_VALUE:
+ put(m.getFqn(),m.getKey(),m.getValue());
+ break;
+ case Modification.REMOVE_DATA:
+ removeData(m.getFqn());
+ break;
+ case Modification.REMOVE_KEY_VALUE:
+ remove(m.getFqn(),m.getKey());
+ break;
+ case Modification.REMOVE_NODE:
+ remove(m.getFqn());
+ break;
+ default:
+ throw new IllegalStateException("Unexpected modification code: " + m.getType());
+ }
+ }
+ }
+ }
+
+ /**
+ *
+ */
+ public Object remove(Fqn fqn, Object key) throws Exception
+ {
+ Object removedValue = null;
+ String node = fqn.toString();
+ String id = (String)key;
+ String query = null;
+
+
+ if(node.startsWith(WSP_PROP_NODE))
+ {
+ query = loadWSPProp;
+ }
+ else if(node.startsWith(VERSION_PROP_NODE))
+ {
+ query = loadVersionProp;
+ }
+ else if(node.startsWith(WSP_NODE_NODE))
+ {
+ query = loadWSPNode;
+ }
+ else if(node.startsWith(VERSION_NODE_NODE))
+ {
+ query = loadVersionNode;
+ }
+ else if(node.startsWith(WSP_REF_NODE))
+ {
+ query = loadWSPRef;
+ }
+ else if(node.startsWith(VERSION_REF_NODE))
+ {
+ query = loadVersionRef;
+ }
+
+ if(query != null && query.trim().length()>0)
+ {
+ removedValue = this.delete(query,id);
+ }
+
+ return removedValue;
+ }
+
+ /**
+ *
+ */
+ public void remove(Fqn fqn) throws Exception
+ {
+ //just for safety this is not implemented.
+ //the cache should not be used for this kind of stuff
+
+ //the admin tool is suited for that
+ }
+
+ /**
+ *
+ */
+ public void removeData(Fqn fqn) throws Exception
+ {
+ //just for safety this is not implemented.
+ //the cache should not be used for this kind of stuff
+
+ //the admin tool is suited for that
+ }
+ //------------cache unit of work transaction-management--------------------------------------------------------------------------------------------------------------------
+ /**
+ *
+ */
+ public void prepare(Object tx,List modifications,boolean one_phase) throws Exception
+ {
+ this.put(modifications);
+ }
+
+ /**
+ *
+ */
+ public void commit(Object tx) throws Exception
+ {
+ }
+
+ /**
+ *
+ */
+ public void rollback(Object tx)
+ {
+ }
+ //--------------------------------------------------------------------------------------------------------------------------------------------------------
+ /**
+ *
+ */
+ public byte[] loadEntireState() throws Exception
+ {
+ //loading the entire cms into a byteBuffer and sending it over the network to a remote cache
+ //is not feasible for this loader
+ //plus, all distributed caches/cache loaders will be loading/saving data to the same database
+ //so the content is in sync across all the caches in the cluster
+ return null;
+ }
+
+ /**
+ *
+ */
+ public void storeEntireState(byte[] arg0) throws Exception
+ {
+ //no need for this since all the distributed caches/cacheloaders will be loading/saving data to the same
+ //database
+ }
+ //------Service lifecycle implementation---------------------------------------------------------------------------------------------------------------------
+ /**
+ *
+ */
+ public void create() throws Exception
+ {
+ }
+
+ /**
+ *
+ */
+ public void start() throws Exception
+ {
+ log.info("------------------------------------------------------");
+ log.info("PersistenceManager Cache successfully started.....(ClusterName="+this.cache.getClusterName()+")");
+ log.info("------------------------------------------------------");
+ }
+
+ /**
+ *
+ */
+ public void stop()
+ {
+ this.cache = null;
+ }
+
+ /**
+ *
+ */
+ public void destroy()
+ {
+ }
+ //------internal implementation-----------------------------------------------------------------------------------------------------------------------
+ /**
+ *
+ *
+ */
+ private Object saveWSPPropNodeEntry(WSPProp wspProp) throws Exception
+ {
+ Object oldValue = null;
+
+ oldValue = this.loadManagedNode(loadWSPProp,wspProp.getPropId());
+ if(oldValue!=null)
+ {
+ Integer id = ((WSPProp)oldValue).getKey();
+ wspProp.setKey(id);
+ }
+ else
+ {
+ wspProp.setKey(null);
+ }
+ this.save(wspProp);
+
+ return oldValue;
+ }
+
+ /**
+ *
+ *
+ */
+ private Object saveVersionPropNodeEntry(VersionProp versionProp) throws Exception
+ {
+ Object oldValue = null;
+
+ oldValue = this.loadManagedNode(loadVersionProp,versionProp.getPropId());
+ if(oldValue!=null)
+ {
+ Integer id = ((VersionProp)oldValue).getKey();
+ versionProp.setKey(id);
+ }
+ else
+ {
+ versionProp.setKey(null);
+ }
+ this.save(versionProp);
+
+ return oldValue;
+ }
+
+ /**
+ *
+ *
+ */
+ private Object saveWSPNodeNodeEntry(WSPNode wspNode) throws Exception
+ {
+ Object oldValue = null;
+
+ oldValue = this.loadManagedNode(loadWSPNode,wspNode.getNodeId());
+ if(oldValue!=null)
+ {
+ Integer id = ((WSPNode)oldValue).getKey();
+ wspNode.setKey(id);
+ }
+ else
+ {
+ wspNode.setKey(null);
+ }
+ this.save(wspNode);
+
+ return oldValue;
+ }
+
+ /**
+ *
+ *
+ */
+ private Object saveVersionNodeNodeEntry(VersionNode versionNode) throws Exception
+ {
+ Object oldValue = null;
+
+ oldValue = this.loadManagedNode(loadVersionNode,versionNode.getNodeId());
+ if(oldValue!=null)
+ {
+ Integer id = ((VersionNode)oldValue).getKey();
+ versionNode.setKey(id);
+ }
+ else
+ {
+ versionNode.setKey(null);
+ }
+ this.save(versionNode);
+
+ return oldValue;
+ }
+
+ /**
+ *
+ *
+ */
+ private Object saveWSPRefNodeEntry(WSPRefs wspRef) throws Exception
+ {
+ Object oldValue = null;
+
+ oldValue = this.loadManagedNode(loadWSPRef,wspRef.getRefId());
+ if(oldValue!=null)
+ {
+ Integer id = ((WSPRefs)oldValue).getKey();
+ wspRef.setKey(id);
+ }
+ else
+ {
+ wspRef.setKey(null);
+ }
+ this.save(wspRef);
+
+ return oldValue;
+ }
+
+ /**
+ *
+ *
+ */
+ private Object saveVersionRefNodeEntry(VersionRefs versionRef) throws Exception
+ {
+ Object oldValue = null;
+
+ oldValue = this.loadManagedNode(loadVersionRef,versionRef.getRefId());
+ if(oldValue!=null)
+ {
+ Integer id = ((VersionRefs)oldValue).getKey();
+ versionRef.setKey(id);
+ }
+ else
+ {
+ versionRef.setKey(null);
+ }
+ this.save(versionRef);
+
+ return oldValue;
+ }
+ //-----------------------------------------------------------------------------------------------------------------------------------------------------
+ /**
+ *
+ *
+ */
+ private Set getChildrenNames(String query) throws Exception
+ {
+ Set children = null;
+ Session session = null;
+ try
+ {
+ session = Tools.getOpenSession();
+
+ List rs = session.createQuery(query).list();
+ for(Iterator itr=rs.iterator();itr.hasNext();)
+ {
+ String id = (String)itr.next();
+ if(children==null)
+ {
+ children = new HashSet();
+ }
+ children.add(PortalCMSCacheLoader.parseNodeName(id));
+ }
+ }
+ finally
+ {
+ Tools.closeSession(session);
+ }
+ return children;
+ }
+
+ /**
+ *
+ *
+ */
+ private Object loadNode(String query,String id) throws Exception
+ {
+ Object node = null;
+ Session session = null;
+ try
+ {
+ session = Tools.getOpenSession();
+
+ //node = session.createQuery(query).setString(0,id).uniqueResult();
+ List rs = session.createQuery(query).setString(0,id).list();
+ if(rs !=null && !rs.isEmpty())
+ {
+ node = rs.iterator().next();
+ }
+ }
+ finally
+ {
+ Tools.closeSession(session);
+ }
+ return node;
+ }
+
+ /**
+ *
+ *
+ */
+ private Object loadManagedNode(String query,String id) throws Exception
+ {
+ Object node = null;
+
+ Session session = Tools.getCurrentSession();
+ //node = session.createQuery(query).setString(0,id).uniqueResult();
+ List rs = session.createQuery(query).setString(0,id).list();
+ if(rs !=null && !rs.isEmpty())
+ {
+ node = rs.iterator().next();
+ }
+
+ return node;
+ }
+
+ /**
+ *
+ */
+ private void save(Object object) throws Exception
+ {
+ Session session = Tools.getCurrentSession();
+ if(((Base)object).getKey() != null)
+ {
+ session.merge(object);
+ }
+ else
+ {
+ session.save(object);
+ }
+ }
+
+ /**
+ *
+ *
+ */
+ private Object delete(String loadQuery,String id) throws Exception
+ {
+ Object removedValue = null;
+ removedValue = this.loadManagedNode(loadQuery,id);
+ if(removedValue!=null)
+ {
+ Session session = Tools.getCurrentSession();
+ session.delete(removedValue);
+ }
+ return removedValue;
+ }
+ //---------------nodeName related methods-------------------------------------------------------------------------------------------------------------
+ /**
+ *
+ *
+ */
+ public static String parseNodeName(String id)
+ {
+ String node = (String)PortalCMSCacheLoader.nodeNames.get(id);
+
+ if(node == null)
+ {
+ node = id.replace('/','_');
+ node = node.replace(':','_');
+ node = node.replace('{','_');
+ node = node.replace('}','_');
+ PortalCMSCacheLoader.nodeNames.put(id,node);
+ }
+
+ return node;
+ }
+
+ /**
+ *
+ *
+ */
+ private static String lookupNodeId(String nodeName)
+ {
+ String id = null;
+
+ Object[] keys = PortalCMSCacheLoader.nodeNames.keySet().toArray();
+ for(int i=0;i<keys.length;i++)
+ {
+ String key = (String)keys[i];
+ String value = (String)PortalCMSCacheLoader.nodeNames.get(key);
+ if(value.equals(nodeName))
+ {
+ id = key;
+ break;
+ }
+ }
+
+ return id;
+ }
+}
Added: trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/Tools.java
===================================================================
--- trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/Tools.java 2006-09-17 15:27:03 UTC (rev 5216)
+++ trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/Tools.java 2006-09-18 04:21:11 UTC (rev 5217)
@@ -0,0 +1,199 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.portal.cms.hibernate.state;
+
+import javax.naming.InitialContext;
+
+import org.apache.log4j.Logger;
+
+import org.hibernate.cfg.Configuration;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Query;
+import org.hibernate.HibernateException;
+import org.hibernate.metadata.ClassMetadata;
+import org.hibernate.tool.hbm2ddl.SchemaExport;
+import org.hibernate.Transaction;
+
+/*
+ * Created on Aug 29, 2006
+ *
+ * A Tool for performing some Hibernate related utilities. This is designed to work in both managed as well as non-managed environments
+ *
+ * @author <a href="mailto:sohil.shah at jboss.com">Sohil Shah</a>
+ */
+public class Tools
+{
+ private static final Logger log = Logger.getLogger(Tools.class);
+
+ //hibernate configuration relation information
+ private static SessionFactory sessionFactory = null;
+ private static Configuration cfg = null;
+ private static boolean autoClose = false;
+
+ /**
+ *
+ *
+ */
+ public static void init(String jndiName)
+ {
+ if(Tools.sessionFactory == null)
+ {
+ try
+ {
+ log.info("Loading the PersistenceManager Hibernate System (Started)...........................");
+
+ boolean loadSuccess = true;
+ try
+ {
+ //just to initialize the session factory
+ Tools.sessionFactory = (SessionFactory)new InitialContext().lookup(jndiName);
+ }
+ catch(Exception e)
+ {
+ //some reason this is not found in JNDI environment....try and load from hibernate.cfg.xml from
+ //classpath
+ loadSuccess = false;
+ }
+
+ if(!loadSuccess)
+ {
+ //configure session factory from configuration
+ Tools.cfg = new Configuration();
+ Tools.cfg.configure();
+ Tools.sessionFactory = Tools.cfg.buildSessionFactory();
+ Tools.generateSiteSchema(Tools.cfg);
+ }
+
+
+ log.info("Loading the PersistenceManager Hibernate System (Done)...........................");
+ }
+ catch(Exception e)
+ {
+ log.error("org.jboss.portal.cms.hibernate.state.Tools",e);
+ }
+ }
+ }
+
+ //---------------------------------------------------------------------------------------------------------------------------------------------------
+ /**
+ *
+ */
+ public static SessionFactory getSessionFactory()
+ {
+ return Tools.sessionFactory;
+ }
+
+ /**
+ *
+ * @return
+ */
+ public static Session getCurrentSession()
+ {
+ Session session = Tools.sessionFactory.getCurrentSession();
+ return session;
+ }
+
+ /**
+ *
+ * @return
+ */
+ public static Session getOpenSession()
+ {
+ Session session = Tools.sessionFactory.openSession();
+ return session;
+ }
+
+ /**
+ *
+ * @param session
+ */
+ public static void closeSession(Session session)
+ {
+ if(session!=null && session.isOpen() && !Tools.autoClose)
+ {
+ session.close();
+ }
+ }
+ //-----------------------schema generation capabilities-------------------------------------------------------------------------------------------
+ /**
+ *
+ * @param cfg
+ */
+ private static void generateSiteSchema(Configuration cfg)
+ {
+ if(!doesSiteSchemaExist())
+ {
+ SchemaExport export = new SchemaExport(cfg);
+ export.create(true, //print to the console
+ true //run inside the database
+ );
+ }
+ else
+ {
+ log.info("Site Schema successfully found....No need to recreate it.");
+ }
+ }
+
+ /**
+ *
+ * @return
+ */
+ private static boolean doesSiteSchemaExist()
+ {
+ Session session = null;
+ Transaction tx = null;
+ try
+ {
+ session = Tools.sessionFactory.openSession();
+ tx = session.beginTransaction();
+ ClassMetadata cmd = (ClassMetadata)Tools.sessionFactory.getAllClassMetadata().values().iterator().next();
+ if(cmd!=null)
+ {
+ Query query = session.createQuery("from " + cmd.getEntityName());
+ query.setFirstResult(0);
+ query.setMaxResults(0);
+ try
+ {
+ query.list();
+ }
+ catch (HibernateException e)
+ {
+ // We consider that exception means that the schema deos not exist
+ return false;
+ }
+ }
+ //if I get here the schemaExists, dont recreate it
+ return true;
+ }
+ finally
+ {
+ if(tx!=null)
+ {
+ tx.rollback(); //does not matter since this is only a read operation
+ //this is only so that this operation executes within the context
+ //of a transaction that performs any necessary cleanup automatically
+ }
+ Tools.closeSession(session);
+ }
+ }
+}
Modified: trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/VersionNode.java
===================================================================
--- trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/VersionNode.java 2006-09-17 15:27:03 UTC (rev 5216)
+++ trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/VersionNode.java 2006-09-18 04:21:11 UTC (rev 5217)
@@ -27,52 +27,41 @@
/**
* @author <a href="mailto:roy at jboss.org">Roy Russo</a>
*/
-public class VersionNode implements Serializable
+public class VersionNode extends Base implements Serializable
{
/** The serialVersionUID */
private static final long serialVersionUID = -2699419131858972327L;
- private Integer key;
- private String id;
- private java.sql.Blob data;
+ private String nodeId;
+ private byte[] data;
public VersionNode()
{
}
- public VersionNode(String id, Blob data)
+ public VersionNode(String id, byte[] data)
{
- this.key = null;
- this.id = id;
+ this.nodeId = id;
this.data = data;
}
- public Integer getKey()
+
+ public String getNodeId()
{
- return key;
+ return nodeId;
}
- public void setKey(Integer key)
+ public void setNodeId(String id)
{
- this.key = key;
+ this.nodeId = id;
}
- public String getId()
+ public byte[] getData()
{
- return id;
- }
-
- public void setId(String id)
- {
- this.id = id;
- }
-
- public Blob getData()
- {
return data;
}
- public void setData(Blob data)
+ public void setData(byte[] data)
{
this.data = data;
}
Modified: trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/VersionProp.java
===================================================================
--- trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/VersionProp.java 2006-09-17 15:27:03 UTC (rev 5216)
+++ trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/VersionProp.java 2006-09-18 04:21:11 UTC (rev 5217)
@@ -27,52 +27,41 @@
/**
* @author <a href="mailto:roy at jboss.org">Roy Russo</a>
*/
-public class VersionProp implements Serializable
+public class VersionProp extends Base implements Serializable
{
/** The serialVersionUID */
private static final long serialVersionUID = -699585138297339148L;
- private Integer key;
- private String id;
- private java.sql.Blob data;
+ private String propId;
+ private byte[] data;
public VersionProp()
{
}
- public VersionProp(String id, Blob data)
+ public VersionProp(String id, byte[] data)
{
- this.key = null;
- this.id = id;
+ this.propId = id;
this.data = data;
}
- public Integer getKey()
+
+ public String getPropId()
{
- return key;
+ return propId;
}
- public void setKey(Integer key)
+ public void setPropId(String id)
{
- this.key = key;
+ this.propId = id;
}
- public String getId()
+ public byte[] getData()
{
- return id;
- }
-
- public void setId(String id)
- {
- this.id = id;
- }
-
- public Blob getData()
- {
return data;
}
- public void setData(Blob data)
+ public void setData(byte[] data)
{
this.data = data;
}
Modified: trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/VersionRefs.java
===================================================================
--- trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/VersionRefs.java 2006-09-17 15:27:03 UTC (rev 5216)
+++ trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/VersionRefs.java 2006-09-18 04:21:11 UTC (rev 5217)
@@ -22,59 +22,45 @@
package org.jboss.portal.cms.hibernate.state;
import java.io.Serializable;
-import java.sql.Blob;
/**
* @author <a href="mailto:roy at jboss.org">Roy Russo</a>
*/
-public class VersionRefs implements Serializable
+public class VersionRefs extends Base implements Serializable
{
/** The serialVersionUID */
private static final long serialVersionUID = -4096847492469682729L;
- private Integer key;
- private String id;
- private java.sql.Blob data;
+ private String refId;
+ private byte[] data;
public VersionRefs()
{
}
- public VersionRefs(String id, Blob data)
+ public VersionRefs(String refId, byte[] data)
{
- this.key = null;
- this.id = id;
+ this.refId = refId;
this.data = data;
}
- public Integer getKey()
+ public String getRefId()
{
- return key;
+ return this.refId;
}
- public void setKey(Integer key)
+ public void setRefId(String refId)
{
- this.key = key;
+ this.refId = refId;
}
- public String getId()
+ public byte[] getData()
{
- return id;
- }
-
- public void setId(String id)
- {
- this.id = id;
- }
-
- public Blob getData()
- {
return data;
}
- public void setData(Blob data)
+ public void setData(byte[] data)
{
this.data = data;
}
-
}
Modified: trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/WSPNode.java
===================================================================
--- trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/WSPNode.java 2006-09-17 15:27:03 UTC (rev 5216)
+++ trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/WSPNode.java 2006-09-18 04:21:11 UTC (rev 5217)
@@ -27,51 +27,39 @@
/**
* @author <a href="mailto:roy at jboss.org">Roy Russo</a>
*/
-public class WSPNode implements Serializable
+public class WSPNode extends Base implements Serializable
{
/** The serialVersionUID */
private static final long serialVersionUID = 624216529218745492L;
- private Integer key;
- private String id;
- private java.sql.Blob data;
+ private String nodeId;
+ private byte[] data;
public WSPNode()
{
}
- public WSPNode(String id, Blob data)
+ public WSPNode(String id, byte[] data)
{
- this.key = null;
- this.id = id;
+ this.nodeId = id;
this.data = data;
}
- public Integer getKey()
+ public String getNodeId()
{
- return key;
+ return nodeId;
}
- public void setKey(Integer key)
+ public void setNodeId(String id)
{
- this.key = key;
+ this.nodeId = id;
}
- public String getId()
+ public byte[] getData()
{
- return id;
- }
-
- public void setId(String id)
- {
- this.id = id;
- }
-
- public Blob getData()
- {
return data;
}
- public void setData(Blob data)
+ public void setData(byte[] data)
{
this.data = data;
}
Modified: trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/WSPProp.java
===================================================================
--- trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/WSPProp.java 2006-09-17 15:27:03 UTC (rev 5216)
+++ trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/WSPProp.java 2006-09-18 04:21:11 UTC (rev 5217)
@@ -27,51 +27,39 @@
/**
* @author <a href="mailto:roy at jboss.org">Roy Russo</a>
*/
-public class WSPProp implements Serializable
+public class WSPProp extends Base implements Serializable
{
/** The serialVersionUID */
private static final long serialVersionUID = 6490887142311625721L;
- private Integer key;
- private String id;
- private java.sql.Blob data;
+ private String propId;
+ private byte[] data;
public WSPProp()
{
}
- public WSPProp(String id, Blob data)
+ public WSPProp(String id, byte[] data)
{
- this.key = null;
- this.id = id;
+ this.propId = id;
this.data = data;
}
- public Integer getKey()
+ public String getPropId()
{
- return key;
+ return propId;
}
- public void setKey(Integer key)
+ public void setPropId(String id)
{
- this.key = key;
+ this.propId = id;
}
- public String getId()
+ public byte[] getData()
{
- return id;
- }
-
- public void setId(String id)
- {
- this.id = id;
- }
-
- public Blob getData()
- {
return data;
}
- public void setData(Blob data)
+ public void setData(byte[] data)
{
this.data = data;
}
Modified: trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/WSPRefs.java
===================================================================
--- trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/WSPRefs.java 2006-09-17 15:27:03 UTC (rev 5216)
+++ trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/WSPRefs.java 2006-09-18 04:21:11 UTC (rev 5217)
@@ -22,58 +22,45 @@
package org.jboss.portal.cms.hibernate.state;
import java.io.Serializable;
-import java.sql.Blob;
/**
* @author <a href="mailto:roy at jboss.org">Roy Russo</a>
*/
-public class WSPRefs implements Serializable
+public class WSPRefs extends Base implements Serializable
{
/** The serialVersionUID */
private static final long serialVersionUID = 5259852110944824462L;
- private Integer key;
- private String id;
- private java.sql.Blob data;
+ private String refId;
+ private byte[] data;
public WSPRefs()
{
}
- public WSPRefs(String id, Blob data)
+ public WSPRefs(String refId,byte[] data)
{
- this.key = null;
- this.id = id;
+ this.refId = refId;
this.data = data;
}
- public Integer getKey()
+
+ public String getRefId()
{
- return key;
+ return this.refId;
}
- public void setKey(Integer key)
+ public void setRefId(String refId)
{
- this.key = key;
+ this.refId = refId;
}
- public String getId()
+ public byte[] getData()
{
- return id;
- }
-
- public void setId(String id)
- {
- this.id = id;
- }
-
- public Blob getData()
- {
return data;
}
- public void setData(Blob data)
+ public void setData(byte[] data)
{
this.data = data;
}
-
}
Modified: trunk/cms/src/main/org/jboss/portal/cms/impl/jcr/command/ContentGetVersionsCommand.java
===================================================================
--- trunk/cms/src/main/org/jboss/portal/cms/impl/jcr/command/ContentGetVersionsCommand.java 2006-09-17 15:27:03 UTC (rev 5216)
+++ trunk/cms/src/main/org/jboss/portal/cms/impl/jcr/command/ContentGetVersionsCommand.java 2006-09-18 04:21:11 UTC (rev 5217)
@@ -36,10 +36,12 @@
import org.jboss.portal.cms.model.Content;
import org.jboss.portal.cms.util.FileUtil;
+
/**
* Returns all versions for a given path, except the rootVersion.
*
* @author <a href="mailto:roy at jboss.org">Roy Russo</a>
+ * @author <a href="mailto:sohil.shah at jboss.com">Sohil Shah</a>
*/
public class ContentGetVersionsCommand extends JCRCommand
{
@@ -60,30 +62,50 @@
{
Session session = context.getSession();
Node fileNode = (Node) session.getItem(this.msFilePath);
+
VersionHistory vh = fileNode.getVersionHistory();
- VersionIterator vi = vh.getAllVersions();
Version liveVersion = vh.getVersionByLabel("LIVE");
+ Version rootVersion = vh.getRootVersion();
+
+
+ VersionIterator vi = vh.getAllVersions();
while(vi.hasNext()) // loop versions
{
Content content = new ContentImpl();
+
Version version = vi.nextVersion();
- if(!version.getName().equalsIgnoreCase("jcr:rootVersion")) // ignore the root version
- {
+ if(!(version.equals(rootVersion))) // ignore the root version
+ {
NodeIterator ni = version.getNodes();
while(ni.hasNext())
{
Node node = ni.nextNode();
-
+
content.setTitle(node.getProperty("portalcms:title").getString());
content.setDescription(node.getProperty("portalcms:description").getString());
content.setLocale(new Locale(node.getProperty("portalcms:language").getString()));
+ content.setVersionPath(node.getPath());
content.setBaseUUID(node.getProperty("jcr:frozenUuid").getString());
- content.setBasePath(session.getNodeByUUID(content.getBaseUUID()).getPath());
- content.setVersionPath(node.getPath());
+ content.setBasePath(session.getNodeByUUID(content.getBaseUUID()).getPath());
content.setVersionUUID(node.getUUID());
-
- content.setBytes(FileUtil.getBytes(node.getProperty("jcr:data").getStream()));
+
+ /**
+ * TODO: integate content size as a node property instead of a derived value
+ * see explanation in comments
+ */
+ //this is the hacked code for now, until the size property is integrated end-to-end.
+ //getting the size this way leads to unnecessary extraction of actual content
+ //which slows the system down dramatically
+ content.setBytes("".getBytes());
+
+ //this should be the new code
+ /*int size = 0;
+ if(node.hasProperty("portalcms:size"))
+ {
+ size = Integer.parseInt(node.getProperty("portalcms:size").getString());
+ }*/
+
content.setMimeType(node.getProperty("jcr:mimeType").getString());
content.setLastModified(node.getProperty("jcr:lastModified").getDate().getTime());
content.setName(node.getName());
@@ -94,11 +116,14 @@
{
content.setLive(true);
}
+
+
content.setEncoding(node.getProperty("jcr:encoding").getString());
+
contents.addElement(content);
}
}
- }
+ }
}
catch(Exception e)
{
Added: trunk/cms/src/main/org/jboss/portal/cms/impl/jcr/jackrabbit/ClusteredCacheListener.java
===================================================================
--- trunk/cms/src/main/org/jboss/portal/cms/impl/jcr/jackrabbit/ClusteredCacheListener.java 2006-09-17 15:27:03 UTC (rev 5216)
+++ trunk/cms/src/main/org/jboss/portal/cms/impl/jcr/jackrabbit/ClusteredCacheListener.java 2006-09-18 04:21:11 UTC (rev 5217)
@@ -0,0 +1,213 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.portal.cms.impl.jcr.jackrabbit;
+
+import java.util.Collections;
+import java.util.Map;
+
+import org.jboss.cache.Fqn;
+import org.jboss.cache.TreeCache;
+import org.jboss.cache.TreeCacheListener;
+import org.jgroups.View;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.jackrabbit.core.state.ItemStateCache;
+import org.apache.jackrabbit.core.state.ItemState;
+import org.apache.jackrabbit.core.ItemId;
+
+import org.apache.commons.collections.map.ReferenceMap;
+
+
+/*
+ * Created on Sep 6, 2006
+ *
+ * @author <a href="mailto:sohil.shah at jboss.com">Sohil Shah</a>
+ */
+public class ClusteredCacheListener implements TreeCacheListener
+{
+ /**
+ *
+ */
+ private static Logger log = LoggerFactory.getLogger(ClusteredCacheListener.class);
+
+ /**
+ * map of node to corresponding cacheItem to be used for doing itemStateCache invalidation in a cluster
+ */
+ private static Map internalCaches = Collections.synchronizedMap(new ReferenceMap(ReferenceMap.HARD,ReferenceMap.WEAK));
+ private static Map nodeToItem = Collections.synchronizedMap(new ReferenceMap(ReferenceMap.HARD,ReferenceMap.WEAK));
+ private static int cacheKeyCounter = 0;
+
+ /**
+ *
+ */
+ private TreeCache treeCache = null;
+
+ /**
+ *
+ *
+ */
+ public ClusteredCacheListener()
+ {
+ }
+
+ /**
+ *
+ *
+ */
+ public static void storeInternalCache(String node,ItemId item,ItemStateCache cache)
+ {
+ if(!ClusteredCacheListener.internalCaches.containsValue(cache))
+ {
+ ClusteredCacheListener.internalCaches.put(getCacheKey(),cache);
+ }
+ ClusteredCacheListener.nodeToItem.put(node,item);
+ }
+
+ /**
+ *
+ *
+ */
+ private static synchronized String getCacheKey()
+ {
+ return String.valueOf(cacheKeyCounter++);
+ }
+
+
+ /**
+ *
+ */
+ public void nodeEvicted(Fqn fqn)
+ {
+ try
+ {
+ String nodeName = fqn.toString();
+ ItemId item = (ItemId)ClusteredCacheListener.nodeToItem.get(nodeName);
+ if(item != null)
+ {
+ synchronized(item)
+ {
+ if(!ClusteredCacheListener.nodeToItem.containsKey(nodeName))
+ {
+ return;
+ }
+ ClusteredCacheListener.nodeToItem.remove(nodeName);
+ Object[] values = ClusteredCacheListener.internalCaches.values().toArray();
+ for(int i=0;i<values.length;i++)
+ {
+ ItemStateCache internalCache = (ItemStateCache)values[i];
+ synchronized(internalCache)
+ {
+ if(internalCache.isCached(item))
+ {
+ ItemState state = internalCache.retrieve(item);
+
+ log.debug("Evicting..."+item.toString()+" (Transient:"+state.isTransient()+")");
+
+ state.discard();
+ }
+ }
+ }
+ }
+ }
+ }
+ catch(Exception e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ *
+ */
+ public void nodeModified(Fqn fqn)
+ {
+ }
+
+ /**
+ *
+ */
+ public void nodeCreated(Fqn fqn)
+ {
+ }
+
+ /**
+ *
+ */
+ public void nodeRemoved(Fqn fqn)
+ {
+ }
+
+ /**
+ *
+ */
+ public void nodeLoaded(Fqn fqn)
+ {
+ }
+
+ /**
+ *
+ */
+ public void nodeVisited(Fqn fqn)
+ {
+ }
+ //----------------------------------------------------------------------------------------------------------------------------------------------------
+ /**
+ *
+ */
+ public void cacheStarted(TreeCache treeCache)
+ {
+ this.treeCache = treeCache;
+ }
+
+ /**
+ *
+ */
+ public void cacheStopped(TreeCache treeCache)
+ {
+ }
+
+ /**
+ *
+ */
+ public void viewChange(View view)
+ {
+ }
+
+ //---------------nodeName related methods-------------------------------------------------------------------------------------------------------------
+ /**
+ *
+ *
+ */
+ public static String parseNodeName(String id)
+ {
+ String node = null;
+
+ node = id.replace('/','_');
+ node = node.replace(':','_');
+ node = node.replace('{','_');
+ node = node.replace('}','_');
+
+ return node;
+ }
+ //--------------------------------------------------------------------------------------------------------------------------------------------------
+}
Modified: trunk/core/build.xml
===================================================================
--- trunk/core/build.xml 2006-09-17 15:27:03 UTC (rev 5216)
+++ trunk/core/build.xml 2006-09-18 04:21:11 UTC (rev 5217)
@@ -292,7 +292,21 @@
<fileset dir="${jcr.jcr.lib}" includes="jcr-1.0.jar"/>
<fileset dir="${apache.collections.lib}" includes="commons-collections.jar"/>
<fileset dir="${apache.lucene.lib}" includes="lucene.jar"/>
- <fileset dir="${jackrabbit.jackrabbit.lib}" includes="jackrabbit-core-1.0.jar"/>
+
+ <!-- cms optimization integration - this contains a clustered cache enabled version
+ of jackrabbit customization of jackrabbit-core-1.0.1 codebase
+ For details regarding this customization see: cms/jackrabbit-customization
+ also needed are jboss-cache.jar and jgroups.jar to support this customization
+ 1.4.0SP1
+
+ TODO: This is fine for this iteration. Eventually we need to integrate these libraries
+ for bundling in the thirdparty mechanism. This will follow in the next iteration
+ -->
+ <!--fileset dir="${jackrabbit.jackrabbit.lib}" includes="jackrabbit-core-1.0.jar"/-->
+ <fileset dir="../cms/jackrabbit-customization/lib" includes="jackrabbit-core-1.0.1.jar"/>
+ <fileset dir="../cms/jackrabbit-customization/lib" includes="jboss-cache.jar"/>
+ <fileset dir="../cms/jackrabbit-customization/lib" includes="jgroups.jar"/>
+
<fileset dir="${slf4j.slf4j.lib}" includes="slf4j-log4j12.jar"/>
</copy>
<!-- portal-cms.war -->
Property changes on: trunk/core/src/resources/portal-cms-sar/META-INF
___________________________________________________________________
Name: svn:ignore
+ jboss-service.xml.bak
Modified: trunk/core/src/resources/portal-cms-sar/META-INF/jboss-service.xml
===================================================================
--- trunk/core/src/resources/portal-cms-sar/META-INF/jboss-service.xml 2006-09-17 15:27:03 UTC (rev 5216)
+++ trunk/core/src/resources/portal-cms-sar/META-INF/jboss-service.xml 2006-09-18 04:21:11 UTC (rev 5217)
@@ -120,7 +120,7 @@
-->
<!-- HibernatePersistentManager: uses RDBMS + Hibernate for storage -->
- <PersistenceManager class="org.jboss.portal.cms.hibernate.state.HibernatePersistenceManager">
+ <PersistenceManager class="org.jboss.portal.cms.hibernate.state.JBossCachePersistenceManager">
<param name="schemaObjectPrefix" value="WSP"/>
<param name="JNDIName" value="java:portal/cms/CMSSessionFactory"/>
<param name="externalBLOBs" value="false"/>
@@ -167,7 +167,7 @@
-->
<!-- HibernatePersistentManager: uses RDBMS + Hibernate for storage -->
- <PersistenceManager class="org.jboss.portal.cms.hibernate.state.HibernatePersistenceManager">
+ <PersistenceManager class="org.jboss.portal.cms.hibernate.state.JBossCachePersistenceManager">
<param name="schemaObjectPrefix" value="Version"/>
<param name="JNDIName" value="java:portal/cms/CMSSessionFactory"/>
<param name="externalBLOBs" value="false"/>
@@ -270,4 +270,285 @@
<attribute name="Prefix">content</attribute>
<depends optional-attribute-name="Factory" proxy-type="attribute">portal:urlFactory=Delegating</depends>
</mbean>
+
+ <!-- TreeCache configuration used to cache CMS data -->
+ <mbean code="org.jboss.cache.TreeCache"
+ name="cms.pm.cache:service=TreeCache">
+
+ <depends>jboss:service=Naming</depends>
+ <depends>jboss:service=TransactionManager</depends>
+ <depends>portal:service=Hibernate,type=CMS</depends>
+
+ <!--
+ Configure the TransactionManager
+ -->
+ <attribute name="TransactionManagerLookupClass">org.jboss.cache.GenericTransactionManagerLookup</attribute>
+
+ <!--
+ Node locking scheme:
+ OPTIMISTIC
+ PESSIMISTIC (default)
+ using the OPTIMISTIC scheme, the ISOLATION_LEVEL value is ignored
+ -->
+ <!--attribute name="NodeLockingScheme">OPTIMISTIC</attribute-->
+
+ <!--
+ Isolation level : SERIALIZABLE
+ REPEATABLE_READ (default)
+ READ_COMMITTED
+ READ_UNCOMMITTED
+ NONE
+ -->
+ <attribute name="IsolationLevel">REPEATABLE_READ</attribute>
+
+
+
+ <!--
+ Valid modes are LOCAL
+ REPL_ASYNC
+ REPL_SYNC
+ INVALIDATION_ASYNC
+ INVALIDATION_SYNC
+ -->
+ <attribute name="CacheMode">INVALIDATION_ASYNC</attribute>
+
+ <!--
+ Just used for async repl: use a replication queue
+ -->
+ <attribute name="UseReplQueue">false</attribute>
+
+ <!--
+ Replication interval for replication queue (in ms)
+ -->
+ <attribute name="ReplQueueInterval">0</attribute>
+
+ <!--
+ Max number of elements which trigger replication
+ -->
+ <attribute name="ReplQueueMaxElements">0</attribute>
+
+ <!-- Name of cluster. Needs to be the same for all clusters, in order
+ to find each other
+ -->
+ <attribute name="ClusterName">JCRPMCache</attribute>
+
+ <!-- JGroups protocol stack properties. Can also be a URL,
+ e.g. file:/home/bela/default.xml
+ <attribute name="ClusterProperties"></attribute>
+ -->
+
+ <attribute name="ClusterConfig">
+ <config>
+ <!-- UDP: if you have a multihomed machine,
+ set the bind_addr attribute to the appropriate NIC IP address -->
+ <!-- UDP: On Windows machines, because of the media sense feature
+ being broken with multicast (even after disabling media sense)
+ set the loopback attribute to true -->
+ <UDP mcast_addr="228.1.2.3" mcast_port="48866"
+ ip_ttl="64" ip_mcast="true"
+ receive_on_all_interfaces="true"
+ mcast_send_buf_size="150000" mcast_recv_buf_size="80000"
+ ucast_send_buf_size="150000" ucast_recv_buf_size="80000"
+ loopback="false"/>
+ <PING timeout="2000" num_initial_members="3"
+ up_thread="false" down_thread="false"/>
+ <MERGE2 min_interval="10000" max_interval="20000"/>
+ <!-- <FD shun="true" up_thread="true" down_thread="true" />-->
+ <FD_SOCK/>
+ <VERIFY_SUSPECT timeout="1500"
+ up_thread="false" down_thread="false"/>
+ <pbcast.NAKACK gc_lag="50" retransmit_timeout="600,1200,2400,4800"
+ max_xmit_size="8192" up_thread="false" down_thread="false"/>
+ <UNICAST timeout="600,1200,2400" window_size="100" min_threshold="10"
+ down_thread="false"/>
+ <pbcast.STABLE desired_avg_gossip="20000"
+ up_thread="false" down_thread="false"/>
+ <FRAG frag_size="8192"
+ down_thread="false" up_thread="false"/>
+ <pbcast.GMS join_timeout="5000" join_retry_timeout="2000"
+ shun="true" print_local_addr="true"/>
+ <pbcast.STATE_TRANSFER up_thread="true" down_thread="true"/>
+ </config>
+ </attribute>
+
+ <!--
+ Whether or not to fetch state on joining a cluster
+ NOTE this used to be called FetchStateOnStartup and has been renamed to be more descriptive.
+ -->
+ <attribute name="FetchInMemoryState">false</attribute>
+
+ <!--
+ The max amount of time (in milliseconds) we wait until the
+ initial state (ie. the contents of the cache) are retrieved from
+ existing members in a clustered environment
+ -->
+ <attribute name="InitialStateRetrievalTimeout">20000</attribute>
+
+ <!--
+ Number of milliseconds to wait until all responses for a
+ synchronous call have been received.
+ -->
+ <attribute name="SyncReplTimeout">20000</attribute>
+
+ <!-- Max number of milliseconds to wait for a lock acquisition -->
+ <attribute name="LockAcquisitionTimeout">15000</attribute>
+
+
+ <!-- Name of the eviction policy class. -->
+ <attribute name="EvictionPolicyClass"></attribute>
+
+ <!--
+ Indicate whether to use region based marshalling or not. Set this to true if you are running under a scoped
+ class loader, e.g., inside an application server. Default is "false".
+ -->
+ <attribute name="UseRegionBasedMarshalling">false</attribute>
+
+ <!--
+ Configuring the JDBCCacheLoader
+ -->
+ <attribute name="CacheLoaderConfiguration">
+ <config>
+ <passivation>false</passivation>
+ <preload></preload>
+ <shared>false</shared>
+ <cacheloader>
+ <class>org.jboss.portal.cms.hibernate.state.PortalCMSCacheLoader</class>
+ <properties></properties>
+ <async>false</async>
+ <fetchPersistentState>true</fetchPersistentState>
+ <ignoreModifications>false</ignoreModifications>
+ </cacheloader>
+ </config>
+ </attribute>
+ </mbean>
+
+ <!-- TreeCache configuration for the clustered JackRabbit in-memory cache -->
+ <mbean code="org.jboss.cache.TreeCache"
+ name="jackrabbit.inmemory.cache:service=TreeCache">
+
+ <depends>jboss:service=Naming</depends>
+ <depends>jboss:service=TransactionManager</depends>
+
+ <!--
+ Configure the TransactionManager
+ -->
+ <attribute name="TransactionManagerLookupClass">org.jboss.cache.GenericTransactionManagerLookup</attribute>
+
+ <!--
+ Node locking scheme:
+ OPTIMISTIC
+ PESSIMISTIC (default)
+ using the OPTIMISTIC scheme, the ISOLATION_LEVEL value is ignored
+ -->
+ <!--attribute name="NodeLockingScheme">OPTIMISTIC</attribute-->
+
+ <!--
+ Isolation level : SERIALIZABLE
+ REPEATABLE_READ (default)
+ READ_COMMITTED
+ READ_UNCOMMITTED
+ NONE
+ -->
+ <attribute name="IsolationLevel">NONE</attribute>
+
+ <!--
+ Valid modes are LOCAL
+ REPL_ASYNC
+ REPL_SYNC
+ INVALIDATION_ASYNC
+ INVALIDATION_SYNC
+ -->
+ <attribute name="CacheMode">INVALIDATION_ASYNC</attribute>
+
+ <!--
+ Just used for async repl: use a replication queue
+ -->
+ <attribute name="UseReplQueue">false</attribute>
+
+ <!--
+ Replication interval for replication queue (in ms)
+ -->
+ <attribute name="ReplQueueInterval">0</attribute>
+
+ <!--
+ Max number of elements which trigger replication
+ -->
+ <attribute name="ReplQueueMaxElements">0</attribute>
+
+ <!-- Name of cluster. Needs to be the same for all clusters, in order
+ to find each other
+ -->
+ <attribute name="ClusterName">JackRabbitInternalCache</attribute>
+
+ <!-- JGroups protocol stack properties. Can also be a URL,
+ e.g. file:/home/bela/default.xml
+ <attribute name="ClusterProperties"></attribute>
+ -->
+
+ <attribute name="ClusterConfig">
+ <config>
+ <!-- UDP: if you have a multihomed machine,
+ set the bind_addr attribute to the appropriate NIC IP address -->
+ <!-- UDP: On Windows machines, because of the media sense feature
+ being broken with multicast (even after disabling media sense)
+ set the loopback attribute to true -->
+ <UDP mcast_addr="228.1.2.3" mcast_port="48866"
+ ip_ttl="64" ip_mcast="true"
+ receive_on_all_interfaces="true"
+ mcast_send_buf_size="150000" mcast_recv_buf_size="80000"
+ ucast_send_buf_size="150000" ucast_recv_buf_size="80000"
+ loopback="false"/>
+ <PING timeout="2000" num_initial_members="3"
+ up_thread="false" down_thread="false"/>
+ <MERGE2 min_interval="10000" max_interval="20000"/>
+ <!-- <FD shun="true" up_thread="true" down_thread="true" />-->
+ <FD_SOCK/>
+ <VERIFY_SUSPECT timeout="1500"
+ up_thread="false" down_thread="false"/>
+ <pbcast.NAKACK gc_lag="50" retransmit_timeout="600,1200,2400,4800"
+ max_xmit_size="8192" up_thread="false" down_thread="false"/>
+ <UNICAST timeout="600,1200,2400" window_size="100" min_threshold="10"
+ down_thread="false"/>
+ <pbcast.STABLE desired_avg_gossip="20000"
+ up_thread="false" down_thread="false"/>
+ <FRAG frag_size="8192"
+ down_thread="false" up_thread="false"/>
+ <pbcast.GMS join_timeout="5000" join_retry_timeout="2000"
+ shun="true" print_local_addr="true"/>
+ <pbcast.STATE_TRANSFER up_thread="true" down_thread="true"/>
+ </config>
+ </attribute>
+
+ <!--
+ Whether or not to fetch state on joining a cluster
+ NOTE this used to be called FetchStateOnStartup and has been renamed to be more descriptive.
+ -->
+ <attribute name="FetchInMemoryState">false</attribute>
+
+ <!--
+ The max amount of time (in milliseconds) we wait until the
+ initial state (ie. the contents of the cache) are retrieved from
+ existing members in a clustered environment
+ -->
+ <attribute name="InitialStateRetrievalTimeout">20000</attribute>
+
+ <!--
+ Number of milliseconds to wait until all responses for a
+ synchronous call have been received.
+ -->
+ <attribute name="SyncReplTimeout">20000</attribute>
+
+ <!-- Max number of milliseconds to wait for a lock acquisition -->
+ <attribute name="LockAcquisitionTimeout">15000</attribute>
+
+
+ <!-- Name of the eviction policy class. -->
+ <attribute name="EvictionPolicyClass"></attribute>
+
+ <!--
+ Indicate whether to use region based marshalling or not. Set this to true if you are running under a scoped
+ class loader, e.g., inside an application server. Default is "false".
+ -->
+ <attribute name="UseRegionBasedMarshalling">false</attribute>
+ </mbean>
</server>
Modified: trunk/core/src/resources/portal-cms-sar/conf/hibernate/cms/domain.hbm.xml
===================================================================
--- trunk/core/src/resources/portal-cms-sar/conf/hibernate/cms/domain.hbm.xml 2006-09-17 15:27:03 UTC (rev 5216)
+++ trunk/core/src/resources/portal-cms-sar/conf/hibernate/cms/domain.hbm.xml 2006-09-18 04:21:11 UTC (rev 5217)
@@ -30,14 +30,14 @@
<generator class="native"/>
</id>
<property
- name="id"
+ name="nodeId"
column="NODE_ID"
type="string"
length="36"/>
<property
name="data"
column="NODE_DATA"
- type="blob"
+ type="binary"
length="100000000"
not-null="true"/>
</class>
@@ -49,14 +49,14 @@
<generator class="native"/>
</id>
<property
- name="id"
+ name="propId"
column="PROP_ID"
type="string"
length="255"/>
<property
name="data"
column="PROP_DATA"
- type="blob"
+ type="binary"
length="100000000"
not-null="true"/>
</class>
@@ -68,14 +68,14 @@
<generator class="native"/>
</id>
<property
- name="id"
+ name="refId"
column="NODE_ID"
type="string"
length="36"/>
<property
name="data"
column="REFS_DATA"
- type="blob"
+ type="binary"
length="100000000"
not-null="true"/>
</class>
@@ -106,14 +106,14 @@
<generator class="native"/>
</id>
<property
- name="id"
+ name="nodeId"
column="NODE_ID"
type="string"
length="36"/>
<property
name="data"
column="NODE_DATA"
- type="blob"
+ type="binary"
length="100000000"
not-null="true"/>
</class>
@@ -125,14 +125,14 @@
<generator class="native"/>
</id>
<property
- name="id"
+ name="propId"
column="PROP_ID"
type="string"
length="255"/>
<property
name="data"
column="PROP_DATA"
- type="blob"
+ type="binary"
length="100000000"
not-null="true"/>
</class>
@@ -144,14 +144,14 @@
<generator class="native"/>
</id>
<property
- name="id"
+ name="refId"
column="NODE_ID"
type="string"
length="36"/>
<property
name="data"
column="REFS_DATA"
- type="blob"
+ type="binary"
length="100000000"
not-null="true"/>
</class>
@@ -252,3 +252,4 @@
not-null="true"/>
</class>
</hibernate-mapping>
+
Modified: trunk/core/src/resources/portal-cms-sar/conf/hibernate/cms/hibernate.cfg.xml
===================================================================
--- trunk/core/src/resources/portal-cms-sar/conf/hibernate/cms/hibernate.cfg.xml 2006-09-17 15:27:03 UTC (rev 5216)
+++ trunk/core/src/resources/portal-cms-sar/conf/hibernate/cms/hibernate.cfg.xml 2006-09-18 04:21:11 UTC (rev 5217)
@@ -8,6 +8,10 @@
<property name="show_sql">@portal.sql.show@</property>
<property name="cache.use_second_level_cache">false</property>
<property name="cache.use_query_cache">false</property>
+
+ <!-- managed environment transaction configuration -->
+ <property name="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.JBossTransactionManagerLookup</property>
+ <property name="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</property>
<!-- Force the dialect instead of using autodetection -->
<!--
More information about the jboss-svn-commits
mailing list