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

org.wildfly.plugins.bootablejar.maven.goals.ScannedModules Maven / Gradle / Ivy

There is a newer version: 11.0.2.Final
Show newest version
/*
 * Copyright 2021 Red Hat, Inc. and/or its affiliates
 * and other contributors as indicated by the @author tags.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.wildfly.plugins.bootablejar.maven.goals;

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.maven.plugin.MojoExecutionException;
import org.jboss.galleon.ProvisioningException;
import org.jboss.galleon.api.GalleonFeaturePackRuntime;
import org.jboss.galleon.api.GalleonPackageRuntime;
import org.jboss.galleon.api.GalleonProvisioningRuntime;
import org.jboss.galleon.api.Provisioning;
import org.jboss.galleon.api.config.GalleonProvisioningConfig;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.wildfly.plugin.tools.bootablejar.BootableJarSupport;
import org.xml.sax.SAXException;

final class ScannedModules {

    private static final String MODULE_XML = "module.xml";
    private static final String PM = "pm";
    private static final String WILDFLY = "wildfly";
    private static final String MODULE = "module";
    private static final String TASKS_XML = "tasks.xml";
    private static final String MODULE_RUNTIME_KEY = "org.jboss.modules:jboss-modules";

    private final Map> perModule;
    private final Map copiedArtifacts;
    private final String moduleRuntimeKey;
    private final String moduleRuntimeValue;

    ScannedModules(Map> perModule, String moduleRuntimeKey, String moduleRuntimeValue,
            Map copiedArtifacts) {
        this.perModule = perModule;
        this.moduleRuntimeKey = moduleRuntimeKey;
        this.moduleRuntimeValue = moduleRuntimeValue;
        this.copiedArtifacts = copiedArtifacts;
    }

    Map> getPerModuleArtifacts() {
        return perModule;
    }

    Map getCopiedArtifacts() {
        return copiedArtifacts;
    }

    String getModuleRuntime() {
        return moduleRuntimeValue;
    }

    Map getProvisionedArtifacts() {
        Map all = new HashMap<>();
        for (Map artifacts : perModule.values()) {
            all.putAll(artifacts);
        }
        all.put(moduleRuntimeKey, moduleRuntimeValue);
        all.putAll(copiedArtifacts);
        return all;
    }

    static ScannedModules scanProvisionedArtifacts(Provisioning pm, GalleonProvisioningConfig config)
            throws ProvisioningException, MojoExecutionException {
        Map propsMap = new HashMap<>();
        Map> perModule = new TreeMap<>();
        Map copiedArtifacts = new HashMap<>();
        try (GalleonProvisioningRuntime rt = pm.getProvisioningRuntime(config)) {
            for (GalleonFeaturePackRuntime fprt : rt.getGalleonFeaturePacks()) {
                Path artifactProps = fprt.getResource(BootableJarSupport.WILDFLY_ARTIFACT_VERSIONS_RESOURCE_PATH);
                try {
                    AbstractBuildBootableJarMojo.readProperties(artifactProps, propsMap);
                } catch (Exception ex) {
                    throw new MojoExecutionException("Error reading artifact versions", ex);
                }
            }
            for (GalleonFeaturePackRuntime fprt : rt.getGalleonFeaturePacks()) {
                processPackages(fprt, perModule, propsMap, copiedArtifacts);
            }
        }

        String moduleRuntimeValue = propsMap.get(MODULE_RUNTIME_KEY);
        if (moduleRuntimeValue == null) {
            throw new ProvisioningException("No JBoss Modules runtime found");
        }
        return new ScannedModules(perModule, MODULE_RUNTIME_KEY, moduleRuntimeValue, copiedArtifacts);
    }

    private static void processPackages(final GalleonFeaturePackRuntime fp,
            Map> perModule,
            Map propsMap,
            Map copiedArtifacts) throws ProvisioningException {
        Map jbossModules = new HashMap<>();
        for (GalleonPackageRuntime pkg : fp.getGalleonPackages()) {
            final Path pmWfDir = pkg.getResource(PM, WILDFLY);
            if (!Files.exists(pmWfDir)) {
                continue;
            }
            final Path moduleDir = pmWfDir.resolve(MODULE);
            if (Files.exists(moduleDir)) {
                processModules(pkg, moduleDir, jbossModules);
            }
            final Path tasks = pmWfDir.resolve(TASKS_XML);
            if (Files.exists(tasks)) {
               processTasks(pkg, tasks, propsMap, copiedArtifacts);
            }
        }
        for (Map.Entry entry : jbossModules.entrySet()) {
            final GalleonPackageRuntime pkg = entry.getValue();
            try {
                processModuleTemplate(pkg, entry.getKey(), perModule, propsMap);
            } catch (IOException | ParserConfigurationException | ProvisioningException | SAXException e) {
                throw new ProvisioningException("Failed to process JBoss module XML template for feature-pack "
                        + pkg.getFeaturePackFPID() + " package " + pkg.getName(), e);
            }
        }
    }

    private static void processTasks(GalleonPackageRuntime pkg, Path tasks, Map propsMap,
            Map artifacts) throws ProvisioningException {
        try {
            try (InputStream reader = Files.newInputStream(tasks)) {
                DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
                DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();

                Document document = documentBuilder.parse(reader);
                Element root = document.getDocumentElement();
                NodeList lst = root.getChildNodes();
                for (int i = 0; i < lst.getLength(); i++) {
                    Node n = lst.item(i);
                    if (n instanceof Element) {
                        if ("copy-artifact".equals(n.getNodeName())) {
                            Element copyArtifact = (Element) n;
                            String artifact = copyArtifact.getAttribute("artifact");
                            String optional = copyArtifact.getAttribute("optional");
                            String value = propsMap.get(artifact);
                            if (value == null) {
                                if ("true".equals(optional)) {
                                    // Could be unknown.
                                    artifacts.put(artifact, artifact + ":unknown::jar");
                                }
                            } else {
                                artifacts.put(artifact, value);
                            }
                        }
                    }
                }
            }
        } catch (SAXException | ParserConfigurationException | IOException e) {
            throw new ProvisioningException("Failed to process tasks from package " + pkg.getName()
                    + " from feature-pack " + pkg.getFeaturePackFPID(), e);
        }
    }

    private static void processModules(GalleonPackageRuntime pkg, Path fpModuleDir,
            Map jbossModules) throws ProvisioningException {
        try {
            Files.walkFileTree(fpModuleDir, new SimpleFileVisitor() {
                @Override
                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
                        throws IOException {
                    if (file.getFileName().toString().equals(MODULE_XML)) {
                        jbossModules.put(fpModuleDir.relativize(file), pkg);
                    }
                    return FileVisitResult.CONTINUE;
                }
            });
        } catch (IOException e) {
            throw new ProvisioningException("Failed to process modules from package " + pkg.getName()
                    + " from feature-pack " + pkg.getFeaturePackFPID(), e);
        }
    }

    private static void processModuleTemplate(GalleonPackageRuntime pkg, Path moduleXmlRelativePath,
            Map> perModule, Map propsMap) throws ProvisioningException, IOException, ParserConfigurationException, SAXException {
        final Path moduleTemplate = pkg.getResource(PM, WILDFLY, MODULE).resolve(moduleXmlRelativePath);

        try (InputStream reader = Files.newInputStream(moduleTemplate)) {
            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();

            Document document = documentBuilder.parse(reader);
            Element root = document.getDocumentElement();
            NodeList lst = root.getChildNodes();
            for (int i = 0; i < lst.getLength(); i++) {
                Node n = lst.item(i);
                if (n instanceof Element) {
                    if ("resources".equals(n.getNodeName())) {
                        Element resources = (Element) n;
                        NodeList artifacts = resources.getChildNodes();
                        for (int j = 0; j < artifacts.getLength(); j++) {
                            Node a = artifacts.item(j);
                            if (a instanceof Element) {
                                if ("artifact".equals(a.getNodeName())) {
                                    String name = ((Element) a).getAttribute("name");
                                    if (name.startsWith("${")) {
                                        name = name.substring(2, name.length() - 1);
                                        Map m = perModule.get(pkg.getName());
                                        if (m == null) {
                                            m = new TreeMap<>();
                                            perModule.put(pkg.getName(), m);
                                        }
                                        String value = propsMap.get(name);
                                        m.put(name, value);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy