FileDocCategorySizeDatePackage
ElementChangeHelper.javaAPI DocGlassfish v2 API20285Mon Jul 02 10:49:54 BST 2007com.sun.enterprise.admin.event

ElementChangeHelper

public class ElementChangeHelper extends Object
Config Element Change Helper - class providing ElementChangeEvent related services (events constructing/ change lists filtering etc.

Fields Summary
static final String
eventType
Event type
private static com.sun.enterprise.util.i18n.StringManager
localStrings
private static String
PROPERTY_SUBSTR
String
lastXpath
com.sun.enterprise.admin.meta.MBeanRegistryEntry
lastEntry
public static final String
EVENT_PACKAGE_PATH_PREFIX
private static String[]
restartExcludeXPaths
Constructors Summary
public ElementChangeHelper()

    
    //**********************************************************************
      
    
    
Methods Summary
static booleancheckChangeListForElement(java.util.ArrayList list)

        if(list==null || list.size()<=0)
            return false;
        for(int i=1; i<list.size(); i++)
            if(!isChangesToMerge((ConfigChange)list.get(i-1), (ConfigChange)list.get(i))) 
               return false;
        return true;
    
private static booleancompareXPathes(java.lang.String xpath1, java.lang.String xpath2)

        int iProp;
        if((iProp = xpath1.indexOf(PROPERTY_SUBSTR))>0)
            xpath1 = xpath1.substring(0, iProp);
        if((iProp = xpath2.indexOf(PROPERTY_SUBSTR))>0)
            xpath2 = xpath2.substring(0, iProp);
        return xpath1.equals(xpath2); 
    
public java.util.ArrayListcreateEventsForElementChange(java.lang.String instanceName, java.util.ArrayList changeList, com.sun.enterprise.config.ConfigContext domainContext, java.util.ArrayList globalChangeList)

       return createEventsForElementChange(instanceName, changeList, domainContext, true, globalChangeList);
    
private java.util.ArrayListcreateEventsForElementChange(java.lang.String instanceName, java.util.ArrayList changeList, com.sun.enterprise.config.ConfigContext domainContext, boolean bCheckList, java.util.ArrayList globalChangeList)

        
        if(bCheckList && !checkChangeListForElement(changeList))
        {
            String msg = localStrings.getString( "admin.event.wrong_configchange" );
            throw new IllegalArgumentException( msg );
        }

        String xpath0  = getElementXPath(changeList);
        if(xpath0==null)
            return null;
        // instantiate the proper Event
        //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        // 1. get event name

        MBeanRegistryEntry  entry = getRegistryEntry(xpath0);
        if(entry==null)
            return null;

        String              eventName = entry.getElementChangeEventName();
        if(eventName!=null && eventName.indexOf('.")<0)
            eventName = EVENT_PACKAGE_PATH_PREFIX + eventName;
        if(eventName==null)
            return null; //element is not a subject for ElementChangeEvent

        //  2. instantiate event
        try {
           return ElementChangeEventsFactory.createEvents(eventName, instanceName, 
                      entry.getName(), changeList, domainContext, globalChangeList);
        } catch(Exception e)
        {
            e.printStackTrace();
            String msg = localStrings.getString( "admin.event.cannot_create_eventforchange", eventName, xpath0 );
            throw new IllegalArgumentException( msg );
        }
    
public static java.lang.BooleanfindEnabledChange(java.util.ArrayList changeList)

        if(changeList==null)
            return null;
        for(int i=changeList.size()-1; i>=0; i--)
        {
            if ( changeList.get(i) instanceof ConfigUpdate) 
                {
                    ConfigUpdate update = (ConfigUpdate)changeList.get(i);
                    String enableStr = update.getNewValue(ServerTags.ENABLED);
                    if (enableStr != null) 
                        return new Boolean(ElementChangeHelper.getBooleanValue(enableStr));
                }
        }
        return null;
    
public com.sun.enterprise.admin.event.AdminEvent[]generateElementChangeEventsFromChangeList(java.lang.String instanceName, java.util.ArrayList changeList, com.sun.enterprise.config.ConfigContext domainContext)

        ArrayList merged = new ArrayList();
        ArrayList events = new ArrayList();
        ConfigChange change, lastChange = null;
        for(int i=0; i<changeList.size(); i++)
        {
            change = (ConfigChange)changeList.get(i);
            if(merged.isEmpty() || 
               isChangesToMerge(lastChange, change))
            {
                //add change to list
                merged.add(change);
                lastChange = change;
            }
            else
            {
                //here we are only if collected changes portion completed
                // it is time to create ElementChangeEvent 
                if(!merged.isEmpty())
                {
                    ArrayList new_events = createEventsForElementChange(instanceName, merged, domainContext, changeList);
                    if(new_events!=null && new_events.size()>0)
                        events.addAll(new_events);
                    //FIXME: - do we need treat empty answer as "restart is needed" sign?
                    merged.clear();
                    //add change to list
                    merged.add(change);
                    lastChange = change;
                }
            }
        }
        // last portion could be here
        if(!merged.isEmpty())
        {
            ArrayList new_events = createEventsForElementChange(instanceName, merged, domainContext, changeList);
            if(new_events!=null && new_events.size()>0)
                events.addAll(new_events);
            //FIXME: - do we need treat empty answer as "restart is needed" sign?
        }
        return (AdminEvent[])events.toArray(new AdminEvent[events.size()]);   
    
static intgetActionCodeForChange(com.sun.enterprise.config.ConfigChange change)

        if(isPropertyXPath(change.getXPath()))
            return ElementChangeEvent.ACTION_ELEMENT_UPDATE;
        int action;
	//set action code
        if(change instanceof ConfigSet)
            action = ElementChangeEvent.ACTION_ELEMENT_CREATE;
        else if(change instanceof ConfigAdd)
            action = ElementChangeEvent.ACTION_ELEMENT_CREATE;
        else if(change instanceof ConfigUpdate)
            action = ElementChangeEvent.ACTION_ELEMENT_UPDATE;
        else if(change instanceof ConfigDelete)
            action = ElementChangeEvent.ACTION_ELEMENT_DELETE;
        else
            action = ElementChangeEvent.ACTION_ELEMENT_UNDEFINED;
        return action;
    
static intgetActionCodeForChanges(java.util.ArrayList changes)

        return getActionCodeForChange((ConfigChange)changes.get(0));
    
public static booleangetBooleanValue(java.lang.String strValue)
Get a boolean value corresponding to the string value in xml.

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

        boolean retval = false;
        if (strValue == null) {
            return retval;
        }
        if (strValue.equalsIgnoreCase("true")
                || strValue.equalsIgnoreCase("yes")
                || strValue.equalsIgnoreCase("on")
                || strValue.equalsIgnoreCase("1")) {
            retval = true;
        }
        return retval;
    
static java.lang.StringgetConfigElementPrimaryKey(java.lang.String xpath)

        if (xpath != null) {
            xpath = xpath.trim();
        }
        if((xpath!= null) && (xpath.endsWith("']")))
        {
            int idx = xpath.lastIndexOf('\'", xpath.length()-3);
            return xpath.substring(idx+1, xpath.length()-2);
        }
        return null;
    
static java.lang.StringgetConfigElementTargetName(java.lang.String xpath, com.sun.enterprise.config.ConfigContext ctx)

        String targetName = null;
        try {
            // Get target name for event
            TargetBuilder targetBuilder = new TargetBuilder();
            return targetBuilder.getTargetNameForXPath(xpath, ctx, true);
        } catch(Exception e)
        {
            //can not find target -> get default (domain)
        }
        return null;
    
static java.lang.StringgetConfigElementType(java.lang.String xpath)

        if(xpath.trim().endsWith("]"))
            xpath =  xpath.substring(0, xpath.lastIndexOf('["));
        return xpath.substring(0, xpath.lastIndexOf('/"));
    
static java.lang.StringgetElementXPath(com.sun.enterprise.config.ConfigChange change)

        String xpath = change.getXPath();
        if(xpath==null)
            return xpath;
        int iMatch = xpath.indexOf(PROPERTY_SUBSTR);
        if(iMatch<0)
            return xpath;
        return xpath.substring(0, iMatch); 
    
static java.lang.StringgetElementXPath(java.util.ArrayList changes)

        return getElementXPath((ConfigChange)changes.get(0));
    
private synchronized com.sun.enterprise.admin.meta.MBeanRegistryEntrygetRegistryEntry(java.lang.String xpath)

    
        
    
        if(xpath.equals(lastXpath))
            return lastEntry; 
        MBeanRegistry       registry = MBeanRegistryFactory.getAdminMBeanRegistry();
        MBeanRegistryEntry  entry = registry.findMBeanRegistryEntryByXPath(xpath);
        if(entry!=null)
        {
            lastXpath = xpath;
            lastEntry = entry;
        }
        return entry;
    
public static java.util.SetgetXPathesForDynamicallyNotReconfigurableElements(java.util.ArrayList changeList)

        HashSet xpathes = new HashSet();
        if(changeList==null)
            return xpathes;

        MBeanRegistry       registry = MBeanRegistryFactory.getAdminMBeanRegistry();
        String xpath_last = null;
        MBeanRegistryEntry  entry = null;
        boolean bLastEntryHasEvent = false;
        String propertyName = null;
        
        for(int i=0; i<changeList.size();i++)
        {
            ConfigChange change = (ConfigChange)changeList.get(i);
            int action = getActionCodeForChange(change);
            if(action==ElementChangeEvent.ACTION_ELEMENT_UNDEFINED)
                continue; //??? not add/set/update/delete
            String xpath = change.getXPath();
            // Check if this xpath belongs to one of the excluded 
            // XPaths. Excluded xpaths include lb-configs, lb-config
            // etc. Where restart checks do not apply.
            if (  (xpath == null) || isXPathExcludedForRestartCheck(xpath) ) {
                continue;
            }
            if(!xpath.equals(xpath_last))
            {
                xpath_last = xpath;
                if(isPropertyXPath(change.getXPath()))
                {
                    propertyName = getConfigElementPrimaryKey(xpath);
                    xpath = getElementXPath(change);
                }
                else
                {
                    propertyName = null;
                }
                entry = registry.findMBeanRegistryEntryByXPath(xpath);
                if(entry==null)
                {
                    xpathes.add(xpath);
                    continue;
                }
                bLastEntryHasEvent = (entry.getElementChangeEventName()!=null);
            }
            if(bLastEntryHasEvent)
                continue;
            // check whether creation reconfigurable
            if( (action==ElementChangeEvent.ACTION_ELEMENT_CREATE &&
                 entry.isElementCreationDynamicallyReconfigurable()))
            {
                xpathes.add(xpath);
                continue;
            }
            // check whether deletion reconfigurable
            if( (action==ElementChangeEvent.ACTION_ELEMENT_DELETE &&
                 entry.isElementDeletionDynamicallyReconfigurable()))
            {
                xpathes.add(xpath);
                continue;
            }
            // check properties changes
            if(propertyName!=null)
            {
                if(!entry.isPropertyDynamicallyReconfigurable(propertyName))
                {
                    xpathes.add(xpath);
                    continue;
                }
            }
            if ( !(change instanceof ConfigUpdate))
            {
                xpathes.add(xpath);
                continue;
            }
            //here we are only for attributes
            Set attrs = ((ConfigUpdate)change).getAttributeSet();
            Iterator iter  = attrs.iterator();
            while(iter.hasNext())
            {
                String attr = (String)iter.next();
                // check if dynamic reconfig is needed for the attribute, bug# 6509963
                try {
                    if (! entry.isAttributeDynamicReconfigNeeded(attr)) 
                    {
                        break;
                    }
                } catch (MBeanMetaException mme)
                {
                	//field not found in registry
                }

                if(!entry.isAttributeDynamicallyReconfigurable(attr))
                {
                    xpathes.add(xpath);
                    break;
                }
            }
        }
        return xpathes;
    
static booleanisChangesToMerge(com.sun.enterprise.config.ConfigChange change1, com.sun.enterprise.config.ConfigChange change2)

        String xpath1, xpath2;
        if( change1==null || change2==null ||
            (xpath1 = change1.getXPath())==null ||
            (xpath2 = change2.getXPath())==null ||
            !compareXPathes( xpath1, xpath2) )
            return false;
        if(isPropertyXPath(xpath2)) //optimize it later
            return true;
        return ( xpath1.equals(change2.getXPath()) &&
            change1.getClass().equals(change2.getClass()) );
    
static booleanisPropertyChange(com.sun.enterprise.config.ConfigChange change)

        String xpath;
        return (change!=null &&
                (xpath = change.getXPath())!=null &&
                (xpath.indexOf(PROPERTY_SUBSTR))>=0 );
    
static booleanisPropertyXPath(java.lang.String xpath)

        return ((xpath != null) && ((xpath.indexOf(PROPERTY_SUBSTR))>=0));
    
private static booleanisXPathExcludedForRestartCheck(java.lang.String xpath)
Checks if an XPath is excluded for restart required check. Restart required check is skipped for lb-configs and lb-config elements.

param
xpath XPath of the config change
return
boolean true - if restart required check to be ignored, false otherwise

        if (xpath == null) {
            return false;
        }

        for(int excludeIdx =0; excludeIdx < restartExcludeXPaths.length; 
                excludeIdx++) {

            if ( xpath.startsWith(restartExcludeXPaths[excludeIdx]) ) {
                return true;
            }
        }
        return false;
    
public static com.sun.enterprise.config.ConfigChangeremoveEnabledChange(java.util.ArrayList changeList)

        if(changeList==null)
            return null;
        for(int i=changeList.size()-1; i>=0; i--)
        {
            if ( changeList.get(i) instanceof ConfigUpdate)
                {
                    ConfigUpdate update = (ConfigUpdate)changeList.get(i);
                    String enableStr = update.getNewValue(ServerTags.ENABLED);
                    if (enableStr != null) {
                        return (ConfigChange)changeList.remove(i);
                    }
                }
        }
        return null;