RegistryHelper.java :  » ESB » open-esb » com » sun » jbi » framework » sun » Java Open Source

Java Open Source » ESB » open esb 
open esb » com » sun » jbi » framework » sun » RegistryHelper.java
/*
 * BEGIN_HEADER - DO NOT EDIT
 *
 * The contents of this file are subject to the terms
 * of the Common Development and Distribution License
 * (the "License").  You may not use this file except
 * in compliance with the License.
 *
 * You can obtain a copy of the license at
 * https://open-esb.dev.java.net/public/CDDLv1.0.html.
 * See the License for the specific language governing
 * permissions and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL
 * HEADER in each file and include the License file at
 * https://open-esb.dev.java.net/public/CDDLv1.0.html.
 * If applicable add the following below this CDDL HEADER,
 * with the fields enclosed by brackets "[]" replaced with
 * your own identifying information: Portions Copyright
 * [year] [name of copyright owner]
 */

/*
 * @(#)RegistryHelper.java
 * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
 *
 * END_HEADER - DO NOT EDIT
 */
/**
 *  RegistryHelper.java
 *
 *  SUN PROPRIETARY/CONFIDENTIAL.
 *  This software is the proprietary information of Sun Microsystems, Inc.
 *  Use is subject to license terms.
 *
 *  Created on January 2, 2006, 4:49 PM
 */

package com.sun.jbi.framework.sun;

import com.sun.jbi.StringTranslator;

import com.sun.jbi.ComponentInfo;
import com.sun.jbi.ComponentState;
import com.sun.jbi.ServiceAssemblyInfo;
import com.sun.jbi.ServiceAssemblyState;
import com.sun.jbi.platform.PlatformContext;
import com.sun.jbi.framework.EnvironmentContext;
import com.sun.jbi.framework.sun.LocalStringKeys;
import com.sun.jbi.management.ComponentInfo.Variable;
import com.sun.jbi.management.registry.GenericQuery;
import com.sun.jbi.management.registry.Registry;
import com.sun.jbi.management.registry.RegistryBuilder;
import com.sun.jbi.management.registry.RegistryDiff;
import com.sun.jbi.management.registry.RegistryException;
import com.sun.jbi.management.registry.RegistrySpecImpl;
import com.sun.jbi.management.registry.RegistryType;


import com.sun.jbi.management.MBeanNames;

import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.PrintStream;

import javax.management.MBeanServerConnection;
import javax.management.ObjectName;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;

/*
 * This class is a helper that hides the lower level details involved with 
 * getting remote files and diff'ing jbi registries.
 */
public class RegistryHelper
{
    private static final String DOMAIN = "domain";
    private static final String DAS_RELATIVE_PATH = "config";
    private static final String STRING_TRANSLATOR_NAME = "com.sun.jbi.management.facade";
    
    private static final String SL_KEY = "sl";
    private static final String COMP_KEY = "comp";
    private static final String SA_KEY = "sa";
    private static final String DOMAIN_KEY = "domain";
    private static final String INSTANCE_KEY = "instance";
    private static final String STATIC_CONF_KEY = "static";
    private static final String APPVAR_CONF_KEY = "appvar";
    private static final String APPCON_CONF_KEY = "appcon";
    
    private static final String JBI_SCHEMA_CONFIGS = "configs";
    private static final String JBI_SCHEMA_CONFIG = "config";
    private static final String JBI_SCHEMA_CONFIG_TYPE = "config-type";
    private static final String JBI_SCHEMA_CATEGORY = "category";
    private static final String JBI_SCHEMA_PROPERTY = "property";
    private static final String JBI_SCHEMA_VALUE = "value";
    
    private static final String JBI_SCHEMA_APPLICATION_VARIABLE = "application-variable";
    private static final String JBI_SCHEMA_APPLICATION_CONFIGURATION = "application-configuration";
    private static final String JBI_SCHEMA_COMPONENT = "component";
    private static final String JBI_SCHEMA_COMPONENT_REF = "component-ref";
    private static final String JBI_SCHEMA_COMPONENT_CONFIG = "component-config";
    private static final String JBI_SCHEMA_SHARED_LIBRARY = "shared-library";
    private static final String JBI_SCHEMA_SHARED_LIBRARY_REF = "shared-library-ref";
    private static final String JBI_SCHEMA_SERVICE_ASSEMBLY = "service-assembly";
    private static final String JBI_SCHEMA_SERVICE_ASSEMBLY_REF = "service-assembly-ref";
    private static final String JBI_SCHEMA_SERVICE_UNIT = "service-unit";
    private static final String JBI_SCHEMA_NAME = "name";
    private static final String JBI_SCHEMA_NAME_REF = "name-ref";
    private static final String JBI_SCHEMA_TIMESTAMP = "timestamp";
    private static final String JBI_SCHEMA_STATE = "state";
    private static final String JBI_SCHEMA_UPDATENUMBER = "upgrade-number";
    
    static final int    INITIALIZED = 1;
    static final int    SYNC_REQUIRED = 2;
    static final int    ALL_NOT_SHUTDOWN = 4;
    
    private Registry                mRegistry;
    private Registry                mMasterRegistry;
    private String                  mDASRegistryFileName;
    private String                  mSyncRegistryFileName;
    private String                  mSyncFolder;
    private RegistryDiff            mDiff;            
    private Logger                  mLogger;
    private String                  mTarget;
    private PlatformContext         mPlatform;
    private StringTranslator        mTranslator;
    private ObjectName              mDASDownloadMBeanName;
    private MBeanServerConnection   mMBeanServer;
    private String                  mInstanceRootPath;
    private HashMap                 mLocalReg;
    private int                     mSyncState;
    
    /**
     * Constructor for new instance of the RegistryHelper.
     * @param envCtx the environment context.
     */
    public RegistryHelper(EnvironmentContext envCtx)
    {
        mPlatform = envCtx.getPlatformContext();
        mTranslator = envCtx.getStringTranslator(STRING_TRANSLATOR_NAME);
        mLogger = Logger.getLogger("com.sun.jbi.framework.sun");  
        mDASDownloadMBeanName = envCtx.getMBeanNames().getSystemServiceMBeanName(
                MBeanNames.ServiceName.FileTransferService, 
                MBeanNames.ServiceType.Download, DOMAIN);         
        mInstanceRootPath = envCtx.getJbiInstanceRoot();
    }
    
    /**
     * Determine if JBI needs to be started completely or if it can come up
     * in a passive (i.e. initialized but not started) state. This determination
     * is made by checking the desired state of components in the JBI registry.
     * If all components are SHUTDOWN, then we can start in passive state and
     * the framework will start system services on demand.
     */
    public boolean isActiveStartup()
    {
        boolean isActive = true;

        if (mPlatform.isAdminServer())
        {
            //
            //  On DAS we don't have to sync, but we do have to watch out for services
            //  that are not shutdown and may require XA recovery at restart.
            //
            if (allShutdown(getLocalRegInfo()))
            {
                isActive = false;
            }
        }
        else
        {
            //
            // More detailed check needed on instance.
            //
            if ((mSyncState & INITIALIZED) == 0)
            {
                computeXAActiveOrSyncRequired();
            }
            isActive = (mSyncState & ~INITIALIZED) != 0;
        }

        return isActive;
    }
   
    /**
     * Determine if synchronization and/or XA recovery are required.
     * Copy the master registry from the DAS. 
     * Open that master and the local and extract the information needed to answer the question.
     * @return boolean containing the answer.
     */
    private void computeXAActiveOrSyncRequired()
   
    {
        Exception   e = null;
        int         result = 0;
         
        try
        {
            HashMap                 syncReg;
            HashMap                 localReg;
            ByteArrayInputStream    bais;
            
            getDASDownloadMBeanServer();        
            mTarget = mPlatform.getTargetName();
            syncReg = scanRegistry(bais = downloadRegistry());
            localReg = getLocalRegInfo();            
            result = regMapsDiff(syncReg, localReg) |
                    (allShutdown(localReg) ? 0: ALL_NOT_SHUTDOWN) |
                    INITIALIZED;
            
            /*
             * If we are going to need the registry for synchronization, copy the registry from memory to
             * a file.
             */
            if ((result & SYNC_REQUIRED) != 0)
            {
                byte[]              buffer = new byte[8192];
                int                 count;
                FileOutputStream     fos;
                
                bais.reset();
                fos = new FileOutputStream(com.sun.jbi.util.EnvironmentAccess.getContext().getJbiInstanceRoot() + "/tmp/jbi-registry-sync.xml");
                while ((count = bais.read(buffer)) > 0)
                {
                    fos.write(buffer, 0, count);
                }
                fos.flush();
                fos.close();
            }
        }
        catch (SyncException sEx)
        {
            e = sEx;
        }
        catch (Exception ex)
        {
            e = ex;
        }
        if (e != null)
        {
            ByteArrayOutputStream   b = new ByteArrayOutputStream();
            PrintStream             ps = new PrintStream(b);
            e.printStackTrace(ps);
            ps.flush();
            mLogger.info(mTranslator.getString(LocalStringKeys.JBI_SYNC_DAS_NOT_AVAILABLE));                   
            mLogger.fine(mTranslator.getString(LocalStringKeys.JBI_SYNC_CHECK_FAILED , b.toString()));                   
        }

        mLogger.fine("JBI-Synchronization required state is: " + result);
        mSyncState = result;
    }
 
    public boolean isSyncRequired()
    {
        return ((mSyncState & SYNC_REQUIRED) != 0);
    }
    
    void getDASDownloadMBeanServer()
    {
        //
        //  Get a connection to the DAS MBean Server for Synchronization downloads.
        //
        try
        {
            mMBeanServer = mPlatform.getMBeanServerConnection(mPlatform.getAdminServerName());
        }
        catch (Exception e)
        {
            mLogger.info(mTranslator.getString(LocalStringKeys.JBI_SYNC_DAS_NOT_AVAILABLE));
            {
                ByteArrayOutputStream   baos = new ByteArrayOutputStream
();
                PrintStream             ps = new PrintStream(baos);
                e.printStackTrace(ps);
                ps.flush();
                mLogger.fine(mTranslator.getString(LocalStringKeys.JBI_SYNC_DAS_FAILURE, baos.toString()));
            }        
        }
    }
    
    /**
     * Cleanup anything created by RegistryHelper.
     */
    public void cleanup()
    {
        if (mMasterRegistry != null)
        {
            mMasterRegistry.destroy();
            mMasterRegistry = null;
        }
    }

    /**
     * Get local registry information. The result is cached internally so repeated calls
     * are cheap.
     */
    
    synchronized HashMap getLocalRegInfo()
    {
        File                    reg;
        
        if (mLocalReg == null)
        {
            try
            {
                Document regDoc = com.sun.jbi.util.EnvironmentAccess.getContext().getReadOnlyRegistry();
                if ( regDoc != null )
                {
                    mLocalReg = scanRegistry(regDoc);
                }
            }
            catch (Exception ex)
            {
                
            }
        }
        return (mLocalReg);
    }

