org.teiid.plugin.maven.Generator.java Source code

Java tutorial

Introduction

Here is the source code for org.teiid.plugin.maven.Generator.java

Source

/*
 * JBoss, Home of Professional Open Source.
 * See the COPYRIGHT.txt file distributed with this work for information
 * regarding copyright ownership.  Some portions may be licensed
 * to Red Hat, Inc. under one or more contributor license agreements.
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301 USA.
 */
package org.teiid.plugin.maven;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.maven.model.Dependency;
import org.apache.maven.model.Model;
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.plugin.logging.SystemStreamLog;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
import org.jboss.shrinkwrap.descriptor.spi.node.Node;
import org.jboss.shrinkwrap.descriptor.spi.node.NodeImporter;
import org.jboss.shrinkwrap.descriptor.spi.node.dom.XmlDomNodeImporterImpl;

/**
 * A pojo class used to collect module.xml from Teiid code base or Teiid wildfly-dist
 * and replace module.xml resource's 'resource-root' to 'artifact'.
 * @author kylin
 *
 */
public class Generator {

    private Path modulesTargetDir;

    private Path pomPath;

    private Set<String> modules;

    private List<String> dependencyArtifact;

    private Log log;

    private Charset charset = StandardCharsets.UTF_8;

    protected Generator(Path modulesTargetDir, Path pomPath, Set<String> modules) {
        this(modulesTargetDir, pomPath, modules, null, new SystemStreamLog());
    }

    protected Generator(Path modulesTargetDir, Path pomPath, Set<String> modules, List<String> dependencyArtifact,
            Log log) {
        this.modulesTargetDir = modulesTargetDir;
        this.pomPath = pomPath;
        this.modules = modules;
        this.dependencyArtifact = dependencyArtifact;
        this.log = log;
    }

    /**
     * Two aspects functions supplied:
     *   a. Replace wildfly modules's resources from resource-root to artifact, for example, a module.xml has define
     *      resource-root like
     *          <resources>
     *              <resource-root path="teiid-engine-9.1.0.Alpha2.jar" />
     *          </resources>
     *      it will be replace to
     *          <resources>
     *              <artifact name="${org.jboss.teiid:teiid-engine}" />
     *          </resources>
     *   b. Verify modules system and wildfly feature pack pom.xml, for example, if the modules system can be 
     *      'TEIID_SERVER_HOME/modules/system/layers/dv/', then feature pack pom.xml can be verified whether
     *      a module in modules system have a reference dependency in feature pack pom.xml, this can guarantee
     *      feature pack build success
     * @throws IOException
     */
    public void processGeneratorTargets() throws IOException {

        for (String path : modules) {
            copy(Paths.get(path).toFile(), modulesTargetDir.toFile());
            log.debug("Copy " + path + " to " + modulesTargetDir); //$NON-NLS-1$ //$NON-NLS-2$
        }

        if (dependencyArtifact == null) {
            dependencyArtifact = getArtifactsDependencies();
        }

        Files.walkFileTree(modulesTargetDir, new SimpleFileVisitor<Path>() {

            @Override
            public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) throws IOException {
                if (path.endsWith("module.xml")) { //$NON-NLS-1$
                    String content = new String(Files.readAllBytes(path), charset);

                    Map<String, String> replacementMap = getReplacementMap(dependencyArtifact, path);
                    replacementMap.put("urn:jboss:module:1.0", "urn:jboss:module:1.3"); //$NON-NLS-1$ //$NON-NLS-2$
                    replacementMap.put("urn:jboss:module:1.1", "urn:jboss:module:1.3"); //$NON-NLS-1$ //$NON-NLS-2$
                    for (String key : replacementMap.keySet()) {
                        if (replacementMap.get(key).equals("")) { //$NON-NLS-1$
                            if (content.contains(key + "\" />")) { //$NON-NLS-1$
                                content = content.replace(key + "\" />", replacementMap.get(key)); //$NON-NLS-1$
                            } else if (content.contains(key + "\"/>")) { //$NON-NLS-1$
                                content = content.replace(key + "\"/>", replacementMap.get(key)); //$NON-NLS-1$
                            }
                        } else {
                            content = content.replace(key, replacementMap.get(key));
                        }
                    }
                    Files.write(path, content.getBytes(charset));
                    log.debug("rewrite " + path + " base on " + replacementMap); //$NON-NLS-1$ //$NON-NLS-2$
                }
                return super.visitFile(path, attrs);
            }
        });

    }

    private void copy(File sourceLocation, File targetLocation) throws IOException {
        if (sourceLocation.isDirectory()) {
            copyDirectory(sourceLocation, targetLocation);
        } else {
            copyFile(sourceLocation, targetLocation);
        }
    }

    private void copyDirectory(File source, File target) throws IOException {
        if (!target.exists()) {
            target.mkdir();
        }

        for (String f : source.list()) {
            copy(new File(source, f), new File(target, f));
        }
    }

    private void copyFile(File source, File target) throws IOException {
        try (InputStream in = new FileInputStream(source); OutputStream out = new FileOutputStream(target)) {
            byte[] buf = new byte[1024];
            int length;
            while ((length = in.read(buf)) > 0) {
                out.write(buf, 0, length);
            }
        }
    }

    protected Map<String, String> getReplacementMap(List<String> dependencies, Path path)
            throws IllegalArgumentException, IOException {

        Map<String, String> replacementMap = new HashMap<>();

        NodeImporter importer = new XmlDomNodeImporterImpl();
        Node node = importer.importAsNode(Files.newInputStream(path), true);
        Node resources = null;

        // find all resources
        for (Node subNode : node.getChildren()) {
            if (subNode.getName().equals("resources")) { //$NON-NLS-1$
                resources = subNode;
                break;
            }
        }

        if (resources == null) {
            return replacementMap;
        }

        for (Node subNode : resources.getChildren()) {
            String attr = subNode.getAttribute("path");
            if (attr != null) {
                String key = "<resource-root path=\"" + attr; //$NON-NLS-1$
                String value = formReplacement(path, dependencies, attr);
                replacementMap.put(key, value);
            }
        }

        return replacementMap;

        /*
        node = node.getChildren().stream().filter(n -> n.getName().equals("resources")).collect(Collectors.toList()).get(0);
        Map<String, String> replacementMap = node.getChildren().stream().map(n -> n.getAttribute("path")).filter(p -> p != null)
        .collect(Collectors.toMap(p -> "<resource-root path=\"" + p, p -> {
            String artifactId = p.toString();
            String replacement = "";
            if(artifactId.contains(".jar")){                   
                String suffix = findSuffix(artifactId);
                replacement = dependencies.stream().filter(d -> d.endsWith(suffix)).findAny().orElse(null);
                if(null != replacement){
                    replacement = "<artifact name=\"${" + replacement + "}";
                } else {
                    throw new IllegalArgumentException(path + "'s resource-root " + p + " not define a dependency in wildfly feature pack");
                }
            } else {
                log.warning(path + "'s resource-root " + p + " not a jar resource, skipped");
            }
            return replacement;
        }));*/
    }

    private String formReplacement(Path path, List<String> dependencies, String artifactId) {
        String replacement = ""; //$NON-NLS-1$
        if (artifactId.contains(".jar")) { //$NON-NLS-1$
            String suffix = findSuffix(artifactId);
            replacement = findReplacement(dependencies, suffix);
            if (null != replacement) {
                replacement = "<artifact name=\"${" + replacement + "}"; //$NON-NLS-1$ //$NON-NLS-2$
            } else {
                throw new IllegalArgumentException(path + "'s resource-root " + artifactId //$NON-NLS-1$
                        + " not define a dependency in feature pack pom.xml"); //$NON-NLS-1$
            }
        } else {
            log.warn(path + "'s resource-root " + artifactId + " not a jar resource, skipped"); //$NON-NLS-1$ //$NON-NLS-2$
        }
        return replacement;
    }

    private String findReplacement(List<String> dependencies, String suffix) {
        for (String d : dependencies) {
            if (d.endsWith(suffix)) {
                return d;
            }
        }
        return null;
    }

    private String findSuffix(String artifactId) {
        if (artifactId.contains("-${")) { //$NON-NLS-1$ 
            artifactId = artifactId.substring(0, artifactId.indexOf("-${")); //$NON-NLS-1$ 
        } else {
            artifactId = artifactId.substring(0, artifactId.lastIndexOf("-")); //$NON-NLS-1$ 
            if (artifactId.endsWith("-teiid") || artifactId.endsWith("-redhat")) { //$NON-NLS-1$ 
                artifactId = artifactId.substring(0, artifactId.lastIndexOf("-")); //$NON-NLS-1$ 
            }
            while (Character.isDigit(artifactId.charAt(artifactId.length() - 1))
                    && artifactId.charAt(artifactId.length() - 2) == '.' && artifactId.lastIndexOf("-") > 0) { //$NON-NLS-1$  //$NON-NLS-2$ 
                artifactId = artifactId.substring(0, artifactId.lastIndexOf("-")); //$NON-NLS-1$ 
            }
        }
        return ":" + artifactId;
    }

    protected List<String> getArtifactsDependencies() throws IOException {

        if (!Files.exists(pomPath)) {
            throw new IllegalArgumentException("Wildfly Feature Pack pom.xml argument not exist, " + pomPath); //$NON-NLS-1$
        }

        MavenXpp3Reader mavenReader = new MavenXpp3Reader();
        Model model;
        try {
            model = mavenReader.read(Files.newInputStream(pomPath));
        } catch (XmlPullParserException e) {
            throw new RuntimeException(e);
        }
        MavenProject project = new MavenProject(model);

        List<Dependency> dependencies = project.getDependencies();
        //        return dependencies.stream().map(d -> d.getGroupId() + ":" + d.getArtifactId()).collect(Collectors.toList());
        List<String> dependencyArtifact = new ArrayList<>(dependencies.size());
        for (Dependency d : dependencies) {
            dependencyArtifact.add(d.getGroupId() + ":" + d.getArtifactId());
        }
        return dependencyArtifact;
    }

}