FileDocCategorySizeDatePackage
AdminEventCache.javaAPI DocGlassfish v2 API68132Fri May 04 22:33:34 BST 2007com.sun.enterprise.admin.event

AdminEventCache

public class AdminEventCache extends Object
AdminEventCache is used to cache events during "Apply". It also is the single point where ConfigChange objects are associated to the events. This class has evolved from being a cache that tracked events between "Apply" boundaries to its current form, so a lot of methods have been deprecated.

User interface allows several changes to configuration to be sent to the instance by one operation -- Apply. The cache is used to store events generated by processing configuration changes obtained from ConfigContext. The apply operation then sends all events one after another to the administered instance.

A typical sequence of calls will be -- where name is a String representing name of the server instance and context is an instance of type com.sun.enterprise.config.ConfigContext applicable to the server instance.

AdminEventCache eventCache = AdminEventCache.getInstance(name);
ArrayList changeList = context.getConfigChangeList();
context.resetConfigChangeList();
eventCache.processConfigChangeList(changeList);
ArrayList eventList = eventCache.getAndResetCachedEvents();
Iterator iter = eventList.iterator();
while (iter.hasNext()) {
AdminEvent event = (AdminEvent)iter.next();
AdminEventResult result = AdminEventMulticaster.multicastEvent(event);
if (result.getResultCode() != AdminEventResult.SUCCESS) {
// Handle error
}
}

The method processConfigChangeList now handles all events, including those related to deployment of applications and modules. If Deployment action is accompanied with a implicit apply then it should be handled by the method populateConfigChange.

Fields Summary
static Logger
logger
A reference to logger object
private static final transient HashMap
instanceCacheMap
A map of instance and its cache
private String
instanceName
Name of the server instance. The event cache is for this instance.
private ArrayList
cache
Event cache. The cache is used to keep events during "Apply" processing
private boolean
restartNeeded
Is restart needed.
private long
tsRestartNeededSince
Timestamp restart is needed since.
private com.sun.enterprise.config.ConfigContext
adminConfigContext
Admin config context. This is used to resolve application and resource references. The references do not contain types and a search through the config context is needed to determine the type.
private static final String
RES_PFX
private static final String
APP_PFX
private static final String
WEB_PFX
private static final String
EJB_PFX
private static final String
RAR_PFX
private static final String
ACC_PFX
private static final String
HTTP_SERVICE
private static final String
WEB_CONTAINER
private static final String
PROPERTY_REGEX
private static final String
LOG_LEVEL_XPATH
private static final String
MONITORING_LEVEL_XPATH
private static final String
PROCESS_CHANGE
private static final String
CHANGE_NULL
private static final String
EXTRACT_CHANGE
private static final String
CONFIG_CHANGE_XPATH
private static final String
PURGE_NOOP
private static final String
NULL_UPDATED_ATTRS
private static final String
INVALID_XPATH_TOKENIZATION
private static com.sun.enterprise.util.i18n.StringManager
localStrings
Constructors Summary
AdminEventCache(String instanceName)
Create an instance of AdminEventCache. Every event cache is for a specific instance.

param
instanceName name of the instance


                            
      
        this.instanceName = instanceName;
        cache = new ArrayList();
        RMIClient channel = AdminChannel.getRMIClient(instanceName);
        if (channel.isRestartNeeded()) {
            setRestartNeededTrue(false);
        }
    
Methods Summary
public voidaddEvent(AdminEvent event)
Add an event to the cache.

param
event Event to be added to cache
deprecated
with no substitution

        cache.add(event);
    
public voidaddEvents(java.util.ArrayList eventList)
Add specified list of events to the cache.

param
eventList list of events to add to the cache
deprecated
with no substitution

        cache.addAll(eventList);
    
public voidcacheResourceChange(java.lang.String resourceType, java.lang.String resourceName, java.lang.String actionCode)
Cache a resource change. This method inspects the cache and either updates the existing event or creates a new resource event.

param
resourceType Type of the resource
param
resourceName Name of the resource
param
actionCode Action code, one of BaseDeployEvent.DEPLOY, BaseDeployEvent.REDEPLOY or BaseDeployEvent.UNDEPLOY
deprecated
with no substitution.

        // Valid values for actionCode are DEPLOY, UNDEPLOY and REDEPLOY and
        // not ENABLE and DISABLE which can come only from analyzing config
        // changes. 
        if (!isActionValidForCache(actionCode)) {
			String msg = localStrings.getString( "admin.event.invalid_action", actionCode );
            throw new IllegalArgumentException( msg );
        }
        ResourceDeployEvent resEvent = findResourceDeployEvent(resourceType,
                resourceName);
        if (resEvent == null) {
            resEvent = new ResourceDeployEvent(instanceName, resourceName,
                    resourceType, actionCode);
            cache.add(resEvent);
        } else {
            resEvent.setNewAction(actionCode);
        }
    
private static java.lang.StringcleanXPath(java.lang.String xpath)
Clean XPath. This method converts all xpaths to lower case and replaces two or more consecutive forward slash ('/') character by a single forward slash.

return
modified XPath

        if (xpath == null) {
            return xpath;
        }
        return xpath.replaceAll("/{2,}", "/");
    
private com.sun.enterprise.config.ConfigUpdateconvertToConfigUpdate(com.sun.enterprise.config.ConfigChange change)
Convert to config update, if possible. If specified change is not an instanceof ConfigUpdate, the method returns null

        ConfigUpdate update = null;
        if (change instanceof ConfigUpdate) {
            update = (ConfigUpdate)change;
        }
        return update;
    
private voiddoChangeBucketing(com.sun.enterprise.config.ConfigChange change, ConfigChangeEvent dflt, java.util.ArrayList changeList)
Process the specifid change and generate appropriate events.

param
change the config change
param
dflt the default config change event
param
changeList all changes being processed. This is needed to handle references because if a resource has been deleted its type can only be found from the change list.

        logger.log(Level.FINE, PROCESS_CHANGE, change);
        if (change == null || change.getXPath() == null) {
            logger.log(Level.FINE, CHANGE_NULL, change);
            return;
        }
        boolean processed = false;
        //processed = processLogLevelChangeEvent(change);
//        if (!processed) {
//            processed = processMonitoringLevelChangeEvent(change);
//        }
//        if (!processed) {
//            processed = processResourceChangeEvent(change);
//        }
//        if (!processed) {
//            processed = processResourceReference(change, changeList);
//        }
/*
        if (!processed) {
            processed = processOtherDeployEvent(change);
        }
        if (!processed) {
            processed = processApplicationReference(change, changeList);
        }
*/
        if (( dflt != null) && (!processed)) {
            dflt.addConfigChange(change);
            if (!dflt.isWebCoreReconfigNeeded()) {
                setWebCoreReconfig(change, dflt);
            }
        }
    
private static java.util.ArrayListextractConfigChanges(com.sun.enterprise.config.ConfigContext configContext, java.lang.String xpath)
Extract config changes matching specified xpath from config context.

param
configContext the context from where changes are extracted
param
xpath the xpath for which all changes should be extracted
throws
IllegalArgumentException if specified config context is null
throws
IllegalStateException if list of changes maintained by config context is null.

        if (configContext == null) {
			String msg = localStrings.getString( "admin.event.null_config_context" );
            throw new IllegalArgumentException( msg );
        }
        ArrayList myChanges = new ArrayList();
        ArrayList allChanges = configContext.getConfigChangeList();
        if (allChanges == null) {
			String msg = localStrings.getString( "admin.event.null_config_changes_in_configcontext" );
            throw new IllegalStateException( msg );
        }
        logger.log(Level.FINE, EXTRACT_CHANGE, xpath);
        Iterator iter = allChanges.iterator();
        while (iter.hasNext()) {
            ConfigChange change = (ConfigChange)iter.next();
            logger.log(Level.FINE, PROCESS_CHANGE, change);
            String changeXPath = null;
            if (change != null) {
                changeXPath = cleanXPath(change.getXPath());
                logger.log(Level.FINEST, CONFIG_CHANGE_XPATH, changeXPath);
            }
            if (change == null || changeXPath == null) {
                logger.log(Level.FINE, CHANGE_NULL, change);
                continue;
            }
            if (changeXPath.equals(xpath)) {
		//System.out.println("Xpath matches, adding change to the list");
                myChanges.add(change);
            } else {
		//System.out.println("No match, ignoring");
            }
        }
        iter = myChanges.iterator();
        while (iter.hasNext()) {
            configContext.removeConfigChange((ConfigChange)iter.next());
        }
        return myChanges;
    
private ApplicationDeployEventfindApplicationDeployEvent(java.lang.String appName)
Find matching application deploy event in the cache. This method iterates through all cached events and tries to find an ApplicationDeployEvent for specified name. The method returns null if it doesn't find a match.

param
appName name of the application
throws
IllegalArgumentException if specified application name is null
return
matching ApplicationDeployEvent if found, null otherwise.

        if (appName == null) {
			String msg = localStrings.getString( "admin.event.null_application_name" );
            throw new IllegalArgumentException( msg );
        }
        ApplicationDeployEvent appEvent = null;
        Iterator iter = cache.iterator();
        while (iter.hasNext()) {
            AdminEvent event = (AdminEvent)iter.next();
            if (event instanceof ApplicationDeployEvent) {
                appEvent = (ApplicationDeployEvent)event;
                if (appName.equals(appEvent.getApplicationName())) {
                    break;
                } else {
                    appEvent = null;
                }
            }
        }
        return appEvent;
    
private ModuleDeployEventfindModuleDeployEvent(java.lang.String modType, java.lang.String modName)
Find matching module deploy event in the cache. This method iterates through all cached events and tries to find a ModuleDeployEvent for specified module type and name. The method returns null if it doesn't find a match.

param
modType type of the module
param
modName name of the module
throws
IllegalArgumentException if module type or name is null
return
matching ModuleDeployEvent if found, null otherwise.

        if (modType == null || modName == null) {
			String msg = localStrings.getString( "admin.event.null_module_type_or_name", modType, modName );
            throw new IllegalArgumentException( msg );
        }
        ModuleDeployEvent modEvent = null;
        Iterator iter = cache.iterator();
        while (iter.hasNext()) {
            AdminEvent event = (AdminEvent)iter.next();
            if (event instanceof ModuleDeployEvent) {
                modEvent = (ModuleDeployEvent)event;
                if (modEvent.getModuleType().equals(modType)
                        && modEvent.getModuleName().equals(modName)) {
                    break;
                } else {
                    modEvent = null;
                }
            }
        }
        return modEvent;
    
private ResourceDeployEventfindResourceDeployEvent(java.lang.String resType, java.lang.String resName)
Find matching resource deploy event in the cache. This method iterates through all cached events and tries to find a ResourceDeployEvent for specified resource type and name. The method returns null if it doesn't find a match.

param
resType type of the resource
param
resName name of the resource
throws
IllegalArgumentException if resource type or name is null
return
matching ResourceDeployEvent if found, null otherwise.

        if (resType == null || resName == null) {
			String msg = localStrings.getString( "admin.event.null_resource_type_or_name", resType, resName );
            throw new IllegalArgumentException( msg );
        }
        ResourceDeployEvent resEvent = null;
        Iterator iter = cache.iterator();
        while (iter.hasNext()) {
            AdminEvent event = (AdminEvent)iter.next();
            if (event instanceof ResourceDeployEvent) {
                resEvent = (ResourceDeployEvent)event;
                if (resType.equals(resEvent.getResourceType())
                        && resName.equals(resEvent.getResourceName())) {
                    break;
                } else {
                    resEvent = null;
                }
            }
        }
        return resEvent;
    
public synchronized java.util.ArrayListgetAndResetCachedEvents()
Get list of cached events and re-initialize the cache. This method should be called only after a call to processConfigChangeList(),

return
list of cached events

        ArrayList saved = cache;
        cache = new ArrayList();
        return saved;
    
private static java.lang.StringgetAppRefXPath(java.lang.String instance, java.lang.String appName)
Get app ref xpath for specified app and server.

param
instance name of the server
param
appName name of the application
return
xpath corresponding to the application ref

        return ServerXPathHelper.getServerIdXpath(instance)
                + ServerXPathHelper.XPATH_SEPARATOR
                + ServerTags.APPLICATION_REF + "[@"
                + ServerTags.REF + "='" + appName + "']";
    
java.util.ArrayListgetCachedEvents()
Get list of cached events. This method returns the list object being used inside this class, therefore, all changes to the list should be carefully considered.

return
list of cached events.

        return cache;
    
public static synchronized com.sun.enterprise.admin.event.AdminEventCachegetInstance(java.lang.String instanceName)
Get event cache for specified instance.

param
instanceName name of the instance
return
event cache for the specified instance

        AdminEventCache aec =
                (AdminEventCache)instanceCacheMap.get(instanceName);
        if (aec == null) {
            aec = new AdminEventCache(instanceName);
            instanceCacheMap.put(instanceName, aec);
        }
        return aec;
    
private java.lang.StringgetResourceName(java.lang.String xpath)
Get name of the resource from a resource xpath.

param
xpath the xpath for a resource
return
the name of the resource

        return getXPathToken(xpath, 1);
    
private java.lang.StringgetResourceType(java.lang.String xpath)
Get resource type from the xpath.

param
xpath the xpath for a resource
return
the type of the resource, appropriate for use in constructor of ResourceDeployEvent.

        String resType = "unknown";
        String xpathLcase = xpath.toLowerCase();
        if (xpathLcase.startsWith(ServerXPathHelper.XPATH_CUSTOM_RESOURCE)) {
            resType = ResourceDeployEvent.RES_TYPE_CUSTOM;
        } else if (xpathLcase.startsWith(ServerXPathHelper.XPATH_JNDI_RESOURCE)) {
            resType = ResourceDeployEvent.RES_TYPE_EXTERNAL_JNDI;
        } else if (xpathLcase.startsWith(ServerXPathHelper.XPATH_JDBC_CONNECTION_POOL)) {
            resType = ResourceDeployEvent.RES_TYPE_JCP;
        } else if (xpathLcase.startsWith(ServerXPathHelper.XPATH_JDBC_RESOURCE)) {
            resType = ResourceDeployEvent.RES_TYPE_JDBC;
        } else if (xpathLcase.startsWith(ServerXPathHelper.XPATH_MAIL_RESOURCE)) {
            resType = ResourceDeployEvent.RES_TYPE_MAIL;
        } else if (xpathLcase.startsWith(ServerXPathHelper.XPATH_PM_FACTORY_RESOURCE)) {
            resType = ResourceDeployEvent.RES_TYPE_PMF;
        } else if (xpathLcase.startsWith(ServerXPathHelper.XPATH_ADMIN_OBJECT_RESOURCE)) {
            resType = ResourceDeployEvent.RES_TYPE_AOR;
        }  else if (xpathLcase.startsWith(ServerXPathHelper.XPATH_CONNECTOR_CONNECTION_POOL)) {
            resType = ResourceDeployEvent.RES_TYPE_CCP;
        }  else if (xpathLcase.startsWith(ServerXPathHelper.XPATH_CONNECTOR_RESOURCE)) {
            resType = ResourceDeployEvent.RES_TYPE_CR;
        }  else if (xpathLcase.startsWith(ServerXPathHelper.XPATH_RESOURCE_ADAPTER_CONFIG)) {
             resType = ResourceDeployEvent.RES_TYPE_RAC;
        }

        return resType;
    
