portals-jetspeed-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From tay...@apache.org
Subject svn commit: r925710 - in /portals/jetspeed-2/portal/trunk: components/jetspeed-security/src/main/java/org/apache/jetspeed/security/impl/ components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/ components/jetspeed-security/src/main/...
Date Sun, 21 Mar 2010 01:12:51 GMT
Author: taylor
Date: Sun Mar 21 01:12:50 2010
New Revision: 925710

URL: http://svn.apache.org/viewvc?rev=925710&view=rev
Log:
JS2-964 - contribution from Joachim Muller

Added:
    portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/JetspeedPrincipalLookupManager.java
    portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/JetspeedPrincipalLookupManagerAbstract.java
    portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/JetspeedPrincipalLookupManagerDefault.java
    portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/JetspeedPrincipalLookupManagerFactory.java
    portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/JetspeedPrincipalLookupManagerMySql.java
    portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/test/java/org/apache/jetspeed/security/TestUserManagerExtLookupManager.java
    portals/jetspeed-2/portal/trunk/jetspeed-api/src/main/java/org/apache/jetspeed/security/JetspeedPrincipalQueryContext.java
    portals/jetspeed-2/portal/trunk/jetspeed-api/src/main/java/org/apache/jetspeed/security/JetspeedPrincipalResultList.java
    portals/jetspeed-2/portal/trunk/jetspeed-api/src/main/java/org/apache/jetspeed/security/UserResultList.java
Modified:
    portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/impl/BaseJetspeedPrincipalManager.java
    portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/impl/UserManagerImpl.java
    portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/JetspeedPrincipalAccessManager.java
    portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/JetspeedSecurityPersistenceManager.java
    portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/test/java/org/apache/jetspeed/security/stubs/StubGroupManager.java
    portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/test/java/org/apache/jetspeed/security/stubs/StubUserManager.java
    portals/jetspeed-2/portal/trunk/jetspeed-api/src/main/java/org/apache/jetspeed/security/JetspeedPrincipalManager.java
    portals/jetspeed-2/portal/trunk/jetspeed-api/src/main/java/org/apache/jetspeed/security/UserManager.java
    portals/jetspeed-2/portal/trunk/jetspeed-portal-resources/src/main/resources/assembly/security-spi.xml

Modified: portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/impl/BaseJetspeedPrincipalManager.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/impl/BaseJetspeedPrincipalManager.java?rev=925710&r1=925709&r2=925710&view=diff
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/impl/BaseJetspeedPrincipalManager.java (original)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/impl/BaseJetspeedPrincipalManager.java Sun Mar 21 01:12:50 2010
@@ -31,6 +31,8 @@ import org.apache.jetspeed.security.Jets
 import org.apache.jetspeed.security.JetspeedPrincipalAssociationType;
 import org.apache.jetspeed.security.JetspeedPrincipalManager;
 import org.apache.jetspeed.security.JetspeedPrincipalManagerProvider;
+import org.apache.jetspeed.security.JetspeedPrincipalQueryContext;
+import org.apache.jetspeed.security.JetspeedPrincipalResultList;
 import org.apache.jetspeed.security.JetspeedPrincipalType;
 import org.apache.jetspeed.security.PrincipalManagerEventListener;
 import org.apache.jetspeed.security.SecurityException;
@@ -166,6 +168,11 @@ public abstract class BaseJetspeedPrinci
         return jpam.getPrincipals(nameFilter, principalType);
     }
 
