All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.chrisjaehnen.tibco.bw.maven.plugin.TibcoBwPropertiesMavenPlugin Maven / Gradle / Ivy

Go to download

tibco-bw-properties-maven-plugin is an Apache Maven plugin for syncing TIBCO BW 6 module properties between shared modules and application modules and their application package projects

The newest version!
package org.chrisjaehnen.tibco.bw.maven.plugin;

import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.events.Characters;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.chrisjaehnen.tibco.bw.maven.plugin.model.ModuleManifestProperty;
import org.chrisjaehnen.tibco.bw.maven.plugin.model.ModuleMetadataProperty;
import org.chrisjaehnen.tibco.bw.maven.plugin.model.ModuleNamespace;
import org.chrisjaehnen.tibco.bw.maven.plugin.model.ModuleProperty;
import org.chrisjaehnen.tibco.bw.maven.plugin.util.LogUtils;
import org.chrisjaehnen.tibco.bw.maven.plugin.util.SaxUtils;
import org.jdom2.Attribute;
import org.jdom2.Document;
import org.jdom2.Element;

/**
 * The TibcoBwPropertiesMavenPlugin provides an implementation of a Maven
 * {@link Mojo} plugin used to sync a TIBCO BW application module with
 * module properties from a TIBCO BW shared module.
 *
 * By default, in order to limit the number of synced module properties,
 * no module properties will be synced. One will need to explicitly define
 * the module properties to sync or set all module properties to be synced.
 */
@Mojo(name = "sync-props")
public class TibcoBwPropertiesMavenPlugin extends AbstractMojo
{
    //------------------------------------------------------------------------------------------------------------------
    // Static Fields
    //------------------------------------------------------------------------------------------------------------------

    /**
     * Defines the name of the TIBCO BW module properties directory.
     */
    private static final String TIBCO_BW_PROPS_DIR = "META-INF";

    /**
     * Defines the name of the TIBCO BW module properties file.
     */
    private static final String TIBCO_BW_PROPS_FILE = "default.substvar";

    /**
     * Defines the name of the TIBCO BW module metadata properties file.
     */
    private static final String TIBCO_BW_PROPS_META_FILE = "module.bwm";

    /**
     * Defines the name of the TIBCO BW module manifest properties file.
     */
    private static final String TIBCO_BW_PROPS_MANIFEST_FILE = "props.mf";

    /**
     * Defines the prefix for system TIBCO BW module properties.
     */
    private static final String TIBCO_BW_SYS_PROP_PREFIX = "BW";

    //------------------------------------------------------------------------------------------------------------------
    // Fields
    //------------------------------------------------------------------------------------------------------------------

    /**
     * Defines the absolute path to the shared module properties file.
     */
    private File sharedModPropsFile;

    /**
     * Defines the absolute path to the shared module metadata properties file.
     */
    private File sharedModMetaPropsFile;

    /**
     * Defines the absolute path to the project application module properties
     * file.
     */
    private File projectModPropsFile;

    /**
     * Defines the absolute path to the project application module metadata
     * properties file.
     */
    private File projectModMetaPropsFile;

    /**
     * Defines the absolute path to the project application module manifest
     * properties file.
     */
    private File projectModManifestPropsFile;

    //------------------------------------------------------------------------------------------------------------------
    // Mojo Parameters
    //------------------------------------------------------------------------------------------------------------------

    /**
     * Defines a reference to the current {@link MavenProject} instance configured
     * to use this plugin.
     */
    @Parameter(defaultValue = "${project}", required = true, readonly = true)
    private MavenProject project;

    /**
     * Defines the name of the TIBCO BW shared module project.
     */
    @Parameter(property = "sharedModuleProject", defaultValue = "tibco-shared-mod")
    private String sharedModuleProject;

    /**
     * Defines a value indicating if all TIBCO BW module properties should
     * be synced.
     */
    @Parameter(property = "syncAllModuleProperties", defaultValue = "false")
    private boolean syncAllModuleProperties;

    /**
     * Defines a {@link List} of TIBCO BW module properties be included in
     * the sync.
     */
    @Parameter(property = "modulePropertyInclusions")
    private List modulePropertyInclusions;

    //------------------------------------------------------------------------------------------------------------------
    // Getters/Setters
    //------------------------------------------------------------------------------------------------------------------

    /**
     * Gets a reference to the {@link MavenProject} object.
     * @return A reference to the {@link MavenProject} object.
     */
    public MavenProject getProject()
    {
        return project;
    }

    /**
     * Sets a reference to the {@link MavenProject} object.
     * @param project A reference to the {@link MavenProject} object.
     */
    public void setProject(MavenProject project)
    {
        this.project = project;
    }

    /**
     * Gets the name of the TIBCO BW shared module project.
     * @return The name of the TIBCO BW shared module project.
     */
    public String getSharedModuleProject()
    {
        return sharedModuleProject;
    }

    /**
     * Sets the name of the TIBCO BW shared module project.
     * @param sharedModuleProject The name of the TIBCO BW shared module
     * project.
     */
    public void setSharedModuleProject(String sharedModuleProject)
    {
        this.sharedModuleProject = sharedModuleProject;
    }

    /**
     * Gets a value indicating if all TIBCO BW module properties should be
     * synced.
     * @return A value indicating if all TIBCO BW module properties should be
     * synced.
     */
    public boolean isSyncAllModuleProperties()
    {
        return syncAllModuleProperties;
    }

    /**
     * Sets a value indicating if all TIBCO BW module properties should be
     * synced.
     * @param syncAllModuleProperties A value indicating if all TIBCO BW module
     * properties should be synced.
     */
    public void setSyncAllModuleProperties(boolean syncAllModuleProperties)
    {
        this.syncAllModuleProperties = syncAllModuleProperties;
    }

    /**
     * Gets a list of module properties to include.
     * @return The list of module properties to include.
     */
    public List getModulePropertyInclusions()
    {
        return modulePropertyInclusions;
    }

    /**
     * Sets a list of module properties to include.
     * @param modulePropertyInclusions The list of module properties to include.
     */
    public void setModulePropertyInclusions(List modulePropertyInclusions)
    {
        this.modulePropertyInclusions = modulePropertyInclusions;
    }

    //------------------------------------------------------------------------------------------------------------------
    // Mojo Implementation
    //------------------------------------------------------------------------------------------------------------------

    @Override
    public void execute() throws MojoExecutionException
    {
        LogUtils.info("Syncing TIBCO BW shared module properties to application module...");

        // set Mojo fields
        this.setMojoFields();

        // initialize module properties files
        this.initModulePropertiesFile();

        // sync module properties
        this.syncModProps();

        // sync module metadata properties
        this.syncModMetadataProps();

        // sync orphaned module properties
        this.syncOrphanedModProps();

        LogUtils.info("Completed syncing of TIBCO BW shared module properties to application module!");
    }

