org.openspaces.maven.plugin.CreatePUProjectMojo.java Source code

Java tutorial

Introduction

Here is the source code for org.openspaces.maven.plugin.CreatePUProjectMojo.java

Source

/*
 * Copyright 2006-2007 the original author or authors.
 *
 * 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.openspaces.maven.plugin;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;

import org.apache.maven.plugin.MojoExecutionException;
import org.springframework.util.StringUtils;

/**
 * Goal which creates the openspaces project.
 *
 * @goal create
 * @requiresProject false
 */
public class CreatePUProjectMojo extends AbstractOpenSpacesMojo {

    /**
     * the groupId string to replace with the package name
     */
    private static final String FILTER_GROUP_ID = "${puGroupId}";

    /**
     * the groupId string to replace with the package name
     */
    private static final String FILTER_GROUP_PATH = "${puGroupPath}";

    /**
     * the groupId string to replace with the package name
     */
    private static final String FILTER_ARTIFACT_ID = "${puArtifactId}";

    /**
     * Templates directory name
     */
    private static final String DIR_TEMPLATES = "pu-templates";

    /**
     * Project directory.
     *
     * @parameter expression="${artifactId}" default-value="my-app"
     */
    private File projectDir;

    /**
     * The packageName.
     *
     * @parameter expression="${groupId}" default-value="com.mycompany.app"
     */
    private String packageName;

    /**
     * The template.
     *
     * @parameter expression="${template}"
     */
    private String template;

    /**
     * The directory structure of the package.
     */
    private String packageDirs;

    public void executeMojo() throws MojoExecutionException {
        try {
            List urls = getTemplatesURLs();
            ClassLoader cl = Utils.createClassLoader(urls, Thread.currentThread().getContextClassLoader());
            Thread.currentThread().setContextClassLoader(cl);

            if (template == null || template.trim().length() == 0) {
                //throw new IllegalArgumentException(createAvailableTemplatesMessage());
                System.out.println(createAvailableTemplatesMessage());
                return;
            }

            Enumeration templateUrl = Thread.currentThread().getContextClassLoader()
                    .getResources(DIR_TEMPLATES + "/" + template + "/");
            if (templateUrl.hasMoreElements()) {
                // template found
                URL url = (URL) templateUrl.nextElement();
                PluginLog.getLog().debug("Found template at: " + url);

                // extract the jar path from the url
                url = getJarURLFromURL(url, "/" + template + "/");
                PluginLog.getLog().debug("Template JAR url: " + url);

                extract(url);
            } else {
                // the template was not found - show available templates
                throw new IllegalArgumentException(createAvailableTemplatesMessage());
            }
        } catch (Exception e) {
            throw new MojoExecutionException("Failed to create processing unit project", e);
        }
    }

    /**
     * Returns a list that contains all extension templates URLs.
     */
    private List getTemplatesURLs() throws Exception {
        String pluginPath = getPluginPath();
        List urls = new ArrayList();
        if (pluginPath != null) {
            PluginLog.getLog().debug("Plugin path: " + pluginPath);
            File f = new File(pluginPath);
            File dir = f.getParentFile();
            File templatesDir = new File(dir, DIR_TEMPLATES);
            if (templatesDir.exists()) {
                File[] templates = templatesDir.listFiles();
                if (templates != null) {
                    for (int i = 0; i < templates.length; i++) {
                        //urls.add(Utils.getURL(templates[i]));
                        urls.add(templates[i].toURL());
                    }
                }
            }
        }
        return urls;
    }

    /**
     * Extracts the project files to the project directory.
     */
    private void extract(URL url) throws Exception {
        packageDirs = packageName.replaceAll("\\.", "/");
        String puTemplate = DIR_TEMPLATES + "/" + template + "/";
        int length = puTemplate.length() - 1;
        BufferedInputStream bis = new BufferedInputStream(url.openStream());
        JarInputStream jis = new JarInputStream(bis);
        JarEntry je;
        byte[] buf = new byte[1024];
        int n;
        while ((je = jis.getNextJarEntry()) != null) {
            String jarEntryName = je.getName();
            PluginLog.getLog().debug("JAR entry: " + jarEntryName);
            if (je.isDirectory() || !jarEntryName.startsWith(puTemplate)) {
                continue;
            }
            String targetFileName = projectDir + jarEntryName.substring(length);

            // convert the ${gsGroupPath} to directory
            targetFileName = StringUtils.replace(targetFileName, FILTER_GROUP_PATH, packageDirs);
            PluginLog.getLog().debug("Extracting entry " + jarEntryName + " to " + targetFileName);

            // read the bytes to the buffer
            ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
            while ((n = jis.read(buf, 0, 1024)) > -1) {
                byteStream.write(buf, 0, n);
            }

            // replace property references with the syntax ${property_name}
            // to their respective property values.
            String data = byteStream.toString();
            data = StringUtils.replace(data, FILTER_GROUP_ID, packageName);
            data = StringUtils.replace(data, FILTER_ARTIFACT_ID, projectDir.getName());
            data = StringUtils.replace(data, FILTER_GROUP_PATH, packageDirs);

            // write the entire converted file content to the destination file.
            File f = new File(targetFileName);
            File dir = f.getParentFile();
            if (!dir.exists()) {
                dir.mkdirs();
            }
            FileWriter writer = new FileWriter(f);
            writer.write(data);
            jis.closeEntry();
            writer.close();
        }
        jis.close();
    }

    /**
     * Returns the plugin path.
     * Needs to be invoked from the main thread.
     * @return the path to the plugin JAR file.
     * @throws Exception
     */
    private String getPluginPath() throws Exception {
        Enumeration urls = Thread.currentThread().getContextClassLoader().getResources(DIR_TEMPLATES);
        while (urls.hasMoreElements()) {
            URL url = (URL) urls.nextElement();
            url = getJarURLFromURL(url, "");
            if (url.getProtocol().equals("file")) {
                return url.getPath();
            }
        }
        return null;
    }

    /**
     * Returns the path of a JAR file that appears in the URL
     */
    private URL getJarURLFromURL(URL url, String suffix) throws MalformedURLException {
        String urlString = url.toString();
        suffix = "!/" + DIR_TEMPLATES + suffix;
        if (urlString.endsWith(suffix)) {
            urlString = urlString.substring(4);
            urlString = urlString.substring(0, urlString.length() - suffix.length());
            url = new URL(urlString);
        }
        return url;
    }

    /**
     * Returns a set containing all templates defined in this JAR file.
     */
    public HashMap getJarTemplates(URL url) throws Exception {
        PluginLog.getLog().debug("retrieving all templates from jar file: " + url);
        String lookFor = DIR_TEMPLATES + "/";
        int length = lookFor.length();
        HashMap templates = new HashMap();
        BufferedInputStream bis = new BufferedInputStream(url.openStream());
        JarInputStream jis = new JarInputStream(bis);
        JarEntry je;
        Set temp = new HashSet();
        while ((je = jis.getNextJarEntry()) != null) {
            // find the template name
            String jarEntryName = je.getName();
            PluginLog.getLog().debug("Found entry: " + jarEntryName);
            if (jarEntryName.length() <= length || !jarEntryName.startsWith(lookFor)) {
                continue;
            }
            int nextSlashIndex = jarEntryName.indexOf("/", length);
            if (nextSlashIndex == -1) {
                continue;
            }
            String jarTemplate = jarEntryName.substring(length, nextSlashIndex);
            PluginLog.getLog().debug("Found template: " + jarTemplate);
            if (templates.containsKey(jarTemplate)) {
                continue;
            }
            if (jarEntryName.endsWith("readme.txt")) {
                // a description found - add to templates
                String description = getShortDescription(jis);
                templates.put(jarTemplate, description);
                // remove from temp
                temp.remove(jarTemplate);
            } else {
                // add to temp until a description is found
                temp.add(jarTemplate);
            }
        }
        // add all templates that has no description
        Iterator iter = temp.iterator();
        while (iter.hasNext()) {
            templates.put(iter.next(), "No description found.");
        }
        return templates;
    }

    private String getShortDescription(JarInputStream jis) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(jis));
        StringBuffer sb = new StringBuffer();
        boolean first = true;
        while (true) {
            String line = reader.readLine();
            if (line == null || !StringUtils.hasText(line)) {
                break;
            }
            if (!first) {
                sb.append("\n\r");
            } else {
                first = false;
            }
            sb.append(line);
        }
        jis.closeEntry();
        return sb.toString();
    }

    /**
     * Returns an array of available project templates names.
     */
    private HashMap getAvailableTemplates() throws Exception {
        HashMap templates = new HashMap();
        Enumeration urls = Thread.currentThread().getContextClassLoader().getResources(DIR_TEMPLATES);
        while (urls.hasMoreElements()) {
            URL url = (URL) urls.nextElement();
            PluginLog.getLog().debug("retrieving all templates from url: " + url);
            HashMap jarTemplates = getJarTemplates(getJarURLFromURL(url, ""));
            templates.putAll(jarTemplates);
        }
        LinkedHashMap sortedTemplates = new LinkedHashMap();
        String desc = (String) templates.remove("event-processing");
        if (desc != null) {
            sortedTemplates.put("event-processing", desc);
        }
        desc = (String) templates.remove("persistent-event-processing");
        if (desc != null) {
            sortedTemplates.put("persistent-event-processing", desc);
        }
        sortedTemplates.putAll(templates);
        return sortedTemplates;
    }

    /**
     * Creates a String message showing all available templates.
     * @return a String message showing all available templates
     * @throws Exception
     */
    private String createAvailableTemplatesMessage() throws Exception {
        HashMap availableTemplates = getAvailableTemplates();
        StringBuffer sb = new StringBuffer();
        sb.append("\n\n\n\n\n\n");
        if (template == null || template.trim().length() == 0) {
            sb.append("\nPlease use the -Dtemplate=<template> argument to specify a project template.\n");
        } else {
            sb.append("\nThe template '");
            sb.append(template);
            sb.append("' was not found.\n");
        }
        sb.append("Available templates:\n");
        sb.append("--------------------\n");
        Iterator iter = availableTemplates.keySet().iterator();
        int i = 1;
        while (iter.hasNext()) {
            String tmpl = (String) iter.next();
            String desc = (String) availableTemplates.get(tmpl);
            sb.append(i++);
            sb.append(". ");
            sb.append(tmpl);
            sb.append(" - ");
            sb.append(desc);
            sb.append("\n\n");
        }
        return sb.toString();
    }

}