package org.codehaus.mojo.springide; /* * 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.FileReader; import java.io.FileWriter; import java.io.FilenameFilter; import java.io.IOException; import java.io.Writer; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import org.apache.commons.io.FileUtils; import org.apache.maven.model.Resource; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.project.MavenProject; import org.codehaus.plexus.util.DirectoryScanner; import org.codehaus.plexus.util.xml.Xpp3Dom; import org.codehaus.plexus.util.xml.Xpp3DomBuilder; import org.codehaus.plexus.util.xml.Xpp3DomWriter; import freemarker.template.Configuration; import freemarker.template.Template; import freemarker.template.TemplateException; /** * @author <a href="mailto:nicolas@apache.org">nicolas de loof</a> * @goal generate */ public class SpringIDEMojo extends AbstractMojo { /** * @parameter default-value="xml" * @alias configExtensions */ private String configSuffixes; /** * @parameter default-value="**\/applicationContext*.xml, META-INF/spring/**\/*.xml" */ private String includes; /** * @parameter */ private String excludes; /** * @parameter default-value="true" */ private boolean allowBeanDefinitionOverriding; /** * @parameter default-value="true" */ private boolean enableImports; /** * @parameter default-value="true" */ private boolean incomplete; /** * @parameter default-value="${project.artifactId}" */ private String name; /** * The project whose project files to create. * * @parameter expression="${project}" * @required */ private MavenProject project; /** * @parameter expression="${springide.skip}" */ private boolean skip; /** * {@inheritDoc} * * @see org.apache.maven.plugin.Mojo#execute() */ public void execute() throws MojoExecutionException, MojoFailureException { if ( skip ) { getLog().info( "SpringIDE configuration is skipped." ); return; } if ( "pom".equals( project.getPackaging() ) ) { return; } List configs = new LinkedList(); String src = project.getBuild().getSourceDirectory(); scan( configs, new File( src ) ); for ( Iterator iterator = project.getBuild().getResources().iterator(); iterator.hasNext(); ) { Resource resource = (Resource) iterator.next(); scan( configs, new File( resource.getDirectory() ) ); } String[] generated = new File( project.getBuild().getOutputDirectory() ).list( new FilenameFilter() { public boolean accept( File dir, String name ) { return name.startsWith( "generated-" ); } } ); if (generated != null) { for ( int i = 0; i < generated.length; i++ ) { scan( configs, new File( generated[i] ) ); } } if ( configs.size() > 0 ) { forceSpringNature(); Map context = new HashMap(); context.put( "configs", configs ); context.put( "configSuffixes", configSuffixes.split( "," ) ); context.put( "allowBeanDefinitionOverriding", String.valueOf( allowBeanDefinitionOverriding ) ); context.put( "incomplete", String.valueOf( incomplete ) ); context.put( "enableImports", String.valueOf( enableImports ) ); context.put( "name", name ); getLog().info( "create SpringIDE configuration for " + name ); File dotSpringBeans = new File( project.getBasedir(), ".springBeans" ); applyTemplate( context, dotSpringBeans, "springBeans.fm" ); File prefs = new File( project.getBasedir(), ".settings/org.springframework.ide.eclipse.core.prefs" ); applyTemplate( context, prefs, "prefs.fm" ); } else { getLog().info( "No spring context file found in project" ); } } private void scan( List configs, File src ) { if ( !src.exists() ) { return; } DirectoryScanner scanner = new DirectoryScanner(); scanner.setBasedir( src ); scanner.setIncludes( includes.split( "," ) ); if (excludes != null) { scanner.setExcludes( excludes.split( "," ) ); } scanner.scan(); String[] files = scanner.getIncludedFiles(); for ( int i = 0; i < files.length; i++ ) { configs.add( src.getAbsolutePath().substring( project.getBasedir().getAbsolutePath().length() ) + "/" + files[i] ); } return; } protected void applyTemplate( Map context, File out, String template ) throws MojoExecutionException { Configuration cfg = new Configuration(); cfg.setClassForTemplateLoading( getClass(), "" ); out.getParentFile().mkdirs(); try { Writer configWriter = new FileWriter( out ); Template tpl = cfg.getTemplate( template ); tpl.process( context, configWriter ); configWriter.flush(); configWriter.close(); getLog().debug( "Write SpringIDE configuration to: " + out.getAbsolutePath() ); } catch ( IOException ioe ) { throw new MojoExecutionException( "Unable to write SpringIDE configuration file", ioe ); } catch ( TemplateException te ) { throw new MojoExecutionException( "Unable to merge freemarker template", te ); } } protected void forceSpringNature() { try { File dotProject = new File( project.getBasedir(), ".project" ); String content = FileUtils.readFileToString( dotProject, null ); if ( content.indexOf( "<nature>org.springframework.ide.eclipse.core.springnature</nature>" ) < 0 ) { getLog().info( "Add spring nature to the eclipse .project file" ); try { Xpp3Dom dom = Xpp3DomBuilder.build( new FileReader( dotProject ) ); Xpp3Dom nature = new Xpp3Dom( "nature" ); nature.setValue( "org.springframework.ide.eclipse.core.springnature" ); dom.getChild( "natures" ).addChild( nature ); FileWriter writer = new FileWriter( dotProject ); Xpp3DomWriter.write( writer, dom ); writer.close(); } catch ( Exception e ) { getLog().warn( "Failed to add missing tomcat nature to the eclipse .project file", e ); } } } catch ( IOException e ) { getLog().info( "Failed to retrieve the Eclipse .project file" ); } } }