    //------------------------------------------------------------------------------------------------------------------
    // Main Processing Methods
    //------------------------------------------------------------------------------------------------------------------

    /**
     * Sets fields used by this Mojo plugin to sync TIBCO BW module properties
     * from a shared module to a project application module.
     */
    private void setMojoFields()
    {
        // get absolute path to TIBCO BW projects source root directory
        String srcRootDirPath = new File(project.getBasedir().getParent()).getParent();

        // get directory name of TIBCO BW application module
        String appModDir = project.getBasedir().getName();

        // set absolute path to TIBCO BW shared module properties file
        sharedModPropsFile = new File(String.format("%s/%s/%s/%s",
                srcRootDirPath,
                sharedModuleProject,
                TIBCO_BW_PROPS_DIR,
                TIBCO_BW_PROPS_FILE));

        LogUtils.info("TIBCO BW shared module properties file: '%s'", sharedModPropsFile.getAbsolutePath());

        // set absolute path to TIBCO BW shared module metadata properties file
        sharedModMetaPropsFile = new File(String.format("%s/%s/%s/%s",
                srcRootDirPath,
                sharedModuleProject,
                TIBCO_BW_PROPS_DIR,
                TIBCO_BW_PROPS_META_FILE));

        LogUtils.info("TIBCO BW shared module metadata properties file: '%s'", sharedModMetaPropsFile.getAbsolutePath());

        // set absolute path to TIBCO BW project application module properties file
        projectModPropsFile = new File(String.format("%s/%s/%s/%s/%s",
                srcRootDirPath,
                appModDir,
                appModDir,
                TIBCO_BW_PROPS_DIR,
                TIBCO_BW_PROPS_FILE));

        LogUtils.info("TIBCO BW project application module properties file: '%s'", projectModPropsFile.getAbsolutePath());

        // set absolute path to TIBCO BW project application module metadata properties file
        projectModMetaPropsFile = new File(String.format("%s/%s/%s/%s/%s",
                srcRootDirPath,
                appModDir,
                appModDir,
                TIBCO_BW_PROPS_DIR,
                TIBCO_BW_PROPS_META_FILE));

        LogUtils.info("TIBCO BW project application module metadata properties file: '%s'", projectModMetaPropsFile.getAbsolutePath());

        // set absolute path to TIBCO BW project application module manifest properties file
        projectModManifestPropsFile = new File(String.format("%s/%s/%s/%s/%s",
                srcRootDirPath,
                appModDir,
                appModDir,
                TIBCO_BW_PROPS_DIR,
                TIBCO_BW_PROPS_MANIFEST_FILE));

        LogUtils.info("TIBCO BW project application module manifest properties file: '%s'", projectModManifestPropsFile.getAbsolutePath());
    }

    /**
     * Initializes module properties files, where applicable, prior to syncing
     * module properties.
     */
    private void initModulePropertiesFile()
    {
        // create empty project application module manifest properties file
        if (!projectModManifestPropsFile.exists())
        {
            SaxUtils.createEmptyXmlDocument(projectModManifestPropsFile, ModuleManifestProperty.MOD_MANIFEST_PROP_ROOT_ELEMENT);
            LogUtils.info("Creating empty TIBCO BW project application module manifest properties file: '%s'", projectModManifestPropsFile.getAbsolutePath());
        }
    }

    /**
     * Syncs TIBCO BW module properties defined in the shared module with module
     * properties defined in the project application module.
     */
    private void syncModProps()
    {
        // create XMLEventReader instances
        final XMLEventReader sourceXmlReader = SaxUtils.createXmlEventReader(sharedModPropsFile);
        final XMLEventReader targetXmlReader = SaxUtils.createXmlEventReader(projectModPropsFile);
        final XMLEventReader manifestXmlReader = SaxUtils.createXmlEventReader(projectModManifestPropsFile);

        // ensure XMLEventReader instances are set
        if (sourceXmlReader != null && targetXmlReader != null)
        {
            // parse XMLEventReader instances and get lists of module properties
            List sourceModProps = this.parseModuleProperties(sourceXmlReader);
            List targetModProps = this.parseModuleProperties(targetXmlReader);
            List modManifestProps = this.parseModuleManifestProperties(manifestXmlReader);

            // ensure module property lists are set
            if (sourceModProps != null && !sourceModProps.isEmpty() &&
                    targetModProps != null && !targetModProps.isEmpty())
            {
                // iterate through source module properties
                for (ModuleProperty sourceModProp : sourceModProps)
                {
                    // skip system module properties
                    if (sourceModProp.getName() != null &&
                            !sourceModProp.getName().startsWith(TIBCO_BW_SYS_PROP_PREFIX))
                    {
                        // only sync source module property to target if all or explicitly included
                        if (syncAllModuleProperties ||
                                (modulePropertyInclusions != null &&
                                modulePropertyInclusions.contains(sourceModProp.getName())))
                        {
                            // create module manifest property
                            ModuleManifestProperty modManifestProp = new ModuleManifestProperty(sourceModProp.getName());

                            // determine if source module property is not contained in target list
                            if (!this.hasModuleProperty(sourceModProp, targetModProps))
                            {
                                // sync source module property to target
                                this.createModuleProperty(sourceModProp, projectModPropsFile);

                                // sync module manifest property
                                if (!this.hasModuleManifestProperty(modManifestProp, modManifestProps))
                                {
                                    this.createModuleManifestProperty(modManifestProp, projectModManifestPropsFile);
                                }
                            }
                            else
                            {
                                // get target module property
                                ModuleProperty targetModProp = this.getModuleProperty(
                                        sourceModProp.getName(), targetModProps);

                                // sync source module property to target
                                this.updateModuleProperty(sourceModProp, targetModProp, projectModPropsFile);

                                // sync module manifest property to target
                                if (!this.hasModuleManifestProperty(modManifestProp, modManifestProps))
                                {
                                    this.createModuleManifestProperty(modManifestProp, projectModManifestPropsFile);
                                }
                            }
                        }
                        else
                        {
                            LogUtils.info("Skipping excluded module property: '%s'", sourceModProp.getName());
                        }
                    }
                }
            }
        }
    }