+    public JetspeedPrincipalResultList getPrincipals(JetspeedPrincipalQueryContext queryContext)
+    {
+        return jpam.getPrincipals(queryContext, principalType);
+    }
+    
     public List<? extends JetspeedPrincipal> getPrincipalsByAttribute(String attributeName, String attributeValue)
     {
         return jpam.getPrincipalsByAttribute(attributeName, attributeValue, principalType);

Modified: portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/impl/UserManagerImpl.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/impl/UserManagerImpl.java?rev=925710&r1=925709&r2=925710&view=diff
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/impl/UserManagerImpl.java (original)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/impl/UserManagerImpl.java Sun Mar 21 01:12:50 2010
@@ -32,6 +32,7 @@ import org.apache.jetspeed.security.Auth
 import org.apache.jetspeed.security.GroupManager;
 import org.apache.jetspeed.security.JetspeedPrincipal;
 import org.apache.jetspeed.security.JetspeedPrincipalAssociationType;
+import org.apache.jetspeed.security.JetspeedPrincipalQueryContext;
 import org.apache.jetspeed.security.JetspeedPrincipalType;
 import org.apache.jetspeed.security.JetspeedSubjectFactory;
 import org.apache.jetspeed.security.PasswordCredential;
@@ -41,6 +42,7 @@ import org.apache.jetspeed.security.Secu
 import org.apache.jetspeed.security.User;
 import org.apache.jetspeed.security.UserCredential;
 import org.apache.jetspeed.security.UserManager;
+import org.apache.jetspeed.security.UserResultList;
 import org.apache.jetspeed.security.spi.JetspeedPrincipalAccessManager;
 import org.apache.jetspeed.security.spi.JetspeedPrincipalStorageManager;
 import org.apache.jetspeed.security.spi.UserPasswordCredentialManager;
@@ -58,6 +60,8 @@ import org.apache.jetspeed.security.spi.
  */
 public class UserManagerImpl extends BaseJetspeedPrincipalManager implements UserManager, UserSubjectPrincipalsProvider
 {
+	private static final long serialVersionUID = 2811398259474293885L;
+
 	private static final Logger log = LoggerFactory.getLogger(UserManagerImpl.class);
 
 	private String anonymousUser = "guest";
@@ -194,6 +198,10 @@ public class UserManagerImpl extends Bas
 		return (List<User>) getPrincipals(nameFilter);
 	}
 
+	public UserResultList getUsersExtended(JetspeedPrincipalQueryContext queryContext) throws SecurityException {
+		return new UserResultList(getPrincipals(queryContext));
+	}
+	
 	public List<User> getUsersInGroup(String groupFullPathName) throws SecurityException
 	{
 		return (List<User>) super.getAssociatedTo(groupFullPathName, groupType, JetspeedPrincipalAssociationType.IS_MEMBER_OF);

Modified: portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/JetspeedPrincipalAccessManager.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/JetspeedPrincipalAccessManager.java?rev=925710&r1=925709&r2=925710&view=diff
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/JetspeedPrincipalAccessManager.java (original)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/JetspeedPrincipalAccessManager.java Sun Mar 21 01:12:50 2010
@@ -19,6 +19,8 @@ package org.apache.jetspeed.security.spi
 import java.util.List;
 
 import org.apache.jetspeed.security.JetspeedPrincipal;
+import org.apache.jetspeed.security.JetspeedPrincipalQueryContext;
+import org.apache.jetspeed.security.JetspeedPrincipalResultList;
 import org.apache.jetspeed.security.JetspeedPrincipalType;
 
 /**
@@ -53,4 +55,31 @@ public interface JetspeedPrincipalAccess
     List<String> getAssociatedNamesTo(String principalToName, JetspeedPrincipalType from, JetspeedPrincipalType to, String associationName);
 
     List<String> getAssociatedNamesTo(Long principalToId, JetspeedPrincipalType from, JetspeedPrincipalType to, String associationName);
+    
+    /**
+     * Retrieve all principals that match the queryContext.
+     * It returns a {@link JetspeedPrincipalResultList}, containing
+     * the actual result list an the total number of results from the query.
+     * 
+     * The returned principals are detached.
+     * 
+     * @param queryContext The (@see JetspeedPrincipalQueryContext) for this query.
+     * @param type The principals type (@see JetspeedPrincipalType).
+     * @return
+     */
+    public JetspeedPrincipalResultList getPrincipals(JetspeedPrincipalQueryContext queryContext, JetspeedPrincipalType type);
+	
+    /**
+     * Retrieve all principals that match the queryContext.
+     * It returns a {@link JetspeedPrincipalResultList}, containing
+     * the actual result list an the total number of results from the query.
+     * 
+     * The returned principals are detached.
+     * 
+     * @param queryContext The (@see JetspeedPrincipalQueryContext) for this query.
+     * @param type The principals type (@see JetspeedPrincipalType).
+	 * @param securityDomain The principals security domain.
+     * @return
+     */
+	public JetspeedPrincipalResultList getPrincipals(JetspeedPrincipalQueryContext queryContext, JetspeedPrincipalType type, Long securityDomain);    
 }

Added: portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/JetspeedPrincipalLookupManager.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/JetspeedPrincipalLookupManager.java?rev=925710&view=auto
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/JetspeedPrincipalLookupManager.java (added)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/JetspeedPrincipalLookupManager.java Sun Mar 21 01:12:50 2010
@@ -0,0 +1,40 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jetspeed.security.spi;
+
+import org.apache.jetspeed.security.JetspeedPrincipalQueryContext;
+import org.apache.jetspeed.security.JetspeedPrincipalResultList;
+
+/**
+ * @author <a href="mailto:joachim@wemove.com">Joachim Mueller</a>
+ * 
+ */
+public interface JetspeedPrincipalLookupManager {
+
+	/**
+	 * Retrieves all principals that match the <em>queryContext</em>. It
+	 * actually takes care of the SQL generation, querying and building the
+	 * {@see JetspeedPrincipalResultList}.
+	 * 
+	 * The implementation of this method can be database specific.
+	 * 
+	 * @param queryContext
+	 * @return
+	 */
+	JetspeedPrincipalResultList getPrincipals(JetspeedPrincipalQueryContext queryContext);
+
+}

Added: portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/JetspeedPrincipalLookupManagerAbstract.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/JetspeedPrincipalLookupManagerAbstract.java?rev=925710&view=auto
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/JetspeedPrincipalLookupManagerAbstract.java (added)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/JetspeedPrincipalLookupManagerAbstract.java Sun Mar 21 01:12:50 2010
@@ -0,0 +1,306 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jetspeed.security.spi.impl;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.jetspeed.security.JetspeedPrincipal;
+import org.apache.jetspeed.security.JetspeedPrincipalAssociationType;
+import org.apache.jetspeed.security.JetspeedPrincipalQueryContext;
+import org.apache.jetspeed.security.JetspeedPrincipalResultList;
+import org.apache.jetspeed.security.impl.PersistentJetspeedPrincipal;
+import org.apache.jetspeed.security.spi.JetspeedPrincipalLookupManager;
+import org.apache.ojb.broker.PBFactoryException;
+import org.apache.ojb.broker.PersistenceBrokerFactory;
+import org.apache.ojb.broker.accesslayer.LookupException;
+import org.apache.ojb.broker.accesslayer.RowReader;
+import org.apache.ojb.broker.query.QueryByCriteria;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Abstract base class for the principal lookup manager. Defines possible
+ * database specific abstract methods and provides more generic methods to all
+ * database specific principal lookup managers.
+ * 
+ * @author <a href="mailto:joachim@wemove.com">Joachim Mueller</a>
+ * 
+ */
+public abstract class JetspeedPrincipalLookupManagerAbstract implements JetspeedPrincipalLookupManager {
+
+	static final Logger log = LoggerFactory.getLogger(JetspeedPrincipalLookupManagerAbstract.class);
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.apache.jetspeed.security.spi.JetspeedPrincipalPersistanceManager#
+	 * getPrincipals(org.apache.jetspeed.security.JetspeedPrincipalQueryContext)
+	 */
+	public JetspeedPrincipalResultList getPrincipals(JetspeedPrincipalQueryContext queryContext) {
+		String baseSqlStr = this.generateBaseSql(queryContext);
+
+		// create paging sql statement if possible for database based paging
+		String sqlStr = getPagingSql(baseSqlStr, queryContext);
+
+		int numberOfRecords = 0;
+		ArrayList<JetspeedPrincipal> results = new ArrayList<JetspeedPrincipal>();
+		PreparedStatement pstmt = null;
+		Connection conn = null;
+		try {
+			conn = PersistenceBrokerFactory.defaultPersistenceBroker().serviceConnectionManager().getConnection();
+
+			pstmt = conn.prepareStatement(sqlStr, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
+			// pstmt = conn.prepareStatement(sqlStr,
+			// ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
+			pstmt.setFetchSize((int) (queryContext.getOffset() + queryContext.getLength()));
+			ResultSet rs = pstmt.executeQuery();
+			boolean hasRecords = rs.next();
+
+			if (hasRecords) {
+				// scroll the result set to the offset
+				scrollToOffset(conn, rs, queryContext.getOffset());
+				for (int i = 0; i < queryContext.getLength(); i++) {
+					// now materialize the ResultSet into a JetspeedPrincipal
+					RowReader rr = PersistenceBrokerFactory.defaultPersistenceBroker().getClassDescriptor(
+							PersistentJetspeedPrincipal.class).getRowReader();
+					Map<Object, Object> row = new HashMap<Object, Object>();
+					// TODO: optimize, just retrieve the id from the DB and setup
+					// a JetspeedPrincipal template on that.
+					rr.readObjectArrayFrom(rs, row);
+					PersistentJetspeedPrincipal p = (PersistentJetspeedPrincipal) rr.readObjectFrom(row);
+					QueryByCriteria query = new QueryByCriteria(p);
+					p = (PersistentJetspeedPrincipal) PersistenceBrokerFactory.defaultPersistenceBroker()
+							.getObjectByQuery(query);
+					results.add(p);
+					if (!rs.next()) {
+						break;
+					}
+				}
+				rs.close();
+
+				// get the total number of results effected by the query
+				int fromPos = baseSqlStr.toUpperCase().indexOf(" FROM ");
+				if (fromPos >= 0) {
+					baseSqlStr = "select count(security_principal.principal_id)" + baseSqlStr.substring(fromPos);
+				}
+				// strip ORDER BY clause
+				int orderPos = baseSqlStr.toUpperCase().indexOf(" ORDER BY ");
+				if (orderPos >= 0) {
+					baseSqlStr = baseSqlStr.substring(0, orderPos);
+				}
+				pstmt = conn.prepareStatement(baseSqlStr);
+				rs = pstmt.executeQuery();
+				while (rs.next()) {
+					numberOfRecords += rs.getInt(1);
+				}
+				rs.close();
+			}
+		} catch (SQLException e) {
+			log.error("Error reading principal.", e);
+		} catch (PBFactoryException e) {
+			log.error("Error reading principal.", e);
+		} catch (LookupException e) {
+			log.error("Error reading principal.", e);
+		} finally {
+			try {
+				if (conn != null && !conn.isClosed()) {
+					conn.close();
+				}
+			} catch (SQLException e) {
+				log.error("Error closing connection.", e);
+			}
+		}
+		return new JetspeedPrincipalResultList(results, numberOfRecords);
+	}
+
+	/**
+	 * Generate the base SQL syntax for selecting principals. This must not
+	 * contain any database specifics.
+	 * 
+	 * @param queryContext
+	 * @return
+	 */
+	protected String generateBaseSql(JetspeedPrincipalQueryContext queryContext) {
+		String attributeConstraint = null;
+		String fromPart = "security_principal";
+		if (queryContext.getSecurityAttributes() != null) {
+			int cnt = 1;
+			for (Map.Entry<String, String> attribute : queryContext.getSecurityAttributes().entrySet()) {
+				if (attributeConstraint == null) {
+					attributeConstraint = "a" + cnt + ".PRINCIPAL_ID=security_principal.PRINCIPAL_ID AND a" + cnt
+							+ ".ATTR_NAME = '" + attribute.getKey() + "' AND a" + cnt + ".ATTR_VALUE LIKE '"
+							+ attribute.getValue() + "'";
+				} else {
+					attributeConstraint += " AND a" + cnt + ".PRINCIPAL_ID=security_principal.PRINCIPAL_ID AND a" + cnt
+							+ ".ATTR_NAME = '" + attribute.getKey() + "' AND a" + cnt + ".ATTR_VALUE LIKE '"
+							+ attribute.getValue() + "'";
+				}
+				fromPart += ", security_attribute a" + cnt;
+				cnt++;
+			}
+		}
+
+		String constraint = null;
+		if (queryContext.getNameFilter() != null && queryContext.getNameFilter().length() > 0) {
+			constraint = "security_principal.PRINCIPAL_NAME LIKE '" + queryContext.getNameFilter().replace('*', '%')
+					+ "'";
+		}
+
+		// find principals that are member of one or many roles
+		// the principal must be member in all supplied roles.
+		String roleConstraints = null;
+		if (queryContext.getAssociatedRoles() != null && queryContext.getAssociatedRoles().size() > 0
+				&& queryContext.getAssociatedRoles().get(0).length() > 0) {
+			int cnt = 1;
+			for (String roleName : queryContext.getAssociatedRoles()) {
+				if (roleConstraints == null) {
+					roleConstraints = "r" + cnt + ".ASSOC_NAME='" + JetspeedPrincipalAssociationType.IS_MEMBER_OF
+							+ "' AND r" + cnt + ".TO_PRINCIPAL_ID=rp" + cnt + ".PRINCIPAL_ID AND rp" + cnt
+							+ ".PRINCIPAL_NAME LIKE '" + roleName + "' AND rp" + cnt + ".PRINCIPAL_TYPE='role' AND r"
+							+ cnt + ".FROM_PRINCIPAL_ID=security_principal.PRINCIPAL_ID";
+				} else {
+					roleConstraints = " AND r" + cnt + ".ASSOC_NAME='" + JetspeedPrincipalAssociationType.IS_MEMBER_OF
+							+ "' AND r" + cnt + ".TO_PRINCIPAL_ID=rp" + cnt + ".PRINCIPAL_ID AND rp" + cnt
+							+ ".PRINCIPAL_NAME LIKE '" + roleName + "' AND rp" + cnt + ".PRINCIPAL_TYPE='role' AND r"
+							+ cnt + ".FROM_PRINCIPAL_ID=security_principal.PRINCIPAL_ID";
+				}
+			}
+			fromPart += ", security_principal_assoc r" + cnt + ", security_principal rp" + cnt;
+			cnt++;
+		}
+
+		// find principals that are member of one or many groups
+		// the principal must be member in all supplied groups.
+		String groupConstraints = null;
+		if (queryContext.getAssociatedGroups() != null && queryContext.getAssociatedGroups().size() > 0
+				&& queryContext.getAssociatedGroups().get(0).length() > 0) {
+			int cnt = 1;
+			for (String groupName : queryContext.getAssociatedGroups()) {
+				if (groupConstraints == null) {
+					groupConstraints = "r" + cnt + ".ASSOC_NAME='" + JetspeedPrincipalAssociationType.IS_MEMBER_OF
+							+ "' AND r" + cnt + ".TO_PRINCIPAL_ID=rp" + cnt + ".PRINCIPAL_ID AND rp" + cnt
+							+ ".PRINCIPAL_NAME LIKE '" + groupName + "' AND rp" + cnt + ".PRINCIPAL_TYPE='group' AND r"
+							+ cnt + ".FROM_PRINCIPAL_ID=security_principal.PRINCIPAL_ID";
+				} else {
+					groupConstraints = " AND r" + cnt + ".ASSOC_NAME='" + JetspeedPrincipalAssociationType.IS_MEMBER_OF
+							+ "' AND r" + cnt + ".TO_PRINCIPAL_ID=rp" + cnt + ".PRINCIPAL_ID AND rp" + cnt
+							+ ".PRINCIPAL_NAME LIKE '" + groupName + "' AND rp" + cnt + ".PRINCIPAL_TYPE='group' AND r"
+							+ cnt + ".FROM_PRINCIPAL_ID=security_principal.PRINCIPAL_ID";
+				}
+			}
+			fromPart += ", security_principal_assoc r" + cnt + ", security_principal rp" + cnt;
+			cnt++;
+		}
+
+		// find principals that contain one or many users
+		// the principal must contain all supplied users.
+		String userConstraints = null;
+		if (queryContext.getAssociatedUsers() != null && queryContext.getAssociatedUsers().size() > 0) {
+			int cnt = 1;
+			for (String userName : queryContext.getAssociatedGroups()) {
+				if (userConstraints == null) {
+					userConstraints = "r" + cnt + ".ASSOC_NAME='" + JetspeedPrincipalAssociationType.IS_MEMBER_OF
+							+ "' AND r" + cnt + ".FROM_PRINCIPAL_ID=rp" + cnt + ".PRINCIPAL_ID AND rp" + cnt
+							+ ".PRINCIPAL_NAME LIKE '" + userName + "' AND rp" + cnt + ".PRINCIPAL_TYPE='user' AND r"
+							+ cnt + ".TO_PRINCIPAL_ID=security_principal.PRINCIPAL_ID";
+				} else {
+					userConstraints = " AND r" + cnt + ".ASSOC_NAME='" + JetspeedPrincipalAssociationType.IS_MEMBER_OF
+							+ "' AND r" + cnt + ".FROM_PRINCIPAL_ID=rp" + cnt + ".PRINCIPAL_ID AND rp" + cnt
+							+ ".PRINCIPAL_NAME LIKE '" + userName + "' AND rp" + cnt + ".PRINCIPAL_TYPE='group' AND r"
+							+ cnt + ".TO_PRINCIPAL_ID=security_principal.PRINCIPAL_ID";
+				}
+			}
+			fromPart += ", security_principal_assoc r" + cnt + ", security_principal rp" + cnt;
+			cnt++;
+		}
+
+		if (attributeConstraint != null) {
+			if (constraint != null) {
+				constraint += " AND " + attributeConstraint;
+			} else {
+				constraint = attributeConstraint;
+			}
+		}
+
+		if (roleConstraints != null) {
+			if (constraint != null) {
+				constraint += " AND " + roleConstraints;
+			} else {
+				constraint = roleConstraints;
+			}
+		}
+
+		if (groupConstraints != null) {
+			if (constraint != null) {
+				constraint += " AND " + groupConstraints;
+			} else {
+				constraint = groupConstraints;
+			}
+		}
+
+		if (userConstraints != null) {
+			if (constraint != null) {
+				constraint += " AND " + userConstraints;
+			} else {
+				constraint = userConstraints;
+			}
+		}
+
+		String baseSqlStr = "SELECT security_principal.* from " + fromPart + " WHERE security_principal.PRINCIPAL_TYPE='"
+				+ queryContext.getJetspeedPrincipalType() + "' AND security_principal.DOMAIN_ID="
+				+ queryContext.getSecurityDomain();
+		
+		if (constraint != null) {
+			baseSqlStr += " AND " + constraint;
+		}
+		
+		if (queryContext.getOrder() != null && queryContext.getOrder().equalsIgnoreCase("desc")) {
+			baseSqlStr += " ORDER BY security_principal.PRINCIPAL_NAME DESC";
+		} else {
+			baseSqlStr += " ORDER BY security_principal.PRINCIPAL_NAME";
+		}
+		return baseSqlStr;
+	}
+
+	/**
+	 * Add database specific paging to the SQL.
+	 * 
+	 * @param sql
+	 * @param queryContext
+	 * @return
+	 */
+	protected abstract String getPagingSql(String sql, JetspeedPrincipalQueryContext queryContext);
+
+	/**
+	 * Add database specific code for scrolling the dataset to the specified
+	 * offset.
+	 * 
+	 * @param con
+	 * @param rs
+	 * @param offset
+	 * @throws SQLException
+	 */
+	protected abstract void scrollToOffset(Connection con, ResultSet rs, long offset) throws SQLException;
+
+}

Added: portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/JetspeedPrincipalLookupManagerDefault.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/JetspeedPrincipalLookupManagerDefault.java?rev=925710&view=auto
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/JetspeedPrincipalLookupManagerDefault.java (added)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/JetspeedPrincipalLookupManagerDefault.java Sun Mar 21 01:12:50 2010
@@ -0,0 +1,69 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jetspeed.security.spi.impl;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.apache.jetspeed.security.JetspeedPrincipalQueryContext;
+
+/**
+ * Default implementation of the principal lookup manager. This implementation
+ * uses no database specifics.
+ * 
+ * @author <a href="mailto:joachim@wemove.com">Joachim Mueller</a>
+ * 
+ */
+public class JetspeedPrincipalLookupManagerDefault extends JetspeedPrincipalLookupManagerAbstract {
+
+	/* (non-Javadoc)
+	 * @see org.apache.jetspeed.security.spi.impl.JetspeedPrincipalLookupManagerAbstract#getPagingSql(java.lang.String, org.apache.jetspeed.security.JetspeedPrincipalQueryContext)
+	 */
+	@Override
+	protected String getPagingSql(String sql, JetspeedPrincipalQueryContext queryContext) {
+		// no database specifics in the default manager
+		return sql;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.jetspeed.security.spi.impl.JetspeedPrincipalLookupManagerAbstract#scrollToOffset(java.sql.Connection, java.sql.ResultSet, long)
+	 */
+	@Override
+	protected void scrollToOffset(Connection con, ResultSet rs, long offset) throws SQLException {
+		// no database specifics in the default manager
+		// must use JDBC based scrolling
+		boolean supportsScrollable = false;
+		if (con.getMetaData().supportsResultSetConcurrency(ResultSet.TYPE_SCROLL_INSENSITIVE,
+				ResultSet.CONCUR_READ_ONLY)) {
+			supportsScrollable = true;
+		}
+		if (supportsScrollable) {
+			if (!rs.absolute((int) (offset + 1))) {
+				supportsScrollable = false;
+			}
+		}
+		if (!supportsScrollable) {
+			for (int i = 0; i <= (offset - 1); i++) {
+				if (rs.isAfterLast() || !rs.next()) {
+					break;
+				}
+			}
+		}
+	}
+
+}

Added: portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/JetspeedPrincipalLookupManagerFactory.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/JetspeedPrincipalLookupManagerFactory.java?rev=925710&view=auto
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/JetspeedPrincipalLookupManagerFactory.java (added)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/JetspeedPrincipalLookupManagerFactory.java Sun Mar 21 01:12:50 2010
@@ -0,0 +1,100 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jetspeed.security.spi.impl;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.jetspeed.security.spi.JetspeedPrincipalLookupManager;
+import org.apache.ojb.broker.metadata.ConnectionRepository;
+import org.apache.ojb.broker.metadata.JdbcConnectionDescriptor;
+import org.apache.ojb.broker.metadata.MetadataManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Factory for getting the database specific principal lookup manager. The
+ * database platform is determined by the OJB connection repository.
+ * 
+ * The factory is actually a singleton facade, since it returns always the same
+ * instance of the {@see JetspeedPrincipalLookupManager} once it was determined.
+ * 
+ * @author <a href="mailto:joachim@wemove.com">Joachim Mueller</a>
+ * 
+ */
+public class JetspeedPrincipalLookupManagerFactory {
+
+	static final Logger log = LoggerFactory.getLogger(JetspeedPrincipalLookupManagerFactory.class);
+
+	private static JetspeedPrincipalLookupManager jppm = null;
+
+	private Map<String, JetspeedPrincipalLookupManager> mappings = null;
+
+	/**
+	 * Setter for the lookup manager mapping between OJB database platform
+	 * string and the actual lookup manager implementation. Used by Spring.
+	 * 
+	 * @param mappings
+	 */
+	public void setMappings(Map<String, JetspeedPrincipalLookupManager> mappings) {
+		this.mappings = mappings;
+	}
+
+	/**
+	 * Returns the instance of the {@see JetspeedPrincipalLookupManager}
+	 * corresponding to the database platform specified in the OJB connection
+	 * repository. If the platform is not supported the default lookup manager
+	 * is used.
+	 * 
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public JetspeedPrincipalLookupManager getJetspeedPrincipalLookupManager() {
+		if (jppm == null) {
+			String platform = null;
+			ConnectionRepository cr = MetadataManager.getInstance().connectionRepository();
+			List<JdbcConnectionDescriptor> jcdList = cr.getAllDescriptor();
+			for (int i = 0; i < jcdList.size(); i++) {
+				if (platform == null) {
+					platform = jcdList.get(i).getDbms();
+				} else {
+					// if we have more than one descriptor, set platform null to
+					// use default behavior
+					if (!platform.equals(jcdList.get(i).getDbms())) {
+						if (log.isInfoEnabled()) {
+							log.info("Found more than one JdbcConnectionDescriptor. Not sure which one to take, so using compatible default behavior.");
+						}
+						platform = null;
+						break;
+					}
+				}
+			}
+			for (Map.Entry<String, JetspeedPrincipalLookupManager> e : mappings.entrySet()) {
+				if (e.getKey().equalsIgnoreCase(platform)) {
+					jppm = e.getValue();
+					break;
+				}
+			}
+			if (jppm == null) {
+				jppm = mappings.get("default");
+			}
+		}
+		return jppm;
+	}
+
+}

Added: portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/JetspeedPrincipalLookupManagerMySql.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/JetspeedPrincipalLookupManagerMySql.java?rev=925710&view=auto
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/JetspeedPrincipalLookupManagerMySql.java (added)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/JetspeedPrincipalLookupManagerMySql.java Sun Mar 21 01:12:50 2010
@@ -0,0 +1,64 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jetspeed.security.spi.impl;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.apache.jetspeed.security.JetspeedPrincipalQueryContext;
+
+/**
+ * MySql specific implementation of the principal lookup manager.
+ * 
+ * 
+ * @author <a href="mailto:joachim@wemove.com">Joachim Mueller</a>
+ * 
+ */
+public class JetspeedPrincipalLookupManagerMySql extends JetspeedPrincipalLookupManagerAbstract {
+
+	/**
+	 * Add limit operator if we are on MySql. This is much faster than
+	 * paging via JDBC and also is a work around because the MySQL driver
+	 * retrieves the complete result set. This would result in a very high
+	 * memory consumption with large result sets.
+	 * 
+	 * See http://dev.mysql.com/doc/refman/5.0/en/connector-j-reference-
+	 * implementation-notes.html -> Resultset
+	 * 
+	 * @see org.apache.jetspeed.security.spi.impl.JetspeedPrincipalLookupManagerAbstract#getPagingSql(java.lang.String, org.apache.jetspeed.security.JetspeedPrincipalQueryContext)
+	 */
+	@Override
+	protected String getPagingSql(String sql, JetspeedPrincipalQueryContext queryContext) {
+		return sql + " LIMIT " + queryContext.getOffset() + "," + queryContext.getLength();
+	}
+
+	/**
+	 * No scrolling has to be done because first result is already at the
+	 * offset (uses the LIMIT sql operator).
+	 * 
+	 * @see org.apache.jetspeed.security.spi.impl.JetspeedPrincipalLookupManagerAbstract#scrollToOffset(java.sql.Connection, java.sql.ResultSet, long)
+	 */
+	@Override
+	protected void scrollToOffset(Connection con, ResultSet rs, long offset) throws SQLException {
+		// no scrolling has to be done because first result is already at the
+		// offset (uses the LIMIT sql operator)
+		return;
+	}
+
+}

Modified: portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/JetspeedSecurityPersistenceManager.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/JetspeedSecurityPersistenceManager.java?rev=925710&r1=925709&r2=925710&view=diff
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/JetspeedSecurityPersistenceManager.java (original)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/JetspeedSecurityPersistenceManager.java Sun Mar 21 01:12:50 2010
@@ -30,6 +30,8 @@ import org.apache.jetspeed.i18n.KeyedMes
 import org.apache.jetspeed.security.JetspeedPermission;
 import org.apache.jetspeed.security.JetspeedPrincipal;
 import org.apache.jetspeed.security.JetspeedPrincipalAssociationReference;
+import org.apache.jetspeed.security.JetspeedPrincipalQueryContext;
+import org.apache.jetspeed.security.JetspeedPrincipalResultList;
 import org.apache.jetspeed.security.JetspeedPrincipalType;
 import org.apache.jetspeed.security.PasswordCredential;
 import org.apache.jetspeed.security.SecurityDomain;
@@ -43,6 +45,7 @@ import org.apache.jetspeed.security.spi.
 import org.apache.jetspeed.security.spi.JetspeedPermissionStorageManager;
 import org.apache.jetspeed.security.spi.JetspeedPrincipalAccessManager;
 import org.apache.jetspeed.security.spi.JetspeedPrincipalAssociationStorageManager;
+import org.apache.jetspeed.security.spi.JetspeedPrincipalLookupManager;
 import org.apache.jetspeed.security.spi.JetspeedPrincipalStorageManager;
 import org.apache.jetspeed.security.spi.PersistentJetspeedPermission;
 import org.apache.jetspeed.security.spi.SecurityDomainAccessManager;
@@ -58,6 +61,8 @@ import org.apache.ojb.broker.query.Query
 import org.apache.ojb.broker.query.QueryFactory;
 import org.apache.ojb.broker.query.ReportQueryByCriteria;
 import org.apache.ojb.broker.util.collections.ManageableArrayList;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.dao.DataIntegrityViolationException;
 import org.springframework.orm.ObjectRetrievalFailureException;
 import org.springframework.orm.ojb.PersistenceBrokerCallback;
@@ -74,8 +79,12 @@ public class JetspeedSecurityPersistence
 {
     private static final long serialVersionUID = -2689340557699526023L;
 	
+    static final Logger log = LoggerFactory.getLogger(JetspeedSecurityPersistenceManager.class);
+    
     private Long defaultSecurityDomainId;
     
+    private JetspeedPrincipalLookupManagerFactory jpplf = null;
+    
     private static class ManagedListByQueryCallback implements PersistenceBrokerCallback
     {
         private Query query;
@@ -91,9 +100,11 @@ public class JetspeedSecurityPersistence
         }
     }
     
-    public JetspeedSecurityPersistenceManager(String repositoryPath)
+	public JetspeedSecurityPersistenceManager(String repositoryPath, JetspeedPrincipalLookupManagerFactory lookupManagerFactory)
     {
         super(repositoryPath);
+        this.jpplf = lookupManagerFactory;
+        
     }
     
     @SuppressWarnings("unchecked")
@@ -1131,4 +1142,18 @@ public class JetspeedSecurityPersistence
         return (List<SecurityDomain>)getPersistenceBrokerTemplate().execute(new ManagedListByQueryCallback(query));
     }
     
+	public JetspeedPrincipalResultList getPrincipals(JetspeedPrincipalQueryContext queryContext, JetspeedPrincipalType type) {
+		return getPrincipals(queryContext, type, getDefaultSecurityDomainId());
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.apache.jetspeed.security.spi.JetspeedPrincipalAccessManager#getPrincipals(org.apache.jetspeed.security.JetspeedPrincipalQueryContext, org.apache.jetspeed.security.JetspeedPrincipalType, java.lang.Long)
+	 */
+	public JetspeedPrincipalResultList getPrincipals(JetspeedPrincipalQueryContext queryContext, JetspeedPrincipalType type, Long securityDomain) {
+		JetspeedPrincipalLookupManager jppm = jpplf.getJetspeedPrincipalLookupManager();
+		queryContext.put(JetspeedPrincipalQueryContext.JETSPEED_PRINCIPAL_TYPE, type.getName());
+		queryContext.put(JetspeedPrincipalQueryContext.SECURITY_DOMAIN, securityDomain);
+		return jppm.getPrincipals(queryContext);
+	}
+    
 }

Added: portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/test/java/org/apache/jetspeed/security/TestUserManagerExtLookupManager.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/test/java/org/apache/jetspeed/security/TestUserManagerExtLookupManager.java?rev=925710&view=auto
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/test/java/org/apache/jetspeed/security/TestUserManagerExtLookupManager.java (added)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/test/java/org/apache/jetspeed/security/TestUserManagerExtLookupManager.java Sun Mar 21 01:12:50 2010
@@ -0,0 +1,180 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jetspeed.security;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * <p>
+ * Unit testing for {@link UserManager} using the extended pageable API methods.
+ * </p>
+ * 
+ * @author <a href="mailto:joachim@wemove.com">Joachim Mueller</a>
+ */
+public class TestUserManagerExtLookupManager extends AbstractSecurityTestcase
+{
+    public static Test suite()
+    {
+        return new TestSuite(TestUserManagerExtLookupManager.class);
+    }
+    
+    public void testGetUsersExt() throws Exception 
+    {
+		int nUsers = 100;
+    	for (int i=0; i<nUsers; i++) {
+			User user = ums.addUser("anon"+i);
+        	if (i%10 == 0) {
+            	user.getSecurityAttributes().getAttribute("name", true).setStringValue("dude");
+            	user.getSecurityAttributes().getAttribute("fame", true).setStringValue("none");
+            	ums.updateUser(user);
+        	}
+        }
+        UserResultList ul = ums.getUsersExtended(new JetspeedPrincipalQueryContext(null, 0, 10));
+        assertEquals(10, ul.getResults().size());
+        assertEquals(true, ul.getTotalSize() >= nUsers);
+        // check empty string
+        ul = ums.getUsersExtended(new JetspeedPrincipalQueryContext("", 0, 10));
+        assertEquals(10, ul.getResults().size());
+        assertEquals(true, ul.getTotalSize() >= nUsers);
+        // test wildcard
+        ul = ums.getUsersExtended(new JetspeedPrincipalQueryContext("anon%", 0, 10));
+        assertEquals(10, ul.getResults().size());
+        assertEquals(nUsers, ul.getTotalSize());
+        // test wildcard, paging
+        ul = ums.getUsersExtended(new JetspeedPrincipalQueryContext("anon%", 50, 20));
+        assertEquals(20, ul.getResults().size());
+        assertEquals(nUsers, ul.getTotalSize());
+        // test requesting more results than available
+        ul = ums.getUsersExtended(new JetspeedPrincipalQueryContext("anon%", nUsers-5, 10));
+        assertEquals(5, ul.getResults().size());
+        assertEquals(nUsers, ul.getTotalSize());
+        // testing attribute selection
+        Map<String, String> attributeMap = new HashMap<String, String>() {
+            {
+                put("name", "dude");
+            }
+        };
+        JetspeedPrincipalQueryContext c = new JetspeedPrincipalQueryContext(null, 0, 10);
+        c.put(JetspeedPrincipalQueryContext.SECURITY_ATTRIBUTES, attributeMap);
+        ul = ums.getUsersExtended(c);
+        assertEquals(10, ul.getResults().size());
+        assertEquals(10, ul.getTotalSize());
+        // testing attribute selection, user name restriction
+        attributeMap = new HashMap<String, String>() {
+            {
+                put("name", "dude");
+            }
+        };
+        c = new JetspeedPrincipalQueryContext("anon0", 0, 10);
+        c.put(JetspeedPrincipalQueryContext.SECURITY_ATTRIBUTES, attributeMap);
+        ul = ums.getUsersExtended(c);
+        assertEquals(1, ul.getResults().size());
+        assertEquals(1, ul.getTotalSize());
+        // testing attribute selection with wildcard
+        attributeMap = new HashMap<String, String>() {
+            {
+                put("name", "du%");
+            }
+        };
+        c = new JetspeedPrincipalQueryContext(null, 0, 10);
+        c.put(JetspeedPrincipalQueryContext.SECURITY_ATTRIBUTES, attributeMap);
+        ul = ums.getUsersExtended(c);
+        assertEquals(10, ul.getResults().size());
+        assertEquals(10, ul.getTotalSize());        
+        // testing multiple attribute selection
+        attributeMap = new HashMap<String, String>() {
+            {
+                put("name", "du%");
+                put("fame", "none");
+            }
+        };
+        c = new JetspeedPrincipalQueryContext(null, 0, 10);
+        c.put(JetspeedPrincipalQueryContext.SECURITY_ATTRIBUTES, attributeMap);
+        ul = ums.getUsersExtended(c);
+        assertEquals(10, ul.getResults().size());
+        assertEquals(10, ul.getTotalSize());        
+        // testing non existing multiple attribute selection
+        attributeMap = new HashMap<String, String>() {
+            {
+                put("name", "du%");
+                put("fame", "wow");
+            }
+        };
+        c = new JetspeedPrincipalQueryContext(null, 0, 10);
+        c.put(JetspeedPrincipalQueryContext.SECURITY_ATTRIBUTES, attributeMap);
+        ul = ums.getUsersExtended(c);
+        assertEquals(0, ul.getResults().size());
+        assertEquals(0, ul.getTotalSize());        
+        
+        for (int i=0; i<nUsers; i++) {
+        	ums.removeUser("anon"+i);
+        }
+    }
+    
+    public void testGetUserByRoleExt() throws Exception {
+		int nUsers = 100;
+		rms.addRole("role");
+    	for (int i=0; i<nUsers; i++) {
+			User user = ums.addUser("anon"+i);
+			if (i%10 == 0) {
+	        	rms.addRoleToUser(user.getName(), "role");
+        	}
+        }
+        JetspeedPrincipalQueryContext c = new JetspeedPrincipalQueryContext("anon*", 0, 10);
+        List<String> roles = new ArrayList<String>();
+        roles.add("role");
+        c.put(JetspeedPrincipalQueryContext.ASSOCIATED_ROLES, roles);
+        UserResultList ul = ums.getUsersExtended(c);
+        assertEquals(10, ul.getResults().size());
+    	
+    	for (int i=0; i<nUsers; i++) {
+        	ums.removeUser("anon"+i);
+        }
+    	
+    	rms.removeRole("role");
+    }
+    
+    public void testGetUserByGroupExt() throws Exception {
+		int nUsers = 100;
+		gms.addGroup("group");
+    	for (int i=0; i<nUsers; i++) {
+			User user = ums.addUser("anon"+i);
+			if (i%10 == 0) {
+	        	gms.addUserToGroup(user.getName(), "group");
+        	}
+        }
+        JetspeedPrincipalQueryContext c = new JetspeedPrincipalQueryContext("anon*", 0, 10);
+        List<String> groups = new ArrayList<String>();
+        groups.add("group");
+        c.put(JetspeedPrincipalQueryContext.ASSOCIATED_GROUPS, groups);
+        UserResultList ul = ums.getUsersExtended(c);
+        assertEquals(10, ul.getResults().size());
+    	
+    	for (int i=0; i<nUsers; i++) {
+        	ums.removeUser("anon"+i);
+        }
+    	
+    	gms.removeGroup("group");
+    }    
+    
+}
\ No newline at end of file

Modified: portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/test/java/org/apache/jetspeed/security/stubs/StubGroupManager.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/test/java/org/apache/jetspeed/security/stubs/StubGroupManager.java?rev=925710&r1=925709&r2=925710&view=diff
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/test/java/org/apache/jetspeed/security/stubs/StubGroupManager.java (original)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/test/java/org/apache/jetspeed/security/stubs/StubGroupManager.java Sun Mar 21 01:12:50 2010
@@ -17,6 +17,8 @@
 package org.apache.jetspeed.security.stubs;
 
 import org.apache.jetspeed.security.JetspeedPrincipal;
+import org.apache.jetspeed.security.JetspeedPrincipalQueryContext;
+import org.apache.jetspeed.security.JetspeedPrincipalResultList;
 
 
 /**
@@ -33,5 +35,8 @@ public class StubGroupManager extends St
         return null;
     }
 
-    
+	public JetspeedPrincipalResultList getPrincipals(JetspeedPrincipalQueryContext queryContext) {
+		throw new RuntimeException("Not implemented here.");
+	}
+
 }

Modified: portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/test/java/org/apache/jetspeed/security/stubs/StubUserManager.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/test/java/org/apache/jetspeed/security/stubs/StubUserManager.java?rev=925710&r1=925709&r2=925710&view=diff
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/test/java/org/apache/jetspeed/security/stubs/StubUserManager.java (original)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/test/java/org/apache/jetspeed/security/stubs/StubUserManager.java Sun Mar 21 01:12:50 2010
@@ -17,6 +17,8 @@
 package org.apache.jetspeed.security.stubs;
 
 import org.apache.jetspeed.security.JetspeedPrincipal;
+import org.apache.jetspeed.security.JetspeedPrincipalQueryContext;
+import org.apache.jetspeed.security.JetspeedPrincipalResultList;
 import org.apache.jetspeed.security.User;
 import org.apache.jetspeed.security.impl.UserImpl;
 
@@ -38,5 +40,9 @@ public class StubUserManager extends Stu
     {
         return newUser(name, mapped);
     }
-    
+
+	public JetspeedPrincipalResultList getPrincipals(JetspeedPrincipalQueryContext queryContext) {
+		throw new RuntimeException("Not implemented here.");
+	}
+
 }

Modified: portals/jetspeed-2/portal/trunk/jetspeed-api/src/main/java/org/apache/jetspeed/security/JetspeedPrincipalManager.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/jetspeed-api/src/main/java/org/apache/jetspeed/security/JetspeedPrincipalManager.java?rev=925710&r1=925709&r2=925710&view=diff
==============================================================================
--- portals/jetspeed-2/portal/trunk/jetspeed-api/src/main/java/org/apache/jetspeed/security/JetspeedPrincipalManager.java (original)
+++ portals/jetspeed-2/portal/trunk/jetspeed-api/src/main/java/org/apache/jetspeed/security/JetspeedPrincipalManager.java Sun Mar 21 01:12:50 2010
@@ -55,6 +55,18 @@ public interface JetspeedPrincipalManage
      */
     List<? extends JetspeedPrincipal> getPrincipals(String nameFilter);
     
+    /**
+     * Retrieve all principals that match the queryContext.
+     * It returns a {@link JetspeedPrincipalResultList}, containing
+     * the actual result list an the total number of results from the query.
+     * 
+     * The returned principals are detached.
+     * 
+     * @param queryContext The (@see JetspeedPrincipalQueryContext) for this query.
+     * @return
+     */
+    public JetspeedPrincipalResultList getPrincipals(JetspeedPrincipalQueryContext queryContext);    
+    
     List<? extends JetspeedPrincipal> getPrincipalsByAttribute(String attributeName, String attributeValue);
     
     JetspeedPrincipal newPrincipal(String name, boolean mapped);

Added: portals/jetspeed-2/portal/trunk/jetspeed-api/src/main/java/org/apache/jetspeed/security/JetspeedPrincipalQueryContext.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/jetspeed-api/src/main/java/org/apache/jetspeed/security/JetspeedPrincipalQueryContext.java?rev=925710&view=auto
==============================================================================
--- portals/jetspeed-2/portal/trunk/jetspeed-api/src/main/java/org/apache/jetspeed/security/JetspeedPrincipalQueryContext.java (added)
+++ portals/jetspeed-2/portal/trunk/jetspeed-api/src/main/java/org/apache/jetspeed/security/JetspeedPrincipalQueryContext.java Sun Mar 21 01:12:50 2010
@@ -0,0 +1,164 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jetspeed.security;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Principal query context. Simple hash map with convenient methods to put and
+ * get casted types from the map.
+ * 
+ * 
+ * @author <a href="mailto:joachim@wemove.com">Joachim Mueller</a>
+ * 
+ */
+public class JetspeedPrincipalQueryContext extends HashMap<String, Object> {
+
+	/** The serial version uid. */
+	private static final long serialVersionUID = -7606523008399881258L;
+
+	public static final String NAME_FILTER = "nameFilter";
+
+	public static final String SECURITY_ATTRIBUTES = "securityAttributes";
+
+	public static final String ASSOCIATED_ROLES = "associatedRoles";
+
+	public static final String ASSOCIATED_GROUPS = "associatedGroups";
+
+	public static final String ASSOCIATED_USERS = "associatedUsers";
+
+	public static final String ORDER = "order";
+
+	public static final String OFFSET = "offset";
+
+	public static final String LENGTH = "length";
+
+	public static final String JETSPEED_PRINCIPAL_TYPE = "jetspeedPrincipalType";
+
+	public static final String SECURITY_DOMAIN = "securityDomain";
+
+	public JetspeedPrincipalQueryContext(String nameFilter, long offset, long length) {
+		put(NAME_FILTER, nameFilter);
+		put(OFFSET, Long.valueOf(offset));
+		put(LENGTH, Long.valueOf(length));
+	}
+
+	public JetspeedPrincipalQueryContext(String nameFilter, long offset, long length, String order, List<String> roles,
+			List<String> groups, List<String> users, Map<String, String> attributes) {
+		put(NAME_FILTER, nameFilter);
+		put(OFFSET, Long.valueOf(offset));
+		put(LENGTH, Long.valueOf(length));
+		put(ORDER, order);
+		put(ASSOCIATED_ROLES, roles);
+		put(ASSOCIATED_GROUPS, groups);
+		put(ASSOCIATED_USERS, users);
+		put(SECURITY_ATTRIBUTES, attributes);
+	}
+
+	/**
+	 * Return the filter for the principals name. The name can contain a
+	 * wildcard at the right end.
+	 * 
+	 * @return the nameFilter
+	 */
+	public String getNameFilter() {
+		return (String) this.get(NAME_FILTER);
+	}
+
+	/**
+	 * Returns all security attributes for the principal. All security
+	 * attributes MUST exist for the principal.
+	 * 
+	 * @return the securityAttributes
+	 */
+	@SuppressWarnings("unchecked")
+	public Map<String, String> getSecurityAttributes() {
+		return (Map<String, String>) this.get(SECURITY_ATTRIBUTES);
+	}
+
+	/**
+	 * Returns all roles the principal must be member of.
+	 * 
+	 * @return the associatedRoles
+	 */
+	@SuppressWarnings("unchecked")
+	public List<String> getAssociatedRoles() {
+		return (List<String>) this.get(ASSOCIATED_ROLES);
+	}
+
+	/**
+	 * Returns all groups the principal must be member of.
+	 * 
+	 * @return the associatedGroups
+	 */
+	@SuppressWarnings("unchecked")
+	public List<String> getAssociatedGroups() {
+		return (List<String>) this.get(ASSOCIATED_GROUPS);
+	}
+
+	/**
+	 * Returns all users the principal must contain.
+	 * 
+	 * @return the associatedUsers
+	 */
+	@SuppressWarnings("unchecked")
+	public List<String> getAssociatedUsers() {
+		return (List<String>) this.get(ASSOCIATED_USERS);
+	}
+
+	/**
+	 * Returns the sort order for the principals name. If it is 'desc' the
+	 * principals are sorted backwards according to their names, all other
+	 * values result in normal order.
+	 * 
+	 * @return the orderDesc
+	 */
+	public String getOrder() {
+		return (String) this.get(ORDER);
+	}
+
+	/**
+	 * @return the offset
+	 */
+	public Long getOffset() {
+		return (Long) this.get(OFFSET);
+	}
+
+	/**
+	 * @return the length
+	 */
+	public Long getLength() {
+		return (Long) this.get(LENGTH);
+	}
+
+	/**
+	 * @return the JetspeedPrincipalType name
+	 */
+	public String getJetspeedPrincipalType() {
+		return (String) this.get(JETSPEED_PRINCIPAL_TYPE);
+	}
+
+	/**
+	 * @return the security domain id
+	 */
+	public Long getSecurityDomain() {
+		return (Long) this.get(SECURITY_DOMAIN);
+	}
+
+}

Added: portals/jetspeed-2/portal/trunk/jetspeed-api/src/main/java/org/apache/jetspeed/security/JetspeedPrincipalResultList.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/jetspeed-api/src/main/java/org/apache/jetspeed/security/JetspeedPrincipalResultList.java?rev=925710&view=auto
==============================================================================
--- portals/jetspeed-2/portal/trunk/jetspeed-api/src/main/java/org/apache/jetspeed/security/JetspeedPrincipalResultList.java (added)
+++ portals/jetspeed-2/portal/trunk/jetspeed-api/src/main/java/org/apache/jetspeed/security/JetspeedPrincipalResultList.java Sun Mar 21 01:12:50 2010
@@ -0,0 +1,73 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jetspeed.security;
+
+import java.util.List;
+
+/**
+ * A container for principals that have been retrieved from storage with ranged
+ * queries. Additional to the principals itself it also contains the total size
+ * of the query result.
+ * 
+ * @author <a href="mailto:joachim@wemove.com">Joachim Mueller</a>
+ * 
+ */
+public class JetspeedPrincipalResultList {
+
+	private long totalSize = 0;
+
+	private List<? extends JetspeedPrincipal> results = null;
+
+	public JetspeedPrincipalResultList(List<? extends JetspeedPrincipal> results, long totalSize) {
+		this.results = results;
+		this.totalSize = totalSize;
+	}
+
+	/**
+	 * Creates a result list, <em>totalSize</em> will be set to the lists size.
+	 * 
+	 * @param results
+	 * @param firstResult
+	 */
+	public JetspeedPrincipalResultList(List<? extends JetspeedPrincipal> results) {
+		this.results = results;
+		this.totalSize = results.size();
+	}
+
+	/**
+	 * Get the total size of search results. This can be higher than the number
+	 * of returned principals.
+	 * 
+	 * @return
+	 */
+	public long getTotalSize() {
+		return totalSize;
+	}
+
+	public void setTotalSize(long totalSize) {
+		this.totalSize = totalSize;
+	}
+
+	/**
+	 * Get the principal results.
+	 * 
+	 * @return
+	 */
+	public List<? extends JetspeedPrincipal> getResults() {
+		return results;
+	}
+}

Modified: portals/jetspeed-2/portal/trunk/jetspeed-api/src/main/java/org/apache/jetspeed/security/UserManager.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/jetspeed-api/src/main/java/org/apache/jetspeed/security/UserManager.java?rev=925710&r1=925709&r2=925710&view=diff
==============================================================================
--- portals/jetspeed-2/portal/trunk/jetspeed-api/src/main/java/org/apache/jetspeed/security/UserManager.java (original)
+++ portals/jetspeed-2/portal/trunk/jetspeed-api/src/main/java/org/apache/jetspeed/security/UserManager.java Sun Mar 21 01:12:50 2010
@@ -17,6 +17,7 @@
 package org.apache.jetspeed.security;
 
 import java.util.List;
+import java.util.Map;
 
 import javax.security.auth.Subject;
 
@@ -143,6 +144,21 @@ public interface UserManager extends Pri
      */
     List<User> getUsers(String nameFilter) throws SecurityException;
 
+    
+    /**
+     * <p>
+     * Retrieves a detached and modifiable {@link User} list matching the corresponding
+     * query context. It returns a {@link UserResultList}, containing
+     * the actual result list an the total number of results from the query.
+     * 
+     * </p>
+     * 
+     * @param queryContext The (@see JetspeedPrincipalQueryContext) for this query.
+     * @return
+     * @throws SecurityException
+     */
+    UserResultList getUsersExtended(JetspeedPrincipalQueryContext queryContext) throws SecurityException;
+    
     /**
      * <p>
      * Retrieves a a detached and modifiable List user names, finding users matching the corresponding

Added: portals/jetspeed-2/portal/trunk/jetspeed-api/src/main/java/org/apache/jetspeed/security/UserResultList.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/jetspeed-api/src/main/java/org/apache/jetspeed/security/UserResultList.java?rev=925710&view=auto
==============================================================================
--- portals/jetspeed-2/portal/trunk/jetspeed-api/src/main/java/org/apache/jetspeed/security/UserResultList.java (added)
+++ portals/jetspeed-2/portal/trunk/jetspeed-api/src/main/java/org/apache/jetspeed/security/UserResultList.java Sun Mar 21 01:12:50 2010
@@ -0,0 +1,52 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jetspeed.security;
+
+import java.util.List;
+
+/**
+ * Wrapper for a {@link JetspeedPrincipalResultList}. Takes care of casting to a {@link User}
+ * typed result list.
+ * 
+ * 
+ * @author <a href="mailto:joachim@wemove.com">Joachim Mueller</a>
+ * 
+ */
+public class UserResultList extends JetspeedPrincipalResultList {
+
+	/**
+	 * Create a user result list from a JetspeedPrincipalResultList.
+	 * 
+	 * @param jprl
+	 */
+	public UserResultList(JetspeedPrincipalResultList jprl) {
+		super(jprl.getResults(), jprl.getTotalSize());
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.apache.jetspeed.security.JetspeedPrincipalResultList#getResults()
+	 */
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<User> getResults() {
+		return (List<User>) super.getResults();
+	}
+
+}

Modified: portals/jetspeed-2/portal/trunk/jetspeed-portal-resources/src/main/resources/assembly/security-spi.xml
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/jetspeed-portal-resources/src/main/resources/assembly/security-spi.xml?rev=925710&r1=925709&r2=925710&view=diff
==============================================================================
--- portals/jetspeed-2/portal/trunk/jetspeed-portal-resources/src/main/resources/assembly/security-spi.xml (original)
+++ portals/jetspeed-2/portal/trunk/jetspeed-portal-resources/src/main/resources/assembly/security-spi.xml Sun Mar 21 01:12:50 2010
@@ -21,12 +21,28 @@
   <!-- ************** Security SPI Handlers ************** -->
   <!-- Security SPI: CommonQueries -->
 
+  <bean id="org.apache.jetspeed.security.spi.impl.JetspeedPrincipalLookupManagerFactory" class="org.apache.jetspeed.security.spi.impl.JetspeedPrincipalLookupManagerFactory">
+    <meta key="j2:cat" value="default or security" />
+    <property name="mappings">
+     <map>
+       <entry key="default"><ref bean="org.apache.jetspeed.security.spi.impl.JetspeedPrincipalLookupManagerDefault"/></entry>
+       <entry key="mysql"><ref bean="org.apache.jetspeed.security.spi.impl.JetspeedPrincipalLookupManagerMySql"/></entry>
+     </map>
+   </property>
+  </bean>
+  
+  <bean id="org.apache.jetspeed.security.spi.impl.JetspeedPrincipalLookupManagerDefault" class="org.apache.jetspeed.security.spi.impl.JetspeedPrincipalLookupManagerDefault" />
+  <bean id="org.apache.jetspeed.security.spi.impl.JetspeedPrincipalLookupManagerMySql" class="org.apache.jetspeed.security.spi.impl.JetspeedPrincipalLookupManagerMySql" />
+
   <bean id="org.apache.jetspeed.security.spi.impl.JetspeedSecurityPersistenceManager"
     class="org.apache.jetspeed.security.spi.impl.JetspeedSecurityPersistenceManager" init-method="init">
     <meta key="j2:cat" value="default or security" />
     <constructor-arg index="0">
       <value>JETSPEED-INF/ojb/security_repository.xml</value>
     </constructor-arg>
+    <constructor-arg index="1">
+      <ref bean="org.apache.jetspeed.security.spi.impl.JetspeedPrincipalLookupManagerFactory"/>
+    </constructor-arg>
   </bean>
   
   <bean id="org.apache.jetspeed.security.spi.JetspeedSecurityPersistenceManager" parent="baseTransactionProxy">



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


Mime
View raw message