    /**
     * Diff the contents of the construction time registry with the copy of the DAS registry.
     * The DAS registry is considered the master.
     * @return indication of any differences found
     */
    public boolean diffRegistry()
        throws SyncException
    {
        Properties          props = new Properties();
        Registry            syncReg;
        RegistrySpecImpl    rs = null;
       
        try
        {
            //
            //  Finish initialization now that we are going to open the registry.
            //
            mRegistry = (com.sun.jbi.management.registry.Registry)com.sun.jbi.util.EnvironmentAccess.getContext().getRegistry();
            mDASRegistryFileName = DAS_RELATIVE_PATH + File.separator + mRegistry.getProperty(Registry.REGISTRY_FILE_PROPERTY);
            mSyncRegistryFileName = mRegistry.getProperty(Registry.REGISTRY_SYNC_FILE_PROPERTY);
            mSyncFolder = com.sun.jbi.util.EnvironmentAccess.getContext().getJbiInstanceRoot() + "/tmp";

            //
            //  Point at the sync-copy of the master registry.
            //

            props.put(Registry.REGISTRY_FILE_PROPERTY, mSyncRegistryFileName);    
            props.put(Registry.REGISTRY_FOLDER_PROPERTY, mSyncFolder);
            props.put(Registry.REGISTRY_READONLY_PROPERTY, "true");
            
            //
            //  Build and open the master.
            //
            mMasterRegistry = RegistryBuilder.buildRegistry(
                rs = new RegistrySpecImpl(RegistryType.XML, props, mRegistry.getRegistrySpec().getManagementContext()));
            
            //
            //  Compute differences.
            //
            mDiff = new RegistryDiff(mMasterRegistry, mRegistry, mTarget);
            return (mDiff.computeDiff());
        }
        catch (RegistryException rEx)
        {
            throw new SyncException(mTranslator.getString(LocalStringKeys.JBI_SYNC_CONFIG_DIFF, rEx));
        }
    }
    
    /**
     * Get the list of new shared libraries in the master.
     * @return List of shared library names.
     */
    public List<String> getNewSharedLibraries()
    {
        return (mDiff.getNewSharedLibraries());
    }
    
    /**
     * Get ComponentInfo about a new SharedLibrary
     * @param slName - name of shared library in master
     * @return ComponentInfo for the given shared library.
     */
    public ComponentInfo getNewSharedLibraryInfo(String slName)
    {
        return (mDiff.getNewSharedLibraryInfo(slName));
    }
    
    /**
     * Get the list of old shared libraries in the target.
     * @return List of shared library names.
     */
    public List<String> getOldSharedLibraries()
    {
        return (mDiff.getOldSharedLibraries());
    }
    
    /**
     * Get the list of replaced shared libraries in the target.
     * @return List of shared library names.
     */
    public List<String> getReplacedSharedLibraries()
    {
        return (mDiff.getReplacedSharedLibraries());
    }
    
    /**
     * Get the list of replaced service assemblies in the target.
     * @return List of shared library names.
     */
    public List<String> getReplacedServiceAssemblies()
    {
        return (mDiff.getReplacedServiceAssemblies());
    }
    
   /**
     * Get the list of new components  in the master.
     * @return List of component names.
     */
    public List<String> getNewComponents()
    {
        return (mDiff.getNewComponents());
    }
    
    /**
     * Get the list of updated components  in the master.
     * @return List of component names.
     */
    public List<String> getUpdatedComponents()
    {
        return (mDiff.getUpdatedComponents());
    }
 
    /**
     * Get the list of replaced components  in the master.
     * @return List of component names.
     */
    public List<String> getReplacedComponents()
    {
        return (mDiff.getReplacedComponents());
    }
    
    /**
     * Get ComponentInfo about a new Component
     * @param compName - name of component in master
     * @return ComponentInfo for the given component
     */
    public ComponentInfo getNewComponentInfo(String compName)
    {
        return (mDiff.getNewComponentInfo(compName));
    }
    
    /**
     * Get the list of old components in the target.
     * @return List of component names.
     */
    public List<String> getOldComponents()
    {
        return (mDiff.getOldComponents());
    }
    
    /**
     * Get the list of components with lifecycle changes. 
     * @return List of components names.\
     */
    public List<String> getChangedLifeCycleComponents()
    {
        return (mDiff.getChangedLifeCycleComponents());
    }
    
    /**
     * Get the list of components affected by other changes. This typically
     * means a dependent shared libaray has changed.
     * @return List of components names.\
     */
    public List<String> getAffectedComponents()
    {
        return (mDiff.getAffectedComponents());
    }
    
    /**
     * Get the list of new service assemblies in the master.
     * @return List of service assemblies names.
     */
    public List<String> getNewServiceAssemblies()
    {
        return (mDiff.getNewServiceAssemblies());
    }
        
    /**
     * Get the list of old service assemblies in the target.
     * @return List of service assemblies names.
     */
    public List<String> getOldServiceAssemblies()
    {
        return (mDiff.getOldServiceAssemblies());
    }
    
    /**
     * Compute the state of a new service assembly (exists in master) from the state of the service units.
     * @param saName - name of the service assembly
     * @return service assembly state
     */
    public ServiceAssemblyState getNewServiceAssemblyState(String saName)
    {
        return (mDiff.getNewServiceAssemblyState(saName));
    }
    
    /**
     * Get the list of service assemblies affected by other changes. This typically
     * means a dependent component has changed.
     * @return List of service assembly names.
     */
    public List<String> getAffectedServiceAssemblies()
    {
        return (mDiff.getAffectedServiceAssemblies());
    }
    
    /**
     * Get the list of service assemblies with lifecycle changes. 
     * @return List of service assembly names.
     */
    public List<String> getChangedLifeCycleServiceAssemblies()
    {
        return (mDiff.getChangedLifeCycleServiceAssemblies());
    }
    
    /**
     * Compute the set of components that need to be started so that a deploy service assembly
     * operation can execute.
     * @return List of components name that need to be started.
     */
    public List<String> componentsToStartForDeploy()
    {
        return (mDiff.componentsToStartForDeploy());
    }
    
