/* * 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