    /**
     * Syncs TIBCO BW metadata module properties defined in the shared module
     * with metadata module properties defined in the project application module.
     */
    private void syncModMetadataProps()
    {
        // create XMLEventReader instances
        final XMLEventReader sourceXmlReader = SaxUtils.createXmlEventReader(sharedModMetaPropsFile);
        final XMLEventReader targetXmlReader = SaxUtils.createXmlEventReader(projectModMetaPropsFile);

        // ensure XMLEventReader instances are set
        if (sourceXmlReader != null && targetXmlReader != null)
        {
            // parse XMLEventReader instances and get lists of module properties
            List sourceModMetaProps = this.parseModuleMetadataProperties(sourceXmlReader);
            List targetModMetaProps = this.parseModuleMetadataProperties(targetXmlReader);

            // ensure module property lists are set
            if (sourceModMetaProps != null && !sourceModMetaProps.isEmpty() &&
                    targetModMetaProps != null && !targetModMetaProps.isEmpty())
            {
                // iterate through source module metadata properties
                for (ModuleMetadataProperty sourceModMetaProp : sourceModMetaProps)
                {
                    // skip system module metadata properties
                    if (sourceModMetaProp.getName() != null &&
                            !sourceModMetaProp.getName().startsWith(TIBCO_BW_SYS_PROP_PREFIX))
                    {
                        // only sync source module property to target if all or explicitly included
                        if (syncAllModuleProperties ||
                                (modulePropertyInclusions != null &&
                                modulePropertyInclusions.contains(sourceModMetaProp.getName())))
                        {
                            // determine if source module metadata property is not contained in target list
                            if (!this.hasModuleMetadataProperty(sourceModMetaProp, targetModMetaProps))
                            {
                                // sync source module metadata property to target
                                this.createModuleMetadataProperty(sourceModMetaProp, projectModMetaPropsFile);
                            }
                            else
                            {
                                // get target module metadata property
                                ModuleMetadataProperty targetModMetaProp = this.getModuleMetadataProperty(
                                        sourceModMetaProp.getName(), targetModMetaProps);

                                // sync source module metadata property to target
                                this.updateModuleMetadataProperty(sourceModMetaProp, targetModMetaProp, projectModMetaPropsFile);
                            }
                        }
                    }
                }

                // sync root element to target module metadata properties file
                this.updateModuleMetadataPropertyRoot(projectModMetaPropsFile);
            }
        }
    }

    /**
     * Syncs TIBCO BW module properties removed from the shared module with
     * orphaned module properties defined in the project application module.
     */
    private void syncOrphanedModProps()
    {
        // create XMLEventReader instances
        final XMLEventReader sourceModPropsXmlReader = SaxUtils.createXmlEventReader(sharedModPropsFile);
        final XMLEventReader targetModPropsXmlReader = SaxUtils.createXmlEventReader(projectModPropsFile);
        final XMLEventReader targetModMetaPropsXmlReader = SaxUtils.createXmlEventReader(projectModMetaPropsFile);
        final XMLEventReader manifestXmlReader = SaxUtils.createXmlEventReader(projectModManifestPropsFile);

        // ensure XMLEventReader instances are set
        if (sourceModPropsXmlReader != null &&
                targetModPropsXmlReader != null &&
                targetModMetaPropsXmlReader != null)
        {
            // parse XMLEventReader instances and get lists of module properties
            List sourceModProps = this.parseModuleProperties(sourceModPropsXmlReader);
            List targetModProps = this.parseModuleProperties(targetModPropsXmlReader);
            List targetModMetaProps = this.parseModuleMetadataProperties(targetModMetaPropsXmlReader);
            List modManifestProps = this.parseModuleManifestProperties(manifestXmlReader);

            // ensure module property lists are set
            if (sourceModProps != null && !sourceModProps.isEmpty() &&
                    targetModProps != null && !targetModProps.isEmpty() &&
                    targetModMetaProps != null && !targetModMetaProps.isEmpty() &&
                    modManifestProps != null && !modManifestProps.isEmpty())
            {
                // iterate through module manifest properties
                for (ModuleManifestProperty modManifestProp : modManifestProps)
                {
                    // create module properties instances
                    ModuleProperty modProp = new ModuleProperty(modManifestProp.getProperty());
                    ModuleMetadataProperty modMetaProp = new ModuleMetadataProperty(modManifestProp.getProperty());

                    // remove module properties if orphaned
                    if (!this.hasModuleProperty(modProp, sourceModProps))
                    {
                        this.deleteModuleProperty(modProp, projectModPropsFile);
                        this.deleteModuleMetadataProperty(modMetaProp, projectModMetaPropsFile);
                        this.deleteModuleManifestProperty(modManifestProp, projectModManifestPropsFile);
                    }
                }
            }
        }
    }

    //------------------------------------------------------------------------------------------------------------------
    // Other Methods
    //------------------------------------------------------------------------------------------------------------------

    /**
     * Returns a value indicating if the specified {@link ModuleProperty} object
     * for a module property is contained in the specified {@link List} of
     * {@link ModuleProperty} objects.
     * @param modProp A reference to the {@link ModuleProperty} object.
     * @param modProps A reference to the {@link List} of {@link ModuleProperty}
     * objects.
     * @return A value indicating if the {@link ModuleProperty} object is
     * contained in the {@link List} of {@link ModuleProperty} objects.
     */
    private boolean hasModuleProperty(ModuleProperty modProp, List modProps)
    {
        return modProps.stream().anyMatch(mp ->
                modProp.getName() != null &&
                        mp.getName() != null &&
                        mp.getName().equalsIgnoreCase(modProp.getName()));
    }

    /**
     * Gets a {@link ModuleProperty} object from the specified {@link List} of
     * {@link ModuleProperty} objects using the specified module property
     * name.
     * @param modPropName The name of the module property.
     * @param modProps The {@link List} of {@link ModuleProperty} objects.
     * @return The located {@link ModuleProperty} object.
     */
    private ModuleProperty getModuleProperty(
            String modPropName,
            List modProps)
    {
        return modProps.stream().filter(mp ->
                modPropName != null &&
                        mp.getName() != null &&
                        mp.getName().equalsIgnoreCase(modPropName)).findFirst().get();
    }

    /**
     * Parses the specified {@link XMLEventReader} and returns a populated
     * {@link List} of {@link ModuleProperty} objects, otherwise, an empty
     * {@link List} is returned.
     * @param xmlReader The {@link XMLEventReader} to parse.
     * @return A populated {@link List} of {@link ModuleProperty} objects,
     * otherwise, an empty {@link List}.
     */
    private List parseModuleProperties(XMLEventReader xmlReader)
    {
        List modProps = new ArrayList<>();

        if (xmlReader != null)
        {
            while (xmlReader.hasNext())
            {
                ModuleProperty modProp = this.parseModuleProperty(xmlReader);

                if (modProp != null)
                {
                    modProps.add(modProp);
                }
            }
        }

        return modProps;
    }