public static booleangetServerXmlBooleanValue(java.lang.String xmlValue)
Get a boolean value corresponding to the string value in xml.

param
xmlValue the xml string representing a boolean
return
true if the string is "true", "yes", "on" or "1"

        boolean retval = false;
        if (xmlValue == null) {
            return retval;
        }
        if (xmlValue.equalsIgnoreCase("true")
                || xmlValue.equalsIgnoreCase("yes")
                || xmlValue.equalsIgnoreCase("on")
                || xmlValue.equalsIgnoreCase("1")) {
            retval = true;
        }
        return retval;
    
private java.lang.StringgetXPathToken(java.lang.String xpath, int numToDiscard)
Extract token separated by single-quote character (') after discarding specified number of tokens. For example,
xpath numToDiscard Returns
/a/b/c[@name='myName'] 1 myName
/a/b/c[@name='myName']/d[@id='myId'] 3 myId
Note that the value contains single-quote character, the xpath will be formed with ' and the caller has to convert to appropriate character.

param
xpath the xpath from where token needs to be extracted
param
numToDiscard number of tokens to discard
throws
IllegalArgumentException if the xpath does not contain enough tokens.
return
the token after discarding numToDiscard tokens from xpath

        StringTokenizer tok = new StringTokenizer(xpath, "'");
        if (tok.countTokens() <= numToDiscard) {
            Object[] params = new Object[] {xpath,
                    new Integer(numToDiscard + 1),
                    new Integer(tok.countTokens())};
            logger.log(Level.FINE, INVALID_XPATH_TOKENIZATION, params);
            String msg = localStrings.getString(
                    "admin.event.invalid_xpath_tokenization", params );
            throw new IllegalArgumentException(msg);
        }
        for (int i = numToDiscard; i > 0; i--) {
            String discard = tok.nextToken();
        }
        return tok.nextToken();
    
private booleanisActionValidForCache(java.lang.String deployAction)
Check whether specified deploy action can be cached. Only deploy actions - DEPLOY, UNDEPLOY and REDEPLOY can be cached. The other deploy actions ENABLE, DISABLE are derived from the cache of changes.

param
deployAction the deployment action
return
true if deploy action is valid, false otherwise

        boolean valid = false;
        if (deployAction != null) {
            if (deployAction.equals(BaseDeployEvent.DEPLOY)
                    || deployAction.equals(BaseDeployEvent.UNDEPLOY)
                    || deployAction.equals(BaseDeployEvent.REDEPLOY)) {
                valid = true;
            }
        }
        return valid;
    
private booleanisAppRefXPath(java.lang.String xpath)
Is specified xpath for application reference

param
xpath the xpath to be checked
returns
true if the xpath is for application reference, false otherwise

        if (xpath == null) {
            return false;
        }
        String serverXPath = ServerXPathHelper.getServerIdXpath(instanceName);
        String appRefXPath = serverXPath + ServerXPathHelper.XPATH_SEPARATOR
                + ServerTags.APPLICATION_REF;
        return xpath.startsWith(appRefXPath);
    
public booleanisInstanceRestartNeeded()
Is restart of instance required.

        if (restartNeeded) {
            RMIClient channel = AdminChannel.getRMIClient(instanceName);
            boolean alreadyRestarted =
                    channel.hasRestartedSince(tsRestartNeededSince);
            if (alreadyRestarted) {
                restartNeeded = false;
            }
        }
        return restartNeeded;
    
private booleanisLogLevelXPath(java.lang.String xpath)
Is specified xpath for module log levels.

param
xpath the xpath to be checked
returns
true if the xpath is for module log levels, false otherwise

        return (LOG_LEVEL_XPATH.equalsIgnoreCase(xpath));
    
private booleanisMonitoringLevelXPath(java.lang.String xpath)
Is specified xpath for module monitoring levels.

param
xpath the xpath to be checked
returns
true if the xpath is for module monitoring levels, false otherwise

        return (MONITORING_LEVEL_XPATH.equalsIgnoreCase(xpath));
    
private booleanisPropertyXPath(java.lang.String xpath)
Is specified xpath for property.

param
xpath the xpath to be checked
returns
true if the xpath is for a property, false otherwise

        return AdminEventCache.matchRegex(PROPERTY_REGEX, xpath);
    
private booleanisResRefXPath(java.lang.String xpath)
Is specified xpath for application reference

param
xpath the xpath to be checked
returns
true if the xpath is for resource reference, false otherwise

        if (xpath == null) {
            return false;
        }
        String serverXPath = ServerXPathHelper.getServerIdXpath(instanceName);
        String resRefXPath = serverXPath + ServerXPathHelper.XPATH_SEPARATOR
                + ServerTags.RESOURCE_REF;
        return xpath.startsWith(resRefXPath);
    
private booleanisResourceXPath(java.lang.String xpath)
Is this a resource XPATH. The method returns true if the XPATH is for a resource.

param
xpath the xpath
return
true if the xpath is for a resource, false otherwise.

        String xpathLcase = xpath.toLowerCase();
        if (xpathLcase.startsWith(RES_PFX)) {
            return true;
        }
        return false;
    
private booleanisWebCoreXPath(java.lang.String xpath)
Is specified XPath handled only by web core. All elements under http-service and web-container are handled exclusively by web core.

param
xpath the xpath to process
return
true if the xpath is handled only by web core, false otherwise.

        boolean webCoreXPath = false;
        if (xpath == null) {
            return webCoreXPath;
        } else {
            xpath = xpath.toLowerCase();
        }
        if (xpath.startsWith(HTTP_SERVICE) || xpath.startsWith(WEB_CONTAINER)) {
            webCoreXPath = true;
        }
        return webCoreXPath;
    
private static booleanmatchRegex(java.lang.String regex, java.lang.String str)
Match a string against a regular expression.

param
regex the regular expression to match
param
str the string to match
returns
true if the regular expression matches string

        Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher(str);
        return matcher.matches();
    
private static voidpopulateApplicationConfigChange(com.sun.enterprise.config.ConfigContext ctx, ApplicationDeployEvent event)
Populate config changes from specified config context into the specified application deployment event.

param
ctx the config context
param
event the application deployment event

        String xpath = ServerXPathHelper.getAppIdXpathExpression(
                event.getApplicationName());
        xpath = cleanXPath(xpath);
        event.addConfigChange(extractConfigChanges(ctx, xpath));
        // Now look for any changes to application ref
        String refXPath = getAppRefXPath(event.getInstanceName(),
                event.getApplicationName());
        event.addConfigChange(extractConfigChanges(ctx, refXPath));
    
public static voidpopulateConfigChange(com.sun.enterprise.config.ConfigContext ctx, AdminEvent event)
Populate config changes in the specified event. This method looks for changes matching the event in the specified config context and if there are any the changes are moved from config context to the event. This method can only handle ApplicationDeployEvent and ModuleDeployEvent.

param
ctx The config context where the cache of changes is examined for match
param
event The event for which matching changes should be looked up
throws
UnsupportedOperationException if the event is not Application or Module deploy event.

        if (event instanceof ApplicationDeployEvent) {
            populateApplicationConfigChange(ctx, (ApplicationDeployEvent)event);
        } else if (event instanceof ModuleDeployEvent) {
            populateModuleConfigChange(ctx, (ModuleDeployEvent)event);
        } else {
			String msg = localStrings.getString( "admin.event.unsupported_populateconfigchange", event.getClass().getName() );
            throw new UnsupportedOperationException( msg );
        }
    
private static voidpopulateModuleConfigChange(com.sun.enterprise.config.ConfigContext ctx, ModuleDeployEvent event)
Populate config changes from specified config context into the specified module deployment event.

param
ctx the config context
param
event the module deployment event
throws
IllegalArgumentException if module type as specified in the event is not one of EJB, WEB, CONNECTOR or APPCLIENT

        String moduleType = event.getModuleType();
        String moduleName = event.getModuleName();
        String xpath = null;
        if (event.TYPE_WEBMODULE.equals(moduleType)) {
            xpath = ServerXPathHelper.getWebModuleIdXpathExpression(moduleName);
        } else if (event.TYPE_EJBMODULE.equals(moduleType)) {
            xpath = ServerXPathHelper.getEjbModuleIdXpathExpression(moduleName);
        } else if (event.TYPE_CONNECTOR.equals(moduleType)) {
            xpath = ServerXPathHelper.getConnectorModuleIdXpathExpression(
                    moduleName);
        } else if (event.TYPE_APPCLIENT.equals(moduleType)) {
            xpath = ServerXPathHelper.getAppClientModuleIdXpathExpression(
                    moduleName);
        } else {
			String msg = localStrings.getString( "admin.event.invalid_module_type" , moduleType );
            throw new IllegalArgumentException( msg );
        }
        xpath = cleanXPath(xpath);
        event.addConfigChange(extractConfigChanges(ctx, xpath));
        // Now look for any changes to application ref
        String refXPath = getAppRefXPath(event.getInstanceName(), moduleName);
        event.addConfigChange(extractConfigChanges(ctx, refXPath));
    
private booleanprocessApplicationReference(com.sun.enterprise.config.ConfigChange change, java.util.ArrayList changeList)
Process the change and create/update appropriate application or module events, if the change represents a application reference.

param
change the change to be processed
param
changeList all the changes being processed in the current batch
return
true if the change is for a application reference and was added to an existing or a new event.

        return processReference(change, changeList, new AppRefProcessor(this));
    
public synchronized voidprocessConfigChangeList(java.util.ArrayList changeList, boolean initOrObjFilesChanged, boolean mimeFileChanged)
Process config change list and update cache with appropriate events. At the end of this method the cache will have zero or more events. It will contain an instance of ConfigChangeEvent if the specified parameter otherConfFilesChanges is true or if specified changeList is not null and the change does not fit in any of following events -- MonitoringEvent with actionCode START_MONITOR or STOP_MONITOR or ResourceDeployEvent. If the cache already contains an instance ResourceDeployEvent for a given resource, then this method will not add any new instance of ResourceDeployEvent for that resource.

param
changeList list of server.xml config changes
param
initOrObFilesChanged whether conf files init.conf or obj.conf were changed
param
mimeFileChanged whether mime type file(s) were changed

        ConfigChangeEvent dfltEvent = null;
        boolean dfltEventCached = false;
        Iterator iter = cache.iterator();
        while (iter.hasNext()) {
            Object obj = iter.next();
            if (obj instanceof ConfigChangeEvent) {
                dfltEvent = (ConfigChangeEvent)obj;
                dfltEventCached = true;
                break;
            }
        }
        if (initOrObjFilesChanged || mimeFileChanged) {
            if (dfltEvent == null) {
                dfltEvent = new ConfigChangeEvent(instanceName, null);
            }
            dfltEvent.setWebCoreReconfigNeeded(true);
        }
        if (initOrObjFilesChanged) {
            if (dfltEvent == null) {
                dfltEvent = new ConfigChangeEvent(instanceName, null);
            }
            dfltEvent.setInitOrObjConfChanged(true);
        }
        if (changeList != null && !changeList.isEmpty()) {
            iter = changeList.iterator();
            while (iter.hasNext()) {
                ConfigChange change = (ConfigChange)iter.next();
                if (change != null) {
                    doChangeBucketing(change, dfltEvent, changeList);
                }
            }
        }
        if (( dfltEvent != null) && (!dfltEventCached) ){
            cache.add(dfltEvent);
        }
        purgeNopEvents();
    
private booleanprocessLevelChangeEvent(com.sun.enterprise.config.ConfigChange change, com.sun.enterprise.admin.event.AdminEventCache$LevelChangeProcessor processor)
Process changes to module level.

param
change the change to be processed
param
processor the handler for the change
return
true if the change is applicable and events are generated, false otherwise.

        // Only updates for level change can be handled dynamically, all
        // other changes will require restart.
        ConfigUpdate update = convertToConfigUpdate(change);
        if (update == null) {
            return false;
        }
        String xpath = cleanXPath(update.getXPath());
        if (!processor.isRelevant(xpath)) {
            return false;
        }
        Set attrs = update.getAttributeSet();
        if (attrs == null) {
            logger.log(Level.FINEST, "admin.event.null_updated_attrs",
                    update.getXPath());
            return false;
        }
        Iterator iter = attrs.iterator();
        while (iter.hasNext()) {
            String compName = (String)iter.next();
            String oldValue = update.getOldValue(compName);
            String newValue = update.getNewValue(compName);
            AdminEvent event = processor.createEvent(compName, oldValue,
                    newValue);
            cache.add(event);
            ConfigUpdate upd = new ConfigUpdateImpl(xpath, compName, oldValue,
                    newValue);
            event.addConfigChange(upd);
        }
        return true;
    
private booleanprocessLogLevelChangeEvent(com.sun.enterprise.config.ConfigChange change)
Process changes to module log levels. One event is generated for every module whose log level is changed. The method returns true if change is for module log levels (excluding properties).

param
change the change to be processed
return
true if the change is for module log levels, false otherwise.

        return processLevelChangeEvent(change,
                new LogLevelChangeProcessor(this));
    
private booleanprocessMonitoringLevelChangeEvent(com.sun.enterprise.config.ConfigChange change)
Process changes to module monitoring levels. One event is generated for every module whose monitoring level is changed. The method returns true if change is for module monitoring levels (excluding properties).

param
change the change to be processed
return
true if the change is for module monitoring levels, false otherwise.

        return processLevelChangeEvent(change,
                new MonitoringLevelChangeProcessor(this));
    
private booleanprocessOtherDeployEvent(com.sun.enterprise.config.ConfigChange change)
Process the change and generate ApplicationDeployEvent or ModuleDeployEvent. If the change is to a xpath that represents an application or module, then an application or module deploy event for the resource represented by the xpath is added to cache, provided the cache does not already contain a application or module deploy event for the same resource. If the attribute enabled is changed then the actionCode for the event is ENABLE or DISABLE, otherwise it is REDEPLOY. The change is considered fully processed if the xpath is for an application or a module.

return
true if the change is fully processed, false otherwise.

        String xpath = cleanXPath(change.getXPath());
        String xpathLcase = xpath.toLowerCase();
        boolean processed = false;
        String componentType = null;
        String moduleType = null;
        if (xpathLcase.startsWith(APP_PFX)) {
            componentType = BaseDeployEvent.APPLICATION;
        } else if (xpathLcase.startsWith(EJB_PFX)) {
            componentType = BaseDeployEvent.MODULE;
            moduleType = ModuleDeployEvent.TYPE_EJBMODULE;
        } else if (xpathLcase.startsWith(WEB_PFX)) {
            componentType = BaseDeployEvent.MODULE;
            moduleType = ModuleDeployEvent.TYPE_WEBMODULE;
        } else if (xpathLcase.startsWith(RAR_PFX)) {
            componentType = BaseDeployEvent.MODULE;
            moduleType = ModuleDeployEvent.TYPE_CONNECTOR;
        } else if (xpathLcase.startsWith(ACC_PFX)) {
            componentType = BaseDeployEvent.MODULE;
            moduleType = ModuleDeployEvent.TYPE_APPCLIENT;
        } else {
            return false;
        }
        String componentName = getResourceName(xpath);
        BaseDeployEvent theEvent = null;
        if (BaseDeployEvent.APPLICATION.equals(componentType)) {
            theEvent = findApplicationDeployEvent(componentName);
        } else {
            theEvent = findModuleDeployEvent(moduleType, componentName);
        }
        if (theEvent == null) {
            String actionCode = null;
            if (change instanceof ConfigUpdate) {
/* krav
                ConfigUpdate update = (ConfigUpdate)change;
                String enableStr = update.getNewValue(ServerTags.ENABLED);
                if (enableStr != null) {
                    if (getServerXmlBooleanValue(enableStr)) {
                        actionCode = BaseDeployEvent.ENABLE;
                    } else {
                        actionCode = BaseDeployEvent.DISABLE;
                    }
                } else {
                    actionCode = BaseDeployEvent.REDEPLOY;
                }
 */
             } else if (change instanceof ConfigAdd) {
                actionCode = BaseDeployEvent.DEPLOY;
             } else if (change instanceof ConfigDelete) {
                actionCode = BaseDeployEvent.UNDEPLOY;
             } else {
		String msg = localStrings.getString( "admin.event.handle_add_delete_set_configchange" );
                throw new IllegalStateException( msg );
             }
             if (actionCode != null) {
                if (BaseDeployEvent.APPLICATION.equals(componentType)) {
                    theEvent = new ApplicationDeployEvent(instanceName,
                    componentName, actionCode);
                } else {
                    theEvent = new ModuleDeployEvent(instanceName, componentName,
                    moduleType, actionCode);
                }
                cache.add(theEvent);
                processed = true;
            }
        } else { // (theEvent != null)
            // Event is not null. Any update will not affect it. If the change
            // is not update (add, delete or set) -- assume that it already
            // affected the state of event when the change was made
            processed = true;
        }
        theEvent.addConfigChange(change);
        return processed;
    
private booleanprocessReference(com.sun.enterprise.config.ConfigChange change, java.util.ArrayList changeList, com.sun.enterprise.admin.event.AdminEventCache$RefProcessor processor)
Process reference and create/update appropriate event in the cache.

param
change the change to be processed
param
changeList all changes being processed along with this change. The change list is needed to determine type of the config object that the ref is referring to, in cases when the actual config object has been deleted and is no longer present in config context.
param
processor the processor for the reference. It is the abstraction that hides differences between application refs and resource refs.
return
true if the change can be handled by specified processor and is handled successfully, false otherwise.

        String xpath = cleanXPath(change.getXPath());
        if (!processor.isRelevant(xpath)) {
            return false;
        }
        String refName = processor.getRefName(xpath);
        processor.initRefTypeXPathMap(refName);
        String refType = processor.getRefType(refName, changeList);
        if (refType == null) {
            // The ref is not interesting, for example, lifecycle module ref
            return false;
        }
        return processor.process(refName, refType, change);
    
private booleanprocessResourceChangeEvent(com.sun.enterprise.config.ConfigChange change)
Process the change and generate ResourceDeployEvent. If the change is to a xpath that represents a resource, then a resource deploy event for the resource represented by the xpath is added to cache, provided the cache does not already contain a resource deploy event for the same resource. If the attribute enabled is changed then the actionCode for the event is ENABLE or DISABLE, otherwise it is REDEPLOY. The change is considered fully processed if the xpath is for a resource.

return
true if the change is fully processed, false otherwise.

        String xpath = cleanXPath(change.getXPath());
        boolean processed = false;
        if (isResourceXPath(xpath)) {
            String actionCode = null;
            if (change instanceof ConfigUpdate) {
                ConfigUpdate update = (ConfigUpdate)change;
                String enableStr = update.getNewValue(ServerTags.ENABLED);
                if (enableStr != null) {
                    if (getServerXmlBooleanValue(enableStr)) {
                        actionCode = ResourceDeployEvent.ENABLE;
                    } else {
                        actionCode = ResourceDeployEvent.DISABLE;
                    }
                } else {
                    actionCode = ResourceDeployEvent.REDEPLOY;
                }
            } else if (change instanceof ConfigAdd) {
                // In case of security-map, addition should fire 
                // redeploy event as it is part of connector-connection-pool
                // resource.
                boolean isMap = xpath.indexOf(ServerTags.SECURITY_MAP) != -1;
                if (isPropertyXPath(xpath) || isMap) {
                    actionCode = ResourceDeployEvent.REDEPLOY;
                } else {
                    actionCode = ResourceDeployEvent.DEPLOY;
                }
            } else if (change instanceof ConfigDelete) {
                // In case of security-map, delete should fire redeploy event
                // as it is part of connector-connection-pool resource.
                boolean isMap = xpath.indexOf(ServerTags.SECURITY_MAP) != -1;
                if (isPropertyXPath(xpath) || isMap) {
                    actionCode = ResourceDeployEvent.REDEPLOY;
                } else {
                     actionCode = ResourceDeployEvent.UNDEPLOY;
                }
            } else if (change instanceof ConfigSet) {
                // As of now set is used for existing properties in resources.
                // Existing properties imply that resource exists.
                actionCode = ResourceDeployEvent.REDEPLOY;
            } else {
                // Unknown ConfigChange cannot be handled
		String msg = localStrings.getString( "admin.event.unknown_configchange_for_resources");
                throw new IllegalStateException( msg );
            }
            String resType = getResourceType(xpath);
            String resName = getResourceName(xpath);
            ResourceDeployEvent resEvent =
                    findResourceDeployEvent(resType, resName);
            if (resEvent == null) {
                resEvent = new ResourceDeployEvent(instanceName, resName,
                        resType, actionCode);
                cache.add(resEvent);
            } else {
                if (isActionValidForCache(actionCode)) {
                    resEvent.setNewAction(actionCode);
                } else {
                    // As resEvent was not null, this is not the first change
                    // being processed for this xpath. Enable and Disable are
                    // not valid actions for second change of a resource xpath
                }
            }
            resEvent.addConfigChange(change);
            processed = true;
        }
        return processed;
    
private booleanprocessResourceReference(com.sun.enterprise.config.ConfigChange change, java.util.ArrayList changeList)
Process the change and create/update appropriate resource events, if the change represents a resource reference.

param
change the change to be processed
param
changeList all the changes being processed in the current batch
return
true if the change is for a resource reference and was added to an existing or a new event.

        return processReference(change, changeList, new ResRefProcessor(this));
    
private voidpurgeNopEvents()
Purge events that are NO-OP.

        Iterator iter = cache.iterator();
        while (iter.hasNext()) {
            AdminEvent event = (AdminEvent)iter.next();
            if (event.isNoOp()) {
                logger.log(Level.FINE, PURGE_NOOP, event);
                iter.remove();
            }
        }
    
public voidremoveEvent(AdminEvent event)
Remove specified event from the cache.

param
event the event to remove from cache
deprecated
with no substitution

        cache.remove(event);
    
public voidsetAdminConfigContext(com.sun.enterprise.config.ConfigContext ctx)
Set admin config context.

        adminConfigContext = ctx;
    
public voidsetRestartNeeded(boolean flag)
Set whether the instance requires restart. Cache is invalid if instance requires restart.

        if (flag) {
            if (!restartNeeded) {
                setRestartNeededTrue(true);
            }
        } else {
            restartNeeded = false;
        }
    
private voidsetRestartNeededTrue(boolean notifyInstance)
Set restart needed to true. This method also records the timestamp when restart needed was set to true. If parameter notifyInstance is true the instance is notified that it requires a restart.

param
notifyInstance if true the instance is notified of the restart required status.

        restartNeeded = true;
        tsRestartNeededSince = System.currentTimeMillis();
        if (notifyInstance) {
            RMIClient channel = AdminChannel.getRMIClient(instanceName);
            channel.setRestartNeeded(true);
        }
    
private voidsetWebCoreReconfig(com.sun.enterprise.config.ConfigChange change, ConfigChangeEvent dflt)
Set web core reconfig status in specified event if the change warrants that. Any config change to http-service or web container element require a web core reconfig.

param
change the config change object
param
dflt the default config change event

        String xpath = cleanXPath(change.getXPath());
        if (isWebCoreXPath(xpath)) {
            dflt.setWebCoreReconfigNeeded(true);
        }
        return;