    /**
     * Compute the set of components that need to be started so that a undeploy service assembly
     * operation can execute.
     * @return List of components name that need to be started.
     */
    public List<String> componentsToStartForUndeploy()
    {
        return (mDiff.componentsToStartForUndeploy());
    }

    public List<String> getChangedConfigComponents()
    {
        return (mDiff.getChangedConfigComponents());
    }
    
    public Map<String, String> getGlobalConfigChanges(String category)
    {
        return (mDiff.getGlobalConfigChanges(category));
    }
    
    public Map<String, String> getConfigChanges(String category)
    {
        return (mDiff.getConfigChanges(category));
    }
    
    public Map<String, Properties> getComponentPropertyUpdates()
    {
        return (mDiff.getComponentPropertyUpdates());
    }
    
    public Map<String, Variable[]> getAddComponentAppVars()
    {
        return (mDiff.getAddComponentAppVars());
    }
    
    public Map<String, String[]> getRemoveComponentAppVars()
    {
        return (mDiff.getRemoveComponentAppVars());
    }
    
    public Map<String, Map<String, Properties>> getAddComponentConfigs()
    {
        return (mDiff.getAddComponentConfigs());
    }
    
    public Map<String, String> getRemoveComponentConfigs()
    {
        return (mDiff.getRemoveComponentConfigs());
    }
    
   /**
    * Download a shared library archive that will be required to perform synchronization actions.
    * @param slName - name of shared library to download from the DAS
    * @return the string containing the filename with the contents
    * @throws SyncException if anything bad happens
     */
    public String downloadSharedLibraryArchive(String slName)
        throws SyncException
    {
        Exception       e = null;
        
        try
        {
            Object          slId = getSharedLibraryArchiveId(slName);
            ComponentInfo   ci = mDiff.getNewSharedLibraryInfo(slName);
            GenericQuery    mQuery = mMasterRegistry.getGenericQuery();
            String          reposFilename = mQuery.getSharedLibraryFileName(ci.getName());
            long           timestamp = mQuery.getSharedLibraryTimestamp(ci.getName());
            
            return (downloadFile(slId, reposFilename, timestamp));
        }
        catch (Exception ex)
        {        
            throw new SyncException(mTranslator.getString(LocalStringKeys.JBI_SYNC_ARCHIVE, ex));   
        }
    }
        
   /**
    * Download a component archive that will be required to perform synchronization actions.
    * @param compName - name of component to download from the DAS
    * @return the string containing the filename with the contents
    * @throws SyncException if anything bad happens
     */
    public String downloadComponentArchive(String compName)
        throws SyncException
    {
        try
        {
            Object          cId = getComponentArchiveId(compName);
            ComponentInfo   ci = mDiff.getNewComponentInfo(compName);
            GenericQuery    mQuery = mMasterRegistry.getGenericQuery();
            String          reposFilename = mQuery.getComponentFileName(ci.getName());
            long           timestamp = mQuery.getComponentTimestamp(ci.getName());
            
            return (downloadFile(cId, reposFilename, timestamp));
        }
        catch (Exception ex)
        {
            throw new SyncException(mTranslator.getString(LocalStringKeys.JBI_SYNC_ARCHIVE, ex));
        }
    }
        
   /**
    * Download a service assembly archive that will be required to perform synchronization actions.
    * @param saName - name of service assembly to download from the DAS
    * @return the string containing the filename with the contents
    * @throws SyncException if anything bad happens
     */
    public String downloadServiceAssemblyArchive(String saName)
        throws SyncException
    {
        try
        {
            Object                  saaId = getServiceAssemblyArchiveId(saName);
            ServiceAssemblyInfo     sai = mDiff.getNewServiceAssemblyInfo(saName);
            GenericQuery            mQuery = mMasterRegistry.getGenericQuery();
            String                  reposFilename = mQuery.getServiceAssemblyFileName(sai.getName());
            long                   timestamp =  mQuery.getServiceAssemblyTimestamp(sai.getName());
            
            return (downloadFile(saaId, reposFilename, timestamp));
        }
        catch (Exception ex)
        {
            throw new SyncException(mTranslator.getString(LocalStringKeys.JBI_SYNC_ARCHIVE, ex));
        }
    }
    
    /**
     * Download a file from the DAS into the instances JBI temp directory.
     * @param fileId - opaque identifer for remote file on DAS
     * @param fileName - used to create a local file
     * @param timestamp - that should be applied to the downloaded file.
     * @return string containing the name of the file on the local system
     * @throws SyncException if anything bad happens
     */
    private String downloadFile(Object fileId, String fileName, long timestamp)
        throws SyncException
    {
        byte[]             buffer;
        File                outFile = new File (mInstanceRootPath + "/tmp/" + fileName);
        FileOutputStream    fis;
        Object              downId;
        
        try
        {
            downId = initiateDownload(fileId);
            fis = new FileOutputStream(outFile);
            while ((buffer = downloadBytes(downId, 8192)).length > 0)
            {
                fis.write(buffer, 0, buffer.length);
            }
            terminateDownload(downId);
            fis.flush();
            fis.close();
            if (timestamp != 0)
            {
                outFile.setLastModified(timestamp);
            }
            return (outFile.getPath());
        }
        catch (java.lang.Exception ex)
        {
            ByteArrayOutputStream   b = new ByteArrayOutputStream();
            PrintStream             ps = new PrintStream(b);
            ex.printStackTrace(ps);
            ps.flush();
            throw new SyncException(mTranslator.getString(LocalStringKeys.JBI_SYNC_FILE_COPY_FAILED,
                    "jbi-registry.xml", outFile.getName(), b.toString()));
        }  
     }
    
