/*
* 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 .
*
* 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 ,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.venice.community;
import java.util.*;
import org.apache.commons.collections.*;
import org.apache.log4j.Logger;
import org.w3c.dom.*;
import com.silverwrist.util.*;
import com.silverwrist.util.xml.*;
import com.silverwrist.dynamo.db.NamespaceCache;
import com.silverwrist.dynamo.db.UserManagement;
import com.silverwrist.dynamo.except.*;
import com.silverwrist.dynamo.iface.*;
import com.silverwrist.dynamo.module.ModuleOperations;
import com.silverwrist.dynamo.security.SecurityReferenceMonitor;
import com.silverwrist.dynamo.util.*;
import com.silverwrist.venice.CommunitySearchField;
import com.silverwrist.venice.SearchMode;
import com.silverwrist.venice.VeniceNamespaces;
import com.silverwrist.venice.except.*;
import com.silverwrist.venice.iface.*;
public class CommunityManager
implements NamedObject, ComponentInitialize, ComponentShutdown, CommunityService, CommunityProxyService
{
/*--------------------------------------------------------------------------------
* Internal class implementing community proxies
*--------------------------------------------------------------------------------
*/
private class MyCommunityProxy extends CommunityProxy
{
/*====================================================================
* Attributes
*====================================================================
*/
private VeniceCommunity m_real_community = null;
/*====================================================================
* Constructors
*====================================================================
*/
MyCommunityProxy(int cid)
{
super(cid);
} // end constructor
/*====================================================================
* Abstract implementations from class CommunityProxy
*====================================================================
*/
protected synchronized VeniceCommunity getRealCommunity()
{
if (m_real_community==null)
{ // need to retrieve the real community...
try
{ // get the real community...
m_real_community = CommunityManager.this.getCommunity(m_id);
} // end try
catch (DatabaseException e)
{ // wrap it in a runtime exception type
throw new ProxyException(e);
} // end catch
} // end if
return m_real_community;
} // end getRealCommunity
} // end class MyCommunityProxy
/*--------------------------------------------------------------------------------
* Internal property serializer class
*--------------------------------------------------------------------------------
*/
private class CommunitySerializer implements PropertySerializer
{
/*====================================================================
* Constructor
*====================================================================
*/
CommunitySerializer()
{ // do nothing
} // end constructor
/*====================================================================
* Implementations from interface PropertySerializer
*====================================================================
*/
public String serializeProperty(Object value)
{
if (value instanceof VeniceCommunity)
return "Community:" + String.valueOf(((VeniceCommunity)value).getCID());
return null;
} // end serializeProperty
public Object deserializeProperty(String value)
{
try
{ // look for our known prefixes
if (value.startsWith("Community:"))
return getCommunityProxy(Integer.parseInt(value.substring(10)));
return null;
} // end try
catch (NumberFormatException e)
{ // number parse blew up...
return null;
} // end catch
} // end deserializeProperty
} // end class CommunitySerializer
/*--------------------------------------------------------------------------------
* Internal class that initializes the services
*--------------------------------------------------------------------------------
*/
private class ServiceInit implements FinalStageInitHook
{
/*====================================================================
* Constructor
*====================================================================
*/
ServiceInit()
{ // do nothing
} // end constructor
/*====================================================================
* Implementations from interface FinalStageInitHook
*====================================================================
*/
public void initialize(Application application, ServiceProvider services) throws DynamoException
{
logger.info("Initializing community service list");
List svclist = m_ops.getMasterServiceList();
ModuleOperations module_ops = (ModuleOperations)(services.queryService(ModuleOperations.class));
Iterator it = svclist.iterator();
while (it.hasNext())
{ // get the Map full of data
Map item = (Map)(it.next());
// make sure we have the module
PropertyKey pk = (PropertyKey)(item.get(CommunityManagerOps.KEY_MODNAME));
Module module = module_ops.findModule(m_ns_cache.namespaceIdToName(pk.getNamespaceID()),pk.getName());
if (module==null)
{ // the module is not loaded - we have to load it
String filename = (String)(item.get(CommunityManagerOps.KEY_MODFILENAME));
module = module_ops.loadModule(filename,true);
QualifiedNameKey modid = module.getModuleID();
PropertyKey pk2 = new PropertyKey(m_ns_cache.namespaceNameToId(modid.getNamespace()),modid.getName());
if (!(pk.equals(pk2)))
{ // module name does not match what we expect - throw exception
CommunityServiceException cse = new CommunityServiceException(CommunityManager.class,"CommunityMessages",
"svc.modname.mismatch");
cse.setParameter(0,filename);
throw cse;
} // end if
} // end if
// now get the CommunityServiceController from the module
pk = (PropertyKey)(item.get(CommunityManagerOps.KEY_OBJNAME));
DynamicObject dobj = module.getProvidedObject(m_ns_cache.namespaceIdToName(pk.getNamespaceID()),pk.getName());
if (!(dobj instanceof CommunityServiceController))
{ // invalid controller object - throw exception
CommunityServiceException cse = new CommunityServiceException(CommunityManager.class,"CommunityMessages",
"svc.object.badType");
cse.setParameter(0,m_ns_cache.namespaceIdToName(pk.getNamespaceID()));
cse.setParameter(1,pk.getName());
throw cse;
} // end if
CommunityServiceController csc = (CommunityServiceController)dobj;
// preserve the descriptors
pk = (PropertyKey)(item.get(CommunityManagerOps.KEY_SVCNAME));
CommunityServiceDescriptor csdesc =
new CommunityServiceDescriptor((Integer)(item.get(CommunityManagerOps.KEY_SVCID)),
new QualifiedNameKey(m_ns_cache.namespaceIdToName(pk.getNamespaceID()),
pk.getName()),
(String)(item.get(CommunityManagerOps.KEY_SHORTVAR)),csc);
m_qname_to_service.put(csdesc.getName(),csdesc);
m_index_to_service.put(item.get(CommunityManagerOps.KEY_SVCID),csdesc);
} // end while
// Now register our ServiceShutdown class as a pre-stage shutdown hook.
FinalStageRegistration fsreg = (FinalStageRegistration)(services.queryService(FinalStageRegistration.class));
fsreg.registerPreStageShutdown(new ServiceShutdown());
} // end initialize
} // end class ServiceInit
/*--------------------------------------------------------------------------------
* Internal class that shuts down the services
*--------------------------------------------------------------------------------
*/
private class ServiceShutdown implements ComponentShutdown
{
/*====================================================================
* Constructor
*====================================================================
*/
ServiceShutdown()
{ // do nothing
} // end constructor
/*====================================================================
* Implementations from interface ComponentShutdown
*====================================================================
*/
public void shutdown()
{
LinkedList shut_list = new LinkedList(m_qname_to_service.values());
m_qname_to_service.clear();
m_index_to_service.clear();
while (shut_list.size()>0)
{ // shut down this community service
CommunityServiceController csc = ((CommunityServiceDescriptor)(shut_list.removeFirst())).getController();
csc.shutdown();
} // end while
} // end shutdown
} // end class ServiceShutdown
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
*/
private static Logger logger = Logger.getLogger(CommunityManager.class);
/*--------------------------------------------------------------------------------
* Attributes
*--------------------------------------------------------------------------------
*/
private String m_name; // this object's name
private CommunityManagerOps m_ops; // database operations object
private NamespaceCache m_ns_cache; // namespace cache object
private SecurityReferenceMonitor m_srm; // security reference monitor
private UserManagement m_users; // user management object
private AuthenticatorLookup m_alook; // authenticator lookup
private PostDynamicUpdate m_post; // where we post dynamic updates
private CategoryService m_cats; // category service object
private ReferenceMap m_id_to_comm; // ReferenceMap of community IDs to communities
private ReferenceMap m_alias_to_comm; // ReferenceMap of community aliases to communities
private Hashtable m_qname_to_service; // maps service QualifiedNameKeys to descriptord
private Hashtable m_index_to_service; // maps service index numbers to descriptors
private ComponentShutdown m_pszreg; // property serializer registration
/*--------------------------------------------------------------------------------
* Constructor
*--------------------------------------------------------------------------------
*/
public CommunityManager()
{
m_id_to_comm = new ReferenceMap(ReferenceMap.HARD,ReferenceMap.SOFT);
m_alias_to_comm = new ReferenceMap(ReferenceMap.HARD,ReferenceMap.SOFT);
m_qname_to_service = new Hashtable();
m_index_to_service = new Hashtable();
} // end constructor
/*--------------------------------------------------------------------------------
* Internal operations
*--------------------------------------------------------------------------------
*/
private final List translateCIDArray(int[] array) throws DatabaseException
{
if (logger.isDebugEnabled())
logger.debug("translateCIDArray(): translating array of length " + array.length);
if (array.length==0)
return Collections.EMPTY_LIST;
ArrayList rc = new ArrayList(array.length);
for (int i=0; i