996 lines
32 KiB
Java
996 lines
32 KiB
Java
/*
|
|
* The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
* (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.mozilla.org/MPL/>.
|
|
*
|
|
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
|
|
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
|
|
* language governing rights and limitations under the License.
|
|
*
|
|
* The Original Code is the Venice Web Communities System.
|
|
*
|
|
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
|
|
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
|
|
* Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
*/
|
|
package com.silverwrist.dynamo.db;
|
|
|
|
import java.lang.ref.*;
|
|
import java.util.*;
|
|
import org.w3c.dom.*;
|
|
import com.silverwrist.util.xml.*;
|
|
import com.silverwrist.dynamo.UserInfoNamespace;
|
|
import com.silverwrist.dynamo.event.*;
|
|
import com.silverwrist.dynamo.except.*;
|
|
import com.silverwrist.dynamo.iface.*;
|
|
import com.silverwrist.dynamo.security.SecurityReferenceMonitor;
|
|
import com.silverwrist.dynamo.util.*;
|
|
|
|
public class UserManagerObject
|
|
implements NamedObject, ComponentInitialize, ComponentShutdown, UserManagement, UserProxyManagement,
|
|
AuthenticatorLookup, AuthenticatorRegistration, UserInfoNamespace, UserPropertyTranslatorInstall
|
|
{
|
|
/*--------------------------------------------------------------------------------
|
|
* Internal class implementing user proxies
|
|
*--------------------------------------------------------------------------------
|
|
*/
|
|
|
|
private class MyUserProxy extends UserProxy
|
|
{
|
|
/*====================================================================
|
|
* Attributes
|
|
*====================================================================
|
|
*/
|
|
|
|
private DynamoUser m_real_user = null;
|
|
|
|
/*====================================================================
|
|
* Constructors
|
|
*====================================================================
|
|
*/
|
|
|
|
MyUserProxy(int uid)
|
|
{
|
|
super(uid);
|
|
|
|
} // end constructor
|
|
|
|
MyUserProxy(int uid, String username)
|
|
{
|
|
super(uid,username);
|
|
|
|
} // end constructor
|
|
|
|
/*====================================================================
|
|
* Abstract implementations from class UserProxy
|
|
*====================================================================
|
|
*/
|
|
|
|
protected synchronized DynamoUser getRealUser()
|
|
{
|
|
if (m_real_user==null)
|
|
{ // need to retrieve the real user...
|
|
try
|
|
{ // get the real user...
|
|
m_real_user = UserManagerObject.this.getUser(m_uid);
|
|
|
|
} // end try
|
|
catch (DatabaseException e)
|
|
{ // wrap it in a runtime exception type
|
|
throw new ProxyException(e);
|
|
|
|
} // end catch
|
|
|
|
} // end if
|
|
|
|
return m_real_user;
|
|
|
|
} // end getRealUser
|
|
|
|
} // end class MyUserProxy
|
|
|
|
/*--------------------------------------------------------------------------------
|
|
* Internal class implementing group proxies
|
|
*--------------------------------------------------------------------------------
|
|
*/
|
|
|
|
private class MyGroupProxy extends GroupProxy
|
|
{
|
|
/*====================================================================
|
|
* Attributes
|
|
*====================================================================
|
|
*/
|
|
|
|
private DynamoGroup m_real_group = null;
|
|
|
|
/*====================================================================
|
|
* Constructors
|
|
*====================================================================
|
|
*/
|
|
|
|
MyGroupProxy(int gid)
|
|
{
|
|
super(gid);
|
|
|
|
} // end constructor
|
|
|
|
MyGroupProxy(int gid, String groupname)
|
|
{
|
|
super(gid,groupname);
|
|
|
|
} // end constructor
|
|
|
|
/*====================================================================
|
|
* Abstract implementations from class UserProxy
|
|
*====================================================================
|
|
*/
|
|
|
|
protected synchronized DynamoGroup getRealGroup()
|
|
{
|
|
if (m_real_group==null)
|
|
{ // need to retrieve the real group...
|
|
try
|
|
{ // get the real group...
|
|
m_real_group = UserManagerObject.this.getGroup(m_gid);
|
|
|
|
} // end try
|
|
catch (DatabaseException e)
|
|
{ // wrap it in a runtime exception type
|
|
throw new ProxyException(e);
|
|
|
|
} // end catch
|
|
|
|
} // end if
|
|
|
|
return m_real_group;
|
|
|
|
} // end getRealGroup
|
|
|
|
} // end class MyGroupProxy
|
|
|
|
/*--------------------------------------------------------------------------------
|
|
* Internal event listener class
|
|
*--------------------------------------------------------------------------------
|
|
*/
|
|
|
|
private class UpdateListener implements DynamicUpdateListener
|
|
{
|
|
/*====================================================================
|
|
* Constructor
|
|
*====================================================================
|
|
*/
|
|
|
|
UpdateListener()
|
|
{ // do nothing
|
|
} // end constructor
|
|
|
|
/*====================================================================
|
|
* Implementations from interface DynamicUpdateListener
|
|
*====================================================================
|
|
*/
|
|
|
|
public void updateReceived(DynamicUpdateEvent evt)
|
|
{
|
|
if (evt instanceof UserUpdateEvent)
|
|
{ // try to pass the event on to the user
|
|
int uid = ((UserUpdateEvent)evt).getUID();
|
|
Integer key = new Integer(uid);
|
|
synchronized (m_users_sync)
|
|
{ // try looking in the cache for a UserObject
|
|
IDNameCacheObject cobj = (IDNameCacheObject)(m_id_to_user.get(key));
|
|
if (cobj!=null)
|
|
{ // got a cache object - retrieve the user value
|
|
UserObject target = (UserObject)(cobj.get());
|
|
if (target==null)
|
|
{ // the UserObject got kicked out! kick it out of the HashMaps
|
|
m_id_to_user.remove(key);
|
|
m_name_to_user.remove(cobj.getNameKey());
|
|
cobj.clear();
|
|
cobj = null;
|
|
|
|
} // end if
|
|
else if (target!=evt.getSource())
|
|
target.updated((UserUpdateEvent)evt);
|
|
|
|
} // end if
|
|
|
|
} // end synchronized block
|
|
|
|
} // end if
|
|
|
|
} // end updateReceived
|
|
|
|
} // end class UpdateListener
|
|
|
|
/*--------------------------------------------------------------------------------
|
|
* Internal property serializer class
|
|
*--------------------------------------------------------------------------------
|
|
*/
|
|
|
|
private class UserGroupSerializer implements PropertySerializer
|
|
{
|
|
/*====================================================================
|
|
* Constructor
|
|
*====================================================================
|
|
*/
|
|
|
|
UserGroupSerializer()
|
|
{ // do nothing
|
|
} // end constructor
|
|
|
|
/*====================================================================
|
|
* Implementations from interface PropertySerializer
|
|
*====================================================================
|
|
*/
|
|
|
|
public String serializeProperty(Object value)
|
|
{
|
|
if (value instanceof DynamoUser)
|
|
return "User:" + String.valueOf(((DynamoUser)value).getUID());
|
|
|
|
if (value instanceof DynamoGroup)
|
|
return "Group:" + String.valueOf(((DynamoGroup)value).getGID());
|
|
|
|
return null;
|
|
|
|
} // end serializeProperty
|
|
|
|
public Object deserializeProperty(String value)
|
|
{
|
|
try
|
|
{ // look for our known prefixes
|
|
if (value.startsWith("User:"))
|
|
return getUserProxy(Integer.parseInt(value.substring(5)));
|
|
|
|
if (value.startsWith("Group:"))
|
|
return getGroupProxy(Integer.parseInt(value.substring(6)));
|
|
|
|
return null;
|
|
|
|
} // end try
|
|
catch (NumberFormatException e)
|
|
{ // number parse blew up...
|
|
return null;
|
|
|
|
} // end catch
|
|
|
|
} // end deserializeProperty
|
|
|
|
} // end UserGroupSerializer
|
|
|
|
/*--------------------------------------------------------------------------------
|
|
* Internal class implementing the adapter for UserPropertyTranslator
|
|
*--------------------------------------------------------------------------------
|
|
*/
|
|
|
|
class UserPropertyAdapter implements UserPropertyTranslator
|
|
{
|
|
/*====================================================================
|
|
* Attributes
|
|
*====================================================================
|
|
*/
|
|
|
|
private UserPropertyTranslator m_upt = null;
|
|
|
|
/*====================================================================
|
|
* Constructor
|
|
*====================================================================
|
|
*/
|
|
|
|
UserPropertyAdapter()
|
|
{ // do nothing
|
|
} // end constructor
|
|
|
|
/*====================================================================
|
|
* Implementations from interface UserPropertyTranslator
|
|
*====================================================================
|
|
*/
|
|
|
|
public String getUserFullName(DynamoUser user)
|
|
{
|
|
if (m_upt!=null)
|
|
return m_upt.getUserFullName(user);
|
|
else
|
|
return user.getName();
|
|
|
|
} // end getUserFullName
|
|
|
|
/*====================================================================
|
|
* External operations
|
|
*====================================================================
|
|
*/
|
|
|
|
void setTranslator(UserPropertyTranslator upt)
|
|
{
|
|
m_upt = upt;
|
|
|
|
} // end setTranslator
|
|
|
|
} // end class UserPropertyAdapter
|
|
|
|
/*--------------------------------------------------------------------------------
|
|
* Static data members
|
|
*--------------------------------------------------------------------------------
|
|
*/
|
|
|
|
private static final int MAX_USERNAME = 64;
|
|
private static final int MAX_GROUPNAME = 64;
|
|
|
|
/*--------------------------------------------------------------------------------
|
|
* Attributes
|
|
*--------------------------------------------------------------------------------
|
|
*/
|
|
|
|
private UserPropertyAdapter m_adapter; // user property adapter
|
|
private String m_name; // object name
|
|
private NamespaceCache m_ns_cache; // namespace cache object
|
|
private SecurityReferenceMonitor m_srm; // security reference monitor
|
|
private PostDynamicUpdate m_post; // dynamic update poster
|
|
private UserManagerOps m_ops; // database operations object
|
|
private UserObject m_anon_user = null; // permanent reference to anonymous user
|
|
private Object m_anon_user_sync = new Object(); // synchronization on the above field
|
|
private HashMap m_id_to_user = new HashMap(); // map from IDs (Integer) to objects
|
|
private HashMap m_name_to_user = new HashMap(); // map from names (DynamoIDKey) to objects
|
|
private ReferenceQueue m_rq = new ReferenceQueue(); // reference queue for old objects
|
|
private Object m_users_sync = new Object(); // synchronization for user HashMaps
|
|
private HashMap m_id_to_group = new HashMap(); // map from IDs (Integer) to groups
|
|
private HashMap m_name_to_group = new HashMap(); // map from names (DynamoIDKey) to groups
|
|
private ReferenceQueue m_group_rq = new ReferenceQueue(); // reference queue for group objects
|
|
private Object m_groups_sync = new Object(); // synchronization for group HashMaps
|
|
private Hashtable m_authenticators = new Hashtable(); // authenticators list
|
|
private ComponentShutdown m_hook_init; // hook for init service provider
|
|
private ComponentShutdown m_hook_rt; // hook for runtime service provider
|
|
private ComponentShutdown m_pszreg; // property serializer registration
|
|
private ComponentShutdown m_evt_user; // event registration
|
|
|
|
/*--------------------------------------------------------------------------------
|
|
* Constructor
|
|
*--------------------------------------------------------------------------------
|
|
*/
|
|
|
|
public UserManagerObject()
|
|
{
|
|
m_adapter = new UserPropertyAdapter(); // create the adapter
|
|
|
|
// Add some default authenticators.
|
|
m_authenticators.put(new QualifiedNameKey(NAMESPACE,AUTH_DEFAULT),new DefaultHashAuthenticator());
|
|
|
|
} // end constructor
|
|
|
|
/*--------------------------------------------------------------------------------
|
|
* Implementations from interface NamedObject
|
|
*--------------------------------------------------------------------------------
|
|
*/
|
|
|
|
public String getName()
|
|
{
|
|
return m_name;
|
|
|
|
} // end getName
|
|
|
|
/*--------------------------------------------------------------------------------
|
|
* Implementations from interface ComponentInitialize
|
|
*--------------------------------------------------------------------------------
|
|
*/
|
|
|
|
public void initialize(Element config_root, ServiceProvider services) throws ConfigException
|
|
{
|
|
String conn_name = null;
|
|
String nscache_name = null;
|
|
String srm_name = null;
|
|
String connect_name = null;
|
|
XMLLoader loader = XMLLoader.get();
|
|
try
|
|
{ // verify the right node name
|
|
loader.verifyNodeName(config_root,"object");
|
|
|
|
// get the object's name
|
|
m_name = loader.getAttribute(config_root,"name");
|
|
|
|
// get the database configuration connection
|
|
DOMElementHelper config_root_h = new DOMElementHelper(config_root);
|
|
Element elt = loader.getSubElement(config_root_h,"database");
|
|
conn_name = loader.getAttribute(elt,"connection");
|
|
nscache_name = loader.getAttribute(elt,"namespaces");
|
|
|
|
// get the security reference monitor reference
|
|
elt = loader.getSubElement(config_root_h,"security");
|
|
srm_name = loader.getAttribute(elt,"object");
|
|
|
|
// get the name of the connection point to connect ourselves to
|
|
elt = config_root_h.getSubElement("connect-proxy-services");
|
|
if (elt!=null)
|
|
connect_name = loader.getAttribute(elt,"cpoint");
|
|
|
|
} // end try
|
|
catch (XMLLoadException e)
|
|
{ // error loading XML config data
|
|
throw new ConfigException(e);
|
|
|
|
} // end catch
|
|
|
|
// Get the database connection pool, namespace cache, and security reference monitor.
|
|
DBConnectionPool pool = GetObjectUtils.getDatabaseConnection(services,conn_name);
|
|
m_ns_cache =
|
|
(NamespaceCache)(GetObjectUtils.getDynamoComponent(services,NamespaceCache.class,nscache_name));
|
|
m_srm =
|
|
(SecurityReferenceMonitor)(GetObjectUtils.getDynamoComponent(services,SecurityReferenceMonitor.class,
|
|
srm_name));
|
|
m_post = (PostDynamicUpdate)(services.queryService(PostDynamicUpdate.class));
|
|
|
|
// Get the operations object.
|
|
m_ops = UserManagerOps.get(pool);
|
|
|
|
// Connect our proxy services to the connection point.
|
|
if (connect_name!=null)
|
|
{ // get the ConnectionBackend service and use it to jack in
|
|
ConnectionBackEnd backend = (ConnectionBackEnd)(services.queryService(ConnectionBackEnd.class));
|
|
backend.connectObject(connect_name,this);
|
|
|
|
} // end if
|
|
|
|
// Register event listeners that forward events to the right location.
|
|
EventListenerRegistration reg =
|
|
(EventListenerRegistration)(services.queryService(EventListenerRegistration.class));
|
|
UpdateListener ul = new UpdateListener();
|
|
m_evt_user = reg.registerDynamicUpdateListener(UserUpdateEvent.class,ul);
|
|
|
|
// Register our property serializer to let User and Group objects be serialized.
|
|
PropertySerializerRegistration psreg =
|
|
(PropertySerializerRegistration)(services.queryService(PropertySerializerRegistration.class));
|
|
m_pszreg = psreg.registerPropertySerializer(new UserGroupSerializer());
|
|
|
|
// Add us to the initialization services.
|
|
HookServiceProviders hooker = (HookServiceProviders)(services.queryService(HookServiceProviders.class));
|
|
SimpleServiceProvider esp = new SimpleServiceProvider("UserManagerObject");
|
|
esp.addService(AuthenticatorRegistration.class,(AuthenticatorRegistration)this);
|
|
esp.addService(AuthenticatorLookup.class,(AuthenticatorLookup)this);
|
|
m_hook_init = hooker.hookInitServiceProvider(esp);
|
|
|
|
// Add us to the runtime services as well.
|
|
SingletonServiceProvider ssp = new SingletonServiceProvider("UserManagerObject",AuthenticatorLookup.class,
|
|
(AuthenticatorLookup)this);
|
|
m_hook_rt = hooker.hookRuntimeServiceProvider(ssp);
|
|
|
|
} // end initialize
|
|
|
|
/*--------------------------------------------------------------------------------
|
|
* Implementations from interface ComponentShutdown
|
|
*--------------------------------------------------------------------------------
|
|
*/
|
|
|
|
public void shutdown()
|
|
{
|
|
m_evt_user.shutdown();
|
|
m_evt_user = null;
|
|
m_pszreg.shutdown();
|
|
m_pszreg = null;
|
|
m_hook_rt.shutdown();
|
|
m_hook_rt = null;
|
|
m_hook_init.shutdown();
|
|
m_hook_init = null;
|
|
m_authenticators.clear();
|
|
m_id_to_user.clear();
|
|
m_name_to_user.clear();
|
|
m_anon_user = null;
|
|
m_ops.dispose();
|
|
m_ops = null;
|
|
m_post = null;
|
|
m_srm = null;
|
|
m_ns_cache = null;
|
|
|
|
} // end shutdown
|
|
|
|
/*--------------------------------------------------------------------------------
|
|
* Implementations from interface UserManagement
|
|
*--------------------------------------------------------------------------------
|
|
*/
|
|
|
|
public DynamoUser getAnonymousUser() throws DatabaseException
|
|
{
|
|
synchronized (m_anon_user_sync)
|
|
{ // get the anonymous user, if it doesn't already exist
|
|
if (m_anon_user==null)
|
|
{ // get the data for the anonymous user
|
|
Map data = m_ops.getAnonymousUserData();
|
|
if (data==null)
|
|
throw new DatabaseException(UserManagerObject.class,"UserMessages","anon.notFound");
|
|
m_anon_user = new UserObject(data,true,m_ops.getObjectOps(),m_ns_cache,m_srm,this,m_post,m_adapter);
|
|
|
|
} // end if
|
|
|
|
return m_anon_user;
|
|
|
|
} // end synchronized block
|
|
|
|
} // end getAnonymousUser
|
|
|
|
public DynamoUser getUser(int id) throws DatabaseException
|
|
{
|
|
DynamoUser rc = getAnonymousUser();
|
|
if (rc.getUID()==id)
|
|
return rc;
|
|
|
|
rc = null;
|
|
Integer key = new Integer(id);
|
|
synchronized (m_users_sync)
|
|
{ // try to retrieve the user
|
|
IDNameCacheObject cobj = (IDNameCacheObject)(m_id_to_user.get(key));
|
|
if (cobj!=null)
|
|
{ // got a cache object - retrieve the user value
|
|
rc = (DynamoUser)(cobj.get());
|
|
if (rc==null)
|
|
{ // the UserObject got kicked out! kick it out of the HashMaps
|
|
m_id_to_user.remove(key);
|
|
m_name_to_user.remove(cobj.getNameKey());
|
|
cobj.clear();
|
|
cobj = null;
|
|
|
|
} // end if
|
|
|
|
} // end if
|
|
|
|
if (rc==null)
|
|
{ // OK, we have to go to the database to find the user
|
|
Map data = m_ops.getUserData(id);
|
|
if (data!=null)
|
|
{ // create UserObject and add it to our cache maps
|
|
UserObject uobj = new UserObject(data,false,m_ops.getObjectOps(),m_ns_cache,m_srm,this,m_post,
|
|
m_adapter);
|
|
rc = uobj;
|
|
cobj = new IDNameCacheObject(key,uobj.getName(),uobj,m_rq);
|
|
m_id_to_user.put(cobj.getIDKey(),cobj);
|
|
m_name_to_user.put(cobj.getNameKey(),cobj);
|
|
|
|
} // end if
|
|
// else user does not exist - return null
|
|
|
|
} // end if
|
|
|
|
} // end synchronized block
|
|
|
|
return rc;
|
|
|
|
} // end getUser
|
|
|
|
public DynamoUser getUser(String username) throws DatabaseException
|
|
{
|
|
DynamoUser rc = getAnonymousUser();
|
|
if (rc.getName().equalsIgnoreCase(username))
|
|
return rc;
|
|
|
|
rc = null;
|
|
DynamoIDKey key = new DynamoIDKey(username);
|
|
synchronized (m_users_sync)
|
|
{ // try to retrieve the user
|
|
IDNameCacheObject cobj = (IDNameCacheObject)(m_name_to_user.get(key));
|
|
if (cobj!=null)
|
|
{ // got a cache object - retrieve the user value
|
|
rc = (DynamoUser)(cobj.get());
|
|
if (rc==null)
|
|
{ // the UserObject got kicked out! kick it out of the HashMaps
|
|
m_id_to_user.remove(cobj.getIDKey());
|
|
m_name_to_user.remove(key);
|
|
cobj.clear();
|
|
cobj = null;
|
|
|
|
} // end if
|
|
|
|
} // end if
|
|
|
|
if (rc==null)
|
|
{ // OK, we have to go to the database to find the user
|
|
Map data = m_ops.getUserData(username);
|
|
if (data!=null)
|
|
{ // create user object and add it to our cache maps
|
|
UserObject uobj = new UserObject(data,false,m_ops.getObjectOps(),m_ns_cache,m_srm,this,m_post,
|
|
m_adapter);
|
|
rc = uobj;
|
|
cobj = new IDNameCacheObject(uobj.getUID(),key,uobj,m_rq);
|
|
m_id_to_user.put(cobj.getIDKey(),cobj);
|
|
m_name_to_user.put(cobj.getNameKey(),cobj);
|
|
|
|
} // end if
|
|
// else user does not exist - return null
|
|
|
|
} // end if
|
|
|
|
} // end synchronized block
|
|
|
|
return rc;
|
|
|
|
} // end getUser
|
|
|
|
public DynamoUser createUser(String username, String email) throws DatabaseException
|
|
{
|
|
DynamoUser rc = getAnonymousUser();
|
|
if (rc.getName().equalsIgnoreCase(username))
|
|
{ // this user already exists
|
|
DatabaseException de = new DatabaseException(UserManagerObject.class,"UserMessages","user.exists");
|
|
de.setParameter(0,username);
|
|
throw de;
|
|
|
|
} // end if
|
|
|
|
DynamoIDKey key = new DynamoIDKey(username);
|
|
if (!(key.isValid(MAX_USERNAME)))
|
|
{ // the user ID is invalid...
|
|
DatabaseException de = new DatabaseException(UserManagerObject.class,"UserMessages","user.badID");
|
|
de.setParameter(0,username);
|
|
throw de;
|
|
|
|
} // end if
|
|
|
|
rc = null;
|
|
synchronized (m_users_sync)
|
|
{ // see if the user is in our cache already
|
|
IDNameCacheObject cobj = (IDNameCacheObject)(m_name_to_user.get(key));
|
|
if (cobj!=null)
|
|
{ // it's in the cache - we're going to fail this operation. But while we're here, if the
|
|
// actual user object has been kicked out, expunge the reference.
|
|
if (cobj.get()==null)
|
|
{ // the UserObject got kicked out! kick it out of the HashMaps
|
|
m_id_to_user.remove(cobj.getIDKey());
|
|
m_name_to_user.remove(key);
|
|
cobj.clear();
|
|
cobj = null;
|
|
|
|
} // end if
|
|
|
|
// throw the exception saying that we exist
|
|
DatabaseException de = new DatabaseException(UserManagerObject.class,"UserMessages","user.exists");
|
|
de.setParameter(0,username);
|
|
throw de;
|
|
|
|
} // end if
|
|
|
|
// OK, at this point, we can't be any surer the user doesn't already exist without
|
|
// hitting the database. So create it. (createNewUser will throw a DatabaseException if the
|
|
// user already exists.)
|
|
Map data = m_ops.createNewUser(username,email);
|
|
UserObject uobj = new UserObject(data,false,m_ops.getObjectOps(),m_ns_cache,m_srm,this,m_post,m_adapter);
|
|
rc = uobj;
|
|
cobj = new IDNameCacheObject(uobj.getUID(),key,uobj,m_rq);
|
|
m_id_to_user.put(cobj.getIDKey(),cobj);
|
|
m_name_to_user.put(cobj.getNameKey(),cobj);
|
|
|
|
} // end synchronized block
|
|
|
|
return rc; // new user created!
|
|
|
|
} // end createUser
|
|
|
|
public DynamoGroup getGroup(int id) throws DatabaseException
|
|
{
|
|
DynamoGroup rc = null;
|
|
Integer key = new Integer(id);
|
|
synchronized (m_groups_sync)
|
|
{ // try to retrieve the group
|
|
IDNameCacheObject cobj = (IDNameCacheObject)(m_id_to_group.get(key));
|
|
if (cobj!=null)
|
|
{ // got a cache object - retrieve the group value
|
|
rc = (DynamoGroup)(cobj.get());
|
|
if (rc==null)
|
|
{ // the GroupObject got kicked out! kick it out of the HashMaps
|
|
m_id_to_group.remove(key);
|
|
m_name_to_group.remove(cobj.getNameKey());
|
|
cobj.clear();
|
|
cobj = null;
|
|
|
|
} // end if
|
|
|
|
} // end if
|
|
|
|
if (rc==null)
|
|
{ // OK, we have to go to the database to find the group
|
|
Map data = m_ops.getGroupData(id);
|
|
if (data!=null)
|
|
{ // create GroupObject and add it to our cache maps
|
|
GroupObject gobj = new GroupObject(data,m_ops.getGroupOps(),m_ns_cache,m_srm,this);
|
|
rc = gobj;
|
|
cobj = new IDNameCacheObject(key,gobj.getName(),gobj,m_group_rq);
|
|
m_id_to_group.put(cobj.getIDKey(),cobj);
|
|
m_name_to_group.put(cobj.getNameKey(),cobj);
|
|
|
|
} // end if
|
|
// else group does not exist - return null
|
|
|
|
} // end if
|
|
|
|
} // end synchronized block
|
|
|
|
return rc;
|
|
|
|
} // end getGroup
|
|
|
|
public DynamoGroup getGroup(String groupname) throws DatabaseException
|
|
{
|
|
DynamoGroup rc = null;
|
|
DynamoIDKey key = new DynamoIDKey(groupname);
|
|
synchronized (m_groups_sync)
|
|
{ // try to retrieve the group
|
|
IDNameCacheObject cobj = (IDNameCacheObject)(m_name_to_group.get(key));
|
|
if (cobj!=null)
|
|
{ // got a cache object - retrieve the group value
|
|
rc = (DynamoGroup)(cobj.get());
|
|
if (rc==null)
|
|
{ // the GroupObject got kicked out! kick it out of the HashMaps
|
|
m_id_to_group.remove(cobj.getIDKey());
|
|
m_name_to_group.remove(key);
|
|
cobj.clear();
|
|
cobj = null;
|
|
|
|
} // end if
|
|
|
|
} // end if
|
|
|
|
if (rc==null)
|
|
{ // OK, we have to go to the database to find the group
|
|
Map data = m_ops.getGroupData(groupname);
|
|
if (data!=null)
|
|
{ // create group object and add it to our cache maps
|
|
GroupObject gobj = new GroupObject(data,m_ops.getGroupOps(),m_ns_cache,m_srm,this);
|
|
rc = gobj;
|
|
cobj = new IDNameCacheObject(gobj.getGID(),key,gobj,m_group_rq);
|
|
m_id_to_group.put(cobj.getIDKey(),cobj);
|
|
m_name_to_group.put(cobj.getNameKey(),cobj);
|
|
|
|
} // end if
|
|
// else group does not exist - return null
|
|
|
|
} // end if
|
|
|
|
} // end synchronized block
|
|
|
|
return rc;
|
|
|
|
} // end getGroup
|
|
|
|
public DynamoGroup createGroup(String groupname) throws DatabaseException
|
|
{
|
|
DynamoIDKey key = new DynamoIDKey(groupname);
|
|
if (!(key.isValid(MAX_GROUPNAME)))
|
|
{ // the group ID is invalid...
|
|
DatabaseException de = new DatabaseException(UserManagerObject.class,"UserMessages","group.badID");
|
|
de.setParameter(0,groupname);
|
|
throw de;
|
|
|
|
} // end if
|
|
|
|
DynamoGroup rc = null;
|
|
synchronized (m_groups_sync)
|
|
{ // see if the group is in our cache already
|
|
IDNameCacheObject cobj = (IDNameCacheObject)(m_name_to_group.get(key));
|
|
if (cobj!=null)
|
|
{ // it's in the cache - we're going to fail this operation. But while we're here, if the
|
|
// actual group object has been kicked out, expunge the reference.
|
|
if (cobj.get()==null)
|
|
{ // the GroupObject got kicked out! kick it out of the HashMaps
|
|
m_id_to_group.remove(cobj.getIDKey());
|
|
m_name_to_group.remove(key);
|
|
cobj.clear();
|
|
cobj = null;
|
|
|
|
} // end if
|
|
|
|
// throw the exception saying that we exist
|
|
DatabaseException de = new DatabaseException(UserManagerObject.class,"UserMessages","group.exists");
|
|
de.setParameter(0,groupname);
|
|
throw de;
|
|
|
|
} // end if
|
|
|
|
// OK, at this point, we can't be any surer the group doesn't already exist without
|
|
// hitting the database. So create it. (createNewGroup will throw a DatabaseException if the
|
|
// group already exists.)
|
|
Map data = m_ops.createNewGroup(groupname);
|
|
GroupObject gobj = new GroupObject(data,m_ops.getGroupOps(),m_ns_cache,m_srm,this);
|
|
rc = gobj;
|
|
cobj = new IDNameCacheObject(gobj.getGID(),key,gobj,m_group_rq);
|
|
m_id_to_group.put(cobj.getIDKey(),cobj);
|
|
m_name_to_group.put(cobj.getNameKey(),cobj);
|
|
|
|
} // end synchronized block
|
|
|
|
return rc; // new group created!
|
|
|
|
} // end createNewGroup
|
|
|
|
public void loadUserDefaults(DynamoUser user, Collection namespaces) throws DatabaseException
|
|
{
|
|
// Start by translating all the namespaces to namespace IDs.
|
|
int[] nsids = new int[namespaces.size()];
|
|
int i = 0;
|
|
Iterator it = namespaces.iterator();
|
|
while (it.hasNext())
|
|
nsids[i++] = m_ns_cache.namespaceNameToId(it.next().toString());
|
|
|
|
// Now feed it into the database operations.
|
|
m_ops.loadUserDefaults(user.getUID(),nsids);
|
|
|
|
} // end loadUserDefaults
|
|
|
|
/*--------------------------------------------------------------------------------
|
|
* Implementations from interface UserProxyManagement
|
|
*--------------------------------------------------------------------------------
|
|
*/
|
|
|
|
public DynamoUser getUserProxy(int uid)
|
|
{
|
|
synchronized (m_anon_user_sync)
|
|
{ // get the anonymous user, if it's there and matches
|
|
if ((m_anon_user!=null) && (m_anon_user.getUID()==uid))
|
|
return m_anon_user;
|
|
|
|
} // end synchronized block
|
|
|
|
Integer key = new Integer(uid);
|
|
synchronized (m_users_sync)
|
|
{ // try to retrieve the user
|
|
IDNameCacheObject cobj = (IDNameCacheObject)(m_id_to_user.get(key));
|
|
if (cobj!=null)
|
|
{ // got a cache object - retrieve the user value
|
|
DynamoUser rc = (DynamoUser)(cobj.get());
|
|
if (rc==null)
|
|
{ // the UserObject got kicked out! kick it out of the HashMaps
|
|
m_id_to_user.remove(key);
|
|
m_name_to_user.remove(cobj.getNameKey());
|
|
rc = new MyUserProxy(uid,cobj.getNameKey().toString());
|
|
cobj.clear();
|
|
cobj = null;
|
|
|
|
} // end if
|
|
|
|
return rc;
|
|
|
|
} // end if
|
|
|
|
return new MyUserProxy(uid); // just return a proxy object
|
|
|
|
} // end synchronized block
|
|
|
|
} // end getUserProxy
|
|
|
|
public DynamoUser getUserProxy(int uid, String username)
|
|
{
|
|
synchronized (m_anon_user_sync)
|
|
{ // get the anonymous user, if it's there and matches
|
|
if ((m_anon_user!=null) && (m_anon_user.getUID()==uid))
|
|
return m_anon_user;
|
|
|
|
} // end synchronized block
|
|
|
|
Integer key = new Integer(uid);
|
|
synchronized (m_users_sync)
|
|
{ // try to retrieve the user
|
|
IDNameCacheObject cobj = (IDNameCacheObject)(m_id_to_user.get(key));
|
|
if (cobj!=null)
|
|
{ // got a cache object - retrieve the user value
|
|
DynamoUser rc = (DynamoUser)(cobj.get());
|
|
if (rc==null)
|
|
{ // the UserObject got kicked out! kick it out of the HashMaps
|
|
m_id_to_user.remove(key);
|
|
m_name_to_user.remove(cobj.getNameKey());
|
|
rc = new MyUserProxy(uid,cobj.getNameKey().toString());
|
|
cobj.clear();
|
|
cobj = null;
|
|
|
|
} // end if
|
|
|
|
return rc;
|
|
|
|
} // end if
|
|
|
|
return new MyUserProxy(uid,username); // just return a proxy object
|
|
|
|
} // end synchronized block
|
|
|
|
} // end getUserProxy
|
|
|
|
public DynamoGroup getGroupProxy(int gid)
|
|
{
|
|
Integer key = new Integer(gid);
|
|
synchronized (m_groups_sync)
|
|
{ // try to retrieve the group
|
|
IDNameCacheObject cobj = (IDNameCacheObject)(m_id_to_group.get(key));
|
|
if (cobj!=null)
|
|
{ // got a cache object - retrieve the group value
|
|
DynamoGroup rc = (DynamoGroup)(cobj.get());
|
|
if (rc==null)
|
|
{ // the GroupObject got kicked out! kick it out of the HashMaps
|
|
m_id_to_group.remove(key);
|
|
m_name_to_group.remove(cobj.getNameKey());
|
|
rc = new MyGroupProxy(gid,cobj.getNameKey().toString());
|
|
cobj.clear();
|
|
cobj = null;
|
|
|
|
} // end if
|
|
|
|
return rc;
|
|
|
|
} // end if
|
|
|
|
return new MyGroupProxy(gid); // just return a proxy object
|
|
|
|
} // end synchronized block
|
|
|
|
} // end getGroupProxy
|
|
|
|
public DynamoGroup getGroupProxy(int gid, String groupname)
|
|
{
|
|
Integer key = new Integer(gid);
|
|
synchronized (m_groups_sync)
|
|
{ // try to retrieve the group
|
|
IDNameCacheObject cobj = (IDNameCacheObject)(m_id_to_group.get(key));
|
|
if (cobj!=null)
|
|
{ // got a cache object - retrieve the group value
|
|
DynamoGroup rc = (DynamoGroup)(cobj.get());
|
|
if (rc==null)
|
|
{ // the GroupObject got kicked out! kick it out of the HashMaps
|
|
m_id_to_group.remove(key);
|
|
m_name_to_group.remove(cobj.getNameKey());
|
|
rc = new MyGroupProxy(gid,cobj.getNameKey().toString());
|
|
cobj.clear();
|
|
cobj = null;
|
|
|
|
} // end if
|
|
|
|
return rc;
|
|
|
|
} // end if
|
|
|
|
return new MyGroupProxy(gid,groupname); // just return a proxy object
|
|
|
|
} // end synchronized block
|
|
|
|
} // end getGroupProxy
|
|
|
|
/*--------------------------------------------------------------------------------
|
|
* Implementations from interface AuthenticatorLookup
|
|
*--------------------------------------------------------------------------------
|
|
*/
|
|
|
|
public Authenticator findAuthenticator(String method_namespace, String method)
|
|
{
|
|
return (Authenticator)(m_authenticators.get(new QualifiedNameKey(method_namespace,method)));
|
|
|
|
} // end findAuthenticator
|
|
|
|
/*--------------------------------------------------------------------------------
|
|
* Implementations from interface AuthenticatorRegistration
|
|
*--------------------------------------------------------------------------------
|
|
*/
|
|
|
|
public ComponentShutdown registerAuthenticator(String method_namespace, String method, Authenticator auth)
|
|
throws ConfigException
|
|
{
|
|
QualifiedNameKey key = new QualifiedNameKey(method_namespace,method);
|
|
if (m_authenticators.containsKey(key))
|
|
{ // dump out here
|
|
ConfigException ce = new ConfigException(UserManagerObject.class,"DatabaseMessages","auth.register");
|
|
ce.setParameter(0,method_namespace);
|
|
ce.setParameter(1,method);
|
|
throw ce;
|
|
|
|
} // end if
|
|
|
|
m_authenticators.put(key,auth);
|
|
return new ShutdownHashtableRemove(m_authenticators,key);
|
|
|
|
} // end registerAuthenticator
|
|
|
|
/*--------------------------------------------------------------------------------
|
|
* Implementations from interface UserPropertyTranslatorInstall
|
|
*--------------------------------------------------------------------------------
|
|
*/
|
|
|
|
public void installUserPropertyTranslator(UserPropertyTranslator upt)
|
|
{
|
|
m_adapter.setTranslator(upt);
|
|
|
|
} // end installUserPropertyTranslator
|
|
|
|
} // end class UserManagerObject
|