    /**
     * Download a file from the DAS into the instances JBI temp directory.
     * @return string containing the name of the file on the local system
     * @throws SyncException if anything bad happens
     */
    private ByteArrayInputStream downloadRegistry()
        throws SyncException
    {
        byte[]                  buffer;
        ByteArrayOutputStream    baos;
        Object                   downId;
        
        try
        {
            downId = initiateRegistryDownload();
            baos = new ByteArrayOutputStream();
            while ((buffer = downloadBytes(downId, 8192)).length > 0)
            {
                baos.write(buffer, 0, buffer.length);
            }
            terminateDownload(downId);
            baos.flush();
            baos.close();
            return (new ByteArrayInputStream(baos.toByteArray()));
        }
        catch (java.lang.Exception ex)
        {
            ByteArrayOutputStream   b = new ByteArrayOutputStream();
            PrintStream             ps = new PrintStream(b);
            if (ex.getCause() != null)
            {
                ex.getCause().printStackTrace(ps);
            }
            ex.printStackTrace(ps);
            ps.flush();
            throw new SyncException(mTranslator.getString(LocalStringKeys.JBI_SYNC_FILE_COPY_FAILED,
                    "jbi-registry.xml", "<Memory>", b.toString()));
        }  
     }
    
    /** 
     *  Returns the archive id of a service assembly in the repository.
     *  @param saName name of the service assembly
     *  @return archive ID, or null if the service assembly does not exist
     *  in the repository.
     */
    private Object getServiceAssemblyArchiveId(String saName)
        throws Exception
    {
        Object[] params = new Object[]{saName};
        String[] sign = new String[]{"java.lang.String"};
        
        return mMBeanServer.invoke(mDASDownloadMBeanName, "getServiceAssemblyArchiveId", params, sign);        
    }
    
     /** 
     *  Returns the archive id of a component in the repository.
     *  @param componentName name of the component
     *  @return archive ID, or null if the component does not exist
     *  in the repository.
     */
    private Object getComponentArchiveId(String componentName)
        throws Exception
    {
        Object[] params = new Object[]{componentName};
        String[] sign = new String[]{"java.lang.String"};
        
        return mMBeanServer.invoke(mDASDownloadMBeanName, "getComponentArchiveId", params, sign);
    }
    
    /** 
     *  Returns the archive id of a shared library in the repository.
     *  @param sharedLibrayName name of the shared library
     *  @return archive ID, or null if the shared library does not exist
     *  in the repository.
     */
    private Object getSharedLibraryArchiveId(String sharedLibraryName)
        throws Exception
    {
        Object[] params = new Object[]{sharedLibraryName};
        String[] sign = new String[]{"java.lang.String"};
        
        return mMBeanServer.invoke(mDASDownloadMBeanName, "getSharedLibraryArchiveId", params, sign);
    }
    
    /**
     * Initiate the download of the specified file.
     */
    private Object initiateDownload(Object archiveId)
        throws Exception
    {
        Object[] params = new Object[]{archiveId};
        String[] sign = new String[]{"java.lang.Object"};
        
        return mMBeanServer.invoke(mDASDownloadMBeanName, "initiateDownload", params, sign);
    }
    
    /**
     * Initiate the download of the specified file.
     */
    private Object initiateRegistryDownload()
        throws Exception
    {
        return mMBeanServer.invoke(mDASDownloadMBeanName, "initiateRegistryDownload", new Object[0], new String[0]);
    }
    
    /**
     * Download Bytes.
     */
    private byte[] downloadBytes(Object downId, int count)
        throws Exception
    {
        Object[] params = new Object[]{downId, Integer.valueOf(count)};
        String[] sign = new String[]{"java.lang.Object", "int"};
        
        return (byte[])mMBeanServer.invoke(mDASDownloadMBeanName, "downloadBytes", params, sign);
    }

    /**
     * Terminate the Upload.
     */
    private void terminateDownload(Object downId)
        throws Exception
    {
        Object[] params = new Object[]{downId};
        String[] sign = new String[]{"java.lang.Object"};
        
        mMBeanServer.invoke(mDASDownloadMBeanName, "terminateDownload", params, sign);
    }

    
   /** 
     *  This method performs a quick scan of a registry and extracts state needed to 
     *  decide if an instance requires synchronization.
     *  @param filename - contains the registry to scan
     *  @return HashMap 
     *  @throws Exception on any problem
     */
    private HashMap<String,HashMap> scanRegistry(InputStream is)
        throws Exception
    {
        DocumentBuilderFactory      dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder             db = dbf.newDocumentBuilder();
        Document doc =              db.parse(is);
        return scanRegistry(doc);
    }
    
    /** 
     *  This method performs a quick scan of a registry and extracts state needed to 
     *  decide if an instance requires synchronization.
     *  @param doc - the registry document object
     *  @return HashMap 
     *  @throws Exception on any problem
     */
    private HashMap<String,HashMap> scanRegistry(Document doc)
        throws Exception
    {
        String                      targetName = mPlatform.getTargetName();
        HashMap<String, HashMap>    result = new HashMap();
        NodeList                    instances;
        Element                     target = null;

        
        if (mPlatform.isStandaloneServer(targetName))
        {
            instances = doc.getDocumentElement().getElementsByTagName("server");
        }
        else
        {
            instances = doc.getDocumentElement().getElementsByTagName("cluster");
        }
        if (instances != null)
        {
            for (int i = 0; i < instances.getLength(); i++)
            {
                Element instance = (Element)instances.item(i);
                if (instance.getAttribute("name-ref").equalsIgnoreCase(targetName))
                {
                    target = instance;
                    break;
                }
            }
            if (target != null)
            {
                result.put(COMP_KEY, makeRefMap(makeElementMap(
                        doc.getDocumentElement(), JBI_SCHEMA_COMPONENT), 
                            target, JBI_SCHEMA_COMPONENT_REF, JBI_SCHEMA_NAME_REF));
                result.put(SL_KEY, makeRefMap(makeElementMap(
                        doc.getDocumentElement(), JBI_SCHEMA_SHARED_LIBRARY), 
                            target, JBI_SCHEMA_SHARED_LIBRARY_REF, JBI_SCHEMA_NAME_REF));
                result.put(SA_KEY, makeSURefMap(makeElementMap(
                        doc.getDocumentElement(), JBI_SCHEMA_SERVICE_ASSEMBLY), target));
                result.put(DOMAIN_KEY, makeConfigMap(doc.getDocumentElement(), "domain-config"));
                result.put(INSTANCE_KEY, makeConfigMap(doc.getDocumentElement(), targetName + "-config"));            }
                makeConfigurationMap(result, target);
        }
        
        return (result);
    }
    