    /**
     * Parses the specified {@link XMLEventReader} and returns a populated
     * {@link ModuleProperty} object, otherwise, null is returned.
     * @param xmlReader The {@link XMLEventReader} to parse.
     * @return A populated {@link ModuleProperty} object, otherwise, null.
     */
    private ModuleProperty parseModuleProperty(XMLEventReader xmlReader)
    {
        ModuleProperty modProp = null;

        if (xmlReader != null)
        {
            modProp = new ModuleProperty();
            String curElementName = ModuleProperty.MOD_PROP_ELEMENT;

            while (xmlReader.hasNext())
            {
                XMLEvent event = SaxUtils.getNextXmlEvent(xmlReader);

                switch (event.getEventType())
                {
                    case XMLStreamConstants.START_ELEMENT:
                    {
                        StartElement startElement = event.asStartElement();
                        String elementName = startElement.getName().getLocalPart();

                        if (elementName.equalsIgnoreCase(ModuleProperty.NAME_ELEMENT))
                        {
                            curElementName = ModuleProperty.NAME_ELEMENT;
                        }
                        else if (elementName.equalsIgnoreCase(ModuleProperty.VALUE_ELEMENT))
                        {
                            curElementName = ModuleProperty.VALUE_ELEMENT;
                        }
                        else if (elementName.equalsIgnoreCase(ModuleProperty.DEPLOYMENT_SETTABLE_ELEMENT))
                        {
                            curElementName = ModuleProperty.DEPLOYMENT_SETTABLE_ELEMENT;
                        }
                        else if (elementName.equalsIgnoreCase(ModuleProperty.SERVICE_SETTABLE_ELEMENT))
                        {
                            curElementName = ModuleProperty.SERVICE_SETTABLE_ELEMENT;
                        }
                        else if (elementName.equalsIgnoreCase(ModuleProperty.TYPE_ELEMENT))
                        {
                            curElementName = ModuleProperty.TYPE_ELEMENT;
                        }
                        else if (elementName.equalsIgnoreCase(ModuleProperty.IS_OVERRIDE_ELEMENT))
                        {
                            curElementName = ModuleProperty.IS_OVERRIDE_ELEMENT;
                        }
                    }
                    break;

                    case XMLStreamConstants.CHARACTERS:
                    {
                        Characters characters = event.asCharacters();

                        if (!characters.isWhiteSpace())
                        {
                            switch (curElementName)
                            {
                                case ModuleProperty.NAME_ELEMENT:
                                    modProp.setName(characters.getData());
                                    break;
                                case ModuleProperty.VALUE_ELEMENT:
                                    modProp.setValue(characters.getData() != null ? characters.getData() : "");
                                    break;
                                case ModuleProperty.DEPLOYMENT_SETTABLE_ELEMENT:
                                    modProp.setDeploymentSettable(Boolean.valueOf(characters.getData()));
                                    break;
                                case ModuleProperty.SERVICE_SETTABLE_ELEMENT:
                                    modProp.setServiceSettable(Boolean.valueOf(characters.getData()));
                                    break;
                                case ModuleProperty.TYPE_ELEMENT:
                                    modProp.setType(characters.getData());
                                    break;
                                case ModuleProperty.IS_OVERRIDE_ELEMENT:
                                    modProp.setOverride(Boolean.valueOf(characters.getData()));
                                    break;
                            }
                        }
                    }
                    break;

                    case XMLStreamConstants.END_ELEMENT:
                    {
                        EndElement endElement = event.asEndElement();

                        if (endElement.getName().getLocalPart().equalsIgnoreCase(ModuleProperty.MOD_PROP_ELEMENT))
                        {
                            return modProp;
                        }
                    }
                    break;
                }
            }
        }

        return modProp;
    }

    /**
     * Creates an XML representation of a module property using the specified
     * {@link ModuleProperty} object and writes the XML to the specified
     * XML {@link File}.
     * @param modProp A reference to the {@link ModuleProperty} object.
     * @param file A reference to the XML {@link File}.
     */
    private void createModuleProperty(ModuleProperty modProp, File file)
    {
        if (modProp != null && file != null)
        {
            // create XML document for writing
            Document doc = SaxUtils.createXmlDocument(file);

            // retrieve XML elements
            Element eRoot = doc.getRootElement();
            Element eRootGlobalVar = eRoot.getChild(ModuleProperty.MOD_PROP_ROOT_ELEMENT, ModuleNamespace.TIBCO_BW_MOD_PROPS);
            List eGlobalVars = eRootGlobalVar.getChildren(ModuleProperty.MOD_PROP_ELEMENT, ModuleNamespace.TIBCO_BW_MOD_PROPS);

            // create new module property element
            // add to list of module property elements
            Element eGlobalVar = modProp.createElement();
            eGlobalVars.add(eGlobalVar);

            LogUtils.info("Writing new module property '%s=%s'",
                    modProp.getName(), modProp.getValue());

            // write module property to XML document
            SaxUtils.writeXmlDocument(doc, file);
        }
    }

    /**
     * Updates an XML representation of a module property using the specified
     * source {@link ModuleProperty} object, determines if the specified target
     * {@link ModuleProperty} object is different from the source, and, if so,
     * writes the updated XML to the specified XML {@link File}.
     * @param sourceModProp A reference to the source {@link ModuleProperty}
     * object.
     * @param targetModProp A reference to the target {@link ModuleProperty}
     * object.
     * @param file A reference to the XML {@link File}.
     */
    private void updateModuleProperty(
            ModuleProperty sourceModProp,
            ModuleProperty targetModProp,
            File file)
    {
        if (sourceModProp != null && targetModProp != null && file != null)
        {
            // only update target module property if source is different
            if (sourceModProp.getValue() != null &&
                    targetModProp.getValue() != null &&
                    !sourceModProp.getValue().equals(targetModProp.getValue()))
            {
                // create target XMLEventReader instance
                final XMLEventReader targetXmlReader = SaxUtils.createXmlEventReader(file);

                // iterate through target XML
                while (targetXmlReader.hasNext())
                {
                    // get target XML event
                    XMLEvent event = SaxUtils.getNextXmlEvent(targetXmlReader);

                    // update target XML for module property start element
                    switch (event.getEventType())
                    {
                        case XMLStreamConstants.START_ELEMENT:
                        {
                            StartElement startElement = event.asStartElement();
                            String elementName = startElement.getName().getLocalPart();

                            if (elementName.equalsIgnoreCase(ModuleProperty.MOD_PROP_ELEMENT))
                            {
                                // create XML document for writing
                                Document doc = SaxUtils.createXmlDocument(file);

                                if (doc != null)
                                {
                                    // retrieve XML elements
                                    Element eRoot = doc.getRootElement();
                                    Element eRootGlobalVar = eRoot.getChild(ModuleProperty.MOD_PROP_ROOT_ELEMENT, ModuleNamespace.TIBCO_BW_MOD_PROPS);
                                    List eGlobalVars = eRootGlobalVar.getChildren(ModuleProperty.MOD_PROP_ELEMENT, ModuleNamespace.TIBCO_BW_MOD_PROPS);

                                    // update existing module property element
                                    for (Element eGlobalVar : eGlobalVars)
                                    {
                                        Element eName = eGlobalVar.getChild(ModuleProperty.NAME_ELEMENT, ModuleNamespace.TIBCO_BW_MOD_PROPS);

                                        if (sourceModProp.getName().equalsIgnoreCase(eName.getValue()))
                                        {
                                            Element eValue = eGlobalVar.getChild(ModuleProperty.VALUE_ELEMENT, ModuleNamespace.TIBCO_BW_MOD_PROPS);
                                            eValue.setText(sourceModProp.getValue());

                                            Element eDeploymentSettable = eGlobalVar.getChild(ModuleProperty.DEPLOYMENT_SETTABLE_ELEMENT, ModuleNamespace.TIBCO_BW_MOD_PROPS);
                                            eDeploymentSettable.setText(String.valueOf(sourceModProp.isDeploymentSettable()));

                                            Element eServiceSettable = eGlobalVar.getChild(ModuleProperty.SERVICE_SETTABLE_ELEMENT, ModuleNamespace.TIBCO_BW_MOD_PROPS);
                                            eServiceSettable.setText(String.valueOf(sourceModProp.isServiceSettable()));

                                            Element eType = eGlobalVar.getChild(ModuleProperty.TYPE_ELEMENT, ModuleNamespace.TIBCO_BW_MOD_PROPS);
                                            eType.setText(sourceModProp.getType());

                                            Element eIsOverride = eGlobalVar.getChild(ModuleProperty.IS_OVERRIDE_ELEMENT, ModuleNamespace.TIBCO_BW_MOD_PROPS);
                                            eIsOverride.setText(String.valueOf(sourceModProp.isOverride()));
                                        }
                                    }

                                    LogUtils.info("Writing updated module property '%s=%s'",
                                            sourceModProp.getName(), sourceModProp.getValue());

                                    // write module property to XML document
                                    SaxUtils.writeXmlDocument(doc, file);
                                    return;
                                }
                            }
                        }
                        break;
                    }
                }
            }
        }
    }

    /**
     * Deletes an XML representation of a module property using the specified
     * {@link ModuleProperty} object and writes the updated XML to the specified
     * XML {@link File}.
     * @param modProp A reference to the {@link ModuleProperty} object.
     * @param file A reference to the XML {@link File}.
     */
    private void deleteModuleProperty(
            ModuleProperty modProp,
            File file)
    {
        if (modProp != null && file != null)
        {
            // create XMLEventReader instance
            final XMLEventReader xmlReader = SaxUtils.createXmlEventReader(file);

            // iterate through XML
            while (xmlReader.hasNext())
            {
                // get XML event
                XMLEvent event = SaxUtils.getNextXmlEvent(xmlReader);

                // update XML for module property start element
                switch (event.getEventType())
                {
                    case XMLStreamConstants.START_ELEMENT:
                    {
                        StartElement startElement = event.asStartElement();
                        String elementName = startElement.getName().getLocalPart();

                        if (elementName.equalsIgnoreCase(ModuleProperty.MOD_PROP_ELEMENT))
                        {
                            // create XML document for writing
                            Document doc = SaxUtils.createXmlDocument(file);

                            if (doc != null)
                            {
                                // retrieve XML elements
                                Element eRoot = doc.getRootElement();
                                Element eRootGlobalVar = eRoot.getChild(ModuleProperty.MOD_PROP_ROOT_ELEMENT, ModuleNamespace.TIBCO_BW_MOD_PROPS);
                                List eGlobalVars = eRootGlobalVar.getChildren(ModuleProperty.MOD_PROP_ELEMENT, ModuleNamespace.TIBCO_BW_MOD_PROPS);
                                Element eGlobalVarToRemove = null;

                                // locate module metadata property element to remove
                                for (Element eGlobalVar : eGlobalVars)
                                {
                                    Element eName = eGlobalVar.getChild(ModuleProperty.NAME_ELEMENT, ModuleNamespace.TIBCO_BW_MOD_PROPS);

                                    if (modProp.getName() != null &&
                                            eName != null && eName.getValue() != null &&
                                            modProp.getName().equalsIgnoreCase(eName.getValue()))
                                    {
                                        eGlobalVarToRemove = eGlobalVar;
                                        break;
                                    }
                                }

                                // locate module metadata property element if located
                                if (eGlobalVarToRemove != null)
                                {
                                    eGlobalVars.remove(eGlobalVarToRemove);

                                    LogUtils.info("Removing module property '%s'",
                                            modProp.getName());

                                    // remove module property from XML document
                                    SaxUtils.writeXmlDocument(doc, file);
                                }

                                return;
                            }
                        }
                    }
                    break;
                }
            }
        }
    }

    /**
     * Returns a value indicating if the specified {@link ModuleMetadataProperty}
     * object for a module metadata property is contained in the specified
     * {@link List} of {@link ModuleMetadataProperty} objects.
     * @param modMetaProp A reference to the {@link ModuleMetadataProperty} object.
     * @param modMetaProps A reference to the {@link List} of
     * {@link ModuleMetadataProperty} objects.
     * @return A value indicating if the {@link ModuleMetadataProperty} object
     * is contained in the {@link List} of {@link ModuleMetadataProperty} objects.
     */
    private boolean hasModuleMetadataProperty(
            ModuleMetadataProperty modMetaProp,
            List modMetaProps)
    {
        return modMetaProps.stream().anyMatch(mmp ->
                modMetaProp.getName() != null &&
                        mmp.getName() != null &&
                        mmp.getName().equalsIgnoreCase(modMetaProp.getName()));
    }

    /**
     * Gets a {@link ModuleMetadataProperty} object from the specified
     * {@link List} of {@link ModuleMetadataProperty} objects using the specified
     * module metadata property name.
     * @param modMetaPropName The name of the module metadata property.
     * @param modMetaProps The {@link List} of {@link ModuleMetadataProperty}
     * objects.
     * @return The located {@link ModuleMetadataProperty} object.
     */
    private ModuleMetadataProperty getModuleMetadataProperty(
            String modMetaPropName,
            List modMetaProps)
    {
        return modMetaProps.stream().filter(mmp ->
                modMetaPropName != null &&
                        mmp.getName() != null &&
                        mmp.getName().equalsIgnoreCase(modMetaPropName)).findFirst().get();
    }

    /**
     * Parses the specified {@link XMLEventReader} and returns a populated
     * {@link List} of {@link ModuleMetadataProperty} objects, otherwise, an
     * empty {@link List} is returned.
     * @param xmlReader The {@link XMLEventReader} to parse.
     * @return A populated {@link List} of {@link ModuleMetadataProperty}
     * objects, otherwise, an empty {@link List}.
     */
    private List parseModuleMetadataProperties(
            XMLEventReader xmlReader)
    {
        List modMetaProps = new ArrayList<>();

        if (xmlReader != null)
        {
            while (xmlReader.hasNext())
            {
                ModuleMetadataProperty modMetaProp = this.parseModuleMetadataProperty(xmlReader);

                if (modMetaProp != null)
                {
                    modMetaProps.add(modMetaProp);
                }
            }
        }

        return modMetaProps;
    }

    /**
     * Parses the specified {@link XMLEventReader} and returns a populated
     * {@link ModuleMetadataProperty} object, otherwise, null is returned.
     * @param xmlReader The {@link XMLEventReader} to parse.
     * @return A populated {@link ModuleMetadataProperty} object, otherwise,
     * null.
     */
    private ModuleMetadataProperty parseModuleMetadataProperty(XMLEventReader xmlReader)
    {
        ModuleMetadataProperty modMetaProp = null;

        if (xmlReader != null)
        {
            modMetaProp = new ModuleMetadataProperty();

            while (xmlReader.hasNext())
            {
                XMLEvent event = SaxUtils.getNextXmlEvent(xmlReader);

                switch (event.getEventType())
                {
                    case XMLStreamConstants.START_ELEMENT:
                    {
                        StartElement startElement = event.asStartElement();
                        String elementName = startElement.getName().getLocalPart();

                        if (elementName.equalsIgnoreCase(ModuleMetadataProperty.MOD_META_PROP_ELEMENT))
                        {
                            @SuppressWarnings("unchecked")
                            Iterator attributes = startElement.getAttributes();

                            while (attributes.hasNext())
                            {
                                javax.xml.stream.events.Attribute attribute =
                                        (javax.xml.stream.events.Attribute) attributes.next();

                                if (attribute != null)
                                {
                                    switch (attribute.getName().getLocalPart())
                                    {
                                        case ModuleMetadataProperty.ID_ATTRIB:
                                            modMetaProp.setId(attribute.getValue());
                                            break;
                                        case ModuleMetadataProperty.NAME_ATTRIB:
                                            modMetaProp.setName(attribute.getValue());
                                            break;
                                        case ModuleMetadataProperty.TYPE_ATTRIB:
                                            modMetaProp.setType(attribute.getValue());
                                            break;
                                        case ModuleMetadataProperty.SIMPLE_VALUE_ATTRIB:
                                            modMetaProp.setSimpleValue(attribute.getValue());
                                            break;
                                        case ModuleMetadataProperty.PUBLIC_ACCESS_ATTRIB:
                                            modMetaProp.setPublicAccess(Boolean.valueOf(attribute.getValue()));
                                            break;
                                        case ModuleMetadataProperty.SCALABLE_ATTRIB:
                                            modMetaProp.setScalable(Boolean.valueOf(attribute.getValue()));
                                            break;
                                    }
                                }
                            }
                        }
                    }
                    break;

                    case XMLStreamConstants.END_ELEMENT:
                    {
                        EndElement endElement = event.asEndElement();

                        if (endElement.getName().getLocalPart().equalsIgnoreCase(
                                ModuleMetadataProperty.MOD_META_PROP_ELEMENT))
                        {
                            return modMetaProp;
                        }
                    }
                    break;
                }
            }
        }

        return modMetaProp;
    }

    /**
     * Creates an XML representation of a module metadata property using the
     * specified {@link ModuleMetadataProperty} object and writes the XML to
     * the specified XML {@link File}.
     * @param modMetaProp A reference to the {@link ModuleMetadataProperty}
     * object.
     * @param file A reference to the XML {@link File}.
     */
    private void createModuleMetadataProperty(ModuleMetadataProperty modMetaProp, File file)
    {
        if (modMetaProp != null && file != null)
        {
            // create XML document for writing
            Document doc = SaxUtils.createXmlDocument(file);

            if (doc != null)
            {
                // retrieve XML elements
                Element eRoot = doc.getRootElement();
                List eProperties = eRoot.getChildren(ModuleMetadataProperty.MOD_META_PROP_ELEMENT, ModuleNamespace.TIBCO_BW_MOD_META_PROPS);

                // create new module metadata property element
                // add to list of module metadata property elements
                Element eProperty = modMetaProp.createElement();
                eProperties.add(eProperty);

                LogUtils.info("Writing new module metadata property '%s'",
                        modMetaProp.getName());

                // write module metadata property to XML document
                SaxUtils.writeXmlDocument(doc, file);
            }
        }
    }

