001 /* 002 * Copyright 2005 Stephen J. McConnell 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 013 * implied. 014 * 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 019 package net.dpml.tools.checkstyle; 020 021 import java.io.File; 022 import java.net.URI; 023 import java.net.URL; 024 025 import com.puppycrawl.tools.checkstyle.CheckStyleTask; 026 027 import net.dpml.library.Resource; 028 import net.dpml.library.Module; 029 030 import net.dpml.tools.Context; 031 032 import org.apache.tools.ant.Project; 033 import org.apache.tools.ant.BuildException; 034 import org.apache.tools.ant.types.FileSet; 035 036 /** 037 * The checkstyle task handes the establishment of a classic checkstyle task 038 * with automatic resolution of source directories. Typical usage is within 039 * a build file that aggregates results for a module. 040 * 041 * @author <a href="http://www.dpml.net">Digital Product Meta Library</a> 042 * @version 1.2.0 043 */ 044 public class CheckstyleTask extends CheckStyleTask 045 { 046 /** 047 * The format property key. 048 */ 049 public static final String FORMAT_KEY = "project.checkstyle.format"; 050 051 /** 052 * The default format value. 053 */ 054 public static final String FORMAT_VALUE = "local:format:dpml/tools/dpml"; 055 056 private boolean m_init = false; 057 private Context m_context; 058 private boolean m_implicit = true; 059 060 /** 061 * Set the implicit inclusion of the current resource (and potentially 062 * the resources children if the resource is a module). If implicit 063 * file inclusion is disabled then resources must be declared using an 064 * explicit fileset. 065 * 066 * @param flag false if implicit inclusion is to be disabled 067 */ 068 public void setImplicit( boolean flag ) 069 { 070 m_implicit = flag; 071 } 072 073 /** 074 * Task initialization. 075 */ 076 public void init() 077 { 078 super.init(); 079 if( !m_init ) 080 { 081 m_init = true; 082 m_context = (Context) getProject().getReference( "project.context" ); 083 if( null == m_context ) 084 { 085 final String error = 086 "Missing 'project.context' reference."; 087 throw new IllegalStateException( error ); 088 } 089 090 String defaultFormat = "local:format:dpml/tools/dpml"; 091 String spec = m_context.getProperty( FORMAT_KEY, FORMAT_VALUE ); 092 if( !spec.startsWith( "local:" ) ) 093 { 094 final String error = 095 "Invalid checkstyle format uri [" 096 + spec 097 + ". The value must be a 'local:' artifact reference (e.g. " 098 + FORMAT_VALUE 099 + ")."; 100 throw new BuildException( error, getLocation() ); 101 } 102 103 try 104 { 105 URL url = new URI( spec ).toURL(); 106 File format = (File) url.getContent( new Class[]{File.class} ); 107 setConfig( format ); 108 } 109 catch( Throwable e ) 110 { 111 final String error = 112 "Internal error while attempting to resolve the checkstyle format property value [" 113 + spec 114 + "] to a local file."; 115 throw new BuildException( error, e, getLocation() ); 116 } 117 } 118 m_init = true; 119 } 120 121 /** 122 * Execute the checkstyle check. 123 */ 124 public void execute() 125 { 126 Resource resource = m_context.getResource(); 127 if( m_implicit ) 128 { 129 addTargetToFileset( resource ); 130 } 131 super.execute(); 132 } 133 134 private void addTargetToFileset( Resource resource ) 135 { 136 try 137 { 138 File file = resource.getBaseDir(); 139 Project project = getProject(); 140 //File main = new File( file, "target/build/main" ); 141 File main = new File( file, "src/main" ); 142 if( main.exists() ) 143 { 144 FileSet fileset = new FileSet(); 145 fileset.setDir( main ); 146 fileset.setIncludes( "**/*.java" ); 147 super.addFileset( fileset ); 148 } 149 //File test = new File( file, "target/build/test" ); 150 File test = new File( file, "src/test" ); 151 if( test.exists() ) 152 { 153 FileSet fileset = new FileSet(); 154 fileset.setDir( test ); 155 fileset.setIncludes( "**/*.java" ); 156 super.addFileset( fileset ); 157 } 158 if( resource instanceof Module ) 159 { 160 Module module = (Module) resource; 161 Resource[] children = module.getResources(); 162 for( int i=0; i < children.length; i++ ) 163 { 164 Resource child = children[i]; 165 addTargetToFileset( child ); 166 } 167 } 168 } 169 catch( Exception e ) 170 { 171 final String error = 172 "Internal error while attempting to construct implicit fileset for the resource: " + resource; 173 throw new BuildException( error, e, getLocation() ); 174 } 175 } 176 177 private Context getContext() 178 { 179 return m_context; 180 } 181 }