/******************************************************************************* * Copyright (c) 2012 VMware, 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 * * Contributors: * VMware, Inc. - initial API and implementation *******************************************************************************/ package org.springframework.ide.eclipse.maven.internal.core; import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.OutputStreamWriter; import java.io.Writer; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.IJobChangeEvent; import org.eclipse.core.runtime.jobs.JobChangeAdapter; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.m2e.core.MavenPlugin; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.progress.UIJob; import org.springframework.core.io.Resource; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.ide.eclipse.core.SpringCoreUtils; import org.springframework.ide.eclipse.maven.MavenCorePlugin; import org.springframework.util.FileCopyUtils; import org.springsource.ide.eclipse.commons.configurator.ConfigurableExtension; import org.springsource.ide.eclipse.commons.configurator.WorkspaceLocationConfiguratorParticipant; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** * {@link WorkspaceLocationConfiguratorParticipant} to configure a maven repository with M2Eclipse. * @author Christian Dupuis * @author Steffen Pingel * @since 2.5.0 */ public class MavenRepositoryWorkspaceConfigurator extends WorkspaceLocationConfiguratorParticipant { @Override public String getPath() { return "maven-repository"; } @Override public String getVersionRange() { return "0.0.0"; } @Override protected ConfigurableExtension doCreateExtension(File location, IProgressMonitor monitor) { if (MavenCorePlugin.IS_M2ECLIPSE_PRESENT) { return new M2EclipseDependentRepositoryExtension(location.getName(), location); } return null; } /** * Inner class to prevent binary dependency to M2Eclipse. */ private class M2EclipseDependentRepositoryExtension extends ConfigurableExtension { private static final String LOCAL_REPOSITORY_ELEMENT_NAME = "localRepository"; private static final String QUESTION = "SpringSource Tool Suite has detected a local Maven repository at:\n" + "\n" + " %s\n" + "\n" + "Do you want to merge the contents into your global Maven repository? This will make the repository contents available from Maven builds outside of STS as well."; private static final String SETTINGS_TEMPLATE = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<settings></settings>"; private File location; private String oldUserSettingsFileName; public M2EclipseDependentRepositoryExtension(String id, File location) { super(id); this.location = location; setLocation(location.getAbsolutePath()); setLabel("Maven Repository"); } /** * {@inheritDoc} */ public IStatus configure(final IProgressMonitor monitor) { final String userSettingsFileName = MavenPlugin.getMavenConfiguration().getUserSettingsFile(); this.oldUserSettingsFileName = userSettingsFileName; UIJob job = new UIJob("Configure Maven Repository") { @Override public IStatus runInUIThread(IProgressMonitor monitor) { try { File globalRespository = MavenPlugin.getRepositoryRegistry().getLocalRepository() .getBasedir(); if (ask(location.getCanonicalPath())) { PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); Resource[] resources = resolver.getResources("file://" + location.getCanonicalPath() + File.separatorChar + "**"); for (Resource resource : resources) { File fileResource = resource.getFile(); if (fileResource.isFile()) { String relativePath = fileResource.getCanonicalPath().substring( location.getCanonicalPath().length() + 1, fileResource.getCanonicalPath().length()); monitor.subTask(String.format("Copying '%s'", relativePath)); File newFileResource = new File(globalRespository, relativePath); if (!newFileResource.exists()) { newFileResource.getParentFile().mkdirs(); FileCopyUtils.copy(fileResource, newFileResource); } } } } else { File userSettingsFile = new File(userSettingsFileName); // check if the file already exists; if not create new one if (!userSettingsFile.exists()) { BufferedWriter writer = new BufferedWriter(new FileWriter(getSettingsFile())); writer.append(SETTINGS_TEMPLATE); writer.close(); } else { // if the settings.xml file exists; copy it into the workspace FileCopyUtils.copy(userSettingsFile, getSettingsFile()); } // load file to search for existing <localRepository> node Document document = SpringCoreUtils.parseDocument(getSettingsFile().toURI()); NodeList nodes = document.getDocumentElement().getChildNodes(); boolean found = false; for (int i = 0; i < nodes.getLength(); i++) { Node node = nodes.item(i); if (LOCAL_REPOSITORY_ELEMENT_NAME.equals(node.getLocalName()) || LOCAL_REPOSITORY_ELEMENT_NAME.equals(node.getNodeName())) { // point to the detected maven repository node.setTextContent(location.getCanonicalPath()); found = true; break; } } // if no <localRepository> node exists, create a new one if (!found) { Element node = document.createElement(LOCAL_REPOSITORY_ELEMENT_NAME); node.appendChild(document.createTextNode(location.getCanonicalPath())); document.getDocumentElement().appendChild(node); } // write the new settings file out to disk TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); transformer.setOutputProperty(OutputKeys.ENCODING, document.getInputEncoding()); Writer out = new OutputStreamWriter(new FileOutputStream(getSettingsFile()), document.getInputEncoding()); StreamResult result = new StreamResult(out); DOMSource source = new DOMSource(document); transformer.transform(source, result); out.close(); // set the new settings.xml path MavenPlugin.getMavenConfiguration() .setUserSettingsFile(getSettingsFile().getCanonicalPath()); } } catch (Exception e) { MavenCorePlugin.getDefault().getLog() .log(new Status(IStatus.ERROR, MavenCorePlugin.PLUGIN_ID, 1, e.getMessage(), e)); return Status.CANCEL_STATUS; } return Status.OK_STATUS; } }; // we need to wait until the UI job completes as otherwise the workbench might shut down final boolean[] done = new boolean[1]; job.addJobChangeListener(new JobChangeAdapter() { @Override public void done(IJobChangeEvent event) { done[0] = true; } }); job.schedule(); while (!done[0]) { try { Thread.sleep(1000); } catch (InterruptedException e) { return Status.CANCEL_STATUS; } } return Status.OK_STATUS; } /** * {@inheritDoc} */ public IStatus unConfigure(IProgressMonitor monitor) { try { MavenPlugin.getMavenConfiguration().setUserSettingsFile(oldUserSettingsFileName); } catch (CoreException e) {} return Status.OK_STATUS; } private boolean ask(final String repositoryPath) { return MessageDialog.openQuestion(Display.getDefault().getActiveShell(), "Configure Maven Repository", String.format(QUESTION, repositoryPath)); } private File getSettingsFile() { return new File(ResourcesPlugin.getWorkspace().getRoot().getLocation().toFile(), "settings.xml"); } } }