   /** 
     * This method extracts config information from the registry.
     * @param e - DOM Element to start tag search
     * @param targetName - instance to process
     * @return HashMap keyed by name containing the EntityInfo. 
     */
    private static HashMap<String, HashMap> makeConfigMap(Element e, String targetName)
    {
        NodeList                    instances;
        Element                     target = null;
        HashMap                     configMap = new HashMap();
        
        instances = e.getElementsByTagName(JBI_SCHEMA_CONFIG);
        if (instances != null)
        {
            for (int i = 0; i < instances.getLength(); i++)
            {
                Element instance = (Element)instances.item(i);
                if (instance.getAttribute(JBI_SCHEMA_NAME).equalsIgnoreCase(targetName))
                {
                    target = instance;
                    break;
                }
            }
        }
        if (target != null)
        {
            instances = target.getElementsByTagName(JBI_SCHEMA_CONFIG_TYPE);
            if (instances != null)
            {
                for (int i = 0; i < instances.getLength(); i++)
                {
                    Element instance = (Element)instances.item(i);
                    String category = instance.getAttribute(JBI_SCHEMA_CATEGORY);
                    if (category.equals("Logger"))
                    {
                        continue;
                    }
                    
                    NodeList properties = instance.getElementsByTagName(JBI_SCHEMA_PROPERTY);
                    HashMap<String, String> map = null;

                    if (properties != null)
                    {
                        map = new HashMap();
                        for (int j = 0; j < properties.getLength(); j++)
                        {
                            String  name;
                            String  value;
                            Element property;

                            property = (Element)properties.item(j);
                            Text prop1 = (Text)property.getFirstChild();
                            Text prop2 = (Text)property.getLastChild();;

                            if (prop1.getWholeText().equals(JBI_SCHEMA_NAME))
                            {
                                name = prop1.getWholeText();
                                value = prop2.getWholeText();
                            }
                            else
                            {
                                name = prop2.getWholeText();
                                value = prop1.getWholeText();
                            }
                            map.put(name, value);
                        }
                        configMap.put(category, map);
                    }
                }
            }
        }
        return (configMap);
    }

    /**
     * This method extracts NAME and TIMESTAMP attributes from the requested tag.
     * @param e - DOM Element to start tag search
     * @param tag - to search for
     * @return HashMap keyed by name containing the EntityInfo. 
     */
    private static HashMap<String, EntityInfo> makeElementMap(Element e, String tag)
    {
        HashMap<String, EntityInfo> map = new HashMap();
        NodeList tags = e.getElementsByTagName(tag);
        for (int i = 0; i < tags.getLength(); i++)
        {
            Element instance = (Element)tags.item(i);
            EntityInfo  ei = new EntityInfo();
            ei.mName = instance.getAttribute(JBI_SCHEMA_NAME);
            ei.mTimestamp = instance.getAttribute(JBI_SCHEMA_TIMESTAMP);
            ei.mUpdateNumber = instance.getAttribute(JBI_SCHEMA_UPDATENUMBER);
            if (ei.mUpdateNumber == null)
            {
                ei.mUpdateNumber = "";
            }
            map.put(ei.mName, ei);                    
        }
        return (map);        
    }
    
    /**
     * This method merges the generic entity and specific entity information into a single result.
     * Typically, this means extracting the STATE information and updating the cooresponding EntityInfo.
     * @param emap - HashMap containing generic EntityIno
     * @param e - DOM Element to used as the search anchor
     * @param tag - Tag of the Entity to find in e
     * @param nametag - Tag of Attribute in found Entity to use as a lookup for EntityInfo.
     * @return HashMap keyed by name containing the EntityInfo. 
     */
    private static HashMap<String, EntityInfo> makeRefMap(HashMap<String,EntityInfo> emap, Element e, String tag, String nametag)
    {
        HashMap<String, EntityInfo> map = new HashMap();
        NodeList tags = e.getElementsByTagName(tag);
        for (int i = 0; i < tags.getLength(); i++)
        {
            Element instance = (Element)tags.item(i);
            String  nameref = instance.getAttribute(nametag);
            EntityInfo  ei = emap.get(nameref);
            if (nameref != null)
            {
                ei.mState = instance.getAttribute(JBI_SCHEMA_STATE);
                ei.mUpdateNumber = instance.getAttribute(JBI_SCHEMA_UPDATENUMBER);
                if (ei.mUpdateNumber == null)
                {
                    ei.mUpdateNumber = "";
                }
                map.put(nameref, ei);                    
            }
        }
        return (map);        
    }