    /**
     * Updates an XML representation of a module metadata property using the
     * specified source {@link ModuleMetadataProperty} object, determines if
     * the specified target {@link ModuleMetadataProperty} object is different
     * from the source, and, if so, writes the updated XML to the specified
     * XML {@link File}.
     * @param sourceModMetaProp A reference to the source
     * {@link ModuleMetadataProperty} object.
     * @param targetModMetaProp A reference to the target
     * {@link ModuleMetadataProperty} object.
     * @param file A reference to the {@link File}.
     */
    private void updateModuleMetadataProperty(
            ModuleMetadataProperty sourceModMetaProp,
            ModuleMetadataProperty targetModMetaProp,
            File file)
    {
        if (sourceModMetaProp != null && targetModMetaProp != null && file != null)
        {
            // only update target module metadata property if source is different
            if (sourceModMetaProp.getSimpleValue() != null &&
                    targetModMetaProp.getSimpleValue() != null &&
                    !sourceModMetaProp.getSimpleValue().equals(targetModMetaProp.getSimpleValue()))
            {
                // create target XMLEventReader instance
                final XMLEventReader targetXmlReader = SaxUtils.createXmlEventReader(file);

                // iterate through target XML
                while (targetXmlReader.hasNext())
                {
                    // get target XML event
                    XMLEvent event = SaxUtils.getNextXmlEvent(targetXmlReader);

                    // update target XML for module metadata property start element
                    switch (event.getEventType())
                    {
                        case XMLStreamConstants.START_ELEMENT:
                        {
                            StartElement startElement = event.asStartElement();
                            String elementName = startElement.getName().getLocalPart();

                            if (elementName.equalsIgnoreCase(ModuleMetadataProperty.MOD_META_PROP_ELEMENT))
                            {
                                // create XML document for writing
                                Document doc = SaxUtils.createXmlDocument(file);

                                if (doc != null)
                                {
                                    // retrieve XML elements
                                    Element eRoot = doc.getRootElement();
                                    List eProperties = eRoot.getChildren(ModuleMetadataProperty.MOD_META_PROP_ELEMENT, ModuleNamespace.TIBCO_BW_MOD_META_PROPS);

                                    // update existing module metadata property element
                                    for (Element eProperty : eProperties)
                                    {
                                        Attribute aName = eProperty.getAttribute(ModuleMetadataProperty.NAME_ATTRIB, ModuleNamespace.TIBCO_BW_MOD_META_PROPS_SCA);

                                        if (sourceModMetaProp.getName().equalsIgnoreCase(aName.getValue()))
                                        {
                                            Attribute aType = eProperty.getAttribute(ModuleMetadataProperty.TYPE_ATTRIB, ModuleNamespace.TIBCO_BW_MOD_META_PROPS_SCA);
                                            aType.setValue(sourceModMetaProp.getType());

                                            Attribute aValue = eProperty.getAttribute(ModuleMetadataProperty.SIMPLE_VALUE_ATTRIB, ModuleNamespace.TIBCO_BW_MOD_META_PROPS_SCAEXT);
                                            if (aValue != null && !aValue.getValue().isEmpty())
                                            {
                                                aValue.setValue(sourceModMetaProp.getSimpleValue());
                                            }

                                            Attribute aPublicAccess = eProperty.getAttribute(ModuleMetadataProperty.PUBLIC_ACCESS_ATTRIB, ModuleNamespace.TIBCO_BW_MOD_META_PROPS_SCA);
                                            aPublicAccess.setValue(String.valueOf(sourceModMetaProp.isPublicAccess()));

                                            Attribute aScalable = eProperty.getAttribute(ModuleMetadataProperty.SCALABLE_ATTRIB, ModuleNamespace.TIBCO_BW_MOD_META_PROPS_SCA);
                                            aScalable.setValue(String.valueOf(sourceModMetaProp.isScalable()));
                                        }
                                    }

                                    LogUtils.info("Writing updated module metadata property '%s=%s'",
                                            sourceModMetaProp.getName(), sourceModMetaProp.getSimpleValue());

                                    // write module property to XML document
                                    SaxUtils.writeXmlDocument(doc, file);
                                    return;
                                }
                            }
                        }
                        break;
                    }
                }
            }
        }
    }

    /**
     * Updates an XML representation of the root element of the module metadata
     * properties file by writing the updated XML to the specified XML {@link File}.
     * This method ensures root element attributes both always exist and are in
     * the property sequence.
     * @param file A reference to the XML {@link File}.
     */
    private void updateModuleMetadataPropertyRoot(File file)
    {
        if (file != null)
        {
            // create XML document for writing
            Document doc = SaxUtils.createXmlDocument(file);

            if (doc != null)
            {
                // retrieve XML elements
                Element eRoot = doc.getRootElement();

                // re-add required root element attributes
                eRoot.addNamespaceDeclaration(ModuleNamespace.TIBCO_BW_MOD_META_PROPS_HTTPCONN);
                eRoot.addNamespaceDeclaration(ModuleNamespace.TIBCO_BW_MOD_META_PROPS_PROP);

                // write module property to XML document
                SaxUtils.writeXmlDocument(doc, file);
            }
        }
    }

    /**
     * Deletes an XML representation of a module metadata property using the
     * specified {@link ModuleMetadataProperty} object and writes the updated
     * XML to the specified XML {@link File}.
     * @param modMetaProp A reference to the {@link ModuleMetadataProperty}
     * object.
     * @param file A reference to the XML {@link File}.
     */
    private void deleteModuleMetadataProperty(
            ModuleMetadataProperty modMetaProp,
            File file)
    {
        if (modMetaProp != null && file != null)
        {
            // create XMLEventReader instance
            final XMLEventReader xmlReader = SaxUtils.createXmlEventReader(file);

            // iterate through XML
            while (xmlReader.hasNext())
            {
                // get XML event
                XMLEvent event = SaxUtils.getNextXmlEvent(xmlReader);

                // update XML for module metadata property start element
                switch (event.getEventType())
                {
                    case XMLStreamConstants.START_ELEMENT:
                    {
                        StartElement startElement = event.asStartElement();
                        String elementName = startElement.getName().getLocalPart();

                        if (elementName.equalsIgnoreCase(ModuleMetadataProperty.MOD_META_PROP_ELEMENT))
                        {
                            // create XML document for writing
                            Document doc = SaxUtils.createXmlDocument(file);

                            if (doc != null)
                            {
                                // retrieve XML elements
                                Element eRoot = doc.getRootElement();
                                List eProperties = eRoot.getChildren(ModuleMetadataProperty.MOD_META_PROP_ELEMENT, ModuleNamespace.TIBCO_BW_MOD_META_PROPS);
                                Element ePropertyToRemove = null;

                                // locate module metadata property element to remove
                                for (Element eProperty : eProperties)
                                {
                                    Attribute aName = eProperty.getAttribute(ModuleMetadataProperty.NAME_ATTRIB);

                                    if (modMetaProp.getName().equalsIgnoreCase(aName.getValue()))
                                    {
                                        ePropertyToRemove = eProperty;
                                        break;
                                    }
                                }

                                // remove module metadata property element if located
                                if (ePropertyToRemove != null)
                                {
                                    eProperties.remove(ePropertyToRemove);

                                    LogUtils.info("Removing module metadata property '%s'",
                                            modMetaProp.getName());

                                    // remove module metadata property from XML document
                                    SaxUtils.writeXmlDocument(doc, file);
                                }

                                return;
                            }
                        }
                    }
                    break;
                }
            }
        }
    }

    /**
     * Returns a value indicating if the specified {@link ModuleManifestProperty}
     * object for a module manifest property is contained in the specified
     * {@link List} of {@link ModuleManifestProperty} objects.
     * @param modManifestProp A reference to the {@link ModuleManifestProperty}
     * object.
     * @param modManifestProps A reference to the {@link List} of
     * {@link ModuleManifestProperty} objects.
     * @return A value indicating if the {@link ModuleManifestProperty} object
     * is contained in the {@link List} of {@link ModuleManifestProperty}
     * objects.
     */
    private boolean hasModuleManifestProperty(
            ModuleManifestProperty modManifestProp,
            List modManifestProps)
    {
        return modManifestProps.stream().anyMatch(mmp ->
                modManifestProp.getProperty() != null &&
                        mmp.getProperty() != null &&
                        mmp.getProperty().equalsIgnoreCase(modManifestProp.getProperty()));
    }

