exo-jcr SVN: r4771 - jcr/trunk/exo.jcr.component.core.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-08-18 03:25:24 -0400 (Thu, 18 Aug 2011)
New Revision: 4771
Modified:
jcr/trunk/exo.jcr.component.core/pom.xml
Log:
EXOJCR-1428: review TCK tests
Modified: jcr/trunk/exo.jcr.component.core/pom.xml
===================================================================
--- jcr/trunk/exo.jcr.component.core/pom.xml 2011-08-18 06:39:44 UTC (rev 4770)
+++ jcr/trunk/exo.jcr.component.core/pom.xml 2011-08-18 07:25:24 UTC (rev 4771)
@@ -608,20 +608,11 @@
</property>
<property>
<name>known.issues</name>
- <value>org.apache.jackrabbit.test.api.SetValueConstraintViolationExceptionTest#testBooleanProperty
- org.apache.jackrabbit.test.api.SetValueConstraintViolationExceptionTest#testMultipleBooleanProperty
- org.apache.jackrabbit.test.api.version.RestoreTest#testRestoreName
- org.apache.jackrabbit.test.api.version.RestoreTest#testRestoreOrder
+ <value>org.apache.jackrabbit.test.api.version.RestoreTest#testRestoreName
org.apache.jackrabbit.test.api.version.RestoreTest#testRestoreOrder2
org.apache.jackrabbit.test.api.nodetype.PropertyDefTest#testIsRequiredType
- org.apache.jackrabbit.test.api.SetPropertyConstraintViolationExceptionTest#testBooleanProperty
- org.apache.jackrabbit.test.api.nodetype.PredefinedNodeTypeTest#testShareable
- org.apache.jackrabbit.test.api.nodetype.PredefinedNodeTypeTest#testSimpleVersionable
- org.apache.jackrabbit.test.api.nodetype.PredefinedNodeTypeTest#testActivity
- org.apache.jackrabbit.test.api.nodetype.PredefinedNodeTypeTest#testConfiguration
org.apache.jackrabbit.test.api.nodetype.PredefinedNodeTypeTest#testVersionable
- org.apache.jackrabbit.test.api.nodetype.PredefinedNodeTypeTest#testVersion
- org.apache.jackrabbit.test.api.NamespaceRegistryTest#testRegisterNamespace</value>
+ org.apache.jackrabbit.test.api.nodetype.PredefinedNodeTypeTest#testVersion</value>
</property>
<!-- Uncomment the line below if you want to enable the statistics -->
<!--property>
12 years, 9 months
exo-jcr SVN: r4770 - in jcr/trunk/exo.jcr.component.core/src: main/java/org/exoplatform/services/jcr/datamodel and 11 other directories.
by do-not-reply@jboss.org
Author: sergiykarpenko
Date: 2011-08-18 02:39:44 -0400 (Thu, 18 Aug 2011)
New Revision: 4770
Added:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/persistent/WorkspaceStorageCacheListener.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/ACLHolder.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/BloomFilter.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/ShareableSupportedWorkspaceDataManager.java
Removed:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/ACLInheritanceSupportedWorkspaceDataManager.java
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/persistent/WorkspaceStorageCache.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/datamodel/QPath.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/datamodel/QPathEntry.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/CacheableWorkspaceDataManager.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/LinkedWorkspaceStorageCacheImpl.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/VersionableWorkspaceDataManager.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/ISPNCacheWorkspaceStorageCache.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/JBossCacheWorkspaceStorageCache.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/inmemory/InmemoryStorageConnection.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCStorageConnection.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/CQJDBCStorageConnection.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MultiDbJDBCConnection.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/SingleDbJDBCConnection.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/statistics/StatisticsJDBCStorageConnection.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/storage/WorkspaceStorageConnection.java
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/TestCacheableWorkspaceDataManager.java
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/TestWorkspaceStorageCacheInClusterMode.java
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/TestJBossCacheWorkspaceStorageCache.java
Log:
EXOJCR-1456: use bloom filters to store ids of nodes with ACL
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/persistent/WorkspaceStorageCache.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/persistent/WorkspaceStorageCache.java 2011-08-17 14:16:40 UTC (rev 4769)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/persistent/WorkspaceStorageCache.java 2011-08-18 06:39:44 UTC (rev 4770)
@@ -275,16 +275,31 @@
/**
* Start buffering process.
*/
- public void beginTransaction();
+ void beginTransaction();
/**
* Sort changes and commit data to the cache.
*/
- public void commitTransaction();
+ void commitTransaction();
/**
* Forget about changes
*/
- public void rollbackTransaction();
+ void rollbackTransaction();
+ /**
+ * Adds a new listener
+ * @param listener the listener to register
+ * @throws UnsupportedOperationException in case the listeners are not supported by the
+ * implementation
+ */
+ void addListener(WorkspaceStorageCacheListener listener) throws UnsupportedOperationException;
+
+ /**
+ * Removes a listener
+ * @param listener the listener to remove
+ * @throws UnsupportedOperationException in case the listeners are not supported by the
+ * implementation
+ */
+ void removeListener(WorkspaceStorageCacheListener listener) throws UnsupportedOperationException;
}
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/persistent/WorkspaceStorageCacheListener.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/persistent/WorkspaceStorageCacheListener.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/persistent/WorkspaceStorageCacheListener.java 2011-08-18 06:39:44 UTC (rev 4770)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2011 eXo Platform SAS.
+ *
+ * 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.exoplatform.services.jcr.dataflow.persistent;
+
+import org.exoplatform.services.jcr.datamodel.ItemData;
+
+/**
+ * This class allows other class to be notified when a given cache event occurs
+ *
+ * @author <a href="mailto:nfilotto@exoplatform.com">Nicolas Filotto</a>
+ * @version $Id$
+ *
+ */
+public interface WorkspaceStorageCacheListener
+{
+ /**
+ * Called when a cache entry corresponding to the given item has been added
+ * @param data the item corresponding to the added cache entry
+ */
+ void onCacheEntryAdded(ItemData data);
+
+ /**
+ * Called when a cache entry corresponding to the given item has been updated
+ * @param data the item corresponding to the updated cache entry
+ */
+ void onCacheEntryUpdated(ItemData data);
+
+ /**
+ * Called when a cache entry corresponding to the given item has been removed
+ * @param data the item corresponding to the removed cache entry
+ */
+ void onCacheEntryRemoved(ItemData data);
+}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/datamodel/QPath.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/datamodel/QPath.java 2011-08-17 14:16:40 UTC (rev 4769)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/datamodel/QPath.java 2011-08-18 06:39:44 UTC (rev 4770)
@@ -469,6 +469,34 @@
}
/**
+ * Make child path using QName and Item index. <br/>
+ *
+ * @param parent
+ * - parent QPath
+ * @param name
+ * - Item QName
+ * @param itemIndex
+ * - Item index
+ * @param id
+ * - Item id
+ * @return new QPath
+ */
+ public static QPath makeChildPath(final QPath parent, final QName name, final int itemIndex, String id)
+ {
+
+ QPathEntry[] parentEntries = parent.getEntries();
+ QPathEntry[] names = new QPathEntry[parentEntries.length + 1];
+ int index = 0;
+ for (QPathEntry pname : parentEntries)
+ {
+ names[index++] = pname;
+ }
+ names[index] = new QPathEntry(name.getNamespace(), name.getName(), itemIndex, id);
+
+ QPath path = new QPath(names);
+ return path;
+ }
+ /**
* Make child path using array of QPath entries (relative path). <br/>
*
* @param parent
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/datamodel/QPathEntry.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/datamodel/QPathEntry.java 2011-08-17 14:16:40 UTC (rev 4769)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/datamodel/QPathEntry.java 2011-08-18 06:39:44 UTC (rev 4770)
@@ -36,6 +36,8 @@
private String cachedToStringShowIndex;
+ private String id;
+
/**
* QPathEntry constructor.
*
@@ -46,10 +48,27 @@
*/
public QPathEntry(InternalQName qName, int index)
{
+ this(qName, index, null);
+ }
+
+
+ /**
+ * QPathEntry constructor.
+ *
+ * @param qName
+ * - InternalQName (full qualified name)
+ * @param index
+ * - Item index
+ * @param id
+ * - Item id
+ */
+ public QPathEntry(InternalQName qName, int index, String id)
+ {
super(qName.getNamespace(), qName.getName());
this.index = index > 0 ? index : 1;
+ this.id = id;
}
-
+
/**
* QPathEntry constructor.
*
@@ -62,8 +81,26 @@
*/
public QPathEntry(String namespace, String name, int index)
{
+ this(namespace, name, index, null);
+ }
+
+ /**
+ * QPathEntry constructor.
+ *
+ * @param namespace
+ * - namespace URI
+ * @param name
+ * - Item name
+ * @param index
+ * - Item index
+ * @param id
+ * - Item id
+ */
+ public QPathEntry(String namespace, String name, int index, String id)
+ {
super(namespace, name);
this.index = index > 0 ? index : 1;
+ this.id = id;
}
/**
@@ -89,6 +126,16 @@
InternalQName qname = InternalQName.parse(qnameString);
return new QPathEntry(qname, Integer.valueOf(indexString));
+ }
+
+ /**
+ * Return Item id, can be null since it could not be set
+ *
+ * @return the id of the item
+ */
+ public String getId()
+ {
+ return id;
}
/**
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/ACLHolder.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/ACLHolder.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/ACLHolder.java 2011-08-18 06:39:44 UTC (rev 4770)
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2011 eXo Platform SAS.
+ *
+ * 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.exoplatform.services.jcr.impl.dataflow.persistent;
+
+/**
+ * @author <a href="mailto:nfilotto@exoplatform.com">Nicolas Filotto</a>
+ * @version $Id$
+ *
+ */
+public class ACLHolder
+{
+ /**
+ * The id of the node that holds some ACL info
+ */
+ private final String id;
+
+ /**
+ * A flag indicating whether or not the node has owner set
+ */
+ private boolean owner;
+
+ /**
+ * A flag indicating whether or not the node has permissions set
+ */
+ private boolean permissions;
+
+ public ACLHolder(String id)
+ {
+ this.id = id;
+ }
+
+ /**
+ * @return the id
+ */
+ public String getId()
+ {
+ return id;
+ }
+
+ /**
+ * @return the owner
+ */
+ public boolean hasOwner()
+ {
+ return owner;
+ }
+
+ /**
+ * @return the permissions
+ */
+ public boolean hasPermissions()
+ {
+ return permissions;
+ }
+
+ /**
+ * @param owner the owner to set
+ */
+ public void setOwner(boolean owner)
+ {
+ this.owner = owner;
+ }
+
+ /**
+ * @param permissions the permissions to set
+ */
+ public void setPermissions(boolean permissions)
+ {
+ this.permissions = permissions;
+ }
+}
Deleted: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/ACLInheritanceSupportedWorkspaceDataManager.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/ACLInheritanceSupportedWorkspaceDataManager.java 2011-08-17 14:16:40 UTC (rev 4769)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/ACLInheritanceSupportedWorkspaceDataManager.java 2011-08-18 06:39:44 UTC (rev 4770)
@@ -1,174 +0,0 @@
-/*
- * Copyright (C) 2009 eXo Platform SAS.
- *
- * 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.exoplatform.services.jcr.impl.dataflow.persistent;
-
-import org.exoplatform.services.jcr.dataflow.ItemStateChangesLog;
-import org.exoplatform.services.jcr.dataflow.SharedDataManager;
-import org.exoplatform.services.jcr.datamodel.ItemData;
-import org.exoplatform.services.jcr.datamodel.ItemType;
-import org.exoplatform.services.jcr.datamodel.NodeData;
-import org.exoplatform.services.jcr.datamodel.PropertyData;
-import org.exoplatform.services.jcr.datamodel.QPathEntry;
-import org.exoplatform.services.jcr.impl.core.itemfilters.QPathEntryFilter;
-import org.exoplatform.services.log.ExoLogger;
-import org.exoplatform.services.log.Log;
-
-import java.util.Calendar;
-import java.util.List;
-
-import javax.jcr.InvalidItemStateException;
-import javax.jcr.RepositoryException;
-
-/**
- * Created by The eXo Platform SAS. Data Manager supported ACL Inheritance
- *
- * @author Gennady Azarenkov
- * @version $Id: ACLInheritanceSupportedWorkspaceDataManager.java 11907 2008-03-13 15:36:21Z ksm $
- */
-public class ACLInheritanceSupportedWorkspaceDataManager implements SharedDataManager
-{
-
- private static Log LOG = ExoLogger.getLogger("exo.jcr.component.core.ACLInheritanceSupportedWorkspaceDataManager");
-
- protected final CacheableWorkspaceDataManager persistentManager;
-
- public ACLInheritanceSupportedWorkspaceDataManager(CacheableWorkspaceDataManager persistentManager)
- {
- this.persistentManager = persistentManager;
- }
-
- /**
- * {@inheritDoc}
- */
- // ------------ ItemDataConsumer impl ------------
- public List<NodeData> getChildNodesData(NodeData parent) throws RepositoryException
- {
- return persistentManager.getChildNodesData(parent);
- }
-
- /**
- * {@inheritDoc}
- */
- public List<NodeData> getChildNodesData(NodeData parent, List<QPathEntryFilter> patternFilters) throws RepositoryException
- {
- return persistentManager.getChildNodesData(parent, patternFilters);
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean getChildNodesDataByPage(NodeData parent, int fromOrderNum, int limit, List<NodeData> childs)
- throws RepositoryException
- {
- return persistentManager.getChildNodesDataByPage(parent, fromOrderNum, limit, childs);
- }
-
- /**
- * {@inheritDoc}
- */
- public int getLastOrderNumber(final NodeData parent) throws RepositoryException
- {
- return persistentManager.getLastOrderNumber(parent);
- }
-
- /**
- * {@inheritDoc}
- */
- public int getChildNodesCount(final NodeData parent) throws RepositoryException
- {
- return persistentManager.getChildNodesCount(parent);
- }
-
- /**
- * {@inheritDoc}
- */
- public ItemData getItemData(NodeData parent, QPathEntry name) throws RepositoryException
- {
- return getItemData(parent, name, ItemType.UNKNOWN);
- }
-
- /**
- * {@inheritDoc}
- */
- public ItemData getItemData(NodeData parent, QPathEntry name, ItemType itemType) throws RepositoryException
- {
- return persistentManager.getItemData(parent, name, itemType);
- }
-
- /**
- * {@inheritDoc}
- */
- public ItemData getItemData(String identifier) throws RepositoryException
- {
- return persistentManager.getItemData(identifier);
- }
-
- /**
- * {@inheritDoc}
- */
- public List<PropertyData> getChildPropertiesData(NodeData parent) throws RepositoryException
- {
- return persistentManager.getChildPropertiesData(parent);
- }
-
- /**
- * {@inheritDoc}
- */
- public List<PropertyData> getChildPropertiesData(NodeData parent, List<QPathEntryFilter> itemDataFilters)
- throws RepositoryException
- {
- return persistentManager.getChildPropertiesData(parent, itemDataFilters);
- }
-
- /**
- * {@inheritDoc}
- */
- public List<PropertyData> listChildPropertiesData(NodeData parent) throws RepositoryException
- {
- return persistentManager.listChildPropertiesData(parent);
- }
-
- /**
- * {@inheritDoc}
- */
- public List<PropertyData> getReferencesData(String identifier, boolean skipVersionStorage)
- throws RepositoryException
- {
- return persistentManager.getReferencesData(identifier, skipVersionStorage);
- }
-
- // ------------ SharedDataManager ----------------------
-
- /**
- * {@inheritDoc}
- */
- public void save(ItemStateChangesLog changes) throws InvalidItemStateException, UnsupportedOperationException,
- RepositoryException
- {
- persistentManager.save(changes);
- }
-
- /**
- * {@inheritDoc}
- */
- public Calendar getCurrentTime()
- {
- return persistentManager.getCurrentTime();
- }
-}
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/BloomFilter.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/BloomFilter.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/BloomFilter.java 2011-08-18 06:39:44 UTC (rev 4770)
@@ -0,0 +1,403 @@
+/*
+ * Copyright (C) 2011 eXo Platform SAS.
+ *
+ * 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.exoplatform.services.jcr.impl.dataflow.persistent;
+
+import java.io.Serializable;
+import java.nio.charset.Charset;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.BitSet;
+import java.util.Collection;
+
+/**
+ * Implementation of a Bloom-filter, as described here:
+ * http://en.wikipedia.org/wiki/Bloom_filter
+ *
+ * Inspired by the SimpleBloomFilter-class written by Ian Clarke. This
+ * implementation provides a more evenly distributed Hash-function by
+ * using a proper digest instead of the Java RNG. Many of the changes
+ * were proposed in comments in his blog:
+ * http://blog.locut.us/2008/01/12/a-decent-stand-alone-java-bloom-filter-im...
+ *
+ * @param <E> Object type that is to be inserted into the Bloom filter, e.g. String or Integer.
+ * @author Magnus Skjegstad <magnus(a)skjegstad.com>
+ */
+public class BloomFilter<E> implements Serializable {
+ private BitSet bitset;
+ private int bitSetSize;
+ private double bitsPerElement;
+ private int expectedNumberOfFilterElements; // expected (maximum) number of elements to be added
+ private int numberOfAddedElements; // number of elements actually added to the Bloom filter
+ private int k; // number of hash functions
+
+ static final Charset charset = Charset.forName("UTF-8"); // encoding used for storing hash values as strings
+
+ static final String hashName = "MD5"; // MD5 gives good enough accuracy in most circumstances. Change to SHA1 if it's needed
+ static final MessageDigest digestFunction;
+ static { // The digest method is reused between instances
+ MessageDigest tmp;
+ try {
+ tmp = java.security.MessageDigest.getInstance(hashName);
+ } catch (NoSuchAlgorithmException e) {
+ tmp = null;
+ }
+ digestFunction = tmp;
+ }
+
+ /**
+ * Constructs an empty Bloom filter. The total length of the Bloom filter will be
+ * c*n.
+ *
+ * @param c is the number of bits used per element.
+ * @param n is the expected number of elements the filter will contain.
+ * @param k is the number of hash functions used.
+ */
+ public BloomFilter(double c, int n, int k) {
+ this.expectedNumberOfFilterElements = n;
+ this.k = k;
+ this.bitsPerElement = c;
+ this.bitSetSize = (int)Math.ceil(c * n);
+ numberOfAddedElements = 0;
+ this.bitset = new BitSet(bitSetSize);
+ }
+
+ /**
+ * Constructs an empty Bloom filter. The optimal number of hash functions (k) is estimated from the total size of the Bloom
+ * and the number of expected elements.
+ *
+ * @param bitSetSize defines how many bits should be used in total for the filter.
+ * @param expectedNumberOElements defines the maximum number of elements the filter is expected to contain.
+ */
+ public BloomFilter(int bitSetSize, int expectedNumberOElements) {
+ this(bitSetSize / (double)expectedNumberOElements,
+ expectedNumberOElements,
+ (int) Math.round((bitSetSize / (double)expectedNumberOElements) * Math.log(2.0)));
+ }
+
+ /**
+ * Constructs an empty Bloom filter with a given false positive probability. The number of bits per
+ * element and the number of hash functions is estimated
+ * to match the false positive probability.
+ *
+ * @param falsePositiveProbability is the desired false positive probability.
+ * @param expectedNumberOfElements is the expected number of elements in the Bloom filter.
+ */
+ public BloomFilter(double falsePositiveProbability, int expectedNumberOfElements) {
+ this(Math.ceil(-(Math.log(falsePositiveProbability) / Math.log(2))) / Math.log(2), // c = k / ln(2)
+ expectedNumberOfElements,
+ (int)Math.ceil(-(Math.log(falsePositiveProbability) / Math.log(2)))); // k = ceil(-log_2(false prob.))
+ }
+
+ /**
+ * Construct a new Bloom filter based on existing Bloom filter data.
+ *
+ * @param bitSetSize defines how many bits should be used for the filter.
+ * @param expectedNumberOfFilterElements defines the maximum number of elements the filter is expected to contain.
+ * @param actualNumberOfFilterElements specifies how many elements have been inserted into the <code>filterData</code> BitSet.
+ * @param filterData a BitSet representing an existing Bloom filter.
+ */
+ public BloomFilter(int bitSetSize, int expectedNumberOfFilterElements, int actualNumberOfFilterElements, BitSet filterData) {
+ this(bitSetSize, expectedNumberOfFilterElements);
+ this.bitset = filterData;
+ this.numberOfAddedElements = actualNumberOfFilterElements;
+ }
+
+ /**
+ * Generates a digest based on the contents of a String.
+ *
+ * @param val specifies the input data.
+ * @param charset specifies the encoding of the input data.
+ * @return digest as long.
+ */
+ public static long createHash(String val, Charset charset) {
+ return createHash(val.getBytes(charset));
+ }
+
+ /**
+ * Generates a digest based on the contents of a String.
+ *
+ * @param val specifies the input data. The encoding is expected to be UTF-8.
+ * @return digest as long.
+ */
+ public static long createHash(String val) {
+ return createHash(val, charset);
+ }
+
+ /**
+ * Generates a digest based on the contents of an array of bytes.
+ *
+ * @param data specifies input data.
+ * @return digest as long.
+ */
+ public static long createHash(byte[] data) {
+ long h = 0;
+ byte[] res;
+
+ synchronized (digestFunction) {
+ res = digestFunction.digest(data);
+ }
+
+ for (int i = 0; i < 4; i++) {
+ h <<= 8;
+ h |= ((int) res[i]) & 0xFF;
+ }
+ return h;
+ }
+
+ /**
+ * Compares the contents of two instances to see if they are equal.
+ *
+ * @param obj is the object to compare to.
+ * @return True if the contents of the objects are equal.
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final BloomFilter<E> other = (BloomFilter<E>) obj;
+ if (this.expectedNumberOfFilterElements != other.expectedNumberOfFilterElements) {
+ return false;
+ }
+ if (this.k != other.k) {
+ return false;
+ }
+ if (this.bitSetSize != other.bitSetSize) {
+ return false;
+ }
+ if (this.bitset != other.bitset && (this.bitset == null || !this.bitset.equals(other.bitset))) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Calculates a hash code for this class.
+ * @return hash code representing the contents of an instance of this class.
+ */
+ @Override
+ public int hashCode() {
+ int hash = 7;
+ hash = 61 * hash + (this.bitset != null ? this.bitset.hashCode() : 0);
+ hash = 61 * hash + this.expectedNumberOfFilterElements;
+ hash = 61 * hash + this.bitSetSize;
+ hash = 61 * hash + this.k;
+ return hash;
+ }
+
+
+ /**
+ * Calculates the expected probability of false positives based on
+ * the number of expected filter elements and the size of the Bloom filter.
+ * <br /><br />
+ * The value returned by this method is the <i>expected</i> rate of false
+ * positives, assuming the number of inserted elements equals the number of
+ * expected elements. If the number of elements in the Bloom filter is less
+ * than the expected value, the true probability of false positives will be lower.
+ *
+ * @return expected probability of false positives.
+ */
+ public double expectedFalsePositiveProbability() {
+ return getFalsePositiveProbability(expectedNumberOfFilterElements);
+ }
+
+ /**
+ * Calculate the probability of a false positive given the specified
+ * number of inserted elements.
+ *
+ * @param numberOfElements number of inserted elements.
+ * @return probability of a false positive.
+ */
+ public double getFalsePositiveProbability(double numberOfElements) {
+ // (1 - e^(-k * n / m)) ^ k
+ return Math.pow((1 - Math.exp(-k * (double) numberOfElements
+ / (double) bitSetSize)), k);
+
+ }
+
+ /**
+ * Get the current probability of a false positive. The probability is calculated from
+ * the size of the Bloom filter and the current number of elements added to it.
+ *
+ * @return probability of false positives.
+ */
+ public double getFalsePositiveProbability() {
+ return getFalsePositiveProbability(numberOfAddedElements);
+ }
+
+
+ /**
+ * Returns the value chosen for K.<br />
+ * <br />
+ * K is the optimal number of hash functions based on the size
+ * of the Bloom filter and the expected number of inserted elements.
+ *
+ * @return optimal k.
+ */
+ public int getK() {
+ return k;
+ }
+
+ /**
+ * Sets all bits to false in the Bloom filter.
+ */
+ public void clear() {
+ bitset.clear();
+ numberOfAddedElements = 0;
+ }
+
+ /**
+ * Adds an object to the Bloom filter. The output from the object's
+ * toString() method is used as input to the hash functions.
+ *
+ * @param element is an element to register in the Bloom filter.
+ */
+ public void add(E element) {
+ long hash;
+ String valString = element.toString();
+ for (int x = 0; x < k; x++) {
+ hash = createHash(valString + Integer.toString(x));
+ hash = hash % (long)bitSetSize;
+ bitset.set(Math.abs((int)hash), true);
+ }
+ numberOfAddedElements ++;
+ }
+
+ /**
+ * Adds all elements from a Collection to the Bloom filter.
+ * @param c Collection of elements.
+ */
+ public void addAll(Collection<? extends E> c) {
+ for (E element : c)
+ add(element);
+ }
+
+ /**
+ * Returns true if the element could have been inserted into the Bloom filter.
+ * Use getFalsePositiveProbability() to calculate the probability of this
+ * being correct.
+ *
+ * @param element element to check.
+ * @return true if the element could have been inserted into the Bloom filter.
+ */
+ public boolean contains(E element) {
+ long hash;
+ String valString = element.toString();
+ for (int x = 0; x < k; x++) {
+ hash = createHash(valString + Integer.toString(x));
+ hash = hash % (long)bitSetSize;
+ if (!bitset.get(Math.abs((int)hash)))
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Returns true if all the elements of a Collection could have been inserted
+ * into the Bloom filter. Use getFalsePositiveProbability() to calculate the
+ * probability of this being correct.
+ * @param c elements to check.
+ * @return true if all the elements in c could have been inserted into the Bloom filter.
+ */
+ public boolean containsAll(Collection<? extends E> c) {
+ for (E element : c)
+ if (!contains(element))
+ return false;
+ return true;
+ }
+
+ /**
+ * Read a single bit from the Bloom filter.
+ * @param bit the bit to read.
+ * @return true if the bit is set, false if it is not.
+ */
+ public boolean getBit(int bit) {
+ return bitset.get(bit);
+ }
+
+ /**
+ * Set a single bit in the Bloom filter.
+ * @param bit is the bit to set.
+ * @param value If true, the bit is set. If false, the bit is cleared.
+ */
+ public void setBit(int bit, boolean value) {
+ bitset.set(bit, value);
+ }
+
+ /**
+ * Return the bit set used to store the Bloom filter.
+ * @return bit set representing the Bloom filter.
+ */
+ public BitSet getBitSet() {
+ return bitset;
+ }
+
+ /**
+ * Returns the number of bits in the Bloom filter. Use count() to retrieve
+ * the number of inserted elements.
+ *
+ * @return the size of the bitset used by the Bloom filter.
+ */
+ public int size() {
+ return this.bitSetSize;
+ }
+
+ /**
+ * Returns the number of elements added to the Bloom filter after it
+ * was constructed or after clear() was called.
+ *
+ * @return number of elements added to the Bloom filter.
+ */
+ public int count() {
+ return this.numberOfAddedElements;
+ }
+
+ /**
+ * Returns the expected number of elements to be inserted into the filter.
+ * This value is the same value as the one passed to the constructor.
+ *
+ * @return expected number of elements.
+ */
+ public int getExpectedNumberOfElements() {
+ return expectedNumberOfFilterElements;
+ }
+
+ /**
+ * Get expected number of bits per element when the Bloom filter is full. This value is set by the constructor
+ * when the Bloom filter is created. See also getBitsPerElement().
+ *
+ * @return expected number of bits per element.
+ */
+ public double getExpectedBitsPerElement() {
+ return this.bitsPerElement;
+ }
+
+ /**
+ * Get actual number of bits per element based on the number of elements that have currently been inserted and the length
+ * of the Bloom filter. See also getExpectedBitsPerElement().
+ *
+ * @return number of bits per element.
+ */
+ public double getBitsPerElement() {
+ return this.bitSetSize / (double)numberOfAddedElements;
+ }
+}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/CacheableWorkspaceDataManager.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/CacheableWorkspaceDataManager.java 2011-08-17 14:16:40 UTC (rev 4769)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/CacheableWorkspaceDataManager.java 2011-08-18 06:39:44 UTC (rev 4770)
@@ -19,10 +19,14 @@
package org.exoplatform.services.jcr.impl.dataflow.persistent;
import org.exoplatform.commons.utils.SecurityHelper;
+import org.exoplatform.management.annotations.Managed;
+import org.exoplatform.management.annotations.ManagedDescription;
+import org.exoplatform.services.jcr.access.AccessControlEntry;
import org.exoplatform.services.jcr.access.AccessControlList;
import org.exoplatform.services.jcr.dataflow.ItemStateChangesLog;
import org.exoplatform.services.jcr.dataflow.persistent.MandatoryItemsPersistenceListener;
import org.exoplatform.services.jcr.dataflow.persistent.WorkspaceStorageCache;
+import org.exoplatform.services.jcr.dataflow.persistent.WorkspaceStorageCacheListener;
import org.exoplatform.services.jcr.datamodel.ItemData;
import org.exoplatform.services.jcr.datamodel.ItemType;
import org.exoplatform.services.jcr.datamodel.NodeData;
@@ -43,12 +47,14 @@
import org.exoplatform.services.jcr.impl.storage.SystemDataContainerHolder;
import org.exoplatform.services.jcr.impl.storage.jdbc.JDBCStorageConnection;
import org.exoplatform.services.jcr.storage.WorkspaceDataContainer;
+import org.exoplatform.services.jcr.storage.WorkspaceStorageConnection;
import org.exoplatform.services.rpc.RPCException;
import org.exoplatform.services.rpc.RPCService;
import org.exoplatform.services.rpc.RemoteCommand;
import org.exoplatform.services.rpc.TopologyChangeEvent;
import org.exoplatform.services.rpc.TopologyChangeListener;
import org.exoplatform.services.transaction.TransactionService;
+import org.picocontainer.Startable;
import java.io.Serializable;
import java.security.PrivilegedAction;
@@ -64,6 +70,7 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import javax.jcr.RepositoryException;
@@ -80,7 +87,7 @@
* @version $Id$
*/
public class CacheableWorkspaceDataManager extends WorkspacePersistentDataManager implements Suspendable,
- TopologyChangeListener
+ TopologyChangeListener, Startable, WorkspaceStorageCacheListener
{
/**
@@ -98,6 +105,12 @@
*/
private final TransactionableResourceManager txResourceManager;
+ private final AtomicBoolean filtersEnabled = new AtomicBoolean();
+
+ private volatile BloomFilter<String> filterPermissions;
+
+ private volatile BloomFilter<String> filterOwner;
+
private TransactionManager transactionManager;
/**
@@ -2024,16 +2037,30 @@
/**
* Init ACL of the node.
- *
* @param parent
* - a parent, can be null (get item by id)
- * @param data
+ * @param node
* - an item data
* @return - an item data with ACL was initialized
* @throws RepositoryException
*/
private ItemData initACL(NodeData parent, NodeData node) throws RepositoryException
{
+ return initACL(parent, node, null);
+ }
+
+ /**
+ * @param parent
+ * - a parent, can be null (get item by id)
+ * @param node
+ * - an node data
+ * @param search
+ * - indicates what we are looking for
+ * @return - an node data with ACL was initialized
+ * @throws RepositoryException
+ */
+ private NodeData initACL(NodeData parent, NodeData node, ACLSearch search) throws RepositoryException
+ {
if (node != null)
{
AccessControlList acl = node.getACL();
@@ -2049,17 +2076,37 @@
}
else
{
+ if (search == null)
+ {
+ search = new ACLSearch(null, null);
+ }
// use nearest ancestor ACL... case of get by id
node =
new TransientNodeData(node.getQPath(), node.getIdentifier(), node.getPersistedVersion(), node
.getPrimaryTypeName(), node.getMixinTypeNames(), node.getOrderNumber(),
- node.getParentIdentifier(), getNearestACAncestorAcl(node));
+ node.getParentIdentifier(), getNearestACAncestorAcl(node, search));
}
}
else if (!acl.hasPermissions())
{
// use nearest ancestor permissions
- AccessControlList ancestorAcl = getNearestACAncestorAcl(node);
+ if (search == null)
+ {
+ search = new ACLSearch(acl.getOwner(), null);
+ }
+ else
+ {
+ search.setOwner(acl.getOwner());
+ if (search.found())
+ {
+ return new TransientNodeData(node.getQPath(), node.getIdentifier(), node.getPersistedVersion(),
+ node.getPrimaryTypeName(), node.getMixinTypeNames(), node.getOrderNumber(),
+ node.getParentIdentifier(), new AccessControlList(acl.getOwner(), null));
+ }
+ }
+ AccessControlList ancestorAcl =
+ parent != null && parent.getACL() != null && parent.getACL().hasPermissions() ? parent.getACL()
+ : getNearestACAncestorAcl(node, search);
node =
new TransientNodeData(node.getQPath(), node.getIdentifier(), node.getPersistedVersion(), node
@@ -2068,8 +2115,24 @@
}
else if (!acl.hasOwner())
{
+ if (search == null)
+ {
+ search = new ACLSearch(null, acl.getPermissionEntries());
+ }
+ else
+ {
+ search.setPermissions(acl.getPermissionEntries());
+ if (search.found())
+ {
+ return new TransientNodeData(node.getQPath(), node.getIdentifier(), node.getPersistedVersion(),
+ node.getPrimaryTypeName(), node.getMixinTypeNames(), node.getOrderNumber(),
+ node.getParentIdentifier(), new AccessControlList(null, acl.getPermissionEntries()));
+ }
+ }
// use nearest ancestor owner
- AccessControlList ancestorAcl = getNearestACAncestorAcl(node);
+ AccessControlList ancestorAcl =
+ parent != null && parent.getACL() != null && parent.getACL().hasOwner() ? parent.getACL()
+ : getNearestACAncestorAcl(node, search);
node =
new TransientNodeData(node.getQPath(), node.getIdentifier(), node.getPersistedVersion(), node
@@ -2088,27 +2151,289 @@
*
* @param node
* - item
+ * @param search
+ * - indicates what we are looking for
* @return - parent or null
* @throws RepositoryException
*/
- private AccessControlList getNearestACAncestorAcl(NodeData node) throws RepositoryException
+ private AccessControlList getNearestACAncestorAcl(NodeData node, ACLSearch search) throws RepositoryException
{
-
- if (node.getParentIdentifier() != null)
+ String id = node.getParentIdentifier();
+ if (id != null)
{
- NodeData parent = (NodeData)getItemData(node.getParentIdentifier());
- while (parent != null)
+ boolean filtersEnabled = this.filtersEnabled.get();
+ BloomFilter<String> filterPermissions = this.filterPermissions;
+ BloomFilter<String> filterOwner = this.filterOwner;
+ if (filtersEnabled && filterOwner != null && filterPermissions != null)
{
- if (parent.getACL() != null)
+ QPathEntry[] entries = node.getQPath().getEntries();
+ for (int i = entries.length - 2; i >= 0; i--)
{
- // has an AC parent
- return parent.getACL();
+ QPathEntry entry = entries[i];
+ String currentId = entry.getId();
+ if (currentId == null)
+ {
+ // the path doesn't contain any id so we do a normal call
+ break;
+ }
+ else if ((!search.hasOwner() && filterOwner.contains(currentId))
+ || (!search.hasPermissions() && filterPermissions.contains(currentId)))
+ {
+ id = currentId;
+ break;
+ }
+ else
+ {
+ id = currentId;
+ }
}
- // going up to the root
- parent = (NodeData)getItemData(parent.getParentIdentifier());
}
+ NodeData parent = getACL(id, search);
+ if (parent != null && parent.getACL() != null)
+ {
+ // has an AC parent
+ return parent.getACL();
+ }
}
return new AccessControlList();
}
+ /**
+ * Find Item by identifier to get the missing ACL information.
+ *
+ * @param identifier the id of the node that we are looking for to fill the ACL research
+ * @param search the ACL search describing what we are looking for
+ * @return NodeData, data by identifier
+ */
+ private NodeData getACL(String identifier, ACLSearch search) throws RepositoryException
+ {
+ final ItemData item = getItemData(identifier);
+ return item != null && item.isNode() ? initACL(null, (NodeData)item, search) : null;
+ }
+
+ /**
+ * Gets the list of all the ACL holders
+ * @throws RepositoryException if an error occurs
+ */
+ public List<ACLHolder> getACLHolders() throws RepositoryException
+ {
+ WorkspaceStorageConnection conn = dataContainer.openConnection();
+ try
+ {
+ return conn.getACLHolders();
+ }
+ finally
+ {
+ conn.close();
+ }
+ }
+
+ /**
+ * Reloads the bloom filters
+ * @return <code>true</code> if the filters could be reloaded successfully, <code>false</code> otherwise.
+ */
+ @Managed
+ @ManagedDescription("Reloads the bloom filters used to efficiently manage the ACLs")
+ public boolean reloadFilters()
+ {
+ return loadFilters(false);
+ }
+
+ /**
+ * Clears the bloom filters
+ */
+ protected void clear()
+ {
+ this.filterPermissions = null;
+ this.filterOwner = null;
+ }
+
+ /**
+ * @see org.picocontainer.Startable#start()
+ */
+ public void start()
+ {
+ try
+ {
+ this.cache.addListener(this);
+ }
+ catch (UnsupportedOperationException e)
+ {
+ if (LOG.isDebugEnabled())
+ {
+ LOG.debug("The method addListener is not supported", e);
+ }
+ return;
+ }
+
+ loadFilters(true);
+ }
+
+ /**
+ * Loads the bloom filters
+ * @param cleanOnFail clean everything if an error occurs
+ * @return <code>true</code> if the filters could be loaded successfully, <code>false</code> otherwise.
+ */
+ protected boolean loadFilters(boolean cleanOnFail)
+ {
+ filtersEnabled.set(false);
+ // TODO: Make it configurable
+ this.filterPermissions = new BloomFilter<String>(0.1d, 1000000);
+ this.filterOwner = new BloomFilter<String>(0.1d, 1000000);
+ boolean fails = true;
+ List<ACLHolder> holders = null;
+ try
+ {
+ LOG.info("Getting all the ACL Holders from the persistence layer");
+ holders = getACLHolders();
+ fails = false;
+ }
+ catch (UnsupportedOperationException e)
+ {
+ if (LOG.isDebugEnabled())
+ {
+ LOG.debug("The method getACLHolders is not supported", e);
+ }
+ }
+ catch (RepositoryException e)
+ {
+ LOG.error("Could not load all the ACL loaders", e);
+ }
+ if (fails)
+ {
+ if (cleanOnFail)
+ {
+ clear();
+ cache.removeListener(this);
+ }
+ return false;
+ }
+ else if (holders != null && !holders.isEmpty())
+ {
+ LOG.info("Adding all the ACL Holders found into the BloomFilters");
+ for (int i = 0, length = holders.size(); i < length; i++)
+ {
+ ACLHolder holder = holders.get(i);
+ if (holder.hasOwner())
+ {
+ filterOwner.add(holder.getId());
+ }
+ if (holder.hasPermissions())
+ {
+ filterPermissions.add(holder.getId());
+ }
+ }
+ }
+ filtersEnabled.set(true);
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void stop()
+ {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void onCacheEntryAdded(ItemData data)
+ {
+ onCacheEntryUpdated(data);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void onCacheEntryUpdated(ItemData data)
+ {
+ if (data instanceof NodeData)
+ {
+ NodeData node = (NodeData)data;
+ AccessControlList acl = node.getACL();
+ if (acl == null)
+ {
+ return;
+ }
+ if (acl.hasOwner())
+ {
+ filterOwner.add(node.getIdentifier());
+ }
+ if (acl.hasPermissions())
+ {
+ filterPermissions.add(node.getIdentifier());
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void onCacheEntryRemoved(ItemData data)
+ {
+ }
+
+ /**
+ * Defines what we are really looking for
+ */
+ private static class ACLSearch
+ {
+ private String owner;
+
+ private List<AccessControlEntry> permissions;
+
+ ACLSearch(String owner, List<AccessControlEntry> permissions)
+ {
+ this.owner = owner;
+ this.permissions = permissions;
+ }
+
+ /**
+ * @return <code>true</code> if the owner and the permission have been found, <code>false</code>
+ * otherwise
+ */
+ public boolean found()
+ {
+ return owner != null && permissions != null;
+ }
+
+ /**
+ * @param owner the owner to set
+ */
+ public void setOwner(String owner)
+ {
+ if (this.owner == null)
+ {
+ this.owner = owner;
+ }
+ }
+
+ /**
+ * @param permissions the permissions to set
+ */
+ public void setPermissions(List<AccessControlEntry> permissions)
+ {
+ if (this.permissions == null)
+ {
+ this.permissions = permissions;
+ }
+ }
+
+ /**
+ * @return the owner
+ */
+ public boolean hasOwner()
+ {
+ return owner != null;
+ }
+
+ /**
+ * @return the permissions
+ */
+ public boolean hasPermissions()
+ {
+ return permissions != null;
+ }
+ }
}
\ No newline at end of file
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/LinkedWorkspaceStorageCacheImpl.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/LinkedWorkspaceStorageCacheImpl.java 2011-08-17 14:16:40 UTC (rev 4769)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/LinkedWorkspaceStorageCacheImpl.java 2011-08-18 06:39:44 UTC (rev 4770)
@@ -24,6 +24,7 @@
import org.exoplatform.services.jcr.dataflow.ItemState;
import org.exoplatform.services.jcr.dataflow.ItemStateChangesLog;
import org.exoplatform.services.jcr.dataflow.persistent.WorkspaceStorageCache;
+import org.exoplatform.services.jcr.dataflow.persistent.WorkspaceStorageCacheListener;
import org.exoplatform.services.jcr.datamodel.ItemData;
import org.exoplatform.services.jcr.datamodel.ItemType;
import org.exoplatform.services.jcr.datamodel.NodeData;
@@ -2216,4 +2217,20 @@
public void addChildNodesByPage(NodeData parent, List<NodeData> childs, int fromOrderNum)
{
}
+
+ /**
+ * {@inheritDoc}
+ */
+ public void addListener(WorkspaceStorageCacheListener listener) throws UnsupportedOperationException
+ {
+ throw new UnsupportedOperationException("The cache listeners are not supported by the LinkedWorkspaceStorageCacheImpl");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void removeListener(WorkspaceStorageCacheListener listener) throws UnsupportedOperationException
+ {
+ throw new UnsupportedOperationException("The cache listeners are not supported by the LinkedWorkspaceStorageCacheImpl");
+ }
}
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/ShareableSupportedWorkspaceDataManager.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/ShareableSupportedWorkspaceDataManager.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/ShareableSupportedWorkspaceDataManager.java 2011-08-18 06:39:44 UTC (rev 4770)
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * 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.exoplatform.services.jcr.impl.dataflow.persistent;
+
+import org.exoplatform.services.jcr.dataflow.ItemStateChangesLog;
+import org.exoplatform.services.jcr.dataflow.SharedDataManager;
+import org.exoplatform.services.jcr.datamodel.ItemData;
+import org.exoplatform.services.jcr.datamodel.ItemType;
+import org.exoplatform.services.jcr.datamodel.NodeData;
+import org.exoplatform.services.jcr.datamodel.PropertyData;
+import org.exoplatform.services.jcr.datamodel.QPathEntry;
+import org.exoplatform.services.jcr.impl.core.itemfilters.QPathEntryFilter;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+
+import java.util.Calendar;
+import java.util.List;
+
+import javax.jcr.InvalidItemStateException;
+import javax.jcr.RepositoryException;
+
+/**
+ * Created by The eXo Platform SAS. Data Manager supported ACL Inheritance
+ *
+ * @author Gennady Azarenkov
+ * @version $Id: ACLInheritanceSupportedWorkspaceDataManager.java 11907 2008-03-13 15:36:21Z ksm $
+ */
+public class ShareableSupportedWorkspaceDataManager implements SharedDataManager
+{
+
+ private static Log LOG = ExoLogger.getLogger("exo.jcr.component.core.ACLInheritanceSupportedWorkspaceDataManager");
+
+ protected final CacheableWorkspaceDataManager persistentManager;
+
+ public ShareableSupportedWorkspaceDataManager(CacheableWorkspaceDataManager persistentManager)
+ {
+ this.persistentManager = persistentManager;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ // ------------ ItemDataConsumer impl ------------
+ public List<NodeData> getChildNodesData(NodeData parent) throws RepositoryException
+ {
+ return persistentManager.getChildNodesData(parent);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<NodeData> getChildNodesData(NodeData parent, List<QPathEntryFilter> patternFilters) throws RepositoryException
+ {
+ return persistentManager.getChildNodesData(parent, patternFilters);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean getChildNodesDataByPage(NodeData parent, int fromOrderNum, int limit, List<NodeData> childs)
+ throws RepositoryException
+ {
+ return persistentManager.getChildNodesDataByPage(parent, fromOrderNum, limit, childs);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int getLastOrderNumber(final NodeData parent) throws RepositoryException
+ {
+ return persistentManager.getLastOrderNumber(parent);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int getChildNodesCount(final NodeData parent) throws RepositoryException
+ {
+ return persistentManager.getChildNodesCount(parent);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ItemData getItemData(NodeData parent, QPathEntry name) throws RepositoryException
+ {
+ return getItemData(parent, name, ItemType.UNKNOWN);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ItemData getItemData(NodeData parent, QPathEntry name, ItemType itemType) throws RepositoryException
+ {
+ return persistentManager.getItemData(parent, name, itemType);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ItemData getItemData(String identifier) throws RepositoryException
+ {
+ return persistentManager.getItemData(identifier);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<PropertyData> getChildPropertiesData(NodeData parent) throws RepositoryException
+ {
+ return persistentManager.getChildPropertiesData(parent);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<PropertyData> getChildPropertiesData(NodeData parent, List<QPathEntryFilter> itemDataFilters)
+ throws RepositoryException
+ {
+ return persistentManager.getChildPropertiesData(parent, itemDataFilters);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<PropertyData> listChildPropertiesData(NodeData parent) throws RepositoryException
+ {
+ return persistentManager.listChildPropertiesData(parent);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<PropertyData> getReferencesData(String identifier, boolean skipVersionStorage)
+ throws RepositoryException
+ {
+ return persistentManager.getReferencesData(identifier, skipVersionStorage);
+ }
+
+ // ------------ SharedDataManager ----------------------
+
+ /**
+ * {@inheritDoc}
+ */
+ public void save(ItemStateChangesLog changes) throws InvalidItemStateException, UnsupportedOperationException,
+ RepositoryException
+ {
+ persistentManager.save(changes);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Calendar getCurrentTime()
+ {
+ return persistentManager.getCurrentTime();
+ }
+}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/VersionableWorkspaceDataManager.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/VersionableWorkspaceDataManager.java 2011-08-17 14:16:40 UTC (rev 4769)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/VersionableWorkspaceDataManager.java 2011-08-18 06:39:44 UTC (rev 4770)
@@ -53,12 +53,12 @@
* @version $Id$
*/
-public class VersionableWorkspaceDataManager extends ACLInheritanceSupportedWorkspaceDataManager
+public class VersionableWorkspaceDataManager extends ShareableSupportedWorkspaceDataManager
{
private static Log log = ExoLogger.getLogger("exo.jcr.component.core.VersionableWorkspaceDataManager");
- private ACLInheritanceSupportedWorkspaceDataManager versionDataManager;
+ private ShareableSupportedWorkspaceDataManager versionDataManager;
public VersionableWorkspaceDataManager(CacheableWorkspaceDataManager persistentManager)
{
@@ -71,7 +71,7 @@
public void setSystemDataManager(DataManager systemDataManager)
{
- this.versionDataManager = (ACLInheritanceSupportedWorkspaceDataManager)systemDataManager;
+ this.versionDataManager = (ShareableSupportedWorkspaceDataManager)systemDataManager;
}
/**
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/ISPNCacheWorkspaceStorageCache.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/ISPNCacheWorkspaceStorageCache.java 2011-08-17 14:16:40 UTC (rev 4769)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/ISPNCacheWorkspaceStorageCache.java 2011-08-18 06:39:44 UTC (rev 4770)
@@ -28,6 +28,7 @@
import org.exoplatform.services.jcr.dataflow.ItemState;
import org.exoplatform.services.jcr.dataflow.ItemStateChangesLog;
import org.exoplatform.services.jcr.dataflow.persistent.WorkspaceStorageCache;
+import org.exoplatform.services.jcr.dataflow.persistent.WorkspaceStorageCacheListener;
import org.exoplatform.services.jcr.datamodel.IllegalPathException;
import org.exoplatform.services.jcr.datamodel.InternalQName;
import org.exoplatform.services.jcr.datamodel.ItemData;
@@ -53,6 +54,11 @@
import org.exoplatform.services.transaction.ActionNonTxAware;
import org.infinispan.Cache;
import org.infinispan.lifecycle.ComponentStatus;
+import org.infinispan.notifications.Listener;
+import org.infinispan.notifications.cachelistener.annotation.CacheEntryModified;
+import org.infinispan.notifications.cachelistener.annotation.CacheEntryRemoved;
+import org.infinispan.notifications.cachelistener.event.CacheEntryModifiedEvent;
+import org.infinispan.notifications.cachelistener.event.CacheEntryRemovedEvent;
import java.io.File;
import java.io.IOException;
@@ -66,6 +72,7 @@
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
+import java.util.concurrent.CopyOnWriteArrayList;
import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
@@ -99,6 +106,11 @@
private final boolean enabled;
protected final BufferedISPNCache cache;
+
+ /**
+ * The list of all the listeners
+ */
+ private final List<WorkspaceStorageCacheListener> listeners = new CopyOnWriteArrayList<WorkspaceStorageCacheListener>();
private final CacheActionNonTxAware<Void, Void> commitTransaction = new CacheActionNonTxAware<Void, Void>()
{
@@ -462,6 +474,7 @@
// do n't nothing
}
this.cache = new BufferedISPNCache(parentCache, allowLocalChanges);
+ cache.addListener(new CacheEventListener());
}
/**
@@ -1560,6 +1573,68 @@
}
/**
+ * {@inheritDoc}
+ */
+ public void addListener(WorkspaceStorageCacheListener listener)
+ {
+ listeners.add(listener);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void removeListener(WorkspaceStorageCacheListener listener)
+ {
+ listeners.remove(listener);
+ }
+
+ /**
+ * Called when a cache entry corresponding to the given node has item updated
+ * @param data the item corresponding to the updated cache entry
+ */
+ private void onCacheEntryUpdated(ItemData data)
+ {
+ if (data == null || data instanceof NullItemData)
+ {
+ return;
+ }
+ for (WorkspaceStorageCacheListener listener : listeners)
+ {
+ try
+ {
+ listener.onCacheEntryUpdated(data);
+ }
+ catch (Exception e)
+ {
+ LOG.warn("The method onCacheEntryUpdated fails for the listener " + listener.getClass(), e);
+ }
+ }
+ }
+
+ /**
+ * Called when a cache entry corresponding to the given item has been removed
+ * @param data the item corresponding to the removed cache entry
+ */
+ private void onCacheEntryRemoved(ItemData data)
+ {
+ if (data == null || data instanceof NullItemData)
+ {
+ return;
+ }
+ for (WorkspaceStorageCacheListener listener : listeners)
+ {
+ try
+ {
+ listener.onCacheEntryRemoved(data);
+ }
+ catch (Exception e)
+ {
+ LOG.warn("The method onCacheEntryRemoved fails for the listener " + listener.getClass(), e);
+ }
+ }
+ }
+
+ /**
* Actions that are not supposed to be called within a transaction
*
* Created by The eXo Platform SAS
@@ -1577,4 +1652,30 @@
return ISPNCacheWorkspaceStorageCache.this.getTransactionManager();
}
}
+
+ @SuppressWarnings("rawtypes")
+ @Listener
+ public class CacheEventListener
+ {
+
+ @CacheEntryRemoved
+ public void cacheEntryRemoved(CacheEntryRemovedEvent evt)
+ {
+ if (evt.isPre() && evt.getKey() instanceof CacheId)
+ {
+ final ItemData value = (ItemData)evt.getValue();
+ onCacheEntryRemoved(value);
+ }
+ }
+
+ @CacheEntryModified
+ public void cacheEntryModified(CacheEntryModifiedEvent evt)
+ {
+ if (!evt.isPre() && evt.getKey() instanceof CacheId)
+ {
+ final ItemData value = (ItemData)evt.getValue();
+ onCacheEntryUpdated(value);
+ }
+ }
+ }
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/JBossCacheWorkspaceStorageCache.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/JBossCacheWorkspaceStorageCache.java 2011-08-17 14:16:40 UTC (rev 4769)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/JBossCacheWorkspaceStorageCache.java 2011-08-18 06:39:44 UTC (rev 4770)
@@ -29,6 +29,7 @@
import org.exoplatform.services.jcr.dataflow.ItemState;
import org.exoplatform.services.jcr.dataflow.ItemStateChangesLog;
import org.exoplatform.services.jcr.dataflow.persistent.WorkspaceStorageCache;
+import org.exoplatform.services.jcr.dataflow.persistent.WorkspaceStorageCacheListener;
import org.exoplatform.services.jcr.datamodel.IllegalPathException;
import org.exoplatform.services.jcr.datamodel.InternalQName;
import org.exoplatform.services.jcr.datamodel.ItemData;
@@ -62,6 +63,10 @@
import org.jboss.cache.config.EvictionRegionConfig;
import org.jboss.cache.eviction.ExpirationAlgorithmConfig;
import org.jboss.cache.jmx.JmxRegistrationManager;
+import org.jboss.cache.notifications.annotation.NodeModified;
+import org.jboss.cache.notifications.annotation.NodeRemoved;
+import org.jboss.cache.notifications.event.NodeModifiedEvent;
+import org.jboss.cache.notifications.event.NodeRemovedEvent;
import org.picocontainer.Startable;
import java.io.File;
@@ -78,6 +83,7 @@
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
+import java.util.concurrent.CopyOnWriteArrayList;
import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
@@ -186,7 +192,12 @@
protected final Fqn<String> childNodesByPatternList;
protected final Fqn<String> rootFqn;
-
+
+ /**
+ * The list of all the listeners
+ */
+ private final List<WorkspaceStorageCacheListener> listeners = new CopyOnWriteArrayList<WorkspaceStorageCacheListener>();
+
private final CacheActionNonTxAware<Void, Void> commitTransaction = new CacheActionNonTxAware<Void, Void>()
{
@Override
@@ -680,7 +691,8 @@
createResidentNode(childPropsByPatternList);
createResidentNode(childNodesByPatternList);
createResidentNode(itemsRoot);
-
+ this.cache.addCacheListener(new CacheEventListener());
+
if (jmxManager != null)
{
SecurityHelper.doPrivilegedAction(new PrivilegedAction<Void>()
@@ -2079,8 +2091,69 @@
createResidentNode(itemsRoot);
}
}
+ /**
+ * {@inheritDoc}
+ */
+ public void addListener(WorkspaceStorageCacheListener listener)
+ {
+ listeners.add(listener);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void removeListener(WorkspaceStorageCacheListener listener)
+ {
+ listeners.remove(listener);
+ }
/**
+ * Called when a cache entry corresponding to the given node has item updated
+ * @param data the item corresponding to the updated cache entry
+ */
+ private void onCacheEntryUpdated(ItemData data)
+ {
+ if (data == null || data instanceof NullItemData)
+ {
+ return;
+ }
+ for (WorkspaceStorageCacheListener listener : listeners)
+ {
+ try
+ {
+ listener.onCacheEntryUpdated(data);
+ }
+ catch (Exception e)
+ {
+ LOG.warn("The method onCacheEntryUpdated fails for the listener " + listener.getClass(), e);
+ }
+ }
+ }
+
+ /**
+ * Called when a cache entry corresponding to the given item has been removed
+ * @param data the item corresponding to the removed cache entry
+ */
+ private void onCacheEntryRemoved(ItemData data)
+ {
+ if (data == null || data instanceof NullItemData)
+ {
+ return;
+ }
+ for (WorkspaceStorageCacheListener listener : listeners)
+ {
+ try
+ {
+ listener.onCacheEntryRemoved(data);
+ }
+ catch (Exception e)
+ {
+ LOG.warn("The method onCacheEntryRemoved fails for the listener " + listener.getClass(), e);
+ }
+ }
+ }
+
+ /**
* Actions that are not supposed to be called within a transaction
*
* Created by The eXo Platform SAS
@@ -2098,4 +2171,30 @@
return JBossCacheWorkspaceStorageCache.this.getTransactionManager();
}
}
+
+ @org.jboss.cache.notifications.annotation.CacheListener
+ @SuppressWarnings("unchecked")
+ public class CacheEventListener
+ {
+
+ @NodeRemoved
+ public void nodeRemoved(NodeRemovedEvent ne)
+ {
+ if (ne.isPre() && ne.getFqn().isChildOf(itemsRoot))
+ {
+ final Map<Serializable, Object> data = ne.getData();
+ onCacheEntryRemoved((ItemData)(data == null ? null : data.get(ITEM_DATA)));
+ }
+ }
+
+ @NodeModified
+ public void nodeModified(NodeModifiedEvent ne)
+ {
+ if (!ne.isPre() && ne.getFqn().isChildOf(itemsRoot))
+ {
+ final Map<Serializable, Object> data = ne.getData();
+ onCacheEntryUpdated((ItemData)(data == null ? null : data.get(ITEM_DATA)));
+ }
+ }
+ }
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/inmemory/InmemoryStorageConnection.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/inmemory/InmemoryStorageConnection.java 2011-08-17 14:16:40 UTC (rev 4769)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/inmemory/InmemoryStorageConnection.java 2011-08-18 06:39:44 UTC (rev 4770)
@@ -26,6 +26,7 @@
import org.exoplatform.services.jcr.datamodel.QPathEntry;
import org.exoplatform.services.jcr.datamodel.ValueData;
import org.exoplatform.services.jcr.impl.core.itemfilters.QPathEntryFilter;
+import org.exoplatform.services.jcr.impl.dataflow.persistent.ACLHolder;
import org.exoplatform.services.jcr.storage.WorkspaceStorageConnection;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
@@ -289,6 +290,15 @@
throw new UnsupportedOperationException();
}
+
+ /**
+ * @see org.exoplatform.services.jcr.storage.WorkspaceStorageConnection#getACLHolders()
+ */
+ public List<ACLHolder> getACLHolders() throws RepositoryException, IllegalStateException,
+ UnsupportedOperationException
+ {
+ throw new UnsupportedOperationException();
+ }
class MapKey
{
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCStorageConnection.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCStorageConnection.java 2011-08-17 14:16:40 UTC (rev 4769)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCStorageConnection.java 2011-08-18 06:39:44 UTC (rev 4770)
@@ -37,6 +37,7 @@
import org.exoplatform.services.jcr.datamodel.ValueData;
import org.exoplatform.services.jcr.impl.Constants;
import org.exoplatform.services.jcr.impl.core.itemfilters.QPathEntryFilter;
+import org.exoplatform.services.jcr.impl.dataflow.persistent.ACLHolder;
import org.exoplatform.services.jcr.impl.dataflow.persistent.ByteArrayPersistedValueData;
import org.exoplatform.services.jcr.impl.dataflow.persistent.CleanableFilePersistedValueData;
import org.exoplatform.services.jcr.impl.dataflow.persistent.StreamPersistedValueData;
@@ -1228,6 +1229,15 @@
throw new RepositoryException(e);
}
}
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<ACLHolder> getACLHolders() throws RepositoryException, IllegalStateException,
+ UnsupportedOperationException
+ {
+ throw new UnsupportedOperationException("This method is not supported by the old JDBCWorkspaceDataContainer, use CQJDBCWorkspaceDataContainer instead.");
+ }
/**
* {@inheritDoc}
@@ -1500,7 +1510,7 @@
}
QPathEntry qpe =
- new QPathEntry(InternalQName.parse(parent.getString(COLUMN_NAME)), parent.getInt(COLUMN_INDEX));
+ new QPathEntry(InternalQName.parse(parent.getString(COLUMN_NAME)), parent.getInt(COLUMN_INDEX), caid);
qrpath.add(qpe);
caid = parent.getString(COLUMN_PARENTID);
}
@@ -2213,7 +2223,7 @@
if (parentPath != null)
{
// get by parent and name
- qpath = QPath.makeChildPath(parentPath, qname, cindex);
+ qpath = QPath.makeChildPath(parentPath, qname, cindex, cid);
parentCid = cpid;
}
else
@@ -2227,7 +2237,7 @@
}
else
{
- qpath = QPath.makeChildPath(traverseQPath(cpid), qname, cindex);
+ qpath = QPath.makeChildPath(traverseQPath(cpid), qname, cindex, cid);
parentCid = cpid;
}
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/CQJDBCStorageConnection.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/CQJDBCStorageConnection.java 2011-08-17 14:16:40 UTC (rev 4769)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/CQJDBCStorageConnection.java 2011-08-18 06:39:44 UTC (rev 4770)
@@ -20,6 +20,7 @@
import org.exoplatform.services.jcr.access.AccessControlEntry;
import org.exoplatform.services.jcr.access.AccessControlList;
+import org.exoplatform.services.jcr.core.ExtendedPropertyType;
import org.exoplatform.services.jcr.dataflow.ItemState;
import org.exoplatform.services.jcr.dataflow.persistent.PersistedNodeData;
import org.exoplatform.services.jcr.dataflow.persistent.PersistedPropertyData;
@@ -33,6 +34,7 @@
import org.exoplatform.services.jcr.datamodel.ValueData;
import org.exoplatform.services.jcr.impl.Constants;
import org.exoplatform.services.jcr.impl.core.itemfilters.QPathEntryFilter;
+import org.exoplatform.services.jcr.impl.dataflow.persistent.ACLHolder;
import org.exoplatform.services.jcr.impl.dataflow.persistent.StreamPersistedValueData;
import org.exoplatform.services.jcr.impl.storage.JCRInvalidItemStateException;
import org.exoplatform.services.jcr.impl.storage.jdbc.JDBCStorageConnection;
@@ -133,6 +135,13 @@
*/
protected String UPDATE_VALUE;
+ /**
+ * FIND_ACL_HOLDERS.
+ */
+ protected String FIND_ACL_HOLDERS;
+
+ protected PreparedStatement findACLHolders;
+
protected PreparedStatement findNodesByParentIdCQ;
protected PreparedStatement findPropertiesByParentIdCQ;
@@ -177,7 +186,64 @@
{
super(dbConnection, readOnly, containerName, valueStorageProvider, maxBufferSize, swapDirectory, swapCleaner);
}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List<ACLHolder> getACLHolders() throws RepositoryException, IllegalStateException,
+ UnsupportedOperationException
+ {
+ checkIfOpened();
+ ResultSet resultSet = null;
+ try
+ {
+ // query will return all the ACL holder
+ resultSet = findACLHolders();
+ Map<String, ACLHolder> mHolders = new HashMap<String, ACLHolder>();
+
+ while (resultSet.next())
+ {
+ String cpid = resultSet.getString(COLUMN_PARENTID);
+ ACLHolder holder = mHolders.get(cpid);
+ if (holder == null)
+ {
+ holder = new ACLHolder(cpid);
+ mHolders.put(cpid, holder);
+ }
+ int cptype = resultSet.getInt(COLUMN_PTYPE);
+ if (cptype == ExtendedPropertyType.PERMISSION)
+ {
+ holder.setPermissions(true);
+ }
+ else
+ {
+ holder.setOwner(true);
+ }
+ }
+ return new ArrayList<ACLHolder>(mHolders.values());
+ }
+ catch (SQLException e)
+ {
+ throw new RepositoryException(e);
+ }
+ finally
+ {
+ if (resultSet != null)
+ {
+ try
+ {
+ resultSet.close();
+ }
+ catch (SQLException e)
+ {
+ LOG.error("Can't close the ResultSet: " + e);
+ }
+ }
+ }
+ }
+
/**
* {@inheritDoc}
*/
@@ -928,7 +994,7 @@
if (parentPath != null)
{
// get by parent and name
- qpath = QPath.makeChildPath(parentPath, qname, cindex);
+ qpath = QPath.makeChildPath(parentPath, qname, cindex, cid);
parentCid = cpid;
}
else
@@ -942,7 +1008,7 @@
}
else
{
- qpath = QPath.makeChildPath(traverseQPath(cpid), qname, cindex);
+ qpath = QPath.makeChildPath(traverseQPath(cpid), qname, cindex, cid);
parentCid = cpid;
}
}
@@ -1094,13 +1160,13 @@
}
QPathEntry qpe1 =
- new QPathEntry(InternalQName.parse(result.getString(COLUMN_NAME)), result.getInt(COLUMN_INDEX));
+ new QPathEntry(InternalQName.parse(result.getString(COLUMN_NAME)), result.getInt(COLUMN_INDEX), result.getString(COLUMN_ID));
boolean isChild = caid.equals(result.getString(COLUMN_ID));
caid = result.getString(COLUMN_PARENTID);
if (result.next())
{
QPathEntry qpe2 =
- new QPathEntry(InternalQName.parse(result.getString(COLUMN_NAME)), result.getInt(COLUMN_INDEX));
+ new QPathEntry(InternalQName.parse(result.getString(COLUMN_NAME)), result.getInt(COLUMN_INDEX), result.getString(COLUMN_ID));
if (isChild)
{
// The child is the first result then we have the parent
@@ -1166,6 +1232,11 @@
try
{
+ if (findACLHolders != null)
+ {
+ findACLHolders.close();
+ }
+
if (findNodesByParentIdCQ != null)
{
findNodesByParentIdCQ.close();
@@ -1222,6 +1293,8 @@
}
}
+ protected abstract ResultSet findACLHolders() throws SQLException;
+
protected abstract ResultSet findItemQPathByIdentifierCQ(String identifier) throws SQLException;
protected abstract ResultSet findChildNodesByParentIdentifierCQ(String parentIdentifier) throws SQLException;
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MultiDbJDBCConnection.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MultiDbJDBCConnection.java 2011-08-17 14:16:40 UTC (rev 4769)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MultiDbJDBCConnection.java 2011-08-18 06:39:44 UTC (rev 4770)
@@ -217,6 +217,10 @@
+ " P.NAME='[http://www.exoplatform.com/jcr/exo/1.0]owner' or"
+ " P.NAME='[http://www.exoplatform.com/jcr/exo/1.0]permissions')"
+ " and V.PROPERTY_ID=P.ID order by I.N_ORDER_NUM, I.ID";
+
+ FIND_ACL_HOLDERS = "select I.PARENT_ID, I.P_TYPE" +
+ " from JCR_MITEM I" +
+ " where I.I_CLASS=2 and (I.NAME='[http://www.exoplatform.com/jcr/exo/1.0]owner' or I.NAME='[http://www.exoplatform.com/jcr/exo/1.0]permissions')";
}
/**
@@ -1010,4 +1014,18 @@
{
return PATTERN_ESCAPE_STRING;
}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected ResultSet findACLHolders() throws SQLException
+ {
+ if (findACLHolders == null)
+ {
+ findACLHolders = dbConnection.prepareStatement(FIND_ACL_HOLDERS);
+ }
+
+ return findACLHolders.executeQuery();
+ }
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/SingleDbJDBCConnection.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/SingleDbJDBCConnection.java 2011-08-17 14:16:40 UTC (rev 4769)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/SingleDbJDBCConnection.java 2011-08-18 06:39:44 UTC (rev 4770)
@@ -222,6 +222,10 @@
+ " P.NAME='[http://www.exoplatform.com/jcr/exo/1.0]owner' or"
+ " P.NAME='[http://www.exoplatform.com/jcr/exo/1.0]permissions')"
+ " and V.PROPERTY_ID=P.ID order by I.N_ORDER_NUM, I.ID";
+
+ FIND_ACL_HOLDERS = "select I.PARENT_ID, I.P_TYPE" +
+ " from JCR_SITEM I" +
+ " where I.I_CLASS=2 and I.CONTAINER_NAME=? and (I.NAME='[http://www.exoplatform.com/jcr/exo/1.0]owner' or I.NAME='[http://www.exoplatform.com/jcr/exo/1.0]permissions')";
}
/**
@@ -923,4 +927,24 @@
{
return PATTERN_ESCAPE_STRING;
}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected ResultSet findACLHolders() throws SQLException
+ {
+ if (findACLHolders == null)
+ {
+ findACLHolders = dbConnection.prepareStatement(FIND_ACL_HOLDERS);
+ }
+ else
+ {
+ findACLHolders.clearParameters();
+ }
+
+ findACLHolders.setString(1, containerName);
+
+ return findACLHolders.executeQuery();
+ }
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/statistics/StatisticsJDBCStorageConnection.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/statistics/StatisticsJDBCStorageConnection.java 2011-08-17 14:16:40 UTC (rev 4769)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/statistics/StatisticsJDBCStorageConnection.java 2011-08-18 06:39:44 UTC (rev 4770)
@@ -22,6 +22,7 @@
import org.exoplatform.services.jcr.datamodel.PropertyData;
import org.exoplatform.services.jcr.datamodel.QPathEntry;
import org.exoplatform.services.jcr.impl.core.itemfilters.QPathEntryFilter;
+import org.exoplatform.services.jcr.impl.dataflow.persistent.ACLHolder;
import org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer;
import org.exoplatform.services.jcr.statistics.JCRStatisticsManager;
import org.exoplatform.services.jcr.statistics.Statistics;
@@ -128,6 +129,12 @@
* <code>getLastOrderNumber(NodeData parent)</code>
*/
private static final String GET_LAST_ORDER_NUMBER_DESCR = "getLastOrderNumber";
+
+ /**
+ * The description of the statistics corresponding to the method
+ * <code>getACLHolders()</code>
+ */
+ private static final String GET_ACL_HOLDERS = "getACLHolders";
/**
* The description of the statistics corresponding to the method
@@ -192,6 +199,7 @@
ALL_STATISTICS.put(LIST_CHILD_PROPERTIES_DATA_DESCR, new Statistics(GLOBAL_STATISTICS,
LIST_CHILD_PROPERTIES_DATA_DESCR));
ALL_STATISTICS.put(GET_REFERENCES_DATA_DESCR, new Statistics(GLOBAL_STATISTICS, GET_REFERENCES_DATA_DESCR));
+ ALL_STATISTICS.put(GET_ACL_HOLDERS, new Statistics(GLOBAL_STATISTICS, GET_ACL_HOLDERS));
// Write Methods
// Commit
ALL_STATISTICS.put(COMMIT_DESCR, new Statistics(GLOBAL_STATISTICS, COMMIT_DESCR));
@@ -617,4 +625,23 @@
s.end();
}
}
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<ACLHolder> getACLHolders() throws RepositoryException, IllegalStateException,
+ UnsupportedOperationException
+ {
+ Statistics s = ALL_STATISTICS.get(GET_ACL_HOLDERS);
+ try
+ {
+ s.begin();
+ return wcs.getACLHolders();
+ }
+ finally
+ {
+ s.end();
+ }
+ }
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/storage/WorkspaceStorageConnection.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/storage/WorkspaceStorageConnection.java 2011-08-17 14:16:40 UTC (rev 4769)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/storage/WorkspaceStorageConnection.java 2011-08-18 06:39:44 UTC (rev 4770)
@@ -24,6 +24,7 @@
import org.exoplatform.services.jcr.datamodel.PropertyData;
import org.exoplatform.services.jcr.datamodel.QPathEntry;
import org.exoplatform.services.jcr.impl.core.itemfilters.QPathEntryFilter;
+import org.exoplatform.services.jcr.impl.dataflow.persistent.ACLHolder;
import java.util.List;
@@ -387,4 +388,17 @@
* @return boolean, true if connection is open and ready, false - otherwise
*/
boolean isOpened();
+
+ /**
+ * Returns all the nodes that hold some ACL info like owner or permissions
+ *
+ * @return a list of all the ACL holders for this workspace
+ * @throws RepositoryException
+ * if some exception occured
+ * @throws IllegalStateException
+ * if connection is closed
+ * @throws UnsupportedOperationException
+ * if operation is not supported
+ */
+ List<ACLHolder> getACLHolders() throws RepositoryException, IllegalStateException, UnsupportedOperationException;
}
Modified: jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/TestCacheableWorkspaceDataManager.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/TestCacheableWorkspaceDataManager.java 2011-08-17 14:16:40 UTC (rev 4769)
+++ jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/TestCacheableWorkspaceDataManager.java 2011-08-18 06:39:44 UTC (rev 4770)
@@ -22,6 +22,7 @@
import org.exoplatform.services.jcr.dataflow.persistent.PersistedNodeData;
import org.exoplatform.services.jcr.dataflow.persistent.PersistedPropertyData;
import org.exoplatform.services.jcr.dataflow.persistent.WorkspaceStorageCache;
+import org.exoplatform.services.jcr.dataflow.persistent.WorkspaceStorageCacheListener;
import org.exoplatform.services.jcr.datamodel.ItemData;
import org.exoplatform.services.jcr.datamodel.ItemType;
import org.exoplatform.services.jcr.datamodel.NodeData;
@@ -439,6 +440,20 @@
{
}
+ /**
+ * @see org.exoplatform.services.jcr.dataflow.persistent.WorkspaceStorageCache#addListener(org.exoplatform.services.jcr.dataflow.persistent.WorkspaceStorageCacheListener)
+ */
+ public void addListener(WorkspaceStorageCacheListener listener) throws UnsupportedOperationException
+ {
+ }
+
+ /**
+ * @see org.exoplatform.services.jcr.dataflow.persistent.WorkspaceStorageCache#removeListener(org.exoplatform.services.jcr.dataflow.persistent.WorkspaceStorageCacheListener)
+ */
+ public void removeListener(WorkspaceStorageCacheListener listener) throws UnsupportedOperationException
+ {
+ }
+
}
private static class MyWorkspaceStorageConnection implements WorkspaceStorageConnection
@@ -599,6 +614,15 @@
return null;
}
+ /**
+ * @see org.exoplatform.services.jcr.storage.WorkspaceStorageConnection#getACLHolders()
+ */
+ public List<ACLHolder> getACLHolders() throws RepositoryException, IllegalStateException,
+ UnsupportedOperationException
+ {
+ return null;
+ }
+
};
private static class MyWorkspaceDataContainer extends WorkspaceDataContainerBase
Modified: jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/TestWorkspaceStorageCacheInClusterMode.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/TestWorkspaceStorageCacheInClusterMode.java 2011-08-17 14:16:40 UTC (rev 4769)
+++ jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/TestWorkspaceStorageCacheInClusterMode.java 2011-08-18 06:39:44 UTC (rev 4770)
@@ -949,8 +949,15 @@
return children;
}
-
-
+
+ /**
+ * @see org.exoplatform.services.jcr.storage.WorkspaceStorageConnection#getACLHolders()
+ */
+ public List<ACLHolder> getACLHolders() throws RepositoryException, IllegalStateException,
+ UnsupportedOperationException
+ {
+ return null;
+ }
};
private static class MyWorkspaceDataContainer extends WorkspaceDataContainerBase
Modified: jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/TestJBossCacheWorkspaceStorageCache.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/TestJBossCacheWorkspaceStorageCache.java 2011-08-17 14:16:40 UTC (rev 4769)
+++ jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/TestJBossCacheWorkspaceStorageCache.java 2011-08-18 06:39:44 UTC (rev 4770)
@@ -34,6 +34,7 @@
import org.exoplatform.services.jcr.datamodel.QPathEntry;
import org.exoplatform.services.jcr.impl.Constants;
import org.exoplatform.services.jcr.impl.core.itemfilters.QPathEntryFilter;
+import org.exoplatform.services.jcr.impl.dataflow.persistent.ACLHolder;
import org.exoplatform.services.jcr.impl.dataflow.persistent.CacheableWorkspaceDataManager;
import org.exoplatform.services.jcr.impl.dataflow.persistent.WorkspaceStorageCacheBaseCase;
import org.exoplatform.services.jcr.impl.dataflow.persistent.jbosscache.JBossCacheWorkspaceStorageCache;
@@ -315,6 +316,17 @@
return getChildNodesData(parent);
}
+
+ /**
+ * @see org.exoplatform.services.jcr.storage.WorkspaceStorageConnection#getACLHolders()
+ */
+ @Override
+ public List<ACLHolder> getACLHolders() throws RepositoryException, IllegalStateException,
+ UnsupportedOperationException
+ {
+ return null;
+ }
+
};
private static class MyWorkspaceDataContainer extends WorkspaceDataContainerBase
12 years, 9 months
exo-jcr SVN: r4769 - jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr.
by do-not-reply@jboss.org
Author: nzamosenchuk
Date: 2011-08-17 10:16:40 -0400 (Wed, 17 Aug 2011)
New Revision: 4769
Modified:
jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/api-extensions.xml
Log:
EOXJCR-267 : System property notice added to documentation
Modified: jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/api-extensions.xml
===================================================================
--- jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/api-extensions.xml 2011-08-17 13:50:37 UTC (rev 4768)
+++ jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/api-extensions.xml 2011-08-17 14:16:40 UTC (rev 4769)
@@ -49,6 +49,15 @@
functionally-full analogue of specified getNodes() operation. So when
having a deal with huge list of child nodes, getNodes() can be simply
and safely substituted with getNodesLazily().</para>
+
+ <para>JCR gives an experimental opportunity to replace all getNodes()
+ invocations with getNodesLazily() calls. It handles a boolean system
+ property named "org.exoplatform.jcr.forceUserGetNodesLazily" that
+ internally replaces one call with another, without any code changes. But
+ be sure using it only for development purposes. This feature can be used
+ with top level products using eXo JCR to perform a quick compatibility
+ and performance tests without changing any code. This is not recommended
+ to be used as a production solution.</para>
</section>
<section>
12 years, 9 months
exo-jcr SVN: r4768 - jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core.
by do-not-reply@jboss.org
Author: nzamosenchuk
Date: 2011-08-17 09:50:37 -0400 (Wed, 17 Aug 2011)
New Revision: 4768
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/NodeImpl.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionImpl.java
Log:
EXOJCR-267 : getNodesLazily can be invoked instead of API getNodes() call by setting system property. With this property set All TCK passed but one eXo-JCR test fails "testRead(org.exoplatform.services.jcr.impl.access.TestAccess)". This is implementetion specific issue.
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/NodeImpl.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/NodeImpl.java 2011-08-17 09:06:09 UTC (rev 4767)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/NodeImpl.java 2011-08-17 13:50:37 UTC (rev 4768)
@@ -1044,6 +1044,19 @@
*/
public NodeIterator getNodes() throws RepositoryException
{
+
+ if (SessionImpl.FORCE_USE_GET_NODES_LAZILY)
+ {
+ if (LOG.isDebugEnabled())
+ {
+ LOG
+ .debug("EXPERIMENTAL! Be aware that \"getNodesLazily()\" feature is used instead of JCR API getNodes()"
+ + " invocation.To disable this simply cleanup system property \"org.exoplatform.jcr.forceUserGetNodesLazily\""
+ + " and restart JCR.");
+ }
+ return getNodesLazily();
+ }
+
long start = 0;
if (LOG.isDebugEnabled())
{
@@ -1093,6 +1106,7 @@
*/
public NodeIterator getNodesLazily() throws RepositoryException
{
+ checkValid();
return new LazyNodeIteratorByPage(dataManager);
}
@@ -3487,6 +3501,8 @@
private int pos = 0;
+ private int size = -1;
+
private LazyNodeIterator lazyNodeItetator = new LazyNodeIterator(new ArrayList<NodeData>());
LazyNodeIteratorByPage(SessionDataManager dataManager) throws RepositoryException
@@ -3578,11 +3594,10 @@
public void skip(long skipNum)
{
pos += skipNum;
-
long leftToSkip = lazyNodeItetator.trySkip(skipNum, false);
if (leftToSkip != 0)
{
- readNextPage(leftToSkip);
+ readNextPage(leftToSkip + 1);
}
}
@@ -3591,7 +3606,18 @@
*/
public long getSize()
{
- return -1;
+ if (size < 0)
+ {
+ try
+ {
+ size = dataManager.getChildNodesCount(nodeData());
+ }
+ catch (RepositoryException e)
+ {
+ LOG.error("Can't determmine number of child nodes.", e);
+ }
+ }
+ return size;
}
public ItemImpl nextItem()
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionImpl.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionImpl.java 2011-08-17 09:06:09 UTC (rev 4767)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionImpl.java 2011-08-17 13:50:37 UTC (rev 4768)
@@ -53,7 +53,6 @@
import org.exoplatform.services.jcr.impl.xml.importing.ContentImporter;
import org.exoplatform.services.jcr.impl.xml.importing.StreamImporter;
import org.exoplatform.services.jcr.storage.WorkspaceDataContainer;
-import org.exoplatform.services.jcr.util.IdGenerator;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.services.security.ConversationState;
@@ -118,12 +117,21 @@
*/
private static final boolean PROHIBIT_CLOSED_SESSION_USAGE =
Boolean.valueOf(PropertyManager.getProperty("exo.jcr.prohibit.closed.session.usage"));
+
+ protected static boolean FORCE_USE_GET_NODES_LAZILY =
+ Boolean.valueOf(PropertyManager.getProperty("org.exoplatform.jcr.forceUserGetNodesLazily"));
+
static
{
if (PROHIBIT_CLOSED_SESSION_USAGE)
{
log.info("The JCR will throw an exception anytime we will try to use a dead session.");
}
+ if (FORCE_USE_GET_NODES_LAZILY)
+ {
+ log.warn("EXPERIMENTAL! The JCR will use ExtendedNode.getNodesLazily() for each Node.getNodes() "
+ + "invocation. This is an experimental feauture and should be used with care.");
+ }
}
private static final AtomicLong SEQUENCE = new AtomicLong();
12 years, 9 months
exo-jcr SVN: r4767 - core/branches/2.3.x/patch/2.3.10/COR-34.
by do-not-reply@jboss.org
Author: trang_vu
Date: 2011-08-17 05:06:09 -0400 (Wed, 17 Aug 2011)
New Revision: 4767
Added:
core/branches/2.3.x/patch/2.3.10/COR-34/readme.txt
Modified:
core/branches/2.3.x/patch/2.3.10/COR-34/COR-34.patch
Log:
COR-34: readme, updated patch
Modified: core/branches/2.3.x/patch/2.3.10/COR-34/COR-34.patch
===================================================================
--- core/branches/2.3.x/patch/2.3.10/COR-34/COR-34.patch 2011-08-17 08:10:36 UTC (rev 4766)
+++ core/branches/2.3.x/patch/2.3.10/COR-34/COR-34.patch 2011-08-17 09:06:09 UTC (rev 4767)
@@ -1,8 +1,8 @@
Index: exo.core.component.ldap/src/main/java/org/exoplatform/services/ldap/impl/LDAPServiceImpl.java
===================================================================
---- exo.core.component.ldap/src/main/java/org/exoplatform/services/ldap/impl/LDAPServiceImpl.java (revision 4560)
+--- exo.core.component.ldap/src/main/java/org/exoplatform/services/ldap/impl/LDAPServiceImpl.java (revision 4762)
+++ exo.core.component.ldap/src/main/java/org/exoplatform/services/ldap/impl/LDAPServiceImpl.java (working copy)
-@@ -207,6 +207,7 @@
+@@ -218,6 +218,7 @@
}
catch (CommunicationException e1)
{
@@ -10,7 +10,7 @@
// create new LDAP context
ctx = getLdapContext(true);
// try repeat operation where communication error occurs
-@@ -214,6 +215,7 @@
+@@ -225,6 +226,7 @@
}
catch (ServiceUnavailableException e2)
{
@@ -18,7 +18,7 @@
// do the same as for CommunicationException
ctx = getLdapContext(true);
//
-@@ -274,6 +276,7 @@
+@@ -285,6 +287,7 @@
}
catch (CommunicationException e1)
{
@@ -26,7 +26,7 @@
// create new LDAP context
ctx = getLdapContext(true);
// try repeat operation where communication error occurs
-@@ -281,6 +284,7 @@
+@@ -292,6 +295,7 @@
}
catch (ServiceUnavailableException e2)
{
@@ -36,7 +36,7 @@
//
Index: exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/MembershipDAOImpl.java
===================================================================
---- exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/MembershipDAOImpl.java (revision 4560)
+--- exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/MembershipDAOImpl.java (revision 4762)
+++ exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/MembershipDAOImpl.java (working copy)
@@ -29,6 +29,7 @@
import org.exoplatform.services.organization.MembershipType;
@@ -240,7 +240,7 @@
Index: exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/CacheHandler.java
===================================================================
--- exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/CacheHandler.java (revision 0)
-+++ exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/CacheHandler.java (revision 0)
++++ exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/CacheHandler.java (revision 4766)
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2011 eXo Platform SAS.
@@ -420,7 +420,7 @@
+}
Index: exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/GroupDAOImpl.java
===================================================================
---- exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/GroupDAOImpl.java (revision 4560)
+--- exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/GroupDAOImpl.java (revision 4762)
+++ exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/GroupDAOImpl.java (working copy)
@@ -26,11 +26,14 @@
import org.exoplatform.services.organization.GroupEventListenerHandler;
@@ -675,7 +675,7 @@
{
Index: exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/MembershipTypeDAOImpl.java
===================================================================
---- exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/MembershipTypeDAOImpl.java (revision 4560)
+--- exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/MembershipTypeDAOImpl.java (revision 4762)
+++ exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/MembershipTypeDAOImpl.java (working copy)
@@ -24,6 +24,7 @@
import org.exoplatform.services.organization.MembershipType;
@@ -815,7 +815,7 @@
finally
Index: exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/UserProfileDAOImpl.java
===================================================================
---- exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/UserProfileDAOImpl.java (revision 4560)
+--- exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/UserProfileDAOImpl.java (revision 4762)
+++ exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/UserProfileDAOImpl.java (working copy)
@@ -61,9 +61,10 @@
*/
@@ -880,7 +880,7 @@
}
Index: exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/ADMembershipDAOImpl.java
===================================================================
---- exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/ADMembershipDAOImpl.java (revision 4560)
+--- exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/ADMembershipDAOImpl.java (revision 4762)
+++ exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/ADMembershipDAOImpl.java (working copy)
@@ -22,6 +22,7 @@
import org.exoplatform.services.organization.Group;
@@ -979,7 +979,7 @@
for (int x = 0; x < attr.size(); x++)
Index: exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/OrganizationServiceImpl.java
===================================================================
---- exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/OrganizationServiceImpl.java (revision 4560)
+--- exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/OrganizationServiceImpl.java (revision 4762)
+++ exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/OrganizationServiceImpl.java (working copy)
@@ -47,25 +47,27 @@
LDAPAttributeMapping ldapAttrMapping =
@@ -1018,7 +1018,7 @@
if (param != null)
Index: exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/ADGroupDAOImpl.java
===================================================================
---- exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/ADGroupDAOImpl.java (revision 4560)
+--- exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/ADGroupDAOImpl.java (revision 4762)
+++ exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/ADGroupDAOImpl.java (working copy)
@@ -48,12 +48,14 @@
* items
@@ -1052,7 +1052,7 @@
{
Index: exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/LDAPUserPageList.java
===================================================================
---- exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/LDAPUserPageList.java (revision 4560)
+--- exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/LDAPUserPageList.java (revision 4762)
+++ exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/LDAPUserPageList.java (working copy)
@@ -141,7 +141,10 @@
catch (NamingException e)
@@ -1078,7 +1078,7 @@
}
Index: exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/UserDAOImpl.java
===================================================================
---- exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/UserDAOImpl.java (revision 4560)
+--- exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/UserDAOImpl.java (revision 4762)
+++ exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/UserDAOImpl.java (working copy)
@@ -21,8 +21,13 @@
import org.exoplatform.commons.utils.LazyPageList;
@@ -1286,7 +1286,7 @@
Index: exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/ADUserDAOImpl.java
===================================================================
---- exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/ADUserDAOImpl.java (revision 4560)
+--- exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/ADUserDAOImpl.java (revision 4762)
+++ exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/ADUserDAOImpl.java (working copy)
@@ -20,6 +20,7 @@
@@ -1354,7 +1354,7 @@
}
Index: exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/LdapUserListAccess.java
===================================================================
---- exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/LdapUserListAccess.java (revision 4560)
+--- exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/LdapUserListAccess.java (revision 4762)
+++ exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/LdapUserListAccess.java (working copy)
@@ -84,7 +84,10 @@
catch (NamingException e)
@@ -1380,7 +1380,7 @@
}
Index: exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/BaseDAO.java
===================================================================
---- exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/BaseDAO.java (revision 4560)
+--- exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/BaseDAO.java (revision 4762)
+++ exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/BaseDAO.java (working copy)
@@ -24,6 +24,7 @@
import org.exoplatform.services.organization.Group;
Added: core/branches/2.3.x/patch/2.3.10/COR-34/readme.txt
===================================================================
--- core/branches/2.3.x/patch/2.3.10/COR-34/readme.txt (rev 0)
+++ core/branches/2.3.x/patch/2.3.10/COR-34/readme.txt 2011-08-17 09:06:09 UTC (rev 4767)
@@ -0,0 +1,65 @@
+Summary
+
+ * Status: Improve performance of LDAP organization service
+ * CCP Issue: CCP-1032, Product Jira Issue: COR-34.
+ * Complexity: medium
+
+The Proposal
+Problem description
+
+What is the problem to fix?
+
+ * Improve performance of LDAP organization service
+
+Fix description
+
+How is the problem fixed?
+
+ * Cache implementation
+
+Patch file: COR-34.patch
+
+Tests to perform
+
+Reproduction test
+
+ * LDAP organization service is pretty slow and doesn't support cache.
+
+Tests performed at DevLevel
+* Manual testing Tomcat AS with LDAP organization service
+
+Tests performed at QA/Support Level
+*
+Documentation changes
+
+Documentation changes:
+* No
+
+Configuration changes
+
+Configuration changes:
+* No
+
+Will previous configuration continue to work?
+* Yes
+
+Risks and impacts
+
+Can this bug fix have any side effects on current client projects?
+
+ * No
+
+Is there a performance risk/cost?
+* No
+
+Validation (PM/Support/QA)
+
+PM Comment
+* Patch approved
+
+Support Comment
+*
+
+QA Feedbacks
+*
+
12 years, 9 months
exo-jcr SVN: r4766 - core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap.
by do-not-reply@jboss.org
Author: trang_vu
Date: 2011-08-17 04:10:36 -0400 (Wed, 17 Aug 2011)
New Revision: 4766
Added:
core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/CacheHandler.java
Log:
COR-34: add CacheHandler.java
Added: core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/CacheHandler.java
===================================================================
--- core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/CacheHandler.java (rev 0)
+++ core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/CacheHandler.java 2011-08-17 08:10:36 UTC (rev 4766)
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2011 eXo Platform SAS.
+ *
+ * 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.exoplatform.services.organization.ldap;
+
+import org.exoplatform.services.cache.CacheService;
+import org.exoplatform.services.cache.ExoCache;
+import org.exoplatform.services.organization.Group;
+import org.exoplatform.services.organization.Membership;
+import org.exoplatform.services.organization.MembershipType;
+import org.exoplatform.services.organization.User;
+
+import java.io.Serializable;
+
+/**
+ * @author <a href="abazko(a)exoplatform.com">Anatoliy Bazko</a>
+ * @version $Id: CacheHandler.java 34360 2009-07-22 23:58:59Z tolusha $
+ */
+public class CacheHandler
+{
+ public static final String MEMBERSHIPTYPE_PREFIX = "mt=";
+
+ public static final String GROUP_PREFIX = "g=";
+
+ public static final String USER_PREFIX = "u=";
+
+ /**
+ * Cache for Users.
+ */
+ private final ExoCache<Serializable, User> userCache;
+
+ /**
+ * Cache for MembershipTypes.
+ */
+ private final ExoCache<Serializable, MembershipType> membershipTypeCache;
+
+ /**
+ * Cache for Memberships.
+ */
+ private final ExoCache<Serializable, Membership> membershipCache;
+
+ /**
+ * Cache for Groups.
+ */
+ private final ExoCache<Serializable, Group> groupCache;
+
+ /**
+ * Constructor CacheHandler.
+ *
+ * @param cservice
+ * The cache handler
+ */
+ public CacheHandler(CacheService cservice)
+ {
+ this.userCache = cservice.getCacheInstance(this.getClass().getName() + "userCache");
+ this.membershipTypeCache = cservice.getCacheInstance(this.getClass().getName() + "membershipTypeCache");
+ this.groupCache = cservice.getCacheInstance(this.getClass().getName() + "groupCache");
+ this.membershipCache = cservice.getCacheInstance(this.getClass().getName() + "membershipCache");
+ }
+
+ public void put(Serializable key, Object value, CacheType cacheType)
+ {
+ if (cacheType == CacheType.USER)
+ {
+ userCache.put(key, (User)value);
+ }
+ else if (cacheType == CacheType.GROUP)
+ {
+ groupCache.put(key, (Group)value);
+ }
+ else if (cacheType == CacheType.MEMBERSHIP)
+ {
+ membershipCache.put(key, (Membership)value);
+ }
+ else if (cacheType == CacheType.MEMBERSHIPTYPE)
+ {
+ membershipTypeCache.put(key, (MembershipType)value);
+ }
+ }
+
+ public Object get(Serializable key, CacheType cacheType)
+ {
+ if (cacheType == CacheType.USER)
+ {
+ return userCache.get(key);
+ }
+ else if (cacheType == CacheType.GROUP)
+ {
+ return groupCache.get(key);
+ }
+ else if (cacheType == CacheType.MEMBERSHIP)
+ {
+ return membershipCache.get(key);
+ }
+ else if (cacheType == CacheType.MEMBERSHIPTYPE)
+ {
+ return membershipTypeCache.get(key);
+ }
+
+ return null;
+ }
+
+ public void remove(Serializable key, CacheType cacheType)
+ {
+ if (cacheType == CacheType.USER)
+ {
+ userCache.remove(key);
+ }
+ else if (cacheType == CacheType.GROUP)
+ {
+ groupCache.remove(key);
+ }
+ else if (cacheType == CacheType.MEMBERSHIP)
+ {
+ try
+ {
+ String tKey = ((String)key).toUpperCase();
+ for (Membership m : membershipCache.getCachedObjects())
+ {
+ String mkey = getMembershipKey(m);
+ if (mkey.toUpperCase().indexOf(tKey) >= 0)
+ {
+ membershipCache.remove(mkey);
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ }
+ }
+ else if (cacheType == CacheType.MEMBERSHIPTYPE)
+ {
+ membershipTypeCache.remove(key);
+ }
+ }
+
+ public String getMembershipKey(Membership m)
+ {
+ StringBuilder key = new StringBuilder();
+ key.append(GROUP_PREFIX + m.getGroupId());
+ key.append(MEMBERSHIPTYPE_PREFIX + m.getMembershipType());
+ key.append(USER_PREFIX + m.getUserName());
+
+ return key.toString();
+ }
+
+ public String getMembershipKey(String username, String groupId, String type)
+ {
+ StringBuilder key = new StringBuilder();
+ key.append(GROUP_PREFIX + groupId);
+ key.append(MEMBERSHIPTYPE_PREFIX + type);
+ key.append(USER_PREFIX + username);
+
+ return key.toString();
+ }
+
+ static enum CacheType
+ {
+ USER, GROUP, MEMBERSHIP, MEMBERSHIPTYPE
+ }
+}
12 years, 9 months
exo-jcr SVN: r4765 - core/trunk/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-08-17 03:26:56 -0400 (Wed, 17 Aug 2011)
New Revision: 4765
Modified:
core/trunk/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/CacheHandler.java
Log:
EXOJCR-1480: fix
Modified: core/trunk/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/CacheHandler.java
===================================================================
--- core/trunk/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/CacheHandler.java 2011-08-17 07:26:18 UTC (rev 4764)
+++ core/trunk/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/CacheHandler.java 2011-08-17 07:26:56 UTC (rev 4765)
@@ -169,7 +169,7 @@
return key.toString();
}
- public static enum CacheType
+ static enum CacheType
{
USER, GROUP, MEMBERSHIP, MEMBERSHIPTYPE
}
12 years, 9 months
exo-jcr SVN: r4764 - core/trunk/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-08-17 03:26:18 -0400 (Wed, 17 Aug 2011)
New Revision: 4764
Modified:
core/trunk/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/BaseDAO.java
core/trunk/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/CacheHandler.java
Log:
EXOJCR-1480: add class import
Modified: core/trunk/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/BaseDAO.java
===================================================================
--- core/trunk/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/BaseDAO.java 2011-08-17 07:00:26 UTC (rev 4763)
+++ core/trunk/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/BaseDAO.java 2011-08-17 07:26:18 UTC (rev 4764)
@@ -24,6 +24,7 @@
import org.exoplatform.services.organization.Group;
import org.exoplatform.services.organization.User;
import org.exoplatform.services.organization.impl.GroupImpl;
+import org.exoplatform.services.organization.ldap.CacheHandler.CacheType;
import java.util.ArrayList;
import java.util.Enumeration;
Modified: core/trunk/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/CacheHandler.java
===================================================================
--- core/trunk/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/CacheHandler.java 2011-08-17 07:00:26 UTC (rev 4763)
+++ core/trunk/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/CacheHandler.java 2011-08-17 07:26:18 UTC (rev 4764)
@@ -169,7 +169,7 @@
return key.toString();
}
- static enum CacheType
+ public static enum CacheType
{
USER, GROUP, MEMBERSHIP, MEMBERSHIPTYPE
}
12 years, 9 months
exo-jcr SVN: r4763 - in core/branches/2.3.x: exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap and 1 other directory.
by do-not-reply@jboss.org
Author: trang_vu
Date: 2011-08-17 03:00:26 -0400 (Wed, 17 Aug 2011)
New Revision: 4763
Modified:
core/branches/2.3.x/exo.core.component.ldap/src/main/java/org/exoplatform/services/ldap/impl/LDAPServiceImpl.java
core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/ADGroupDAOImpl.java
core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/ADMembershipDAOImpl.java
core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/ADUserDAOImpl.java
core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/BaseDAO.java
core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/GroupDAOImpl.java
core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/LDAPUserPageList.java
core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/LdapUserListAccess.java
core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/MembershipDAOImpl.java
core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/MembershipTypeDAOImpl.java
core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/OrganizationServiceImpl.java
core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/UserDAOImpl.java
core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/UserProfileDAOImpl.java
Log:
COR-34: Improve performance of LDAP organization service
Fix description
* Cache implementation.
Modified: core/branches/2.3.x/exo.core.component.ldap/src/main/java/org/exoplatform/services/ldap/impl/LDAPServiceImpl.java
===================================================================
--- core/branches/2.3.x/exo.core.component.ldap/src/main/java/org/exoplatform/services/ldap/impl/LDAPServiceImpl.java 2011-08-17 06:51:17 UTC (rev 4762)
+++ core/branches/2.3.x/exo.core.component.ldap/src/main/java/org/exoplatform/services/ldap/impl/LDAPServiceImpl.java 2011-08-17 07:00:26 UTC (rev 4763)
@@ -218,6 +218,7 @@
}
catch (CommunicationException e1)
{
+ release(ctx);
// create new LDAP context
ctx = getLdapContext(true);
// try repeat operation where communication error occurs
@@ -225,6 +226,7 @@
}
catch (ServiceUnavailableException e2)
{
+ release(ctx);
// do the same as for CommunicationException
ctx = getLdapContext(true);
//
@@ -285,6 +287,7 @@
}
catch (CommunicationException e1)
{
+ release(ctx);
// create new LDAP context
ctx = getLdapContext(true);
// try repeat operation where communication error occurs
@@ -292,6 +295,7 @@
}
catch (ServiceUnavailableException e2)
{
+ release(ctx);
// do the same as for CommunicationException
ctx = getLdapContext(true);
//
Modified: core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/ADGroupDAOImpl.java
===================================================================
--- core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/ADGroupDAOImpl.java 2011-08-17 06:51:17 UTC (rev 4762)
+++ core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/ADGroupDAOImpl.java 2011-08-17 07:00:26 UTC (rev 4763)
@@ -48,12 +48,14 @@
* items
* @param ldapService {@link LDAPService}
* @param ad See {@link ADSearchBySID}
+ * @param cacheHandler
+ * The Cache Handler
* @throws Exception if any errors occurs
*/
- public ADGroupDAOImpl(LDAPAttributeMapping ldapAttrMapping, LDAPService ldapService, ADSearchBySID ad)
- throws Exception
+ public ADGroupDAOImpl(LDAPAttributeMapping ldapAttrMapping, LDAPService ldapService, ADSearchBySID ad,
+ CacheHandler cacheHandler) throws Exception
{
- super(ldapAttrMapping, ldapService);
+ super(ldapAttrMapping, ldapService, cacheHandler);
adSearch = ad;
}
@@ -126,10 +128,7 @@
}
catch (NamingException e)
{
- if (isConnectionError(e) && err < getMaxConnectionError())
- ctx = ldapService.getLdapContext(true);
- else
- throw e;
+ ctx = reloadCtx(ctx, err, e);
}
finally
{
Modified: core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/ADMembershipDAOImpl.java
===================================================================
--- core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/ADMembershipDAOImpl.java 2011-08-17 06:51:17 UTC (rev 4762)
+++ core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/ADMembershipDAOImpl.java 2011-08-17 07:00:26 UTC (rev 4763)
@@ -22,6 +22,7 @@
import org.exoplatform.services.organization.Group;
import org.exoplatform.services.organization.Membership;
import org.exoplatform.services.organization.impl.MembershipImpl;
+import org.exoplatform.services.organization.ldap.CacheHandler.CacheType;
import java.util.ArrayList;
import java.util.Collection;
@@ -48,12 +49,14 @@
* items
* @param ldapService {@link LDAPService}
* @param ad See {@link ADSearchBySID}
+ * @param cacheHandler
+ * The Cache Handler
* @throws Exception if any errors occurs
*/
- public ADMembershipDAOImpl(LDAPAttributeMapping ldapAttrMapping, LDAPService ldapService, ADSearchBySID ad)
- throws Exception
+ public ADMembershipDAOImpl(LDAPAttributeMapping ldapAttrMapping, LDAPService ldapService, ADSearchBySID ad,
+ CacheHandler cacheHandler) throws Exception
{
- super(ldapAttrMapping, ldapService);
+ super(ldapAttrMapping, ldapService, cacheHandler);
adSearch = ad;
}
@@ -64,6 +67,13 @@
@Override
public Membership findMembershipByUserGroupAndType(String userName, String groupId, String type) throws Exception
{
+ MembershipImpl membership =
+ (MembershipImpl)cacheHandler.get(cacheHandler.getMembershipKey(userName, groupId, type), CacheType.MEMBERSHIP);
+ if (membership != null)
+ {
+ return membership;
+ }
+
LdapContext ctx = ldapService.getLdapContext(true);
String groupDN = getGroupDNFromGroupId(groupId);
try
@@ -74,15 +84,16 @@
{
Collection memberships = findMemberships(ctx, userName, groupDN, type);
if (memberships.size() > 0)
- return (MembershipImpl)memberships.iterator().next();
+ {
+ membership = (MembershipImpl)memberships.iterator().next();
+ cacheHandler.put(cacheHandler.getMembershipKey(membership), membership, CacheType.MEMBERSHIP);
+ return membership;
+ }
return null;
}
catch (NamingException e)
{
- if (isConnectionError(e) && err < getMaxConnectionError())
- ctx = ldapService.getLdapContext(true);
- else
- throw e;
+ ctx = reloadCtx(ctx, err, e);
}
}
}
@@ -110,10 +121,7 @@
}
catch (NamingException e)
{
- if (isConnectionError(e) && err < getMaxConnectionError())
- ctx = ldapService.getLdapContext(true);
- else
- throw e;
+ ctx = reloadCtx(ctx, err, e);
}
}
}
@@ -142,10 +150,7 @@
}
catch (NamingException e)
{
- if (isConnectionError(e) && err < getMaxConnectionError())
- ctx = ldapService.getLdapContext(true);
- else
- throw e;
+ ctx = reloadCtx(ctx, err, e);
}
}
}
@@ -184,7 +189,7 @@
results = ctx.search(userDN, filter, constraints);
while (results.hasMore())
{
- SearchResult sr = (SearchResult)results.next();
+ SearchResult sr = results.next();
Attributes attrs = sr.getAttributes();
Attribute attr = attrs.get("tokenGroups");
for (int x = 0; x < attr.size(); x++)
Modified: core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/ADUserDAOImpl.java
===================================================================
--- core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/ADUserDAOImpl.java 2011-08-17 06:51:17 UTC (rev 4762)
+++ core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/ADUserDAOImpl.java 2011-08-17 07:00:26 UTC (rev 4763)
@@ -20,6 +20,7 @@
import org.exoplatform.services.ldap.LDAPService;
import org.exoplatform.services.organization.User;
+import org.exoplatform.services.organization.ldap.CacheHandler.CacheType;
import javax.naming.Context;
import javax.naming.NamingException;
@@ -61,11 +62,14 @@
/**
* @param ldapAttrMapping {@link LDAPAttributeMapping}
* @param ldapService {@link LDAPService}
+ * @param cservice
+ * The Cache Handler
* @throws Exception if any errors occurs
*/
- public ADUserDAOImpl(LDAPAttributeMapping ldapAttrMapping, LDAPService ldapService) throws Exception
+ public ADUserDAOImpl(LDAPAttributeMapping ldapAttrMapping, LDAPService ldapService, CacheHandler cacheHandler)
+ throws Exception
{
- super(ldapAttrMapping, ldapService);
+ super(ldapAttrMapping, ldapService, cacheHandler);
LDAPUserPageList.SEARCH_CONTROL = Control.CRITICAL;
}
@@ -93,14 +97,13 @@
ctx.createSubcontext(userDN, attrs);
if (broadcast)
postSave(user, true);
+
+ cacheHandler.put(user.getUserName(), user, CacheType.USER);
break;
}
catch (NamingException e)
{
- if (isConnectionError(e) && err < getMaxConnectionError())
- ctx = ldapService.getLdapContext(true);
- else
- throw e;
+ ctx = reloadCtx(ctx, err, e);
}
}
}
@@ -118,7 +121,7 @@
* {@inheritDoc}
*/
@Override
- void saveUserPassword(User user, String userDN) throws Exception
+ protected void saveUserPassword(User user, String userDN) throws Exception
{
Object v = ldapService.getLdapContext().getEnvironment().get(Context.SECURITY_PROTOCOL);
if (v == null)
@@ -147,10 +150,7 @@
}
catch (NamingException e)
{
- if (isConnectionError(e) && err < getMaxConnectionError())
- ctx = ldapService.getLdapContext(true);
- else
- throw e;
+ ctx = reloadCtx(ctx, err, e);
}
}
}
Modified: core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/BaseDAO.java
===================================================================
--- core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/BaseDAO.java 2011-08-17 06:51:17 UTC (rev 4762)
+++ core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/BaseDAO.java 2011-08-17 07:00:26 UTC (rev 4763)
@@ -24,6 +24,7 @@
import org.exoplatform.services.organization.Group;
import org.exoplatform.services.organization.User;
import org.exoplatform.services.organization.impl.GroupImpl;
+import org.exoplatform.services.organization.ldap.CacheHandler.CacheType;
import java.util.ArrayList;
import java.util.Enumeration;
@@ -82,14 +83,21 @@
private static int maxConnectionError = -1;
/**
+ * The Cache Handler.
+ */
+ protected final CacheHandler cacheHandler;
+
+ /**
* @param ldapAttrMapping {@link LDAPAttributeMapping}
* @param ldapService {@link LDAPService}
* @throws Exception if any error occurs
*/
- public BaseDAO(LDAPAttributeMapping ldapAttrMapping, LDAPService ldapService) throws Exception
+ public BaseDAO(LDAPAttributeMapping ldapAttrMapping, LDAPService ldapService, CacheHandler cacheHandler)
+ throws Exception
{
this.ldapAttrMapping = ldapAttrMapping;
this.ldapService = ldapService;
+ this.cacheHandler = cacheHandler;
initializeNameParser();
}
@@ -141,6 +149,26 @@
}
/**
+ * Construct object name from {@link Group} id.
+ *
+ * @param groupDN group DN
+ * @return object name
+ */
+ protected String getGroupIdFromGroupDN(String groupDN) throws NamingException
+ {
+ // extract group's id, group's name and parent's group from DN
+ StringBuffer buffer = new StringBuffer();
+ String[] baseParts = explodeDN(ldapAttrMapping.groupsURL, true);
+ String[] membershipParts = explodeDN(groupDN, true);
+ for (int x = (membershipParts.length - baseParts.length - 1); x > -1; x--)
+ {
+ buffer.append("/" + membershipParts[x]);
+ }
+
+ return buffer.toString();
+ }
+
+ /**
* Get collection of {@link Attribute} with specified name from
* {@link Attributes}.
*
@@ -204,6 +232,20 @@
*/
protected Group getGroupFromMembershipDN(LdapContext ctx, String membershipDN) throws NamingException
{
+ String groupDN = getGroupDNFromMembershipDN(membershipDN);
+ Group group = getGroupByDN(ctx, groupDN);
+ return group;
+ }
+
+ /**
+ * Retrieve Group DN from membership DN.
+ *
+ * @param membershipDN membership Distinguished Name
+ * @return GroupDN
+ * @throws NamingException if any naming errors occurs
+ */
+ protected String getGroupDNFromMembershipDN(String membershipDN) throws NamingException
+ {
String[] membershipParts = explodeDN(membershipDN, false);
StringBuffer buffer = new StringBuffer();
for (int x = 1; x < membershipParts.length; x++)
@@ -217,8 +259,7 @@
buffer.append(membershipParts[x] + ",");
}
}
- Group group = getGroupByDN(ctx, buffer.toString());
- return group;
+ return buffer.toString();
}
/**
@@ -245,12 +286,7 @@
}
catch (NamingException e)
{
- // check is allowed to try one more time
- if (isConnectionError(e) && err < getMaxConnectionError())
- ctx = ldapService.getLdapContext(true);
- else
- // not connection exception or error occurs more than MAX_CONNECTION_ERROR
- throw e;
+ ctx = reloadCtx(ctx, err, e);
}
}
}
@@ -261,6 +297,30 @@
}
/**
+ * Re-load the ctx if the context allows it
+ * @param ctx the previous context
+ * @param err the total of errors that have already occurred
+ * @param e the last exception that occurs
+ * @return the new context if the context reload is allowed throws an exception otherwise
+ * @throws NamingException if context could not be reloaded
+ */
+ protected LdapContext reloadCtx(LdapContext ctx, int err, NamingException e) throws NamingException
+ {
+ // check is allowed to try one more time
+ if (isConnectionError(e) && err < getMaxConnectionError())
+ {
+ // release the previous context
+ ldapService.release(ctx);
+ // reload the context
+ ctx = ldapService.getLdapContext(true);
+ }
+ else
+ // not connection exception or error occurs more than MAX_CONNECTION_ERROR
+ throw e;
+ return ctx;
+ }
+
+ /**
* Get Group what reflected to object with specified Distinguished Name.
*
* @param ctx {@link LdapContext}
@@ -270,6 +330,26 @@
*/
protected Group getGroupByDN(LdapContext ctx, String groupDN) throws NamingException
{
+ try
+ {
+ Attributes attrs = ctx.getAttributes(groupDN);
+ return buildGroup(groupDN, attrs);
+ }
+ catch (NameNotFoundException e)
+ {
+ if (LOG.isDebugEnabled())
+ e.printStackTrace();
+ // Object with specified Distinguished Name not found. Null will be
+ // returned. This result we regard as successful, just nothing found.
+ return null;
+ }
+ }
+
+ protected Group buildGroup(String groupDN, Attributes attrs) throws NamingException
+ {
+ GroupImpl group = new GroupImpl();
+
+ // extract group's id, group's name and parent's group from DN
StringBuffer idBuffer = new StringBuffer();
String parentId = null;
String[] baseParts = explodeDN(ldapAttrMapping.groupsURL, true);
@@ -280,25 +360,17 @@
if (x == 1)
parentId = idBuffer.toString();
}
- try
+
+ group.setGroupName(membershipParts[0]);
+ group.setId(idBuffer.toString());
+ if (attrs != null)
{
- Attributes attrs = ctx.getAttributes(groupDN);
- GroupImpl group = new GroupImpl();
- group.setGroupName(membershipParts[0]);
- group.setId(idBuffer.toString());
group.setDescription(ldapAttrMapping.getAttributeValueAsString(attrs, ldapAttrMapping.ldapDescriptionAttr));
group.setLabel(ldapAttrMapping.getAttributeValueAsString(attrs, ldapAttrMapping.groupLabelAttr));
- group.setParentId(parentId);
- return group;
}
- catch (NameNotFoundException e)
- {
- if (LOG.isDebugEnabled())
- e.printStackTrace();
- // Object with specified Distinguished Name not found. Null will be
- // returned. This result we regard as successful, just nothing found.
- return null;
- }
+ group.setParentId(parentId);
+
+ return group;
}
/**
@@ -352,10 +424,7 @@
}
catch (NamingException e)
{
- if (isConnectionError(e) && err < getMaxConnectionError())
- ctx = ldapService.getLdapContext(true);
- else
- throw e;
+ ctx = reloadCtx(ctx, err, e);
}
}
}
@@ -381,9 +450,7 @@
answer = findUser(ctx, username, true);
while (answer.hasMoreElements())
{
- String userDN = answer.next().getNameInNamespace();
- Attributes attrs = ctx.getAttributes(userDN);
- return ldapAttrMapping.attributesToUser(attrs);
+ return ldapAttrMapping.attributesToUser(answer.next().getAttributes());
}
return null;
}
@@ -465,10 +532,7 @@
}
catch (NamingException e)
{
- if (isConnectionError(e) && err < getMaxConnectionError())
- ctx = ldapService.getLdapContext(true);
- else
- throw e;
+ ctx = reloadCtx(ctx, err, e);
}
}
}
@@ -525,6 +589,10 @@
removeAllSubtree(ctx, sr.getNameInNamespace());
}
ctx.destroySubcontext(dn);
+
+ String groupId = buildGroup(dn, null).getId();
+ cacheHandler.remove(groupId, CacheType.GROUP);
+ cacheHandler.remove(CacheHandler.GROUP_PREFIX + groupId, CacheType.MEMBERSHIP);
}
finally
{
@@ -649,14 +717,7 @@
}
catch (NamingException e)
{
- // check is allowed to try one more time
- if (isConnectionError(e) && err < getMaxConnectionError())
- // update LdapContext
- ctx = ldapService.getLdapContext(true);
- else
- // not connection exception or error occurs more than
- // MAX_CONNECTION_ERROR times
- throw e;
+ ctx = reloadCtx(ctx, err, e);
}
}
}
Modified: core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/GroupDAOImpl.java
===================================================================
--- core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/GroupDAOImpl.java 2011-08-17 06:51:17 UTC (rev 4762)
+++ core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/GroupDAOImpl.java 2011-08-17 07:00:26 UTC (rev 4763)
@@ -26,11 +26,14 @@
import org.exoplatform.services.organization.GroupEventListenerHandler;
import org.exoplatform.services.organization.GroupHandler;
import org.exoplatform.services.organization.impl.GroupImpl;
+import org.exoplatform.services.organization.ldap.CacheHandler.CacheType;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import javax.naming.CompositeName;
import javax.naming.Name;
@@ -69,11 +72,14 @@
* @param ldapAttrMapping mapping LDAP attributes to eXo organization service
* items (users, groups, etc)
* @param ldapService {@link LDAPService}
+ * @param cacheHandler
+ * The Cache Handler
* @throws Exception if any errors occurs
*/
- public GroupDAOImpl(LDAPAttributeMapping ldapAttrMapping, LDAPService ldapService) throws Exception
+ public GroupDAOImpl(LDAPAttributeMapping ldapAttrMapping, LDAPService ldapService, CacheHandler cacheHandler)
+ throws Exception
{
- super(ldapAttrMapping, ldapService);
+ super(ldapAttrMapping, ldapService, cacheHandler);
this.listeners = new ArrayList<GroupEventListener>(3);
}
@@ -136,14 +142,13 @@
ctx.createSubcontext(groupDN, ldapAttrMapping.groupToAttributes(child));
if (broadcast)
postSave(group, true);
+
+ cacheHandler.put(child.getId(), group, CacheType.GROUP);
return;
}
catch (NamingException e)
{
- if (isConnectionError(e) && err < getMaxConnectionError())
- ctx = ldapService.getLdapContext(true);
- else
- throw e;
+ ctx = reloadCtx(ctx, err, e);
}
finally
{
@@ -192,14 +197,13 @@
ctx.modifyAttributes(groupDN, mods);
if (broadcast)
postSave(group, true);
+
+ cacheHandler.put(group.getId(), group, CacheType.GROUP);
return;
}
catch (NamingException e)
{
- if (isConnectionError(e) && err < getMaxConnectionError())
- ctx = ldapService.getLdapContext(true);
- else
- throw e;
+ ctx = reloadCtx(ctx, err, e);
}
}
}
@@ -255,15 +259,13 @@
removeAllSubtree(ctx, groupDN);
if (broadcast)
postDelete(group);
+
return group;
}
catch (NamingException e)
{
- if (isConnectionError(e) && err < getMaxConnectionError())
- ctx = ldapService.getLdapContext(true);
- else
- throw e;
+ ctx = reloadCtx(ctx, err, e);
}
finally
{
@@ -323,10 +325,7 @@
}
catch (NamingException e)
{
- if (isConnectionError(e) && err < getMaxConnectionError())
- ctx = ldapService.getLdapContext(true);
- else
- throw e;
+ ctx = reloadCtx(ctx, err, e);
}
finally
{
@@ -348,6 +347,13 @@
{
if (groupId == null)
return null;
+
+ Group group = (Group)cacheHandler.get(groupId, CacheType.GROUP);
+ if (group != null)
+ {
+ return group;
+ }
+
String parentId = null;
StringBuffer buffer = new StringBuffer();
String[] groupIdParts = groupId.split("/");
@@ -366,17 +372,19 @@
try
{
Attributes attrs = ctx.getAttributes(groupDN);
- Group group = ldapAttrMapping.attributesToGroup(attrs);
+ group = ldapAttrMapping.attributesToGroup(attrs);
((GroupImpl)group).setId(groupId);
((GroupImpl)group).setParentId(parentId);
+
+ if (group != null)
+ {
+ cacheHandler.put(groupId, group, CacheType.GROUP);
+ }
return group;
}
catch (NamingException e)
{
- if (isConnectionError(e) && err < getMaxConnectionError())
- ctx = ldapService.getLdapContext(true);
- else
- throw e;
+ ctx = reloadCtx(ctx, err, e);
}
}
}
@@ -402,6 +410,13 @@
{
if (groupId == null)
return null;
+
+ Group group = (Group)cacheHandler.get(groupId, CacheType.GROUP);
+ if (group != null)
+ {
+ return group;
+ }
+
String parentId = null;
StringBuffer buffer = new StringBuffer();
String[] groupIdParts = groupId.split("/");
@@ -415,9 +430,14 @@
try
{
Attributes attrs = ctx.getAttributes(groupDN);
- Group group = ldapAttrMapping.attributesToGroup(attrs);
+ group = ldapAttrMapping.attributesToGroup(attrs);
((GroupImpl)group).setId(groupId);
((GroupImpl)group).setParentId(parentId);
+
+ if (group != null)
+ {
+ cacheHandler.put(groupId, group, CacheType.GROUP);
+ }
return group;
}
catch (NameNotFoundException e)
@@ -473,7 +493,7 @@
{
Name entryName = parser.parse(name.get(0));
String groupDN = entryName + "," + ldapAttrMapping.groupsURL;
- Group group = this.getGroupByDN(ctx, groupDN);
+ Group group = this.buildGroup(groupDN, sr.getAttributes());
if (group != null)
addGroup(groups, group);
}
@@ -482,10 +502,7 @@
}
catch (NamingException e2)
{
- if (isConnectionError(e2) && err < getMaxConnectionError())
- ctx = ldapService.getLdapContext(true);
- else
- throw e2;
+ ctx = reloadCtx(ctx, err, e2);
}
finally
{
@@ -555,7 +572,7 @@
{
Name entryName = parser.parse(name.get(0));
String groupDN = entryName + "," + searchBase;
- Group group = this.getGroupByDN(ctx, groupDN);
+ Group group = this.buildGroup(groupDN, sr.getAttributes());
if (group != null)
addGroup(groups, group);
}
@@ -564,10 +581,7 @@
}
catch (NamingException e2)
{
- if (isConnectionError(e2) && err < getMaxConnectionError())
- ctx = ldapService.getLdapContext(true);
- else
- throw e2;
+ ctx = reloadCtx(ctx, err, e2);
}
finally
{
@@ -613,21 +627,24 @@
results = ctx.search(ldapAttrMapping.groupsURL, filter, constraints);
// add groups for memberships matching user
- // int total = 0;
+ Set<String> uniqueGroupsDN = new HashSet<String>();
while (results != null && results.hasMore())
{
SearchResult sr = results.next();
- // total++;
NameParser parser = ctx.getNameParser("");
CompositeName name = new CompositeName(sr.getName());
if (name.size() < 1)
break;
Name entryName = parser.parse(name.get(0));
String membershipDN = entryName + "," + ldapAttrMapping.groupsURL;
- Group group = this.getGroupFromMembershipDN(ctx, membershipDN);
- if (group != null)
- addGroup(groups, group);
+ uniqueGroupsDN.add(this.getGroupDNFromMembershipDN(membershipDN));
}
+ for(String groupDN : uniqueGroupsDN)
+ {
+ Group group = this.getGroupByDN(ctx, groupDN);
+ if (group != null)
+ addGroup(groups, group);
+ }
if (LOG.isDebugEnabled())
{
LOG.debug("Retrieved " + groups.size() + " groups from ldap for user " + userName);
@@ -636,10 +653,7 @@
}
catch (NamingException e2)
{
- if (isConnectionError(e2) && err < getMaxConnectionError())
- ctx = ldapService.getLdapContext(true);
- else
- throw e2;
+ ctx = reloadCtx(ctx, err, e2);
}
finally
{
Modified: core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/LDAPUserPageList.java
===================================================================
--- core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/LDAPUserPageList.java 2011-08-17 06:51:17 UTC (rev 4762)
+++ core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/LDAPUserPageList.java 2011-08-17 07:00:26 UTC (rev 4763)
@@ -141,7 +141,10 @@
catch (NamingException e)
{
if (BaseDAO.isConnectionError(e) && err < BaseDAO.getMaxConnectionError())
+ {
+ ldapService.release(ctx);
ctx = ldapService.getLdapContext(true);
+ }
else
throw e;
}
@@ -197,7 +200,10 @@
catch (NamingException e)
{
if (BaseDAO.isConnectionError(e) && err < 1)
+ {
+ ldapService.release(ctx);
ctx = ldapService.getLdapContext(true);
+ }
else
throw e;
}
Modified: core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/LdapUserListAccess.java
===================================================================
--- core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/LdapUserListAccess.java 2011-08-17 06:51:17 UTC (rev 4762)
+++ core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/LdapUserListAccess.java 2011-08-17 07:00:26 UTC (rev 4763)
@@ -84,7 +84,10 @@
catch (NamingException e)
{
if (BaseDAO.isConnectionError(e) && err < BaseDAO.getMaxConnectionError())
+ {
+ ldapService.release(ctx);
ctx = ldapService.getLdapContext(true);
+ }
else
throw e;
}
@@ -113,7 +116,10 @@
catch (NamingException e)
{
if (BaseDAO.isConnectionError(e) && err < BaseDAO.getMaxConnectionError())
+ {
+ ldapService.release(ctx);
ctx = ldapService.getLdapContext(true);
+ }
else
throw e;
}
Modified: core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/MembershipDAOImpl.java
===================================================================
--- core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/MembershipDAOImpl.java 2011-08-17 06:51:17 UTC (rev 4762)
+++ core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/MembershipDAOImpl.java 2011-08-17 07:00:26 UTC (rev 4763)
@@ -29,6 +29,7 @@
import org.exoplatform.services.organization.MembershipType;
import org.exoplatform.services.organization.User;
import org.exoplatform.services.organization.impl.MembershipImpl;
+import org.exoplatform.services.organization.ldap.CacheHandler.CacheType;
import java.util.ArrayList;
import java.util.Collection;
@@ -70,12 +71,15 @@
* mapping LDAP attributes to eXo organization service items (users, groups, etc)
* @param ldapService
* {@link LDAPService}
+ * @param cacheHandler
+ * The Cache Handler
* @throws Exception
* if any errors occurs
*/
- public MembershipDAOImpl(LDAPAttributeMapping ldapAttrMapping, LDAPService ldapService) throws Exception
+ public MembershipDAOImpl(LDAPAttributeMapping ldapAttrMapping, LDAPService ldapService, CacheHandler cacheHandler)
+ throws Exception
{
- super(ldapAttrMapping, ldapService);
+ super(ldapAttrMapping, ldapService, cacheHandler);
this.listeners = new ArrayList<MembershipEventListener>(3);
}
@@ -131,6 +135,8 @@
ctx.createSubcontext(membershipDN, ldapAttrMapping.membershipToAttributes(m, userDN));
if (broadcast)
postSave(m, true);
+
+ cacheHandler.put(cacheHandler.getMembershipKey(m), m, CacheType.MEMBERSHIP);
return;
}
// if contains membership
@@ -148,15 +154,14 @@
ctx.modifyAttributes(membershipDN, mods);
if (broadcast)
postSave(m, true);
+
+ cacheHandler.put(cacheHandler.getMembershipKey(m), m, CacheType.MEMBERSHIP);
return;
}
catch (NamingException e)
{
- if (isConnectionError(e) && err < getMaxConnectionError())
- ctx = ldapService.getLdapContext(true);
- else
- throw e;
+ ctx = reloadCtx(ctx, err, e);
}
}
}
@@ -245,23 +250,25 @@
ctx.modifyAttributes(membershipDN, mods);
if (broadcast)
postSave(m, true);
+
+ cacheHandler.put(cacheHandler.getMembershipKey(m), m, CacheType.MEMBERSHIP);
}
else
{
if (broadcast)
preDelete(m);
ctx.destroySubcontext(membershipDN);
+
if (broadcast)
postDelete(m);
+
+ cacheHandler.remove(cacheHandler.getMembershipKey(m), CacheType.MEMBERSHIP);
}
return m;
}
catch (NamingException e1)
{
- if (isConnectionError(e1) && err < getMaxConnectionError())
- ctx = ldapService.getLdapContext(true);
- else
- throw e1;
+ ctx = reloadCtx(ctx, err, e1);
}
}
}
@@ -318,9 +325,13 @@
new ModificationItem(DirContext.REMOVE_ATTRIBUTE, new BasicAttribute(
ldapAttrMapping.membershipTypeMemberValue, userDN));
ctx.modifyAttributes(membershipDN, mods);
+ cacheHandler.put(cacheHandler.getMembershipKey(membership), membership, CacheType.MEMBERSHIP);
}
else
+ {
ctx.destroySubcontext(membershipDN);
+ cacheHandler.remove(cacheHandler.getMembershipKey(membership), CacheType.MEMBERSHIP);
+ }
}
catch (Exception e1)
{
@@ -331,10 +342,7 @@
}
catch (NamingException e2)
{
- if (isConnectionError(e2) && err < getMaxConnectionError())
- ctx = ldapService.getLdapContext(true);
- else
- throw e2;
+ ctx = reloadCtx(ctx, err, e2);
}
finally
{
@@ -365,12 +373,19 @@
*/
public Membership findMembershipByUserGroupAndType(String userName, String groupId, String type) throws Exception
{
+ MembershipImpl membership =
+ (MembershipImpl)cacheHandler.get(cacheHandler.getMembershipKey(userName, groupId, type), CacheType.MEMBERSHIP);
+ if (membership != null)
+ {
+ return membership;
+ }
+
LdapContext ctx = ldapService.getLdapContext();
try
{
for (int err = 0;; err++)
{
- Membership membership = null;
+ membership = null;
try
{
String userDN = getDNFromUsername(ctx, userName);
@@ -395,14 +410,15 @@
membership = createMembershipObject(userName, groupId, type);
}
+ if (membership != null)
+ {
+ cacheHandler.put(cacheHandler.getMembershipKey(membership), membership, CacheType.MEMBERSHIP);
+ }
return membership;
}
catch (NamingException e)
{
- if (isConnectionError(e) && err < getMaxConnectionError())
- ctx = ldapService.getLdapContext(true);
- else
- throw e;
+ ctx = reloadCtx(ctx, err, e);
}
}
}
@@ -457,10 +473,7 @@
}
catch (NamingException e)
{
- if (isConnectionError(e) && err < getMaxConnectionError())
- ctx = ldapService.getLdapContext(true);
- else
- throw e;
+ ctx = reloadCtx(ctx, err, e);
}
finally
{
@@ -538,9 +551,9 @@
{
SearchResult sr = results.next();
String membershipDN = sr.getNameInNamespace();
- Group group = getGroupFromMembershipDN(ctx, membershipDN);
+ String groupId = getGroupIdFromGroupDN(getGroupDNFromMembershipDN(membershipDN));
String type = explodeDN(membershipDN, true)[0];
- Membership membership = createMembershipObject(userName, group.getId(), type);
+ Membership membership = createMembershipObject(userName, groupId, type);
memberships.add(membership);
}
if (LOG.isDebugEnabled())
@@ -551,10 +564,7 @@
}
catch (NamingException e)
{
- if (isConnectionError(e) && err < getMaxConnectionError())
- ctx = ldapService.getLdapContext(true);
- else
- throw e;
+ ctx = reloadCtx(ctx, err, e);
}
finally
{
@@ -619,10 +629,7 @@
}
catch (NamingException e)
{
- if (isConnectionError(e) && err < getMaxConnectionError())
- ctx = ldapService.getLdapContext(true);
- else
- throw e;
+ ctx = reloadCtx(ctx, err, e);
}
finally
{
Modified: core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/MembershipTypeDAOImpl.java
===================================================================
--- core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/MembershipTypeDAOImpl.java 2011-08-17 06:51:17 UTC (rev 4762)
+++ core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/MembershipTypeDAOImpl.java 2011-08-17 07:00:26 UTC (rev 4763)
@@ -24,6 +24,7 @@
import org.exoplatform.services.organization.MembershipType;
import org.exoplatform.services.organization.MembershipTypeHandler;
import org.exoplatform.services.organization.impl.MembershipTypeImpl;
+import org.exoplatform.services.organization.ldap.CacheHandler.CacheType;
import java.util.ArrayList;
import java.util.Collection;
@@ -56,11 +57,14 @@
* @param ldapAttrMapping mapping LDAP attributes to eXo organization service
* items (users, groups, etc)
* @param ldapService {@link LDAPService}
+ * @param cacheHandler
+ * The Cache Handler
* @throws Exception if any errors occurs
*/
- public MembershipTypeDAOImpl(LDAPAttributeMapping ldapAttrMapping, LDAPService ldapService) throws Exception
+ public MembershipTypeDAOImpl(LDAPAttributeMapping ldapAttrMapping, LDAPService ldapService, CacheHandler cacheHandler)
+ throws Exception
{
- super(ldapAttrMapping, ldapService);
+ super(ldapAttrMapping, ldapService, cacheHandler);
}
/**
@@ -95,15 +99,14 @@
mt.setCreatedDate(now);
mt.setModifiedDate(now);
ctx.createSubcontext(membershipTypeDN, ldapAttrMapping.membershipTypeToAttributes(mt));
+
+ cacheHandler.put(mt.getName(), mt, CacheType.MEMBERSHIPTYPE);
}
return mt;
}
catch (NamingException e1)
{
- if (isConnectionError(e1) && err < getMaxConnectionError())
- ctx = ldapService.getLdapContext(true);
- else
- throw e1;
+ ctx = reloadCtx(ctx, err, e1);
}
}
}
@@ -146,14 +149,13 @@
ldapAttrMapping.ldapDescriptionAttr, mt.getDescription()));
}
ctx.modifyAttributes(membershipTypeDN, mods);
+
+ cacheHandler.put(mt.getName(), mt, CacheType.MEMBERSHIPTYPE);
return mt;
}
catch (NamingException e)
{
- if (isConnectionError(e) && err < getMaxConnectionError())
- ctx = ldapService.getLdapContext(true);
- else
- throw e;
+ ctx = reloadCtx(ctx, err, e);
}
}
}
@@ -181,14 +183,13 @@
MembershipType m = ldapAttrMapping.attributesToMembershipType(attrs);
removeMembership(ctx, name);
ctx.destroySubcontext(membershipTypeDN);
+
+ cacheHandler.remove(name, CacheType.MEMBERSHIPTYPE);
return m;
}
catch (NamingException e)
{
- if (isConnectionError(e) && err < getMaxConnectionError())
- ctx = ldapService.getLdapContext(true);
- else
- throw e;
+ ctx = reloadCtx(ctx, err, e);
}
}
}
@@ -209,6 +210,12 @@
*/
public MembershipType findMembershipType(String name) throws Exception
{
+ MembershipType mt = (MembershipType)cacheHandler.get(name, CacheType.MEMBERSHIPTYPE);
+ if (mt != null)
+ {
+ return mt;
+ }
+
String membershipTypeDN =
ldapAttrMapping.membershipTypeNameAttr + "=" + name + "," + ldapAttrMapping.membershipTypeURL;
LdapContext ctx = ldapService.getLdapContext();
@@ -219,14 +226,16 @@
try
{
Attributes attrs = ctx.getAttributes(membershipTypeDN);
- return ldapAttrMapping.attributesToMembershipType(attrs);
+ mt = ldapAttrMapping.attributesToMembershipType(attrs);
+ if (mt != null)
+ {
+ cacheHandler.put(name, mt, CacheType.MEMBERSHIPTYPE);
+ }
+ return mt;
}
catch (NamingException e)
{
- if (isConnectionError(e) && err < getMaxConnectionError())
- ctx = ldapService.getLdapContext(true);
- else
- throw e;
+ ctx = reloadCtx(ctx, err, e);
}
}
}
@@ -274,10 +283,7 @@
}
catch (NamingException e)
{
- if (isConnectionError(e) && err < getMaxConnectionError())
- ctx = ldapService.getLdapContext(true);
- else
- throw e;
+ ctx = reloadCtx(ctx, err, e);
}
finally
{
@@ -307,6 +313,8 @@
{
SearchResult sr = results.next();
ctx.destroySubcontext(sr.getNameInNamespace());
+
+ cacheHandler.remove(CacheHandler.MEMBERSHIPTYPE_PREFIX + name, CacheType.MEMBERSHIP);
}
}
finally
Modified: core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/OrganizationServiceImpl.java
===================================================================
--- core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/OrganizationServiceImpl.java 2011-08-17 06:51:17 UTC (rev 4762)
+++ core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/OrganizationServiceImpl.java 2011-08-17 07:00:26 UTC (rev 4763)
@@ -47,25 +47,27 @@
LDAPAttributeMapping ldapAttrMapping =
(LDAPAttributeMapping)params.getObjectParam("ldap.attribute.mapping").getObject();
+ CacheHandler cacheHandler = new CacheHandler(cservice);
+
if (ldapService.getServerType() == LDAPService.ACTIVE_DIRECTORY_SERVER)
{
- userDAO_ = new ADUserDAOImpl(ldapAttrMapping, ldapService);
+ userDAO_ = new ADUserDAOImpl(ldapAttrMapping, ldapService, cacheHandler);
// ADSearchBySID adSearch = new ADSearchBySID(ldapAttrMapping, ldapService);
ADSearchBySID adSearch = new ADSearchBySID(ldapAttrMapping);
- groupDAO_ = new ADGroupDAOImpl(ldapAttrMapping, ldapService, adSearch);
- membershipDAO_ = new ADMembershipDAOImpl(ldapAttrMapping, ldapService, adSearch);
+ groupDAO_ = new ADGroupDAOImpl(ldapAttrMapping, ldapService, adSearch, cacheHandler);
+ membershipDAO_ = new ADMembershipDAOImpl(ldapAttrMapping, ldapService, adSearch, cacheHandler);
}
else
{
// ValueParam param = params.getValueParam("ldap.userDN.key");
// ldapAttrMapping.userDNKey = param.getValue();
- userDAO_ = new UserDAOImpl(ldapAttrMapping, ldapService);
- groupDAO_ = new GroupDAOImpl(ldapAttrMapping, ldapService);
- membershipDAO_ = new MembershipDAOImpl(ldapAttrMapping, ldapService);
+ userDAO_ = new UserDAOImpl(ldapAttrMapping, ldapService, cacheHandler);
+ groupDAO_ = new GroupDAOImpl(ldapAttrMapping, ldapService, cacheHandler);
+ membershipDAO_ = new MembershipDAOImpl(ldapAttrMapping, ldapService, cacheHandler);
}
// userProfileHandler_ = new UserProfileHandlerImpl(ldapAttrMapping, ldapService) ;
userProfileDAO_ = new UserProfileDAOImpl(hservice, cservice);
- membershipTypeDAO_ = new MembershipTypeDAOImpl(ldapAttrMapping, ldapService);
+ membershipTypeDAO_ = new MembershipTypeDAOImpl(ldapAttrMapping, ldapService, cacheHandler);
ValueParam param = params.getValueParam("ldap.userDN.key");
if (param != null)
Modified: core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/UserDAOImpl.java
===================================================================
--- core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/UserDAOImpl.java 2011-08-17 06:51:17 UTC (rev 4762)
+++ core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/UserDAOImpl.java 2011-08-17 07:00:26 UTC (rev 4763)
@@ -21,8 +21,13 @@
import org.exoplatform.commons.utils.LazyPageList;
import org.exoplatform.commons.utils.ListAccess;
import org.exoplatform.services.ldap.LDAPService;
-import org.exoplatform.services.organization.*;
+import org.exoplatform.services.organization.Query;
+import org.exoplatform.services.organization.User;
+import org.exoplatform.services.organization.UserEventListener;
+import org.exoplatform.services.organization.UserEventListenerHandler;
+import org.exoplatform.services.organization.UserHandler;
import org.exoplatform.services.organization.impl.UserImpl;
+import org.exoplatform.services.organization.ldap.CacheHandler.CacheType;
import java.util.ArrayList;
import java.util.Collections;
@@ -53,11 +58,14 @@
* @param ldapAttrMapping mapping LDAP attributes to eXo organization service
* items (users, groups, etc)
* @param ldapService {@link LDAPService}
+ * @param cacheHandler
+ * The Cache Handler
* @throws Exception if any errors occurs
*/
- public UserDAOImpl(LDAPAttributeMapping ldapAttrMapping, LDAPService ldapService) throws Exception
+ public UserDAOImpl(LDAPAttributeMapping ldapAttrMapping, LDAPService ldapService, CacheHandler cacheHandler)
+ throws Exception
{
- super(ldapAttrMapping, ldapService);
+ super(ldapAttrMapping, ldapService, cacheHandler);
}
/**
@@ -104,14 +112,13 @@
ctx.createSubcontext(userDN, attrs);
if (broadcast)
postSave(user, true);
+
+ cacheHandler.put(user.getUserName(), user, CacheType.USER);
break;
}
catch (NamingException e)
{
- if (isConnectionError(e) && err < getMaxConnectionError())
- ctx = ldapService.getLdapContext(true);
- else
- throw e;
+ ctx = reloadCtx(ctx, err, e);
}
}
}
@@ -145,14 +152,13 @@
ctx.modifyAttributes(userDN, mods);
if (broadcast)
postSave(user, false);
+
+ cacheHandler.put(user.getUserName(), user, CacheType.USER);
break;
}
catch (NamingException e)
{
- if (isConnectionError(e) && err < getMaxConnectionError())
- ctx = ldapService.getLdapContext(true);
- else
- throw e;
+ ctx = reloadCtx(ctx, err, e);
}
}
}
@@ -174,7 +180,7 @@
* @param userDN Distinguished Name
* @throws Exception if any errors occurs
*/
- void saveUserPassword(User user, String userDN) throws Exception
+ protected void saveUserPassword(User user, String userDN) throws Exception
{
ModificationItem[] mods =
new ModificationItem[]{new ModificationItem(DirContext.REPLACE_ATTRIBUTE, new BasicAttribute(
@@ -191,10 +197,7 @@
}
catch (NamingException e)
{
- if (isConnectionError(e) && err < getMaxConnectionError())
- ctx = ldapService.getLdapContext(true);
- else
- throw e;
+ ctx = reloadCtx(ctx, err, e);
}
}
}
@@ -227,14 +230,14 @@
ctx.destroySubcontext(userDN);
if (broadcast)
postDelete(user);
+
+ cacheHandler.remove(userName, CacheType.USER);
+ cacheHandler.remove(CacheHandler.USER_PREFIX + userName, CacheType.MEMBERSHIP);
return user;
}
catch (NamingException e)
{
- if (isConnectionError(e) && err < getMaxConnectionError())
- ctx = ldapService.getLdapContext(true);
- else
- throw e;
+ ctx = reloadCtx(ctx, err, e);
}
}
}
@@ -249,6 +252,12 @@
*/
public User findUserByName(String userName) throws Exception
{
+ User user = (User)cacheHandler.get(userName, CacheType.USER);
+ if (user != null)
+ {
+ return user;
+ }
+
LdapContext ctx = ldapService.getLdapContext();
try
{
@@ -256,14 +265,16 @@
{
try
{
- return getUserFromUsername(ctx, userName);
+ user = getUserFromUsername(ctx, userName);
+ if (user != null)
+ {
+ cacheHandler.put(user.getUserName(), user, CacheType.USER);
+ }
+ return user;
}
catch (NamingException e)
{
- if (isConnectionError(e) && err < getMaxConnectionError())
- ctx = ldapService.getLdapContext(true);
- else
- throw e;
+ ctx = reloadCtx(ctx, err, e);
}
}
}
@@ -283,51 +294,6 @@
*/
public ListAccess<User> findUsersByGroupId(String groupId) throws Exception
{
- // ArrayList<User> users = new ArrayList<User>();
- // TreeMap<String, User> map = new TreeMap<String, User>();
- //
- // LdapContext ctx = ldapService.getLdapContext();
- // try {
- // NamingEnumeration<SearchResult> results = null;
- // for (int err = 0;; err++) {
- // map.clear();
- // try {
- // String searchBase = this.getGroupDNFromGroupId(groupId);
- // String filter = ldapAttrMapping.membershipObjectClassFilter;
- // SearchControls constraints = new SearchControls();
- // constraints.setSearchScope(SearchControls.ONELEVEL_SCOPE);
- // results = ctx.search(searchBase, filter, constraints);
- // while (results.hasMoreElements()) {
- // SearchResult sr = results.next();
- // Attributes attrs = sr.getAttributes();
- // List<Object> members = this.getAttributes(attrs,
- // ldapAttrMapping.membershipTypeMemberValue);
- // for (int x = 0; x < members.size(); x++) {
- // User user = findUserByDN(ctx, (String) members.get(x));
- // if (user != null)
- // map.put(user.getUserName(), user);
- // }
- // }
- // break;
- // } catch (NamingException e) {
- // if (isConnectionError(e) && err < getMaxConnectionError())
- // ctx = ldapService.getLdapContext(true);
- // else
- // throw e;
- // } finally {
- // if (results != null)
- // results.close();
- // }
- // }
- // } finally {
- // ldapService.release(ctx);
- // }
- //
- // for (Iterator<String> i = map.keySet().iterator(); i.hasNext();)
- // users.add(map.get(i.next()));
- //
- // return new ObjectPageList(users, 10);
-
String searchBase = this.getGroupDNFromGroupId(groupId);
String filter = ldapAttrMapping.membershipObjectClassFilter;
return new ByGroupLdapUserListAccess(ldapAttrMapping, ldapService, searchBase, filter);
@@ -346,8 +312,6 @@
String searchBase = ldapAttrMapping.userURL;
String filter = ldapAttrMapping.userObjectClassFilter;
- // return new LDAPUserPageList(ldapAttrMapping, ldapService, searchBase, filter, pageSize);
-
return new SimpleLdapUserListAccess(ldapAttrMapping, ldapService, searchBase, filter);
}
Modified: core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/UserProfileDAOImpl.java
===================================================================
--- core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/UserProfileDAOImpl.java 2011-08-17 06:51:17 UTC (rev 4762)
+++ core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/UserProfileDAOImpl.java 2011-08-17 07:00:26 UTC (rev 4763)
@@ -61,9 +61,10 @@
*/
private static final Log LOG = ExoLogger.getLogger("exo.core.component.organization.ldap.UserProfileDAOImpl");
- public UserProfileDAOImpl(LDAPAttributeMapping ldapAttrMapping, LDAPService ldapService) throws Exception
+ public UserProfileDAOImpl(LDAPAttributeMapping ldapAttrMapping, LDAPService ldapService, CacheHandler cacheHandler)
+ throws Exception
{
- super(ldapAttrMapping, ldapService);
+ super(ldapAttrMapping, ldapService, cacheHandler);
this.listeners = new ArrayList<UserProfileEventListener>(3);
}
@@ -107,10 +108,7 @@
}
catch (NamingException e)
{
- if (isConnectionError(e) && err < getMaxConnectionError())
- ctx = ldapService.getLdapContext(true);
- else
- throw e;
+ ctx = reloadCtx(ctx, err, e);
}
}
}
@@ -153,10 +151,7 @@
}
catch (NamingException e)
{
- if (isConnectionError(e) && err < getMaxConnectionError())
- ctx = ldapService.getLdapContext(true);
- else
- throw e;
+ ctx = reloadCtx(ctx, err, e);
}
}
}
@@ -191,10 +186,7 @@
}
catch (NamingException e)
{
- if (isConnectionError(e) && err < getMaxConnectionError())
- ctx = ldapService.getLdapContext(true);
- else
- throw e;
+ ctx = reloadCtx(ctx, err, e);
}
}
}
@@ -229,10 +221,7 @@
}
catch (NamingException e)
{
- if (isConnectionError(e) && err < getMaxConnectionError())
- ctx = ldapService.getLdapContext(true);
- else
- throw e;
+ ctx = reloadCtx(ctx, err, e);
}
}
}
12 years, 9 months
exo-jcr SVN: r4762 - core/trunk/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-08-17 02:51:17 -0400 (Wed, 17 Aug 2011)
New Revision: 4762
Modified:
core/trunk/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/BaseDAO.java
Log:
EXOJCR-1480: fix sonar violation
Modified: core/trunk/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/BaseDAO.java
===================================================================
--- core/trunk/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/BaseDAO.java 2011-08-17 04:54:32 UTC (rev 4761)
+++ core/trunk/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/BaseDAO.java 2011-08-17 06:51:17 UTC (rev 4762)
@@ -24,7 +24,6 @@
import org.exoplatform.services.organization.Group;
import org.exoplatform.services.organization.User;
import org.exoplatform.services.organization.impl.GroupImpl;
-import org.exoplatform.services.organization.ldap.CacheHandler.CacheType;
import java.util.ArrayList;
import java.util.Enumeration;
@@ -338,7 +337,9 @@
catch (NameNotFoundException e)
{
if (LOG.isDebugEnabled())
- e.printStackTrace();
+ {
+ LOG.debug(e.getMessage(), e);
+ }
// Object with specified Distinguished Name not found. Null will be
// returned. This result we regard as successful, just nothing found.
return null;
12 years, 9 months