Java tutorial
/* * Copyright 2010 Red Hat, Inc. * * 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.commonjava.emb.boot.embed; import static org.commonjava.emb.conf.EMBLibraries.loadLibraries; import org.apache.maven.Maven; import org.apache.maven.cli.CLIReportingUtils; import org.apache.maven.exception.DefaultExceptionHandler; import org.apache.maven.exception.ExceptionHandler; import org.apache.maven.exception.ExceptionSummary; import org.apache.maven.execution.MavenExecutionRequest; import org.apache.maven.execution.MavenExecutionRequestPopulationException; import org.apache.maven.execution.MavenExecutionRequestPopulator; import org.apache.maven.execution.MavenExecutionResult; import org.apache.maven.lifecycle.LifecycleExecutionException; import org.apache.maven.project.MavenProject; import org.apache.maven.properties.internal.EnvironmentUtils; import org.apache.maven.settings.Settings; import org.apache.maven.settings.building.DefaultSettingsBuildingRequest; import org.apache.maven.settings.building.SettingsBuilder; import org.apache.maven.settings.building.SettingsBuildingException; import org.apache.maven.settings.building.SettingsBuildingRequest; import org.apache.maven.settings.building.SettingsBuildingResult; import org.apache.maven.settings.building.SettingsProblem; import org.codehaus.plexus.PlexusConstants; import org.codehaus.plexus.PlexusContainer; import org.codehaus.plexus.component.annotations.Component; import org.codehaus.plexus.component.repository.exception.ComponentLookupException; import org.codehaus.plexus.logging.Logger; import org.codehaus.plexus.util.StringUtils; import org.commonjava.emb.EMBExecutionRequest; import org.commonjava.emb.boot.log.EventLogger; import org.commonjava.emb.boot.main.EMBMain; import org.commonjava.emb.boot.services.EMBServiceManager; import org.commonjava.emb.conf.EMBConfiguration; import org.commonjava.emb.conf.EMBLibrary; import org.commonjava.emb.conf.loader.EMBLibraryLoader; import org.commonjava.emb.conf.mgmt.EMBManagementException; import org.commonjava.emb.conf.mgmt.EMBManagementView; import org.commonjava.emb.conf.mgmt.LoadOnFinish; import org.commonjava.emb.conf.mgmt.LoadOnStart; import org.commonjava.emb.internal.plexus.ExtrudablePlexusContainer; import org.commonjava.emb.plexus.ComponentKey; import org.sonatype.plexus.components.cipher.DefaultPlexusCipher; import org.sonatype.plexus.components.cipher.PlexusCipherException; import org.sonatype.plexus.components.sec.dispatcher.DefaultSecDispatcher; import org.sonatype.plexus.components.sec.dispatcher.SecDispatcherException; import org.sonatype.plexus.components.sec.dispatcher.SecUtil; import org.sonatype.plexus.components.sec.dispatcher.model.SettingsSecurity; import com.google.inject.Injector; import java.io.IOException; import java.io.PrintStream; import java.util.Collection; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; @Component(role = EMBEmbedder.class) public class EMBEmbedder { private static boolean embInfoShown; private final Logger logger; private final PrintStream standardOut; private final boolean shouldShowErrors; private final Maven maven; private final boolean showVersion; private final ExtrudablePlexusContainer container; private final EMBConfiguration embConfiguration; private final SettingsBuilder settingsBuilder; private final MavenExecutionRequestPopulator executionRequestPopulator; private final DefaultSecDispatcher securityDispatcher; private transient final EMBServiceManager serviceManager; private final List<EMBLibraryLoader> libraryLoaders; private boolean infoPrinted = false; EMBEmbedder(final Maven maven, final EMBConfiguration embConfiguration, final ExtrudablePlexusContainer container, final SettingsBuilder settingsBuilder, final MavenExecutionRequestPopulator executionRequestPopulator, final DefaultSecDispatcher securityDispatcher, final EMBServiceManager serviceManager, final List<EMBLibraryLoader> libraryLoaders, final PrintStream standardOut, final Logger logger, final boolean shouldShowErrors, final boolean showVersion) { this.maven = maven; this.embConfiguration = embConfiguration; this.container = container; this.settingsBuilder = settingsBuilder; this.executionRequestPopulator = executionRequestPopulator; this.securityDispatcher = securityDispatcher; this.serviceManager = serviceManager; this.libraryLoaders = libraryLoaders; this.standardOut = standardOut; this.logger = logger; this.shouldShowErrors = shouldShowErrors; this.showVersion = showVersion; } public synchronized Injector injector() throws EMBEmbeddingException { printInfo(null); return container.getInjector(); } public synchronized Map<Object, Throwable> wire(final Object... instances) throws EMBEmbeddingException { printInfo(null); return container.extrudeDependencies(instances); } public synchronized EMBServiceManager serviceManager() throws EMBEmbeddingException { printInfo(null); return serviceManager; } public MavenExecutionResult execute(final EMBExecutionRequest request) throws EMBEmbeddingException { final PrintStream oldOut = System.out; try { if (standardOut != null) { System.setOut(standardOut); } doExecutionStarting(); injectEnvironment(request); printInfo(request); return maven.execute(request.asMavenExecutionRequest()); } finally { doExecutionFinished(); System.setOut(oldOut); } } public String encryptMasterPassword(final EMBExecutionRequest request) throws EMBEmbeddingException { printInfo(null); String passwd = request.getPasswordToEncyrpt(); if (passwd == null) { passwd = ""; } try { final DefaultPlexusCipher cipher = new DefaultPlexusCipher(); final String result = cipher.encryptAndDecorate(passwd, DefaultSecDispatcher.SYSTEM_PROPERTY_SEC_LOCATION); logger.info(result); return result; } catch (final PlexusCipherException e) { throw new EMBEmbeddingException("Failed to encrypt master password: {0}", e, e.getMessage()); } } public String encryptPassword(final EMBExecutionRequest request) throws EMBEmbeddingException { printInfo(null); final String passwd = request.getPasswordToEncyrpt(); String configurationFile = securityDispatcher.getConfigurationFile(); if (configurationFile.startsWith("~")) { configurationFile = System.getProperty("user.home") + configurationFile.substring(1); } final String file = System.getProperty(DefaultSecDispatcher.SYSTEM_PROPERTY_SEC_LOCATION, configurationFile); String master = null; try { final SettingsSecurity sec = SecUtil.read(file, true); if (sec != null) { master = sec.getMaster(); } if (master == null) { throw new IllegalStateException("Master password is not set in the setting security file: " + file); } final DefaultPlexusCipher cipher = new DefaultPlexusCipher(); final String masterPasswd = cipher.decryptDecorated(master, DefaultSecDispatcher.SYSTEM_PROPERTY_SEC_LOCATION); final String result = cipher.encryptAndDecorate(passwd, masterPasswd); logger.info(result); return result; } catch (final PlexusCipherException e) { throw new EMBEmbeddingException("Failed to encrypt password: {0}", e, e.getMessage()); } catch (final SecDispatcherException e) { throw new EMBEmbeddingException("Failed to encrypt password: {0}", e, e.getMessage()); } } protected void doExecutionStarting() throws EMBEmbeddingException { for (final EMBLibrary library : embConfiguration.getLibraries()) { final Set<ComponentKey<?>> components = library.getManagementComponents(LoadOnStart.class); if (components != null && !components.isEmpty()) { final EMBManagementView mgmtView = new EmbedderManagementView(container, embConfiguration); for (final ComponentKey<?> key : components) { try { final LoadOnStart los = (LoadOnStart) container.lookup(key.getRole(), key.getHint()); los.executionStarting(mgmtView); } catch (final ComponentLookupException e) { throw new EMBEmbeddingException( "Failed to lookup load-on-start component for initialization: %s.\nReason: %s", e, key, e.getMessage()); } } } } } protected void doExecutionFinished() { for (final EMBLibrary library : embConfiguration.getLibraries()) { final Set<ComponentKey<?>> components = library.getManagementComponents(LoadOnFinish.class); if (components != null && !components.isEmpty()) { final EMBManagementView mgmtView = new EmbedderManagementView(container, embConfiguration); for (final ComponentKey<?> key : components) { try { final LoadOnFinish lof = (LoadOnFinish) container.lookup(key.getRole(), key.getHint()); lof.executionFinished(mgmtView); } catch (final ComponentLookupException e) { logger.error(String.format( "Failed to lookup load-on-start component for initialization: %s.\nReason: %s", key, e.getMessage()), e); } } } } } protected synchronized void injectEnvironment(final EMBExecutionRequest request) throws EMBEmbeddingException { injectLogSettings(request); initializeEMB(request); injectProperties(request); injectSettings(request); injectFromProperties(request); } private void initializeEMB(final EMBExecutionRequest request) { embConfiguration.withEMBExecutionRequest(request); if (request.isInteractiveMode()) { embConfiguration.interactive(); } else { embConfiguration.nonInteractive(); } if (Logger.LEVEL_DEBUG == request.getLoggingLevel()) { embConfiguration.withDebug(); } else { embConfiguration.withoutDebug(); } } protected void injectFromProperties(final EMBExecutionRequest request) { String localRepoProperty = request.getUserProperties().getProperty(EMBMain.LOCAL_REPO_PROPERTY); if (localRepoProperty == null) { localRepoProperty = request.getSystemProperties().getProperty(EMBMain.LOCAL_REPO_PROPERTY); } if (localRepoProperty != null) { request.setLocalRepositoryPath(localRepoProperty); } } protected void injectLogSettings(final EMBExecutionRequest request) { final int logLevel = request.getLoggingLevel(); if (Logger.LEVEL_DEBUG == logLevel) { embConfiguration.withDebug(); } else { embConfiguration.withoutDebug(); } logger.setThreshold(logLevel); container.getLoggerManager().setThresholds(request.getLoggingLevel()); // final Configurator log4jConfigurator = new Configurator() // { // @SuppressWarnings( "unchecked" ) // public void doConfigure( final URL notUsed, final LoggerRepository repo ) // { // final Enumeration<org.apache.log4j.Logger> loggers = repo.getCurrentLoggers(); // while ( loggers.hasMoreElements() ) // { // final org.apache.log4j.Logger logger = loggers.nextElement(); // if ( Logger.LEVEL_DEBUG == logLevel ) // { // logger.setLevel( Level.DEBUG ); // } // else if ( Logger.LEVEL_ERROR == logLevel ) // { // logger.setLevel( Level.ERROR ); // } // } // } // }; // // log4jConfigurator.doConfigure( null, LogManager.getLoggerRepository() ); request.setExecutionListener(new EventLogger(logger)); } protected void injectProperties(final EMBExecutionRequest request) { final Properties systemProperties = new Properties(); EnvironmentUtils.addEnvVars(systemProperties); systemProperties.putAll(System.getProperties()); if (request.getSystemProperties() != null) { systemProperties.putAll(request.getSystemProperties()); } request.setSystemProperties(systemProperties); } protected void injectSettings(final EMBExecutionRequest request) throws EMBEmbeddingException { Settings settings = request.getSettings(); SettingsBuildingResult settingsResult = null; if (settings == null) { final SettingsBuildingRequest settingsRequest = new DefaultSettingsBuildingRequest(); settingsRequest.setGlobalSettingsFile(request.getGlobalSettingsFile()); settingsRequest.setUserSettingsFile(request.getUserSettingsFile()); settingsRequest.setSystemProperties(request.getSystemProperties()); settingsRequest.setUserProperties(request.getUserProperties()); try { settingsResult = settingsBuilder.build(settingsRequest); } catch (final SettingsBuildingException e) { throw new EMBEmbeddingException( "Failed to build settings; {0}\nGlobal settings: {1}\nUser settings: {2}", e, e.getMessage(), request.getGlobalSettingsFile(), request.getUserSettingsFile()); } settings = settingsResult.getEffectiveSettings(); } try { executionRequestPopulator.populateFromSettings(request.asMavenExecutionRequest(), settings); } catch (final MavenExecutionRequestPopulationException e) { throw new EMBEmbeddingException("Failed to populate request from settings; {0}", e, e.getMessage()); } if (!settingsResult.getProblems().isEmpty() && logger.isWarnEnabled()) { logger.warn(""); logger.warn("Some problems were encountered while building the effective settings"); for (final SettingsProblem problem : settingsResult.getProblems()) { logger.warn(problem.getMessage() + " @ " + problem.getLocation()); } logger.warn(""); } } public static void showEMBInfo(final EMBConfiguration embConfig, final List<EMBLibraryLoader> loaders, final PrintStream standardOut) throws IOException { if (embInfoShown) { return; } standardOut.println(); standardOut.println("-- EMB Libraries Loaded --"); standardOut.println(); final Collection<EMBLibrary> libraries = loadLibraries(embConfig, loaders); for (final EMBLibrary ext : libraries) { standardOut.println("+" + ext.getLabel() + " (Log handle: '" + ext.getLogHandle() + "')"); } standardOut.println(); standardOut.println("--------------------------"); standardOut.println(); embInfoShown = true; } public static void showVersion(final EMBConfiguration embConfig, final List<EMBLibraryLoader> loaders, final PrintStream standardOut) throws IOException { showEMBInfo(embConfig, loaders, standardOut); CLIReportingUtils.showVersion(standardOut); } protected synchronized void printInfo(final EMBExecutionRequest request) { if (infoPrinted) { return; } infoPrinted = true; if (showVersion || (request != null && Logger.LEVEL_DEBUG == request.getLoggingLevel())) { try { showVersion(embConfiguration, libraryLoaders, standardOut); } catch (final IOException e) { logger.error("Failed to retrieve EMB extension information: " + e.getMessage(), e); } } if (shouldShowErrors) { logger.info("Error stacktraces are turned on."); } if (request != null) { if (MavenExecutionRequest.CHECKSUM_POLICY_WARN.equals(request.getGlobalChecksumPolicy())) { logger.info("Disabling strict checksum verification on all artifact downloads."); } else if (MavenExecutionRequest.CHECKSUM_POLICY_FAIL.equals(request.getGlobalChecksumPolicy())) { logger.info("Enabling strict checksum verification on all artifact downloads."); } } } public int formatErrorOutput(final EMBExecutionRequest request, final MavenExecutionResult result) { if (result.hasExceptions()) { final ExceptionHandler handler = new DefaultExceptionHandler(); final Map<String, String> references = new LinkedHashMap<String, String>(); MavenProject project = null; for (final Throwable exception : result.getExceptions()) { final ExceptionSummary summary = handler.handleException(exception); logSummary(summary, references, "", shouldShowErrors); if (project == null && exception instanceof LifecycleExecutionException) { project = ((LifecycleExecutionException) exception).getProject(); } } logger.error(""); if (!shouldShowErrors) { logger.error("To see the full stack trace of the errors, re-run Maven with the -e switch."); } if (!logger.isDebugEnabled()) { logger.error("Re-run Maven using the -X switch to enable full debug logging."); } if (!references.isEmpty()) { logger.error(""); logger.error("For more information about the errors and possible solutions" + ", please read the following articles:"); for (final Map.Entry<String, String> entry : references.entrySet()) { logger.error(entry.getValue() + " " + entry.getKey()); } } if (project != null && !project.equals(result.getTopologicallySortedProjects().get(0))) { logger.error(""); logger.error("After correcting the problems, you can resume the build with the command"); logger.error(" mvn <goals> -rf :" + project.getArtifactId()); } if (MavenExecutionRequest.REACTOR_FAIL_NEVER.equals(request.getReactorFailureBehavior())) { logger.info("Build failures were ignored."); return 0; } else { return 1; } } else { return 0; } } protected void logSummary(final ExceptionSummary summary, final Map<String, String> references, String indent, final boolean showErrors) { String referenceKey = ""; if (StringUtils.isNotEmpty(summary.getReference())) { referenceKey = references.get(summary.getReference()); if (referenceKey == null) { referenceKey = "[Help " + (references.size() + 1) + "]"; references.put(summary.getReference(), referenceKey); } } String msg = indent + summary.getMessage(); if (StringUtils.isNotEmpty(referenceKey)) { if (msg.indexOf('\n') < 0) { msg += " -> " + referenceKey; } else { msg += '\n' + indent + "-> " + referenceKey; } } if (showErrors) { logger.error(msg, summary.getException()); } else { logger.error(msg); } indent += " "; for (final ExceptionSummary child : summary.getChildren()) { logSummary(child, references, indent, showErrors); } } private static final class EmbedderManagementView implements EMBManagementView { private final PlexusContainer container; private final EMBConfiguration configuration; EmbedderManagementView(final PlexusContainer container, final EMBConfiguration configuration) { this.container = container; this.configuration = configuration; } @Override public <T> T lookup(final Class<T> role, final String hint) throws EMBManagementException { try { return container.lookup(role, hint); } catch (final ComponentLookupException e) { throw new EMBManagementException( "Failed to lookup component for managed component.\nRole: %s\nHint: %s\nReason: %s", e, role, hint, e.getMessage()); } } @Override public <T> T lookup(final Class<T> role) throws EMBManagementException { try { return container.lookup(role); } catch (final ComponentLookupException e) { throw new EMBManagementException( "Failed to lookup component for managed component.\nRole: %s\nHint: %s\nReason: %s", e, role, PlexusConstants.PLEXUS_DEFAULT_HINT, e.getMessage()); } } @Override public EMBConfiguration getConfiguration() { return configuration; } public <T> Map<String, T> lookupMap(final Class<T> role) throws EMBManagementException { try { return container.lookupMap(role); } catch (final ComponentLookupException e) { throw new EMBManagementException( "Failed to lookup component-map for managed component.\nRole: %s\nReason: %s", e, role, e.getMessage()); } } public <T> List<T> lookupList(final Class<T> role) throws EMBManagementException { try { return container.lookupList(role); } catch (final ComponentLookupException e) { throw new EMBManagementException( "Failed to lookup component-list for managed component.\nRole: %s\nReason: %s", e, role, e.getMessage()); } } } }