| /******************************************************************************* |
| * Copyright (c) 2008 Sonatype, Inc. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| *******************************************************************************/ |
| |
| package org.eclipse.m2e.wtp; |
| |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.FileNotFoundException; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.util.Collections; |
| import java.util.Set; |
| |
| import org.apache.maven.artifact.versioning.DefaultArtifactVersion; |
| import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException; |
| import org.apache.maven.artifact.versioning.VersionRange; |
| import org.apache.maven.execution.MavenExecutionRequest; |
| import org.apache.maven.execution.MavenSession; |
| import org.apache.maven.lifecycle.MavenExecutionPlan; |
| import org.apache.maven.plugin.MojoExecution; |
| import org.apache.maven.project.MavenProject; |
| import org.codehaus.plexus.util.xml.Xpp3Dom; |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IFolder; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.m2e.core.MavenPlugin; |
| import org.eclipse.m2e.core.embedder.IMaven; |
| import org.eclipse.m2e.core.internal.IMavenConstants; |
| import org.eclipse.m2e.core.internal.MavenPluginActivator; |
| import org.eclipse.m2e.core.internal.markers.IMavenMarkerManager; |
| import org.eclipse.m2e.core.project.IMavenProjectFacade; |
| import org.eclipse.m2e.core.project.IMavenProjectRegistry; |
| import org.eclipse.m2e.wtp.earmodules.EarModule; |
| import org.eclipse.m2e.wtp.internal.Messages; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.swt.widgets.Display; |
| import org.eclipse.ui.IPageLayout; |
| import org.eclipse.ui.IViewPart; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.navigator.CommonNavigator; |
| |
| |
| /** |
| * Deployment Descriptor Management based on maven-ear-plugin invocation |
| * |
| * @provisional This class has been added as part of a work in progress. |
| * It is not guaranteed to work or remain the same in future releases. |
| * For more information contact <a href="mailto:m2e-wtp-dev@eclipse.org">m2e-wtp-dev@eclipse.org</a>. |
| * |
| * @author Fred Bricon |
| * @author Snjezana Peco |
| */ |
| @SuppressWarnings("restriction") |
| public class MavenDeploymentDescriptorManagement implements DeploymentDescriptorManagement { |
| |
| private static final VersionRange VALID_EAR_PLUGIN_RANGE; |
| static { |
| try { |
| VALID_EAR_PLUGIN_RANGE = VersionRange.createFromVersionSpec("[2.4.3,)"); //$NON-NLS-1$ |
| } catch(InvalidVersionSpecificationException ex) { |
| //Can't happen |
| throw new RuntimeException("Unable to create ear plugin version range from [2.4.3,)", ex); //$NON-NLS-1$ |
| } |
| } |
| |
| /** |
| * Executes ear:generate-application-xml goal to generate application.xml (and jboss-app.xml if needed). Existing |
| * files will be overwritten. |
| * |
| * @throws CoreException |
| */ |
| |
| @Override |
| public void updateConfiguration(IProject project, MavenProject mavenProject, EarPluginConfiguration plugin, |
| boolean useBuildDirectory, IProgressMonitor monitor) throws CoreException { |
| |
| IMavenProjectRegistry projectManager = MavenPlugin.getMavenProjectRegistry(); |
| IMavenProjectFacade mavenFacade = projectManager.getProject(project); |
| IMavenMarkerManager markerManager = MavenPluginActivator.getDefault().getMavenMarkerManager(); |
| |
| IFile pomResource = project.getFile(IMavenConstants.POM_FILE_NAME); |
| markerManager.deleteMarkers(pomResource, MavenWtpConstants.WTP_MARKER_GENERATE_APPLICATIONXML_ERROR); |
| |
| //Create a maven request + session |
| IMaven maven = MavenPlugin.getMaven(); |
| MavenExecutionRequest request = projectManager.createExecutionRequest(pomResource, mavenFacade.getResolverConfiguration(), monitor); |
| MavenSession session = maven.createSession(request, mavenProject); |
| |
| MavenExecutionPlan executionPlan = maven.calculateExecutionPlan(session, mavenProject, Collections.singletonList("ear:generate-application-xml"), true, monitor); //$NON-NLS-1$ |
| MojoExecution genConfigMojo = getExecution(executionPlan, "maven-ear-plugin", "generate-application-xml"); //$NON-NLS-1$ //$NON-NLS-2$ |
| if(genConfigMojo == null) { |
| //TODO Better error management |
| return; |
| } |
| |
| //Let's force the generated config files location |
| Xpp3Dom configuration = genConfigMojo.getConfiguration(); |
| if(configuration == null) { |
| configuration = new Xpp3Dom("configuration"); //$NON-NLS-1$ |
| genConfigMojo.setConfiguration(configuration); |
| } |
| |
| File tempDirectory; |
| try { |
| tempDirectory = getTempDirectory(); |
| } catch(IOException ex) { |
| IStatus status = new Status(IStatus.ERROR, MavenWtpPlugin.ID, ex.getLocalizedMessage(), ex); |
| throw new CoreException(status); |
| } |
| |
| // Some old maven-ear-plugin have a dependency on an old plexus-util version that prevents |
| // using workdirectory == generatedDescriptorLocation, so we keep them separated |
| File generatedDescriptorLocation = new File(tempDirectory, "generatedDescriptorLocation"); //$NON-NLS-1$ |
| File workDirectory = new File(tempDirectory, "workDirectory"); //$NON-NLS-1$ |
| |
| Xpp3Dom workDirectoryDom = configuration.getChild("workDirectory"); //$NON-NLS-1$ |
| if(workDirectoryDom == null) { |
| workDirectoryDom = new Xpp3Dom("workDirectory"); //$NON-NLS-1$ |
| configuration.addChild(workDirectoryDom); |
| } |
| workDirectoryDom.setValue(workDirectory.getAbsolutePath()); |
| |
| Xpp3Dom genDescriptorLocationDom = configuration.getChild("generatedDescriptorLocation"); //$NON-NLS-1$ |
| if(genDescriptorLocationDom == null) { |
| genDescriptorLocationDom = new Xpp3Dom("generatedDescriptorLocation"); //$NON-NLS-1$ |
| configuration.addChild(genDescriptorLocationDom); |
| } |
| genDescriptorLocationDom.setValue(generatedDescriptorLocation.getAbsolutePath()); |
| |
| |
| // Fix for http://jira.codehaus.org/browse/MEAR-116?focusedCommentId=232316&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#action_232316 |
| // affecting maven-ear-plugin version < 2.4.3 |
| if(!VALID_EAR_PLUGIN_RANGE.containsVersion(new DefaultArtifactVersion(genConfigMojo.getVersion()))) { |
| overrideModules(configuration, plugin.getAllEarModules()); |
| } |
| |
| //Execute our modified mojo |
| maven.execute(session, genConfigMojo, monitor); |
| |
| if (session.getResult().hasExceptions()){ |
| markerManager.addMarkers(mavenFacade.getPom(), MavenWtpConstants.WTP_MARKER_GENERATE_APPLICATIONXML_ERROR, session.getResult()); |
| } |
| |
| //Copy generated files to their final location |
| File[] files = generatedDescriptorLocation.listFiles(); |
| |
| //MECLIPSEWTP-56 : application.xml should not be generated in the source directory |
| |
| IFolder targetFolder; |
| IFolder earResourcesFolder = getEarResourcesDir(project, mavenProject, monitor); |
| if (useBuildDirectory) { |
| targetFolder = earResourcesFolder; |
| } else { |
| targetFolder = project.getFolder(plugin.getEarContentDirectory(project)); |
| |
| if (earResourcesFolder.exists() && earResourcesFolder.isAccessible()) { |
| earResourcesFolder.delete(true, monitor); |
| } |
| } |
| |
| IFolder metaInfFolder = targetFolder.getFolder("/META-INF/"); //$NON-NLS-1$ |
| |
| if (files != null && files.length > 0) { |
| for (File file:files) { |
| if (!metaInfFolder.exists()) { |
| ProjectUtils.createFolder(metaInfFolder, monitor); |
| } |
| InputStream is = null; |
| try { |
| is = new FileInputStream(file); |
| IFile targetResource = metaInfFolder.getFile(file.getName()); |
| if (targetResource.exists()) { |
| targetResource.setContents(is, IResource.FORCE, monitor); |
| } else { |
| targetResource.create(is, true, monitor); |
| } |
| } catch (FileNotFoundException ex) { |
| IStatus status = new Status(IStatus.ERROR, MavenWtpPlugin.ID, IStatus.ERROR, ex.getMessage(), ex); |
| throw new CoreException(status); |
| } finally { |
| if (is != null) { |
| try { |
| is.close(); |
| } catch (IOException ex) { |
| // ignore |
| } |
| } |
| } |
| } |
| } |
| |
| deleteDirectory(generatedDescriptorLocation); |
| |
| Display.getDefault().asyncExec(new Runnable() { |
| @Override |
| public void run() { |
| if (PlatformUI.isWorkbenchRunning()) { |
| IViewPart view = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().findView(IPageLayout.ID_PROJECT_EXPLORER); |
| if (view instanceof CommonNavigator) { |
| CommonNavigator navigator = (CommonNavigator) view; |
| navigator.getCommonViewer().refresh(); |
| } |
| } |
| } |
| }); |
| } |
| |
| private IFolder getEarResourcesDir(IProject project, MavenProject mavenProject, IProgressMonitor monitor) |
| throws CoreException { |
| String appResourcesDir = ProjectUtils.getM2eclipseWtpFolder(mavenProject, project).toPortableString()+Path.SEPARATOR+MavenWtpConstants.EAR_RESOURCES_FOLDER; |
| IFolder appResourcesFolder = project.getFolder(appResourcesDir); |
| |
| if (!appResourcesFolder.exists()) { |
| ProjectUtils.createFolder(appResourcesFolder, monitor); |
| } |
| if (!appResourcesFolder.isDerived()) { |
| appResourcesFolder.setDerived(true, monitor); |
| } |
| return appResourcesFolder; |
| } |
| |
| |
| private void overrideModules(Xpp3Dom configuration, Set<EarModule> earModules) { |
| Xpp3Dom modules = configuration.getChild("modules"); //$NON-NLS-1$ |
| if(modules == null) { |
| modules = new Xpp3Dom("modules"); //$NON-NLS-1$ |
| configuration.addChild(modules); |
| } |
| //TODO find a more elegant way to clear the modules |
| while(modules.getChildCount() > 0) { |
| modules.removeChild(0); |
| } |
| //Recreate the module's children, forcing the uri. |
| for(EarModule earModule : earModules) { |
| modules.addChild(earModule.getAsDom()); |
| } |
| } |
| |
| private File getTempDirectory() throws IOException { |
| File tempDir = new File(System.getProperty("java.io.tmpdir")); //$NON-NLS-1$ |
| File dir = new File(tempDir, ".mavenDeploymentDescriptorManagement"); //$NON-NLS-1$ |
| if(dir.exists()) { |
| if(dir.isFile()) { |
| if(!dir.delete()) { |
| throw new IOException(NLS.bind(Messages.MavenDeploymentDescriptorManagement_Error_Deleting_Temp_Folder, dir.getAbsolutePath())); |
| } |
| } else if(!deleteDirectory(dir)) { |
| throw new IOException(NLS.bind(Messages.MavenDeploymentDescriptorManagement_Error_Deleting_Temp_Folder, dir.getAbsolutePath())); |
| } |
| } |
| dir.mkdir(); |
| return dir; |
| } |
| |
| private static boolean deleteDirectory(File path) { |
| if(path.exists()) { |
| File[] files = path.listFiles(); |
| for(int i = 0; i < files.length; i++ ) { |
| if(files[i].isDirectory()) { |
| deleteDirectory(files[i]); |
| } else { |
| files[i].delete(); |
| } |
| } |
| } |
| return (path.delete()); |
| } |
| |
| private MojoExecution getExecution(MavenExecutionPlan executionPlan, String artifactId, String goal) throws CoreException { |
| for(MojoExecution execution : executionPlan.getMojoExecutions()) { |
| if(artifactId.equals(execution.getArtifactId()) && goal.equals(execution.getGoal())) { |
| return execution; |
| } |
| } |
| return null; |
| } |
| } |