    /**
     * This method specificly handles ServiceAssembly/ServiceUnit result building (this is a 1<->N
     * relationship.) The result size corresponds to the ServiceUnit count.
     * @param emap - HashMap containing generic EntityInfo
     * @param e - DOM Element to used as the search anchor
     * @return HashMap keyed by name containing the EntityInfo. 
     */
    private static HashMap<String, EntityInfo> makeSURefMap(HashMap<String,EntityInfo> emap, Element e)
    {
        HashMap<String, EntityInfo> map = new HashMap();
        NodeList tags = e.getElementsByTagName(JBI_SCHEMA_SERVICE_UNIT);
        
        for (int i = 0; i < tags.getLength(); i++)
        {
            Element instance = (Element)tags.item(i);
            String  sanameref = instance.getAttribute(JBI_SCHEMA_SERVICE_ASSEMBLY_REF);
            
            if (sanameref != null)
            {
                EntityInfo  ei = emap.get(sanameref);
                EntityInfo  nei = new EntityInfo();
                
                nei.mName = instance.getAttribute(JBI_SCHEMA_NAME);
                nei.mState = instance.getAttribute(JBI_SCHEMA_STATE);
                nei.mUpdateNumber = instance.getAttribute(JBI_SCHEMA_UPDATENUMBER);
                if (nei.mUpdateNumber == null)
                {
                    nei.mUpdateNumber = "";
                }
                nei.mTimestamp = ei.mTimestamp;
                map.put(nei.mName, nei);                    
            }
        }
        return (map);        
    }
    
    private static void makeConfigurationMap(HashMap<String, HashMap> result, Element e)
    {
        NodeList    components = e.getElementsByTagName(JBI_SCHEMA_COMPONENT_REF);
        
        if (components != null)
        {
            for (int i = 0; i < components.getLength(); i++)
            {
                Element ref = (Element)components.item(i);
                String  nameRef = ref.getAttribute(JBI_SCHEMA_NAME_REF);
                
                NodeList    configs = ref.getElementsByTagName(JBI_SCHEMA_COMPONENT_CONFIG);
                
                if (configs != null)
                {
                    Element config = (Element)configs.item(0);
                    if (config != null)
                    {
                        result.put(STATIC_CONF_KEY, getProperties(config));
                        result.put(APPVAR_CONF_KEY, getApplicationVariables(config));
                        result.put(APPCON_CONF_KEY, getApplicationConfiguration(config));
                    }
                }             
            }            
        }        
    }
    
    
    private static HashMap<String, AppVarInfo> getApplicationVariables(Element e)
    {
        NodeList                       apps = e.getElementsByTagName(JBI_SCHEMA_APPLICATION_VARIABLE);
        HashMap<String, AppVarInfo>    appCon = new HashMap();
        
        if (apps != null)
        {
            for (int i = 0; i < apps.getLength(); i++)
            {
                Element     app = (Element)apps.item(i);
                Node        nameNode = app.getFirstChild();
                Node        valueNode = nameNode.getNextSibling();
                Node        typeNode = valueNode.getNextSibling();
                AppVarInfo  avi = new AppVarInfo();
                avi.mType = typeNode.getTextContent();
                avi.mValue = valueNode.getTextContent();
                
                appCon.put(nameNode.getTextContent(), avi);
            }
        }
        
        return (appCon);
        
    }
    
    private static HashMap<String, HashMap> getApplicationConfiguration(Element e)
    {
        NodeList                    apps = e.getElementsByTagName(JBI_SCHEMA_APPLICATION_CONFIGURATION);
        HashMap<String, HashMap>    appCon = new HashMap();
        
        if (apps != null)
        {
            for (int i = 0; i < apps.getLength(); i++)
            {
                Element app = (Element)apps.item(i);
                String  appconName = app.getAttribute(JBI_SCHEMA_NAME);
                
                appCon.put(appconName, getProperties(app));
            }
        }
        
        return (appCon);
    }
    
    private static HashMap<String, String> getProperties(Element e)
    {
        NodeList                props = e.getElementsByTagName(JBI_SCHEMA_PROPERTY);
        HashMap<String,String>  result = new HashMap();
        
        if (props != null)
        {
            for (int i = 0; i < props.getLength(); i++)
            {
                Element prop = (Element)props.item(i);
                Node    nameNode = prop.getFirstChild();
                Node    valueNode = nameNode.getNextSibling();
        
                result.put(nameNode.getTextContent(), valueNode.getTextContent());
            }
        }
        
        return (result);        
    }
    
   /** 
     *  This method determines if all components are in SHUTDOWN state.
     *  @param map - HashMap containing the local values
     *  @return int answering question is they are different 
    **/
    private boolean allShutdown(HashMap map)
    {
        boolean result = true;
        
        if (map != null)
        {
            HashMap<String,EntityInfo>  local = (HashMap)map.get(COMP_KEY);
            
            if (local != null)
            {
                for (Map.Entry<String,EntityInfo> e : local.entrySet())
                {
                    EntityInfo  ie = e.getValue();

                    if (ie.mState.equals(ComponentState.getLifeCycleState(ComponentState.SHUTDOWN)))
                    {
                        continue;
                    }
                    result = false;
                    break;
                }            
            }
        }
        return (result);
    }

   /** 
     *  This method computes if a material difference exists between two registry contents.
     *  @param syncMap - HashMap containing the reference
     *  @param localMap - HashMap containing the local value
     *  @return boolean answering question is they are different 
    **/
    private int regMapsDiff(HashMap   syncMap, HashMap localMap)
    {
        int result = localMap == null ? SYNC_REQUIRED: 0;
        
        if (result != SYNC_REQUIRED)
        {
            result = diff(syncMap, localMap, COMP_KEY);
        }
        if (result != SYNC_REQUIRED)
        {
            result = diff(syncMap, localMap, SL_KEY);
        }
        if (result != SYNC_REQUIRED)
        {
            result = diff(syncMap, localMap, SA_KEY);
        }
        if (result != SYNC_REQUIRED)
        {
            result = diffConfig(syncMap, localMap, DOMAIN_KEY);
        }
        if (result != SYNC_REQUIRED)
        {
            result = diffConfig(syncMap, localMap, INSTANCE_KEY);
        }
        if (result != SYNC_REQUIRED)
        {
            result = diffStaticProps(syncMap, localMap, STATIC_CONF_KEY);
        }
        if (result != SYNC_REQUIRED)
        {
            result = diffAppVars(syncMap, localMap, APPVAR_CONF_KEY);
        }
        if (result != SYNC_REQUIRED)
        {
            result = diffAppConf(syncMap, localMap, APPCON_CONF_KEY);
        }

        return (result);
    }

    private int diff(HashMap<String, HashMap> syncMap, HashMap<String, HashMap> localMap, String key)
    {
        HashMap<String,EntityInfo>  sync = (HashMap)syncMap.get(key);
        HashMap<String,EntityInfo>  local = (HashMap)localMap.get(key);
        int                         result = SYNC_REQUIRED;
        
        if (sync != null && local != null && sync.size() == local.size())
        {
            result = 0;
            for (Map.Entry<String,EntityInfo> e : sync.entrySet())
            {
                EntityInfo  sie = e.getValue();
                EntityInfo  lie = local.get(sie.mName);
                
                if (lie != null &&
                    sie.mTimestamp.equals(lie.mTimestamp) &&
                    sie.mState.equals(lie.mState) &&
                    sie.mUpdateNumber.equals(lie.mUpdateNumber))
                {
                    continue;
                }
                result = SYNC_REQUIRED;
                break;
            }            
        }
        
        return (result);
    }
    
    private int diffConfig(HashMap<String, HashMap> syncMap, HashMap<String, HashMap> localMap, String key)
    {
        HashMap<String,HashMap>  sync = (HashMap)syncMap.get(key);
        HashMap<String,HashMap>  local = (HashMap)localMap.get(key);
        int                      result = SYNC_REQUIRED;
        
        if (sync != null && local != null && sync.size() == local.size())
        {
            result = 0;
            for (Map.Entry<String,HashMap> e : sync.entrySet())
            {
                String                  category = e.getKey();
                HashMap<String,String>  cats = e.getValue();
                HashMap<String,String>  locals = local.get(category);
                
                if (locals != null &&
                    cats.size() == locals.size())
                {
                    for (String name : cats.keySet())
                    {
                        String  value = locals.get(name);
                        
                        if (value != null)
                        {
                            if (cats.get(name).equals(value))
                            {
                                continue;
                            }
                        }
                        result = SYNC_REQUIRED;
                        break;
                    }
                    if (result == 0)
                    {
                        continue;
                    }
                }
                result = SYNC_REQUIRED;
                break;
            }            
        }
        
        return (result);
    }
    
    
    private int diffStaticProps(HashMap<String, HashMap> syncMap, HashMap<String, HashMap> localMap, String key)
    {
        HashMap<String,String>  sync = (HashMap)syncMap.get(key);
        HashMap<String,String>  local = (HashMap)localMap.get(key);
        int                     result = SYNC_REQUIRED;

        return (diffProps(sync, local));
    }
    
    
    private int diffAppVars(HashMap<String, HashMap> syncMap, HashMap<String, HashMap> localMap, String key)
    {
        HashMap<String,AppVarInfo>  sync = (HashMap)syncMap.get(key);
        HashMap<String,AppVarInfo>  local = (HashMap)localMap.get(key);
        int result = 0;
        
        if (sync != null || local != null)
        {
            result = SYNC_REQUIRED;
            if (sync != null && local != null && sync.size() == local.size())
            {
                result = 0;
                for (Map.Entry<String,AppVarInfo> e : sync.entrySet())
                {
                    String                  confKey = e.getKey();
                    AppVarInfo              value = e.getValue();
                    AppVarInfo              localValue = local.get(confKey);

                    if (localValue != null &&
                            value.mType.equals(localValue.mType) &&
                            value.mValue.equals(localValue.mValue))
                    {
                        continue;
                    }
                    result = SYNC_REQUIRED;
                    break;
                }           
            }
        }
        return (result);
    }
    
    private int diffAppConf(HashMap<String, HashMap> syncMap, HashMap<String, HashMap> localMap, String key)
    {
        HashMap<String,HashMap>  sync = (HashMap)syncMap.get(key);
        HashMap<String,HashMap>  local = (HashMap)localMap.get(key);
        int result = 0;
        
        if (sync != null || local != null)
        {
            result = SYNC_REQUIRED;
            if (sync != null && local != null && sync.size() == local.size())
            {
                result = 0;
                for (Map.Entry<String,HashMap> e : sync.entrySet())
                {
                    String                  config = e.getKey();
                    HashMap<String,String>  value = e.getValue();
                    HashMap<String,String>  localValue = local.get(config);

                    if (diffProps(value, localValue) == 0)
                    {
                        continue;
                    }
                    result = SYNC_REQUIRED;
                    break;
                }            
            }
        }
        return (result);
    }
    
    private int diffProps(HashMap<String,String> sync, HashMap<String,String> local)
    {
        int result = 0;
        
        if (sync != null || local != null)
        {
            result = SYNC_REQUIRED;
            if (sync != null && local != null && sync.size() == local.size())
            {
                result = 0;
                for (Map.Entry<String,String> e : sync.entrySet())
                {
                    String                  confKey = e.getKey();
                    String                  value = e.getValue();
                    String                  localValue = local.get(confKey);

                    if (localValue != null && value.equals(localValue))
                    {
                        continue;
                    }
                    result = SYNC_REQUIRED;
                    break;
                }
            }
        }
        return (result);
    }

    /**
     * Temporary mostly for debugging purposes.
     */
    public void displayActions()
    {
        mLogger.info(mDiff.toString());
    }
}

class EntityInfo
{
    String      mName;
    String      mTimestamp;
    String      mUpdateNumber;
    String      mState;
}

class   AppVarInfo
{
    String      mValue;
    String      mType;
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.