org.objectstyle.woproject.maven2.javamonitor.JavaMonitorDeployMojo.java Source code

Java tutorial

Introduction

Here is the source code for org.objectstyle.woproject.maven2.javamonitor.JavaMonitorDeployMojo.java

Source

package org.objectstyle.woproject.maven2.javamonitor;

/*
 * ====================================================================
 * The ObjectStyle Group Software License, Version 1.0 Copyright (c) 2006 The
 * ObjectStyle Group, and individual authors of the software. All rights
 * reserved. Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer. 2. Redistributions in
 * binary form must reproduce the above copyright notice, this list of
 * conditions and the following disclaimer in the documentation and/or other
 * materials provided with the distribution. 3. The end-user documentation
 * included with the redistribution, if any, must include the following
 * acknowlegement: "This product includes software developed by the ObjectStyle
 * Group (http://objectstyle.org/)." Alternately, this acknowlegement may appear
 * in the software itself, if and wherever such third-party acknowlegements
 * normally appear. 4. The names "ObjectStyle Group" and "Cayenne" must not be
 * used to endorse or promote products derived from this software without prior
 * written permission. For written permission, please contact
 * andrus@objectstyle.org. 5. Products derived from this software may not be
 * called "ObjectStyle" nor may "ObjectStyle" appear in their names without
 * prior written permission of the ObjectStyle Group. THIS SOFTWARE IS PROVIDED
 * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OBJECTSTYLE GROUP OR ITS
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 * This software consists of voluntary contributions made by many individuals on
 * behalf of the ObjectStyle Group. For more information on the ObjectStyle
 * Group, please see <http://objectstyle.org/>.
 */

import java.io.File;

import org.apache.commons.lang.StringUtils;
import org.apache.maven.artifact.manager.WagonConfigurationException;
import org.apache.maven.artifact.manager.WagonManager;
import org.apache.maven.model.Site;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.project.MavenProject;
import org.apache.maven.settings.Server;
import org.apache.maven.settings.Settings;
import org.apache.maven.wagon.CommandExecutionException;
import org.apache.maven.wagon.CommandExecutor;
import org.apache.maven.wagon.ConnectionException;
import org.apache.maven.wagon.ResourceDoesNotExistException;
import org.apache.maven.wagon.TransferFailedException;
import org.apache.maven.wagon.UnsupportedProtocolException;
import org.apache.maven.wagon.Wagon;
import org.apache.maven.wagon.authentication.AuthenticationException;
import org.apache.maven.wagon.authorization.AuthorizationException;
import org.apache.maven.wagon.observers.Debug;
import org.apache.maven.wagon.proxy.ProxyInfo;
import org.apache.maven.wagon.repository.Repository;
import org.codehaus.plexus.PlexusConstants;
import org.codehaus.plexus.PlexusContainer;
import org.codehaus.plexus.component.configurator.ComponentConfigurationException;
import org.codehaus.plexus.component.configurator.ComponentConfigurator;
import org.codehaus.plexus.component.repository.exception.ComponentLifecycleException;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.codehaus.plexus.configuration.PlexusConfiguration;
import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration;
import org.codehaus.plexus.context.Context;
import org.codehaus.plexus.context.ContextException;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
import org.codehaus.plexus.util.xml.Xpp3Dom;

/**
 * Goal which deploy WebObjects Application packages (WOAs) into the JavaMonitor
 * tool.
 *
 * @goal deploy
 * @execute phase="package"
 * @requiresDirectInvocation
 * @author <a href="mailto:hprange@gmail.com">Henrique Prange</a>
 */
public class JavaMonitorDeployMojo extends AbstractMojo implements Contextualizable {
    /**
     * Configure the Wagon with the information from serverConfigurationMap (
     * which comes from settings.xml )
     *
     * @todo Remove when {@link WagonManager#getWagon(Repository) is available}.
     *       It's available in Maven 2.0.5.
     * @param wagon
     * @param repositoryId
     * @param settings
     * @param container
     * @param log
     * @throws WagonConfigurationException
     */
    static void configureWagon(Wagon wagon, String repositoryId, Settings settings, PlexusContainer container,
            Log log) throws WagonConfigurationException {
        // MSITE-25: Make sure that the server settings are inserted
        for (int i = 0; i < settings.getServers().size(); i++) {
            Server server = (Server) settings.getServers().get(i);
            String id = server.getId();
            if (id != null && id.equals(repositoryId)) {
                if (server.getConfiguration() != null) {
                    final PlexusConfiguration plexusConf = new XmlPlexusConfiguration(
                            (Xpp3Dom) server.getConfiguration());

                    ComponentConfigurator componentConfigurator = null;
                    try {
                        componentConfigurator = (ComponentConfigurator) container
                                .lookup(ComponentConfigurator.ROLE);
                        componentConfigurator.configureComponent(wagon, plexusConf, container.getContainerRealm());
                    } catch (final ComponentLookupException e) {
                        throw new WagonConfigurationException(repositoryId,
                                "Unable to lookup wagon configurator." + " Wagon configuration cannot be applied.",
                                e);
                    } catch (ComponentConfigurationException e) {
                        throw new WagonConfigurationException(repositoryId, "Unable to apply wagon configuration.",
                                e);
                    } finally {
                        if (componentConfigurator != null) {
                            try {
                                container.release(componentConfigurator);
                            } catch (ComponentLifecycleException e) {
                                log.error("Problem releasing configurator - ignoring: " + e.getMessage());
                            }
                        }
                    }

                }

            }
        }
    }

    /**
     * <p>
     * Get the <code>ProxyInfo</code> of the proxy associated with the
     * <code>host</code> and the <code>protocol</code> of the given
     * <code>repository</code>.
     * </p>
     * <p>
     * Extract from <a
     * href="http://java.sun.com/j2se/1.5.0/docs/guide/net/properties.html">
     * J2SE Doc : Networking Properties - nonProxyHosts</a> : "The value can be
     * a list of hosts, each separated by a |, and in addition a wildcard
     * character (*) can be used for matching"
     * </p>
     * <p>
     * Defensively support for comma (",") and semi colon (";") in addition to
     * pipe ("|") as separator.
     * </p>
     *
     * @return a ProxyInfo object instantiated or <code>null</code> if no
     *         matching proxy is found
     */
    public static ProxyInfo getProxyInfo(Repository repository, WagonManager wagonManager) {
        ProxyInfo proxyInfo = wagonManager.getProxy(repository.getProtocol());

        if (proxyInfo == null) {
            return null;
        }

        String host = repository.getHost();
        String nonProxyHostsAsString = proxyInfo.getNonProxyHosts();
        String[] nonProxyHosts = StringUtils.split(nonProxyHostsAsString, ",;|");
        for (int i = 0; i < nonProxyHosts.length; i++) {
            String nonProxyHost = nonProxyHosts[i];
            if (StringUtils.contains(nonProxyHost, "*")) {
                // Handle wildcard at the end, beginning or middle of the
                // nonProxyHost
                String nonProxyHostPrefix = StringUtils.substringBefore(nonProxyHost, "*");
                String nonProxyHostSuffix = StringUtils.substringAfter(nonProxyHost, "*");
                // prefix*
                if (StringUtils.isNotEmpty(nonProxyHostPrefix) && host.startsWith(nonProxyHostPrefix)
                        && StringUtils.isEmpty(nonProxyHostSuffix)) {
                    return null;
                }
                // *suffix
                if (StringUtils.isEmpty(nonProxyHostPrefix) && StringUtils.isNotEmpty(nonProxyHostSuffix)
                        && host.endsWith(nonProxyHostSuffix)) {
                    return null;
                }
                // prefix*suffix
                if (StringUtils.isNotEmpty(nonProxyHostPrefix) && host.startsWith(nonProxyHostPrefix)
                        && StringUtils.isNotEmpty(nonProxyHostSuffix) && host.endsWith(nonProxyHostSuffix)) {
                    return null;
                }
            } else if (host.equals(nonProxyHost)) {
                return null;
            }
        }
        return proxyInfo;
    }

    private PlexusContainer container;

    /**
     * The maven project.
     *
     * @parameter expression="${project}"
     * @required
     * @readonly
     */
    private MavenProject project;

    /**
     * @parameter expression="${server}"
     */
    private String server;

    /**
     * The current user system settings for use in Maven.
     *
     * @parameter expression="${settings}"
     * @required
     * @readonly
     */
    private Settings settings;

    /**
     * The WOA package will be deployed to this URL.
     *
     * If you don't specify this, the default-value will be
     * "file:///Library/WebObjects/Applications/${project.build.finalName}.woa".
     *
     * @parameter expression="${url}" default-value=
     *            "file:///Library/WebObjects/Applications/${project.build.finalName}.woa"
     * @required
     */
    private String url;

    /**
     * @component
     */
    private WagonManager wagonManager;

    /**
     * @parameter expression="${woaDirectory}"
     */
    private String woaDirectory;

    /**
     * @parameter expression="${project.build.finalName}"
     * @readonly
     * @required
     */
    private String finalName;

    public void contextualize(Context context) throws ContextException {
        container = (PlexusContainer) context.get(PlexusConstants.PLEXUS_KEY);
    }

    public void execute() throws MojoExecutionException, MojoFailureException {
        getLog().info("Using this URL for application deployment: " + url);
        getLog().info("Application package: " + woaDirectory);

        Repository repository = new Repository(server, url);

        Wagon wagon;
        try {
            wagon = wagonManager.getWagon(repository);
            //configureWagon(wagon, server, settings, container, getLog());
        } catch (UnsupportedProtocolException e) {
            throw new MojoExecutionException("Unsupported protocol: '" + repository.getProtocol() + "'", e);
        } catch (WagonConfigurationException e) {
            throw new MojoExecutionException("Unable to configure Wagon: '" + repository.getProtocol() + "'", e);
        }

        if (!wagon.supportsDirectoryCopy()) {
            throw new MojoExecutionException(
                    "Wagon protocol '" + repository.getProtocol() + "' doesn't support directory copying");
        }

        try {
            Debug debug = new Debug();

            wagon.addSessionListener(debug);

            wagon.addTransferListener(debug);

            ProxyInfo proxyInfo = getProxyInfo(repository, wagonManager);
            if (proxyInfo != null) {
                wagon.connect(repository, wagonManager.getAuthenticationInfo(server), proxyInfo);
            } else {
                wagon.connect(repository, wagonManager.getAuthenticationInfo(server));
            }

            wagon.putDirectory(new File(woaDirectory), "./" + finalName + ".woa");

            // TODO: current wagon uses zip which will use the umask on remote
            // host instead of honouring our settings
            // Force group writeable
            if (wagon instanceof CommandExecutor) {
                CommandExecutor exec = (CommandExecutor) wagon;
                exec.executeCommand("chmod -Rf g+w,a+rX " + repository.getBasedir());
            }
        } catch (ResourceDoesNotExistException e) {
            throw new MojoExecutionException("Error uploading site", e);
        } catch (TransferFailedException e) {
            throw new MojoExecutionException("Error uploading site", e);
        } catch (AuthorizationException e) {
            throw new MojoExecutionException("Error uploading site", e);
        } catch (ConnectionException e) {
            throw new MojoExecutionException("Error uploading site", e);
        } catch (AuthenticationException e) {
            throw new MojoExecutionException("Error uploading site", e);
        } catch (CommandExecutionException e) {
            throw new MojoExecutionException("Error uploading site", e);
        } finally {
            try {
                wagon.disconnect();
            } catch (ConnectionException e) {
                getLog().error("Error disconnecting wagon - ignored", e);
            }
        }
    }

    /**
     * Generates the site structure using the project hiearchy (project and its
     * modules) or using the distributionManagement elements from the pom.xml.
     *
     * @param project
     * @param ignoreMissingSiteUrl
     * @return the structure relative path
     * @throws MojoFailureException
     *             if any
     */
    protected static String getStructure(MavenProject project, boolean ignoreMissingSiteUrl)
            throws MojoFailureException {
        if (project.getDistributionManagement() == null) {
            String hierarchy = project.getArtifactId();

            MavenProject parent = project.getParent();
            while (parent != null) {
                hierarchy = parent.getArtifactId() + "/" + hierarchy;
                parent = parent.getParent();
            }

            return hierarchy;
        }

        Site site = project.getDistributionManagement().getSite();
        if (site == null) {
            if (!ignoreMissingSiteUrl) {
                throw new MojoFailureException(
                        "Missing site information in the distribution management element in the project: '"
                                + project.getName() + "'.");
            }

            return null;
        }

        if (StringUtils.isEmpty(site.getUrl())) {
            if (!ignoreMissingSiteUrl) {
                throw new MojoFailureException("The URL in the site is missing in the project descriptor.");
            }

            return null;
        }

        Repository repository = new Repository(site.getId(), site.getUrl());
        StringBuffer hierarchy = new StringBuffer(1024);
        hierarchy.append(repository.getHost());
        if (!StringUtils.isEmpty(repository.getBasedir())) {
            if (!repository.getBasedir().startsWith("/")) {
                hierarchy.append('/');
            }
            hierarchy.append(repository.getBasedir());
        }

        return hierarchy.toString().replaceAll("[\\:\\?\\*]", "");
    }

}