| package npanday.plugin.aspx; |
| |
| /* |
| * 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.IOException; |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import npanday.ArtifactType; |
| import npanday.PlatformUnsupportedException; |
| import npanday.executable.ExecutionException; |
| import npanday.executable.compiler.CompilerConfig; |
| import npanday.executable.compiler.CompilerExecutable; |
| import npanday.executable.compiler.CompilerRequirement; |
| import npanday.registry.RepositoryRegistry; |
| import npanday.vendor.SettingsException; |
| import npanday.vendor.SettingsUtil; |
| import npanday.vendor.VendorFactory; |
| import org.apache.maven.plugin.AbstractMojo; |
| import org.apache.maven.plugin.MojoExecutionException; |
| import org.apache.maven.project.MavenProject; |
| import org.codehaus.plexus.util.FileUtils; |
| |
| /** |
| * Maven Mojo for precompiling ASPx files |
| * |
| * @goal compile |
| * @phase compile |
| * @description Maven Mojo for precompiling ASPx files |
| */ |
| public class AspxCompilerMojo |
| extends AbstractMojo |
| { |
| private static final String DEFAULT_INCLUDES = "**"; //any extension can be made for request handler in ASPX |
| |
| private static final String DEFAULT_EXCLUDES = "**/.svn/**,.references/**,obj/**, target/**, **/*.pdb, **/*.csproj, **/*.vbproj, **/*.suo, **/*.user,pom.xml, **/*.sln,build.log,PrecompiledApp.config,csproj.user,Properties/**,**.releaseBackup,^-?(?:\\d+|\\d{1,3}(?:,\\d{3})+)(?:\\.\\d+)?$/**,**/*.cs,**/*.vb"; |
| |
| /** |
| * @parameter expression="${npanday.settings}" default-value="${user.home}/.m2" |
| */ |
| private String settingsPath; |
| |
| /** |
| * The maven project. |
| * |
| * @parameter expression="${project}" |
| * @required |
| */ |
| private MavenProject project; |
| |
| /** |
| * The directory for the compiled web application |
| * |
| * @parameter expression = "${outputDirectory}" default-value = "${project.build.directory}" |
| * @required |
| */ |
| private File outputDirectory; |
| |
| /** |
| * This over-rides the defaultAssemblyPath for the compiler plugin. |
| * |
| * @parameter expression = "${profileAssemblyPath} |
| */ |
| private File profileAssemblyPath; |
| |
| /** |
| * The location of the local Maven repository. |
| * |
| * @parameter expression="${settings.localRepository}" |
| */ |
| private File localRepository; |
| |
| /** |
| * .NET Language. The default value is <code>ASPX</code>. Not case or white-space sensitive. |
| * |
| * @parameter expression="${language}" default-value = "ASP" |
| * @required |
| */ |
| private String language; |
| |
| /** |
| * The framework version to compile under: 1.1, 2.0, 3.0 |
| * |
| * @parameter expression = "${frameworkVersion}" |
| */ |
| private String frameworkVersion; |
| |
| /** |
| * The profile that the compiler should use to compile classes: FULL, COMPACT, (or a custom one specified in a |
| * compiler-plugins.xml). |
| * |
| * @parameter expression = "${profile}" default-value = "FULL" |
| */ |
| private String profile; |
| |
| /** |
| * The Vendor for the Compiler. Not case or white-space sensitive. |
| * |
| * @parameter expression="${vendor}" |
| */ |
| private String vendor; |
| |
| /** |
| * @parameter expression = "${vendorVersion}" |
| */ |
| private String vendorVersion; |
| |
| /** |
| * The home directory of your .NET SDK. |
| * |
| * @parameter expression="${netHome}" |
| */ |
| private File netHome; |
| |
| /** |
| * Additional compiler commands |
| * |
| * @parameter expression = "${parameters}" |
| */ |
| private ArrayList<String> parameters; |
| |
| /** |
| * @component |
| */ |
| private npanday.executable.NetExecutableFactory netExecutableFactory; |
| |
| /** |
| * @component |
| */ |
| private npanday.NPandayRepositoryRegistry npandayRegistry; |
| |
| private File webSourceDirectory; |
| |
| /** |
| * @parameter expression = "${excludes}" |
| */ |
| private String[] excludes; |
| |
| /** |
| * @parameter default-value="true" expression="${npanday.aspx.precompile}" |
| */ |
| private boolean precompile; |
| |
| /** |
| * @component |
| */ |
| private RepositoryRegistry repositoryRegistry; |
| |
| public void execute() |
| throws MojoExecutionException |
| { |
| long startTime = System.currentTimeMillis(); |
| |
| try |
| { |
| SettingsUtil.populateSettingsRepository( repositoryRegistry, settingsPath ); |
| } |
| catch ( SettingsException e ) |
| { |
| throw new MojoExecutionException( "NPANDAY-109-001: Error reading settings from " + settingsPath, e ); |
| } |
| |
| webSourceDirectory = new File( project.getBuild().getSourceDirectory() ); |
| |
| if ( profileAssemblyPath != null && !profileAssemblyPath.exists() ) |
| { |
| throw new MojoExecutionException( "NPANDAY-900-000: Profile Assembly Path does not exist: Path = " + |
| profileAssemblyPath.getAbsolutePath() ); |
| } |
| |
| File tmpDir; |
| try |
| { |
| tmpDir = getTempDirectory(); |
| } |
| catch ( IOException e ) |
| { |
| throw new MojoExecutionException( "Unable to create temporary directory", e ); |
| } |
| |
| // since asp_compiler doesn't have excludes, will just copy web source to temp directory |
| File tmpSourceDir = new File( tmpDir, "src" ); |
| tmpSourceDir.mkdirs(); |
| try |
| { |
| FileUtils.copyDirectoryStructure( webSourceDirectory, tmpSourceDir ); |
| |
| // delete target from temp web source |
| FileUtils.deleteDirectory( new File( tmpSourceDir, outputDirectory.getName() ) ); |
| } |
| catch ( IOException e ) |
| { |
| throw new MojoExecutionException( "Unable to copy directory " + webSourceDirectory.getAbsolutePath() + " to " + |
| tmpSourceDir.getAbsolutePath(), e ); |
| } |
| |
| File tmpDestDir; |
| if ( precompile ) |
| { |
| tmpDestDir = new File( tmpDir, "dest" ); |
| tmpDestDir.mkdirs(); |
| |
| CompilerRequirement compilerRequirement = createCompilerRequirement(); |
| |
| CompilerConfig compilerConfig = createCompilerConfig( tmpSourceDir.getAbsolutePath(), tmpDestDir.getAbsolutePath() ); |
| |
| try |
| { |
| CompilerExecutable compilerExecutable = |
| netExecutableFactory.getCompilerExecutableFor( compilerRequirement, compilerConfig, project, |
| profileAssemblyPath ); |
| |
| long startTimeCompile = System.currentTimeMillis(); |
| compilerExecutable.execute(); |
| long endTimeCompile = System.currentTimeMillis(); |
| |
| getLog().info( "NPANDAY-000-000: Compile Time = " + ( endTimeCompile - startTimeCompile ) + " ms" ); |
| project.getArtifact().setFile( compilerExecutable.getCompiledArtifact() ); |
| } |
| catch ( PlatformUnsupportedException e ) |
| { |
| throw new MojoExecutionException( "NPANDAY-900-005: Unsupported Platform: Language = " + language + |
| ", Vendor = " + vendor + ", ArtifactType = " + project.getArtifact().getType(), e ); |
| } |
| catch ( ExecutionException e ) |
| { |
| throw new MojoExecutionException( "NPANDAY-900-006: Unable to Compile: Language = " + language + |
| ", Vendor = " + vendor + ", ArtifactType = " + project.getArtifact().getType() + ", Source Directory = " + |
| project.getBuild().getSourceDirectory(), e ); |
| } |
| } |
| else |
| { |
| tmpDestDir = tmpSourceDir; |
| } |
| |
| File webappDir = new File( outputDirectory, project.getArtifactId() ); |
| webappDir.mkdirs(); |
| |
| try |
| { |
| // NPANDAY-474 |
| String combinedExcludes = ""; |
| if( excludes != null ) |
| { |
| for( int i = 0; i < excludes.length; i++ ) |
| { |
| combinedExcludes = combinedExcludes + excludes[i] + ","; |
| } |
| } |
| combinedExcludes = combinedExcludes + DEFAULT_EXCLUDES; |
| |
| /* keep only the files needed to run the app */ |
| List<File> allFiles = FileUtils.getFiles( tmpDestDir, "**", null ); |
| List<File> filesToKeep = FileUtils.getFiles( tmpDestDir, DEFAULT_INCLUDES, combinedExcludes ); |
| |
| for ( File file : allFiles ) |
| { |
| if ( !filesToKeep.contains( file ) || "App_global.asax.dll".equals(file.getName()) || "App_global.asax.compiled".equals(file.getName())) |
| { |
| file.delete(); |
| deleteDirectoryIfEmpty( file.getParentFile() ); |
| } |
| } |
| } |
| catch ( IOException e ) |
| { |
| throw new MojoExecutionException( "Unable to delete unneccessary files in temporary directory " + |
| tmpDestDir.getAbsolutePath(), e ); |
| } |
| |
| try |
| { |
| FileUtils.copyDirectoryStructure( tmpDestDir, webappDir ); |
| } |
| catch ( IOException e ) |
| { |
| throw new MojoExecutionException( "Unable to copy directory " + tmpDestDir.getAbsolutePath() + " to " + |
| webappDir.getAbsolutePath(), e ); |
| } |
| |
| try |
| { |
| String sourceDirectory = webSourceDirectory.getAbsolutePath(); |
| List<File> fileList = FileUtils.getFiles(new File(sourceDirectory), "**/*.asax", null); |
| getLog().debug("copy .asax to target file (temp source folder: " + sourceDirectory + ")..."); |
| getLog().debug("copy .asax to target file (temp dest folder: " + tmpDestDir + ")..."); |
| getLog().debug("copy .asax to target file (file count: " + fileList.size() + ")..."); |
| |
| for ( File file : fileList ) |
| { |
| try |
| { |
| String fileName = file.getAbsolutePath().substring( (int) sourceDirectory.length() ); |
| FileUtils.copyFile( new File( file.getAbsolutePath() ), new File( webappDir.getAbsolutePath() + fileName ) ); |
| getLog().info("Copying " + fileName.substring(1) + " to " + webappDir.getAbsolutePath() ); |
| } |
| catch ( IOException e ) |
| { |
| throw new MojoExecutionException( "Unable to copy asax file " + file.getAbsolutePath() + " to " + |
| webappDir.getAbsolutePath(), e ); |
| } |
| } |
| } |
| catch ( IOException e ) |
| { |
| throw new MojoExecutionException( "Unable to retrieve asax file", e ); |
| } |
| |
| // cleanup |
| try |
| { |
| FileUtils.deleteDirectory( tmpDir ); |
| } |
| catch ( IOException e ) |
| { |
| getLog().info( "Unable to delete temporary directory " + tmpDir ); |
| // temporary files can't be deleted, ignore |
| } |
| |
| long endTime = System.currentTimeMillis(); |
| getLog().info( "Mojo Execution Time = " + ( endTime - startTime ) ); |
| |
| // TODO: remove hardcoded values |
| String targetFile = |
| project.getBuild().getDirectory() + File.separator + project.getArtifactId() + "-" + project.getVersion() + |
| "-dist" + ".zip"; |
| getLog().info( "NPANDAY-000-000: Setting the target file: " + targetFile ); |
| project.getArtifact().setFile( new File( targetFile ) ); |
| |
| //Delete Bin Folder |
| String binDir = project.getBuild().getSourceDirectory()+File.separator + "Bin"; |
| try |
| { |
| FileUtils.deleteDirectory(binDir); |
| getLog().info("Bin folder deleted: " + binDir); |
| } |
| catch(IOException e) |
| { |
| getLog().info("Failed to delete Bin folder: " + binDir + " : " + e.getMessage()); |
| } |
| } |
| |
| private CompilerConfig createCompilerConfig(String source, String destination) throws MojoExecutionException |
| { |
| CompilerConfig compilerConfig = (CompilerConfig) CompilerConfig.Factory.createDefaultExecutableConfig(); |
| compilerConfig.setLocalRepository( localRepository ); |
| compilerConfig.setCommands( getCommands( source, destination ) ); |
| |
| String artifactTypeName = project.getArtifact().getType(); |
| ArtifactType artifactType = ArtifactType.getArtifactTypeForPackagingName( artifactTypeName ); |
| if ( artifactType.equals( ArtifactType.NULL ) ) |
| { |
| throw new MojoExecutionException( "NPANDAY-900-002: Unrecognized artifact type: Language = " + language + |
| ", Vendor = " + vendor + ", ArtifactType = " + artifactTypeName ); |
| } |
| compilerConfig.setArtifactType( artifactType ); |
| |
| return compilerConfig; |
| } |
| |
| private CompilerRequirement createCompilerRequirement() throws MojoExecutionException |
| { |
| CompilerRequirement compilerRequirement = CompilerRequirement.Factory.createDefaultCompilerRequirement(); |
| compilerRequirement.setLanguage( language ); |
| compilerRequirement.setFrameworkVersion( frameworkVersion ); |
| compilerRequirement.setProfile( profile ); |
| compilerRequirement.setVendorVersion( vendorVersion ); |
| try |
| { |
| if ( vendor != null ) |
| { |
| compilerRequirement.setVendor( VendorFactory.createVendorFromName( vendor ) ); |
| } |
| } |
| catch ( PlatformUnsupportedException e ) |
| { |
| throw new MojoExecutionException( "NPANDAY-900-001: Unknown Vendor: Vendor = " + vendor, e ); |
| } |
| |
| return compilerRequirement; |
| } |
| |
| private List<String> getCommands( String sourceDir, String outputDir ) |
| throws MojoExecutionException |
| { |
| if ( parameters == null ) |
| { |
| parameters = new ArrayList<String>(); |
| } |
| |
| parameters.add( "-v" ); |
| parameters.add( " /" + project.getArtifactId() ); |
| parameters.add( "-p" ); |
| parameters.add( sourceDir ); |
| parameters.add( "-u" ); |
| parameters.add( "-f" ); |
| parameters.add( outputDir ); |
| parameters.add( "-nologo" ); |
| parameters.add( "-fixednames" ); |
| |
| return parameters; |
| } |
| |
| private File getTempDirectory() |
| throws IOException |
| { |
| File tempFile = File.createTempFile( "maven-aspx-plugin-", "" ); |
| File tmpDir = new File( tempFile.getParentFile(), tempFile.getName() ); |
| tempFile.delete(); |
| tmpDir.mkdir(); |
| return tmpDir; |
| } |
| |
| private void deleteDirectoryIfEmpty( File directory ) |
| { |
| if ( directory.listFiles().length == 0 ) |
| { |
| directory.delete(); |
| deleteDirectoryIfEmpty( directory.getParentFile() ); |
| } |
| } |
| } |