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("[\\:\\?\\*]", ""); } }