package com.perforce.p4maven.dev; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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. */ import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; import java.net.URL; import java.util.Properties; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.codehaus.plexus.util.FileUtils; import org.codehaus.plexus.util.IOUtil; import org.codehaus.plexus.util.xml.Xpp3Dom; import org.codehaus.plexus.util.xml.Xpp3DomBuilder; import org.codehaus.plexus.util.xml.pull.XmlPullParserException; /** * This goal creates/updates a eclipse workspace to comply with Maven development code styling rules for Java and XML. * It also hooks up the local Maven distribution ( ie the one that runs this goal) with M2Eclipse. */ @Mojo( name = "configure-eclipse-workspace", requiresProject = false, threadSafe = true ) public class ConfigureEclipseWorkspaceMojo extends AbstractMojo { private static final String HTML_EDITOR_CONFIG_PATH = ".metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.wst.css.core.prefs"; private static final String CSS_EDITOR_CONFIG_PATH = ".metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.wst.html.core.prefs"; private static final String XML_EDITOR_CONFIG_PATH = ".metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.wst.xml.core.prefs"; private static final String JDT_UI_CONFIG_PATH = ".metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.ui.prefs"; private static final String M2E_CORE_CONFIG_PATH = ".metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.m2e.core.prefs"; private static final String EDITOR_LINEWIDTH_KEY = "lineWidth"; private static final String EDITOR_INDENTATIONCHAR_KEY = "indentationChar"; private static final String EDITOR_INDENTATIONSIZE = "indentationSize"; /** * Directory which hosts the eclipse workspace directory ( ie .metadata ) * * @Parameter default-value = "." */ @Parameter( property = "workspaceDirectory", defaultValue = "." ) private File workspaceDirectory; /** * Eclipse Java code formatter file. Default is Maven code formatter * * @Parameter */ @Parameter( property = "javaFormatterLocation", defaultValue = "http://maven.apache.org/developers/maven-eclipse-codestyle.xml" ) private String javaFormatterLocation = "http://maven.apache.org/developers/maven-eclipse-codestyle.xml"; public void execute() throws MojoExecutionException, MojoFailureException { setupHtmlEditorSettings(); setupCssEditorSettings(); setupXmlEditorSettings(); setupJavaFormatter(); setupM2Eclispe(); } private void setupM2Eclispe() { File configFile = new File( workspaceDirectory, M2E_CORE_CONFIG_PATH ); File mvnHome = new File( System.getProperty( "maven.home" ) ); File settingsXml = new File( mvnHome, "conf/settings.xml" ); try { Properties props = loadPropertiesFromFile( configFile ); props.put( "eclipse.m2.defaultRuntime", mvnHome.getAbsolutePath() ); props.put( "eclipse.m2.globalSettingsFile", settingsXml.getAbsolutePath() ); props.put( "eclipse.m2.runtimes", mvnHome.getAbsolutePath() ); props.put( "eclipse.m2.defaultPomEditorPage", "true" ); props.put( "eclipse.preferences.version", "1" ); savePropertiesFromFile( configFile, props ); } catch ( IOException e ) { this.getLog().warn( "Unable to setup m2eclipse preference", e ); } } private void setupJavaFormatter() throws MojoExecutionException, MojoFailureException { File tmpFile = null; File configFile = new File( workspaceDirectory, JDT_UI_CONFIG_PATH ); try { tmpFile = File.createTempFile( "mojodev", "tmp" ); FileUtils.copyURLToFile( new URL( javaFormatterLocation ), tmpFile ); String formatterContent = FileUtils.fileRead( tmpFile ); Properties props = loadPropertiesFromFile( configFile ); props.setProperty( "formatter_profile", "_" + this.loadDefaultProfileName( tmpFile ) ); props.setProperty( "formatter_settings_version", "12" ); props.setProperty( "org.eclipse.jdt.ui.formatterprofiles", formatterContent ); savePropertiesFromFile( configFile, props ); } catch ( IOException e ) { throw new MojoExecutionException( e.getMessage(), e ); } finally { if ( tmpFile != null ) { tmpFile.delete(); } } } private static final String ELT_PROFILE = "profile"; private String loadDefaultProfileName( File file ) throws MojoExecutionException { Reader reader = null; try { reader = new InputStreamReader( new FileInputStream( file ) ); Xpp3Dom dom = Xpp3DomBuilder.build( reader ); Xpp3Dom[] existingProfiles = dom.getChildren( ELT_PROFILE ); if ( existingProfiles.length != 0 ) { Xpp3Dom firstProfile = existingProfiles[0]; return firstProfile.getAttribute( "name" ); } else { throw new MojoExecutionException( "Unable to discover java formatter profile name" ); } } catch ( XmlPullParserException e ) { throw new MojoExecutionException( "Unable to discover java formatter profile name", e ); } catch ( IOException e ) { throw new MojoExecutionException( "Unable to discover java formatter profile name", e ); } finally { IOUtil.close( reader ); } } private void setupHtmlEditorSettings() throws MojoExecutionException, MojoFailureException { File configFile = new File( workspaceDirectory, HTML_EDITOR_CONFIG_PATH ); try { Properties props = loadPropertiesFromFile( configFile ); props.setProperty( EDITOR_LINEWIDTH_KEY, "120" ); props.setProperty( EDITOR_INDENTATIONCHAR_KEY, "space" ); props.setProperty( EDITOR_INDENTATIONSIZE, "2" ); savePropertiesFromFile( configFile, props ); } catch ( IOException e ) { throw new MojoExecutionException( e.getMessage(), e ); } } private void setupXmlEditorSettings() throws MojoExecutionException, MojoFailureException { File configFile = new File( workspaceDirectory, XML_EDITOR_CONFIG_PATH ); try { Properties props = loadPropertiesFromFile( configFile ); props.setProperty( EDITOR_LINEWIDTH_KEY, "120" ); props.setProperty( EDITOR_INDENTATIONCHAR_KEY, "space" ); props.setProperty( EDITOR_INDENTATIONSIZE, "2" ); savePropertiesFromFile( configFile, props ); } catch ( IOException e ) { throw new MojoExecutionException( e.getMessage(), e ); } } private void setupCssEditorSettings() throws MojoExecutionException, MojoFailureException { File configFile = new File( workspaceDirectory, CSS_EDITOR_CONFIG_PATH ); try { Properties props = loadPropertiesFromFile( configFile ); props.setProperty( EDITOR_LINEWIDTH_KEY, "120" ); props.setProperty( EDITOR_INDENTATIONCHAR_KEY, "space" ); props.setProperty( EDITOR_INDENTATIONSIZE, "2" ); savePropertiesFromFile( configFile, props ); } catch ( IOException e ) { throw new MojoExecutionException( e.getMessage(), e ); } } private static Properties loadPropertiesFromFile( File file ) throws IOException { if ( !file.exists() ) { return new Properties(); } FileInputStream is = null; try { is = new FileInputStream( file ); Properties props = new Properties(); props.load( is ); return props; } finally { IOUtil.close( is ); } } private static void savePropertiesFromFile( File file, Properties properties ) throws IOException { file.getParentFile().mkdirs(); FileOutputStream fs = null; try { fs = new FileOutputStream( file ); properties.store( fs, null ); } finally { IOUtil.close( fs ); } } }