    /**
     * Parses the specified {@link XMLEventReader} and returns a populated
     * {@link List} of {@link ModuleManifestProperty} objects, otherwise, an
     * empty {@link List} is returned.
     * @param xmlReader The {@link XMLEventReader} to parse.
     * @return A populated {@link List} of {@link ModuleManifestProperty}
     * objects, otherwise, an empty {@link List}.
     */
    private List parseModuleManifestProperties(XMLEventReader xmlReader)
    {
        List modManifestProps = new ArrayList<>();

        if (xmlReader != null)
        {
            while (xmlReader.hasNext())
            {
                ModuleManifestProperty modManifestProp = this.parseModuleManifestProperty(xmlReader);

                if (modManifestProp != null)
                {
                    modManifestProps.add(modManifestProp);
                }
            }
        }

        return modManifestProps;
    }

    /**
     * Parses the specified {@link XMLEventReader} and returns a populated
     * {@link ModuleManifestProperty} object, otherwise, null is returned.
     * @param xmlReader The {@link XMLEventReader} to parse.
     * @return A populated {@link ModuleManifestProperty} object, otherwise,
     * null.
     */
    private ModuleManifestProperty parseModuleManifestProperty(XMLEventReader xmlReader)
    {
        ModuleManifestProperty modManifestProp = null;

        if (xmlReader != null)
        {
            String curElementName = ModuleManifestProperty.MOD_MANIFEST_PROP_ROOT_ELEMENT;

            while (xmlReader.hasNext())
            {
                XMLEvent event = SaxUtils.getNextXmlEvent(xmlReader);

                switch (event.getEventType())
                {
                    case XMLStreamConstants.START_ELEMENT:
                    {
                        StartElement startElement = event.asStartElement();
                        String elementName = startElement.getName().getLocalPart();

                        if (elementName.equalsIgnoreCase(ModuleManifestProperty.MOD_MANIFEST_PROP_ELEMENT))
                        {
                            curElementName = ModuleManifestProperty.MOD_MANIFEST_PROP_ELEMENT;
                        }
                    }
                    break;

                    case XMLStreamConstants.CHARACTERS:
                    {
                        Characters characters = event.asCharacters();

                        if (!characters.isWhiteSpace())
                        {
                            switch (curElementName)
                            {
                                case ModuleManifestProperty.MOD_MANIFEST_PROP_ELEMENT:
                                    if (characters.getData() != null)
                                    {
                                        modManifestProp = new ModuleManifestProperty(characters.getData());
                                    }
                                    break;
                            }
                        }
                    }
                    break;

                    case XMLStreamConstants.END_ELEMENT:
                    {
                        EndElement endElement = event.asEndElement();

                        if (endElement.getName().getLocalPart().equalsIgnoreCase(ModuleManifestProperty.MOD_MANIFEST_PROP_ELEMENT))
                        {
                            return modManifestProp;
                        }
                    }
                    break;
                }
            }
        }

        return modManifestProp;
    }

    /**
     * Creates an XML representation of a module manifest property using the
     * specified {@link ModuleManifestProperty} object and writes the XML to
     * the specified XML {@link File}.
     * @param modManifestProp A reference to the {@link ModuleManifestProperty}
     * object.
     * @param file A reference to the XML {@link File}.
     */
    private void createModuleManifestProperty(
            ModuleManifestProperty modManifestProp,
            File file)
    {
        if (modManifestProp != null && file != null)
        {
            // create XML document for writing
            Document doc = SaxUtils.createXmlDocument(file);

            if (doc != null)
            {
                // retrieve XML elements
                Element eRoot = doc.getRootElement();

                // create new module manifest property element
                // add to list of module manifest property elements
                Element eProperty = modManifestProp.createElement();
                eRoot.addContent(eProperty);

                LogUtils.info("Writing new module manifest property '%s'",
                        modManifestProp.getProperty());

                // write module manifest property to XML document
                SaxUtils.writeXmlDocument(doc, file);
            }
        }
    }

    /**
     * Deletes an XML representation of a module manifest property using the
     * specified {@link ModuleManifestProperty} object and writes the updated
     * XML to the specified XML {@link File}.
     * @param modManifestProp A reference to the {@link ModuleManifestProperty}
     * object.
     * @param file A reference to the XML {@link File}.
     */
    private void deleteModuleManifestProperty(
            ModuleManifestProperty modManifestProp,
            File file)
    {
        if (modManifestProp != null && file != null)
        {
            // create XMLEventReader instance
            final XMLEventReader xmlReader = SaxUtils.createXmlEventReader(file);

            // iterate through XML
            while (xmlReader.hasNext())
            {
                // get XML event
                XMLEvent event = SaxUtils.getNextXmlEvent(xmlReader);

                // update XML for module manifest property start element
                switch (event.getEventType())
                {
                    case XMLStreamConstants.START_ELEMENT:
                    {
                        StartElement startElement = event.asStartElement();
                        String elementName = startElement.getName().getLocalPart();

                        if (elementName.equalsIgnoreCase(ModuleManifestProperty.MOD_MANIFEST_PROP_ELEMENT))
                        {
                            // create XML document for writing
                            Document doc = SaxUtils.createXmlDocument(file);

                            if (doc != null)
                            {
                                // retrieve XML elements
                                Element eRoot = doc.getRootElement();
                                List eProperties = eRoot.getChildren(ModuleManifestProperty.MOD_MANIFEST_PROP_ELEMENT);
                                Element ePropertyToRemove = null;

                                // locate module manifest property element to remove
                                for (Element eProperty : eProperties)
                                {
                                    if (modManifestProp.getProperty() != null &&
                                            eProperty != null && eProperty.getValue() != null &&
                                            modManifestProp.getProperty().equalsIgnoreCase(eProperty.getValue()))
                                    {
                                        ePropertyToRemove = eProperty;
                                        break;
                                    }
                                }

                                // remove module manifest property element if located
                                if (ePropertyToRemove != null)
                                {
                                    eProperties.remove(ePropertyToRemove);

                                    LogUtils.info("Removing module manifest property '%s'",
                                            modManifestProp.getProperty());

                                    // remove module manifest property from XML document
                                    SaxUtils.writeXmlDocument(doc, file);
                                }

                                return;
                            }
                        }
                    }
                    break;
                }
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy