org.talend.camel.designer.ui.wizards.export.RouteJavaScriptOSGIForESBManager.java Source code

Java tutorial

Introduction

Here is the source code for org.talend.camel.designer.ui.wizards.export.RouteJavaScriptOSGIForESBManager.java

Source

// ============================================================================
//
// Copyright (C) 2006-2018 Talend Inc. - www.talend.com
//
// This source code is available under agreement available at
// %InstallDIR%\features\org.talend.rcp.branding.%PRODUCTNAME%\%PRODUCTNAME%license.txt
//
// You should have received a copy of the agreement
// along with this program; if not, write to Talend SA
// 9 rue Pages 92150 Suresnes, France
//
// ============================================================================
package org.talend.camel.designer.ui.wizards.export;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Namespace;
import org.dom4j.QName;
import org.dom4j.io.SAXReader;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.runtime.IPath;
import org.talend.camel.core.model.camelProperties.CamelProcessItem;
import org.talend.core.GlobalServiceRegister;
import org.talend.core.model.general.ModuleNeeded;
import org.talend.core.model.process.ElementParameterParser;
import org.talend.core.model.process.IProcess;
import org.talend.core.model.properties.ProcessItem;
import org.talend.core.repository.constants.FileConstants;
import org.talend.core.runtime.process.ITalendProcessJavaProject;
import org.talend.designer.camel.dependencies.core.DependenciesResolver;
import org.talend.designer.camel.resource.core.model.ResourceDependencyModel;
import org.talend.designer.camel.resource.core.util.RouteResourceUtil;
import org.talend.designer.core.model.utils.emf.talendfile.ConnectionType;
import org.talend.designer.core.model.utils.emf.talendfile.NodeType;
import org.talend.designer.runprocess.IProcessor;
import org.talend.designer.runprocess.IRunProcessService;
import org.talend.librariesmanager.model.ModulesNeededProvider;
import org.talend.repository.documentation.ExportFileResource;
import org.talend.repository.ui.wizards.exportjob.scriptsmanager.esb.DataSourceConfig;
import org.talend.repository.utils.EmfModelUtils;
import org.talend.repository.utils.TemplateProcessor;
import org.talend.utils.io.FilesUtils;

import aQute.bnd.osgi.Analyzer;

/**
 * DOC ycbai class global comment. Detailled comment
 */
public class RouteJavaScriptOSGIForESBManager extends AdaptedJobJavaScriptOSGIForESBManager {

    private static final String CONVERT_SPRING_IMPORT_PROPERTY = "org.talend.esb.route.spring.import.convert"; //$NON-NLS-1$
    private static final String CONVERT_CAMEL_CONTEXT_PROPERTY = "org.talend.esb.route.spring.camel.convert"; //$NON-NLS-1$
    private static final String TEMPLATE_BLUEPRINT_ROUTE = "/resources/blueprint-template.xml"; //$NON-NLS-1$
    private static final String IMPORT_RESOURCE_PREFIX = ".." + File.separator + ".." + File.separator; //$NON-NLS-1$
    private static final String BLUEPRINT_NSURI = "http://www.osgi.org/xmlns/blueprint/v1.0.0"; //$NON-NLS-1$
    private static final String CAMEL_SPRING_NSURI = "http://camel.apache.org/schema/spring"; //$NON-NLS-1$
    private static final String CAMEL_BLUEPRINT_NSURI = "http://camel.apache.org/schema/blueprint"; //$NON-NLS-1$
    private static final boolean CONVERT_SPRING_IMPORT = isNotNegated(CONVERT_SPRING_IMPORT_PROPERTY);
    private static final boolean CONVERT_CAMEL_CONTEXT = isNotNegated(CONVERT_CAMEL_CONTEXT_PROPERTY);
    private static final boolean CONVERT_CAMEL_CONTEXT_ALL = isAll(CONVERT_CAMEL_CONTEXT_PROPERTY);

    private final Collection<String> routelets;
    private List<ModuleNeeded> defaultModulesNeededForBeans;
    private Set<String> modulesProvidedByFeatures;

    /*
     * Contains manifest Import-Package entries for subjobs used by cTalendJob components
     * Key - ProcessItem.id of the route
     * Value - Import-package string
     */
    private Map<String, String> subjobImportPackages = null;

    public RouteJavaScriptOSGIForESBManager(Map<ExportChoice, Object> exportChoiceMap, String contextName,
            Collection<String> routelets, Set<String> modulesProvidedByFeatures) {
        super(exportChoiceMap, contextName, null, IProcessor.NO_STATISTICS, IProcessor.NO_TRACES);
        this.routelets = routelets;
        this.defaultModulesNeededForBeans = ModulesNeededProvider.getModulesNeededForBeans();
        this.modulesProvidedByFeatures = modulesProvidedByFeatures;
    }

    @Override
    protected ExportFileResource getCompiledLibExportFileResource(ExportFileResource[] processes) {
        ExportFileResource libResource = new ExportFileResource(null, LIBRARY_FOLDER_NAME);
        List<URL> talendLibraries = getExternalLibraries(true, processes, getCompiledModuleNames());
        if (defaultModulesNeededForBeans == null) {
            defaultModulesNeededForBeans = ModulesNeededProvider.getModulesNeededForBeans();
        }
        if (talendLibraries != null) {
            for (URL libUrl : talendLibraries) {
                boolean addRes = true;
                // TESB-21485: Exclude DEFAULT beans model
                for (ModuleNeeded need : defaultModulesNeededForBeans) {
                    if (libUrl.getFile().contains(need.getId())) {
                        addRes = false;
                        break;
                    }
                }
                if (addRes) {
                    libResource.addResource("", libUrl);
                }
            }
        }

        addRoutinesResources(processes, libResource);
        return libResource;
    }

    /**
     * DOC yyan RouteJavaScriptOSGIForESBManager constructor comment.
     * @param exportChoice
     * @param context
     * @param routelets2
     * @param statisticsPort
     * @param tracePort
     */
    public RouteJavaScriptOSGIForESBManager(Map<ExportChoice, Object> exportChoiceMap, String context,
            Collection<String> routelets, Set<String> modulesProvidedByFeatures, int statisticsPort,
            int tracePort) {
        super(exportChoiceMap, context, null, statisticsPort, tracePort);
        this.routelets = routelets;
        this.modulesProvidedByFeatures = modulesProvidedByFeatures;
    }

    public void setSubjobImportPackages(Map<String, String> importPackages) {
        this.subjobImportPackages = importPackages;
    }

    public static String getClassName(ProcessItem processItem) {
        return getPackageName(processItem) + PACKAGE_SEPARATOR + processItem.getProperty().getLabel();
    }

    protected Collection<String> getRoutinesPaths() {
        final Collection<String> include = new ArrayList<String>();
        include.add(USER_BEANS_PATH);
        include.add(SYSTEM_ROUTINES_PATH);
        return include;
    }

    // Add Route Resource http://jira.talendforge.org/browse/TESB-6227
    @Override
    protected void addResources(ExportFileResource osgiResource, ProcessItem processItem) throws Exception {
        IFolder srcFolder = null;
        if (GlobalServiceRegister.getDefault().isServiceRegistered(IRunProcessService.class)) {
            IRunProcessService processService = (IRunProcessService) GlobalServiceRegister.getDefault()
                    .getService(IRunProcessService.class);
            ITalendProcessJavaProject talendProcessJavaProject = processService
                    .getTalendJobJavaProject(processItem.getProperty());
            if (talendProcessJavaProject != null) {
                srcFolder = talendProcessJavaProject.getExternalResourcesFolder();
            }
        }
        if (srcFolder == null) {
            return;
        }
        IPath srcPath = srcFolder.getLocation();

        // http://jira.talendforge.org/browse/TESB-6437
        // https://jira.talendforge.org/browse/TESB-7893
        for (IPath path : RouteResourceUtil.synchronizeRouteResource(processItem)) {
            osgiResource.addResource(path.removeLastSegments(1).makeRelativeTo(srcPath).toString(),
                    path.toFile().toURI().toURL());
        }
    }

    @Override
    protected void generateConfig(ExportFileResource osgiResource, ProcessItem processItem, IProcess process)
            throws IOException {
        final File targetFile = new File(getTmpFolder() + PATH_SEPARATOR + "blueprint.xml"); //$NON-NLS-1$

        Map<String, Object> collectRouteInfo = collectRouteInfo(processItem, process);

        TemplateProcessor.processTemplate("ROUTE_BLUEPRINT_CONFIG", //$NON-NLS-1$
                collectRouteInfo, targetFile, getClass().getResourceAsStream(TEMPLATE_BLUEPRINT_ROUTE));

        osgiResource.addResource(FileConstants.BLUEPRINT_FOLDER_NAME, targetFile.toURI().toURL());

        String springContent = null;
        if (processItem instanceof CamelProcessItem) {
            springContent = ((CamelProcessItem) processItem).getSpringContent();
        }

        if (springContent != null && springContent.length() > 0) {
            String springTargetFilePath = collectRouteInfo.get("name").toString().toLowerCase() + ".xml"; //$NON-NLS-1$
            InputStream springContentInputStream = new ByteArrayInputStream(springContent.getBytes());
            handleSpringXml(springTargetFilePath, processItem, springContentInputStream, osgiResource, true,
                    CONVERT_SPRING_IMPORT);
        }
    }

    @Override
    protected Set<String> getCompiledModuleNames() {
        return super.getCompiledModuleNames();
    }

    @Override
    protected void addOsgiDependencies(Analyzer analyzer, ExportFileResource libResource, ProcessItem processItem)
            throws IOException {

        // Add subjob import packages to be handled by dependencies resolver
        if (subjobImportPackages != null && subjobImportPackages.containsKey(processItem.getProperty().getId())) {
            processItem.getProperty().getAdditionalProperties().put("Import-Package",
                    subjobImportPackages.get(processItem.getProperty().getId()));
            subjobImportPackages.remove(processItem.getProperty().getId());
        }

        final DependenciesResolver resolver = new DependenciesResolver(processItem);
        //exportPackage.append(getPackageName(processItem));
        // Add Route Resource Export packages
        // http://jira.talendforge.org/browse/TESB-6227

        // add manifest items
        analyzer.setProperty(Analyzer.REQUIRE_BUNDLE, resolver.getManifestRequireBundle(MANIFEST_ITEM_SEPARATOR));
        analyzer.setProperty(Analyzer.IMPORT_PACKAGE,
                resolver.getManifestImportPackage(MANIFEST_ITEM_SEPARATOR) + ",*;resolution:=optional"); //$NON-NLS-1$
        analyzer.setProperty(Analyzer.EXPORT_PACKAGE, resolver.getManifestExportPackage(MANIFEST_ITEM_SEPARATOR));

        if (GlobalServiceRegister.getDefault().isServiceRegistered(IRunProcessService.class)) {
            IRunProcessService processService = (IRunProcessService) GlobalServiceRegister.getDefault()
                    .getService(IRunProcessService.class);
            ITalendProcessJavaProject talendProcessJavaProject = processService.getTalendProcessJavaProject();
            if (talendProcessJavaProject != null) {
                final IPath libPath = talendProcessJavaProject.getLibFolder().getLocation();
                // process external libs
                final List<URL> list = new ArrayList<URL>();
                for (String s : resolver.getManifestBundleClasspath(MANIFEST_ITEM_SEPARATOR)
                        .split(Character.toString(MANIFEST_ITEM_SEPARATOR))) {
                    if (!s.isEmpty()) {
                        list.add(libPath.append(s).toFile().toURI().toURL());
                    }
                }
                libResource.addResources(list);
            }
        }
    }

    @Override
    protected boolean isIncludedLib(ModuleNeeded module) {
        return super.isIncludedLib(module) && !(isProvidedByFeature(module) || isOsgiExcluded(module));
    }

    private boolean isProvidedByFeature(ModuleNeeded module) {
        if (modulesProvidedByFeatures == null) {
            return false;
        }
        String id = module.getId();
        if (id == null) {
            // bean dependency module etc.
            return false;
        }
        return modulesProvidedByFeatures.contains(id);
    }

    private boolean isOsgiExcluded(ModuleNeeded module) {
        Object value = module.getExtraAttributes().get("IS_OSGI_EXCLUDED");
        if (value == null) {
            return false;
        }
        if (value instanceof Boolean) {
            return ((Boolean) value).booleanValue();
        }
        if (value instanceof String) {
            return Boolean.parseBoolean((String) value);
        }
        return false;
    }

    private void handleSpringXml(String targetFilePath, ProcessItem processItem, InputStream springInput,
            ExportFileResource osgiResource, boolean convertToBP, boolean convertImports) {

        File targetFile = new File(getTmpFolder() + PATH_SEPARATOR + targetFilePath);
        try {
            SAXReader saxReader = new SAXReader();
            saxReader.setStripWhitespaceText(false);
            Document document = saxReader.read(springInput);
            Element root = document.getRootElement();

            if (convertToBP) {
                if ("blueprint".equals(root.getName())) {
                    formatSchemaLocation(root, false, false);
                    InputStream inputStream = new ByteArrayInputStream(root.asXML().getBytes());
                    FilesUtils.copyFile(inputStream, targetFile);
                    osgiResource.addResource(FileConstants.BLUEPRINT_FOLDER_NAME, targetFile.toURI().toURL());
                    return;
                }

                String bpPrefix = "bp";
                int cnt = 0;
                while (root.getNamespaceForPrefix(bpPrefix) != null) {
                    bpPrefix = "bp" + (++cnt);
                }
                root.setQName(QName.get("blueprint", bpPrefix, BLUEPRINT_NSURI));
            }

            Namespace springCamelNsp = Namespace.get("camel", CAMEL_SPRING_NSURI);
            boolean addCamel = springCamelNsp.equals(root.getNamespaceForPrefix("camel"));
            formatSchemaLocation(root, convertToBP, addCamel);

            for (Iterator<?> i = root.elementIterator("import"); i.hasNext();) {
                Element ip = (Element) i.next();
                Attribute resource = ip.attribute("resource");
                URL path = dummyURL(resource.getValue());
                for (ResourceDependencyModel resourceModel : RouteResourceUtil
                        .getResourceDependencies(processItem)) {
                    if (matches(path, resourceModel)) {
                        IFile resourceFile = RouteResourceUtil.getSourceFile(resourceModel.getItem());
                        String cpUrl = adaptedClassPathUrl(resourceModel, convertImports);
                        handleSpringXml(cpUrl, processItem, resourceFile.getContents(), osgiResource,
                                convertImports, convertImports);
                        resource.setValue(IMPORT_RESOURCE_PREFIX + cpUrl);
                    }
                }
                if (convertImports) {
                    i.remove();
                }
            }

            if (CONVERT_CAMEL_CONTEXT) {
                if (CONVERT_CAMEL_CONTEXT_ALL) {
                    moveNamespace(root, CAMEL_SPRING_NSURI, CAMEL_BLUEPRINT_NSURI);
                } else {
                    Namespace blueprintCamelNsp = Namespace.get("camel", CAMEL_BLUEPRINT_NSURI);
                    moveNamespace(root, springCamelNsp, blueprintCamelNsp);
                    if (springCamelNsp.equals(root.getNamespaceForPrefix("camel"))) {
                        root.remove(springCamelNsp);
                        root.add(blueprintCamelNsp);
                    }
                    Namespace springCamelDefNsp = Namespace.get(CAMEL_SPRING_NSURI);
                    Namespace blueprintCamelDefNsp = Namespace.get(CAMEL_BLUEPRINT_NSURI);
                    for (Iterator<?> i = root.elementIterator("camelContext"); i.hasNext();) {
                        Element cc = (Element) i.next();
                        if (springCamelDefNsp.equals(cc.getNamespace())) {
                            moveNamespace(cc, springCamelDefNsp, blueprintCamelDefNsp);
                        }
                    }
                }
            }

            InputStream inputStream = new ByteArrayInputStream(root.asXML().getBytes());
            FilesUtils.copyFile(inputStream, targetFile);
            osgiResource.addResource(adaptedResourceFolderName(targetFilePath, convertToBP),
                    targetFile.toURI().toURL());
        } catch (Exception e) {
            Logger.getAnonymousLogger().log(Level.WARNING, "Custom Spring to OSGi conversion failed. ", e);
        } finally {
            try {
                springInput.close();
            } catch (IOException e) {
                Logger.getAnonymousLogger().log(Level.WARNING, "Unexpected File closing failure. ", e);
            }
        }
    }

    private Map<String, Object> collectRouteInfo(ProcessItem processItem, IProcess process) {
        Map<String, Object> routeInfo = new HashMap<String, Object>();

        // route name and class name
        routeInfo.put("name", processItem.getProperty().getLabel()); //$NON-NLS-1$
        String className = getClassName(processItem);
        String idName = className;
        String suffix = getOsgiServiceIdSuffix();
        if (suffix != null && suffix.length() > 0) {
            idName += suffix;
        }
        routeInfo.put("className", className); //$NON-NLS-1$
        routeInfo.put("idName", idName); //$NON-NLS-2$

        boolean useSAM = false;
        boolean useSL = false;
        boolean hasCXFUsernameToken = false;
        boolean hasCXFSamlConsumer = false;
        boolean hasCXFSamlProvider = false;
        boolean hasCXFRSSamlProviderAuthz = false;

        Collection<NodeType> cSOAPs = EmfModelUtils.getComponentsByName(processItem, "cSOAP");
        boolean hasCXFComponent = !cSOAPs.isEmpty();
        cSOAPs.addAll(EmfModelUtils.getComponentsByName(processItem, "cREST"));
        if (!cSOAPs.isEmpty()) {
            Set<String> consumerNodes = new HashSet<String>();
            @SuppressWarnings("unchecked")
            List<ConnectionType> connections = processItem.getProcess().getConnection();
            for (ConnectionType conn : connections) {
                consumerNodes.add(conn.getTarget());
            }

            boolean isEEVersion = isStudioEEVersion();
            for (NodeType node : cSOAPs) {
                boolean nodeUseSAM = false;
                boolean nodeUseSaml = false;
                boolean nodeUseAuthz = false;
                boolean nodeUseRegistry = false;

                // http://jira.talendforge.org/browse/TESB-3850
                String format = EmfModelUtils.computeTextElementValue("DATAFORMAT", node); //$NON-NLS-1$

                if (!useSAM && !"RAW".equals(format)) { //$NON-NLS-1$
                    nodeUseSAM = EmfModelUtils.computeCheckElementValue("ENABLE_SAM", node) //$NON-NLS-1$
                            || EmfModelUtils.computeCheckElementValue("SERVICE_ACTIVITY_MONITOR", node); //$NON-NLS-1$
                }

                // security is disable in case CXF_MESSAGE or RAW dataFormat
                if (!"CXF_MESSAGE".equals(format) && !"RAW".equals(format)) { //$NON-NLS-1$  //$NON-NLS-2$
                    if (isEEVersion && EmfModelUtils.computeCheckElementValue("ENABLE_REGISTRY", node)) { //$NON-NLS-1$
                        nodeUseRegistry = true;
                        // https://jira.talendforge.org/browse/TESB-10725
                        nodeUseSAM = false;
                    } else if (EmfModelUtils.computeCheckElementValue("ENABLE_SECURITY", node)) { //$NON-NLS-1$
                        String securityType = EmfModelUtils.computeTextElementValue("SECURITY_TYPE", node); //$NON-NLS-1$
                        if ("USER".equals(securityType)) { //$NON-NLS-1$
                            hasCXFUsernameToken = true;
                        } else if ("SAML".equals(securityType)) { //$NON-NLS-1$
                            nodeUseSaml = true;
                            nodeUseAuthz = isEEVersion
                                    && EmfModelUtils.computeCheckElementValue("USE_AUTHORIZATION", node);
                        }
                    }
                }
                useSAM |= nodeUseSAM;

                useSL = EmfModelUtils.computeCheckElementValue("ENABLE_SL", node) //$NON-NLS-1$
                        || EmfModelUtils.computeCheckElementValue("SERVICE_LOCATOR", node);

                if (consumerNodes.contains(ElementParameterParser.getUNIQUENAME(node))) {
                    hasCXFSamlConsumer |= nodeUseSaml | nodeUseRegistry;
                } else {
                    hasCXFSamlProvider |= nodeUseSaml | nodeUseRegistry;
                    hasCXFRSSamlProviderAuthz |= nodeUseAuthz;
                }
            }
        }
        routeInfo.put("useSAM", useSAM); //$NON-NLS-1$
        routeInfo.put("useSL", useSL); //$NON-NLS-1$
        routeInfo.put("hasCXFUsernameToken", hasCXFUsernameToken); //$NON-NLS-1$
        routeInfo.put("hasCXFSamlConsumer", hasCXFSamlConsumer); //$NON-NLS-1$
        routeInfo.put("hasCXFSamlProvider", hasCXFSamlProvider); //$NON-NLS-1$
        routeInfo.put("hasCXFRSSamlProviderAuthz", hasCXFRSSamlProviderAuthz && !hasCXFComponent); //$NON-NLS-1$
        routeInfo.put("hasCXFComponent", hasCXFComponent); //$NON-NLS-1$

        // route OSGi DataSources
        routeInfo.put("dataSources", DataSourceConfig.getAliases(process)); //$NON-NLS-1$

        routeInfo.put("routelets", routelets); //$NON-NLS-1$

        return routeInfo;
    }

    private static boolean matches(URL importURL, ResourceDependencyModel resourceModel) {
        String path = importURL.getPath();
        String refPath = resourceModel.getClassPathUrl();
        if (path == null || path.length() == 0 || refPath == null || refPath.length() == 0) {
            return false;
        }
        if (path.startsWith("/")) {
            return path.length() == refPath.length() + 1 && path.endsWith(refPath);
        }
        return path.equals(refPath);
    }

    private static String adaptedClassPathUrl(ResourceDependencyModel resourceModel, boolean convertToBP) {
        String cpUrl = resourceModel.getClassPathUrl();
        if (convertToBP) {
            return "csi__" + cpUrl.replaceAll("/", "__");
        }
        int insert = cpUrl.lastIndexOf('/') + 1;
        return cpUrl.substring(0, insert) + "sei__" + cpUrl.substring(insert);
    }

    private static String adaptedResourceFolderName(String filePath, boolean convertToBP) {
        if (convertToBP) {
            return FileConstants.BLUEPRINT_FOLDER_NAME;
        }
        int ndx = filePath.lastIndexOf('/');
        return ndx < 0 ? "" : filePath.substring(0, ndx);
    }

    private static void formatSchemaLocation(Element root, boolean addBlueprint, boolean addCamel) {
        Attribute schemaLocation = root.attribute("schemaLocation");
        if (schemaLocation == null) {
            return;
        }
        String value = schemaLocation.getValue().replaceAll("(\\A|\\b)\\s\\s+\\b", "\n            ");
        if (addBlueprint) {
            value += "\n            http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd";
        }
        if (addCamel) {
            value += "\n            http://camel.apache.org/schema/blueprint http://camel.apache.org/schema/blueprint/camel-blueprint.xsd";
        }
        schemaLocation.setValue(value);
    }

    private static URL dummyURL(String path) throws MalformedURLException {
        return new URL(null, path, new URLStreamHandler() {

            @Override
            protected URLConnection openConnection(URL u) throws IOException {
                return null;
            }

        });
    }

    private static void moveNamespace(Element treeRoot, Namespace oldNsp, Namespace newNsp) {
        if (treeRoot.getNamespace().equals(oldNsp)) {
            treeRoot.setQName(QName.get(treeRoot.getName(), newNsp));
            treeRoot.remove(oldNsp);
        }
        moveNamespaceInChildren(treeRoot, oldNsp, newNsp);
    }

    private static void moveNamespaceInChildren(Element treeRoot, Namespace oldNsp, Namespace newNsp) {
        for (Iterator<?> i = treeRoot.elementIterator(); i.hasNext();) {
            Element e = (Element) i.next();
            if (e.getNamespace().equals(oldNsp)) {
                e.setQName(QName.get(e.getName(), newNsp));
                e.remove(oldNsp);
            }
            moveNamespaceInChildren(e, oldNsp, newNsp);
        }
    }

    private static void moveNamespace(Element treeRoot, String oldNspURI, String newNspURI) {
        Namespace oldNsp = treeRoot.getNamespace();
        if (oldNspURI.equals(oldNsp.getURI())) {
            Namespace newNsp = Namespace.get(oldNsp.getPrefix(), newNspURI);
            treeRoot.setQName(QName.get(treeRoot.getName(), newNsp));
            treeRoot.remove(oldNsp);
        }
        moveNamespaceInChildren(treeRoot, oldNspURI, newNspURI);
    }

    private static void moveNamespaceInChildren(Element treeRoot, String oldNspURI, String newNspURI) {
        for (Iterator<?> i = treeRoot.elementIterator(); i.hasNext();) {
            Element e = (Element) i.next();
            Namespace oldNsp = e.getNamespace();
            if (oldNspURI.equals(oldNsp.getURI())) {
                Namespace newNsp = Namespace.get(oldNsp.getPrefix(), newNspURI);
                e.setQName(QName.get(e.getName(), newNsp));
                e.remove(oldNsp);
            }
            moveNamespaceInChildren(e, oldNspURI, newNspURI);
        }
    }

    /*
    private static boolean isAffirmative(String systemProperty) {
    String option = System.getProperty(systemProperty);
    if (option == null || option.length() == 0) {
        return false;
    }
    if ("true".equalsIgnoreCase(option)) {
        return true;
    }
    if ("1".equalsIgnoreCase(option)) {
        return true;
    }
    if ("on".equalsIgnoreCase(option)) {
        return true;
    }
    if ("yes".equalsIgnoreCase(option)) {
        return true;
    }
    if ("y".equalsIgnoreCase(option)) {
        return true;
    }
    return false;
    }
    */

    private static boolean isNotNegated(String systemProperty) {
        String option = System.getProperty(systemProperty);
        if (option == null || option.length() == 0) {
            return true;
        }
        if ("false".equalsIgnoreCase(option)) {
            return false;
        }
        if ("0".equalsIgnoreCase(option)) {
            return false;
        }
        if ("off".equalsIgnoreCase(option)) {
            return false;
        }
        if ("no".equalsIgnoreCase(option)) {
            return false;
        }
        if ("n".equalsIgnoreCase(option)) {
            return false;
        }
        return true;
    }

    private static boolean isAll(String systemProperty) {
        String option = System.getProperty(systemProperty);
        if (option == null || option.length() == 0) {
            return false;
        }
        if ("all".equalsIgnoreCase(option)) {
            return true;
        }
        return false;
    }
}