1 18 package org.apache.beehive.netui.compiler.grammar; 19 20 import org.apache.beehive.netui.compiler.AnnotationMemberType; 21 import org.apache.beehive.netui.compiler.AnnotationGrammar; 22 import org.apache.beehive.netui.compiler.CompilerUtils; 23 import org.apache.beehive.netui.compiler.FlowControllerInfo; 24 import org.apache.beehive.netui.compiler.FatalCompileTimeException; 25 import org.apache.beehive.netui.compiler.typesystem.declaration.AnnotationValue; 26 import org.apache.beehive.netui.compiler.typesystem.declaration.AnnotationInstance; 27 import org.apache.beehive.netui.compiler.typesystem.declaration.MemberDeclaration; 28 import org.apache.beehive.netui.compiler.typesystem.declaration.AnnotationTypeElementDeclaration; 29 import org.apache.beehive.netui.compiler.typesystem.declaration.TypeDeclaration; 30 import org.apache.beehive.netui.compiler.typesystem.declaration.Modifier; 31 import org.apache.beehive.netui.compiler.typesystem.declaration.PackageDeclaration; 32 import org.apache.beehive.netui.compiler.typesystem.env.AnnotationProcessorEnvironment; 33 34 import java.net.URISyntaxException ; 35 import java.net.URI ; 36 import java.io.File ; 37 38 41 public class WebappPathType 42 extends AnnotationMemberType 43 { 44 private static final String [] CHECKABLE_EXTENSIONS = 45 { 46 JSP_FILE_EXTENSION, 47 XJSP_FILE_EXTENSION, 48 JPF_FILE_EXTENSION, 49 "xml", 50 "htm", 51 "html" 52 }; 53 54 private boolean _pathMustBeRelative = false; 55 private FlowControllerInfo _flowControllerInfo; 56 57 58 public WebappPathType( boolean pathMustBeRelative, String requiredRuntimeVersion, AnnotationGrammar parentGrammar, 59 FlowControllerInfo fcInfo ) 60 { 61 super( requiredRuntimeVersion, parentGrammar ); 62 _pathMustBeRelative = pathMustBeRelative; 63 _flowControllerInfo = fcInfo; 64 } 65 66 private static boolean isCheckableExtension( String filePath ) 67 { 68 for ( int i = 0; i < CHECKABLE_EXTENSIONS.length; ++i ) 69 { 70 if ( filePath.endsWith( CHECKABLE_EXTENSIONS[i] ) ) return true; 71 } 72 73 return false; 74 } 75 76 public Object onCheck( AnnotationTypeElementDeclaration valueDecl, AnnotationValue value, 77 AnnotationInstance[] parentAnnotations, MemberDeclaration classMember, 78 int annotationArrayIndex ) 79 throws FatalCompileTimeException 80 { 81 String filePath = ( String ) value.getValue(); 82 83 try 87 { 88 URI uri = new URI ( filePath ); 89 filePath = uri.getPath(); } 91 catch ( URISyntaxException e ) 92 { 93 addError( value, "error.invalid-uri", e.getLocalizedMessage() ); 94 return null; 95 } 96 97 if ( filePath == null || filePath.length() == 0 ) return null; 101 102 if ( ! checkAnyExtension() && ! isCheckableExtension( filePath ) ) return null; 106 107 boolean fileExists = true; 108 TypeDeclaration outerClass = CompilerUtils.getOutermostClass( classMember ); 109 File fileToCheck = null; 110 111 if ( filePath.charAt( 0 ) == '/' ) { 113 if ( _pathMustBeRelative ) addError( value, "error.relative-uri" ); 114 115 if ( filePath.endsWith( JPF_FILE_EXTENSION_DOT ) ) 116 { 117 TypeDeclaration type = CompilerUtils.inferTypeFromPath( filePath, getEnv() ); 118 fileToCheck = type != null ? CompilerUtils.getSourceFile( type, false ) : null; 119 120 } 123 124 if ( fileToCheck == null ) 125 { 126 File jpfSourceFile = CompilerUtils.getSourceFile( CompilerUtils.getOuterClass( classMember ), false ); 127 128 if ( jpfSourceFile != null ) 133 { 134 fileToCheck = CompilerUtils.getWebappRelativeFile( filePath, allowFileInPageFlowSourceDir(), getEnv() ); 135 136 if ( ! fileToCheck.exists() && ! ( ignoreDirectories() && fileToCheck.isDirectory() ) ) 137 { 138 fileExists = false; 139 } 140 } 141 } 142 } 143 144 else if ( filePath.indexOf( '/' ) != 0 && ! outerClass.hasModifier( Modifier.ABSTRACT ) ) 149 { 150 CompilerUtils.Mutable retFileToCheck = new CompilerUtils.Mutable(); 151 fileExists = checkRelativePath( filePath, outerClass, retFileToCheck, ignoreDirectories(), 152 allowFileInPageFlowSourceDir(), getEnv() ); 153 fileToCheck = ( File ) retFileToCheck.get(); 154 } 155 156 if ( fileExists ) 157 { 158 if ( fileToCheck != null ) runAdditionalChecks( fileToCheck, value ); 159 } 160 else 161 { 162 if ( doFatalError() ) 163 { 164 addError( value, "error.file-not-found", filePath ); 165 } 166 else 167 { 168 addWarning( value, "warning.file-not-found", filePath ); 169 } 170 } 171 172 if ( fileToCheck != null ) _flowControllerInfo.addReferencedFile( fileToCheck ); 173 174 return null; 175 } 176 177 public static boolean relativePathExists( String filePath, TypeDeclaration outerClass, 178 AnnotationProcessorEnvironment env ) 179 throws FatalCompileTimeException 180 { 181 assert filePath.charAt( 0 ) != '/' : filePath + " is not a relative path"; 182 if ( ! isCheckableExtension( filePath ) ) return true; 183 return checkRelativePath( filePath, outerClass, null, true, false, env ); 184 } 185 186 private static boolean checkRelativePath( String filePath, TypeDeclaration outerClass, 187 CompilerUtils.Mutable retFileToCheck, 188 boolean ignoreDirectories, boolean allowFileInPageFlowSourceDir, 189 AnnotationProcessorEnvironment env ) 190 throws FatalCompileTimeException 191 192 { 193 File fileToCheck = null; 194 boolean fileExists = true; 195 196 if ( filePath.endsWith( JPF_FILE_EXTENSION_DOT ) ) 197 { 198 String className = filePath.substring( 0, filePath.length() - JPF_FILE_EXTENSION_DOT.length() ); 199 String pkg = outerClass.getPackage().getQualifiedName(); 200 while ( className.startsWith( "../" ) && className.length() > 3 ) 201 { 202 className = className.substring( 3 ); 203 int lastDot = pkg.lastIndexOf( '.' ); 204 pkg = lastDot != -1 ? pkg.substring( 0, lastDot ) : ""; 205 } 206 className = ( pkg.length() > 0 ? pkg + '.' : "" ) + className.replace( '/', '.' ); 207 TypeDeclaration type = env.getTypeDeclaration( className ); 208 fileToCheck = type != null ? CompilerUtils.getSourceFile( type, false ) : null; 209 if ( fileToCheck == null ) fileExists = false; 210 } 211 else if ( CompilerUtils.getSourceFile( outerClass, false ) != null ) 213 { 214 if ( allowFileInPageFlowSourceDir ) 215 { 216 fileToCheck = CompilerUtils.getFileRelativeToSourceFile( outerClass, filePath, env ); 217 } 218 else 219 { 220 String webContentRoot = CompilerUtils.getWebContentRoot( env ); 222 String jpfParentRelativePath = ""; 223 PackageDeclaration jpfPackage = outerClass.getPackage(); 224 if ( jpfPackage != null ) jpfParentRelativePath = jpfPackage.getQualifiedName().replace( '.', '/' ); 225 File desiredParentDir = new File ( webContentRoot, jpfParentRelativePath ); 226 fileToCheck = new File ( desiredParentDir, filePath ); 227 } 228 229 if ( ! fileToCheck.exists() && ! ( ignoreDirectories && fileToCheck.isDirectory() ) ) 230 { 231 fileExists = false; 232 } 233 } 234 235 if ( retFileToCheck != null ) retFileToCheck.set( fileToCheck ); 236 return fileExists; 237 } 238 239 protected boolean checkAnyExtension() 240 { 241 return false; 242 } 243 244 protected boolean doFatalError() 245 { 246 return false; 247 } 248 249 protected void runAdditionalChecks( File file, AnnotationValue member ) 250 { 251 } 252 253 protected boolean ignoreDirectories() 254 { 255 return true; 256 } 257 258 262 protected boolean allowFileInPageFlowSourceDir() 263 { 264 return false; 265 } 266 267 protected FlowControllerInfo getFlowControllerInfo() 268 { 269 return _flowControllerInfo; 270 } 271 } 272 | Popular Tags |