Coverage Report - org.apache.maven.plugin.resource.loader.ProjectResourceLoader
 
Classes in this File Line Coverage Branch Coverage Complexity
ProjectResourceLoader
59%
34/57
36%
13/36
6
 
 1  
 package org.apache.maven.plugin.resource.loader;
 2  
 
 3  
 /*
 4  
  * Licensed to the Apache Software Foundation (ASF) under one
 5  
  * or more contributor license agreements.  See the NOTICE file
 6  
  * distributed with this work for additional information
 7  
  * regarding copyright ownership.  The ASF licenses this file
 8  
  * to you under the Apache License, Version 2.0 (the
 9  
  * "License"); you may not use this file except in compliance
 10  
  * with the License.  You may obtain a copy of the License at
 11  
  *
 12  
  *   http://www.apache.org/licenses/LICENSE-2.0
 13  
  *
 14  
  * Unless required by applicable law or agreed to in writing,
 15  
  * software distributed under the License is distributed on an
 16  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 17  
  * KIND, either express or implied.  See the License for the
 18  
  * specific language governing permissions and limitations
 19  
  * under the License.
 20  
  */
 21  
 
 22  
 import java.io.BufferedInputStream;
 23  
 import java.io.File;
 24  
 import java.io.FileInputStream;
 25  
 import java.io.FileNotFoundException;
 26  
 import java.io.InputStream;
 27  
 import java.util.ArrayList;
 28  
 import java.util.Hashtable;
 29  
 import java.util.List;
 30  
 
 31  
 import org.apache.commons.collections.ExtendedProperties;
 32  
 import org.apache.velocity.exception.ResourceNotFoundException;
 33  
 import org.apache.velocity.runtime.resource.Resource;
 34  
 import org.apache.velocity.runtime.resource.loader.ResourceLoader;
 35  
 import org.apache.velocity.util.StringUtils;
 36  
 
 37  
 /**
 38  
  * Resource Loader for external projects.
 39  
  * 
 40  
  * @version $Id: ProjectResourceLoader.java 1098343 2011-05-01 14:41:23Z dennisl $
 41  
  */
 42  2
 public class ProjectResourceLoader
 43  
     extends ResourceLoader
 44  
 {
 45  
     /**
 46  
      * The paths to search for templates.
 47  
      */
 48  2
     private List<String> paths = null;
 49  
 
 50  
     /**
 51  
      * Used to map the path that a template was found on
 52  
      * so that we can properly check the modification
 53  
      * times of the files.
 54  
      */
 55  2
     private Hashtable<String,String> templatePaths = new Hashtable<String,String>();
 56  
 
 57  
     public void init( ExtendedProperties configuration )
 58  
     {
 59  2
         rsvc.getLog().info( "ProjectResourceLoader : initialization starting." );
 60  
 
 61  2
         String separator = System.getProperty( "file.separator" );
 62  
 
 63  2
         String path = System.getProperty( "user.dir" ) + separator + "src" + separator + "main" + separator
 64  
             + "resources" + separator;
 65  
 
 66  2
         rsvc.getLog().info( "path :" + path );
 67  
         
 68  2
         paths = new ArrayList<String>();
 69  
 
 70  2
         paths.add( path );
 71  
         
 72  2
         int sz = paths.size();
 73  
 
 74  4
         for ( int i = 0; i < sz; i++ )
 75  
         {
 76  2
             rsvc.getLog().info( "ProjectResourceLoader : adding path '" + paths.get( i ) + "'" );
 77  
         }
 78  2
         rsvc.getLog().info( "ProjectResourceLoader : initialization complete." );
 79  2
     }
 80  
 
 81  
     /**
 82  
      * Get an InputStream so that the Runtime can build a
 83  
      * template with it.
 84  
      *
 85  
      * @param templateName name of template to get
 86  
      * @return InputStream containing the template
 87  
      * @throws ResourceNotFoundException if template not found
 88  
      *         in the file template path.
 89  
      */
 90  
     public synchronized InputStream getResourceStream( String templateName )
 91  
         throws ResourceNotFoundException
 92  
     {
 93  
         /*
 94  
          * Make sure we have a valid templateName.
 95  
          */
 96  2
         if ( templateName == null || templateName.length() == 0 )
 97  
         {
 98  
             /*
 99  
              * If we don't get a properly formed templateName then
 100  
              * there's not much we can do. So we'll forget about
 101  
              * trying to search any more paths for the template.
 102  
              */
 103  0
             throw new ResourceNotFoundException( "Need to specify a file name or file path!" );
 104  
         }
 105  
 
 106  2
         String template = StringUtils.normalizePath( templateName );
 107  2
         if ( template == null || template.length() == 0 )
 108  
         {
 109  0
             String msg = "Project Resource loader error : argument " + template
 110  
                 + " contains .. and may be trying to access " + "content outside of template root.  Rejected.";
 111  
 
 112  0
             rsvc.getLog().error( "ProjectResourceLoader : " + msg );
 113  
 
 114  0
             throw new ResourceNotFoundException( msg );
 115  
         }
 116  
 
 117  
         /*
 118  
          *  if a / leads off, then just nip that :)
 119  
          */
 120  2
         if ( template.startsWith( "/" ) )
 121  
         {
 122  2
             template = template.substring( 1 );
 123  
         }
 124  
         
 125  
         // MCHANGES-118 adding the basedir path
 126  2
         paths.add( (String) rsvc.getApplicationAttribute( "baseDirectory" ) );
 127  
 
 128  2
         for ( String path : paths )
 129  
         {
 130  4
             InputStream inputStream = findTemplate( path, template );
 131  
 
 132  4
             if ( inputStream != null )
 133  
             {
 134  
                 /*
 135  
                  * Store the path that this template came
 136  
                  * from so that we can check its modification
 137  
                  * time.
 138  
                  */
 139  
 
 140  2
                 templatePaths.put( templateName, path );
 141  2
                 return inputStream;
 142  
             }
 143  2
         }
 144  
 
 145  
         /*
 146  
          * We have now searched all the paths for
 147  
          * templates and we didn't find anything so
 148  
          * throw an exception.
 149  
          */
 150  0
         String msg = "ProjectResourceLoader Error: cannot find resource " + template;
 151  
 
 152  0
         throw new ResourceNotFoundException( msg );
 153  
     }
 154  
 
 155  
     /**
 156  
      * Try to find a template given a normalized path.
 157  
      * 
 158  
      * @param path a normalized path
 159  
      * @return InputStream input stream that will be parsed
 160  
      *
 161  
      */
 162  
     private InputStream findTemplate( String path, String template )
 163  
     {
 164  
         try
 165  
         {
 166  4
             File file = new File( path, template );
 167  
             
 168  4
             if ( file.canRead() )
 169  
             {
 170  2
                 return new BufferedInputStream( new FileInputStream( file.getAbsolutePath() ) );
 171  
             }
 172  
             else
 173  
             {
 174  2
                 return null;
 175  
             }
 176  
         }
 177  0
         catch ( FileNotFoundException fnfe )
 178  
         {
 179  
             /*
 180  
              *  log and convert to a general Velocity ResourceNotFoundException
 181  
              */
 182  0
             return null;
 183  
         }
 184  
     }
 185  
 
 186  
     /**
 187  
      * How to keep track of all the modified times
 188  
      * across the paths.  Note that a file might have
 189  
      * appeared in a directory which is earlier in the
 190  
      * path; so we should search the path and see if
 191  
      * the file we find that way is the same as the one
 192  
      * that we have cached.
 193  
      */
 194  
     public boolean isSourceModified( Resource resource )
 195  
     {
 196  
         /*
 197  
          * we assume that the file needs to be reloaded; 
 198  
          * if we find the original file and it's unchanged,
 199  
          * then we'll flip this.
 200  
          */
 201  0
         boolean modified = true;
 202  
 
 203  0
         String fileName = resource.getName();
 204  0
         String path = templatePaths.get( fileName );
 205  0
         File currentFile = null;
 206  
 
 207  0
         for ( int i = 0; currentFile == null && i < paths.size(); i++ )
 208  
         {
 209  0
             String testPath = paths.get( i );
 210  0
             File testFile = new File( testPath, fileName );
 211  0
             if ( testFile.canRead() )
 212  
             {
 213  0
                 currentFile = testFile;
 214  
             }
 215  
         }
 216  0
         File file = new File( path, fileName );
 217  0
         if ( currentFile == null || !file.exists() )
 218  
         {
 219  
             /*
 220  
              * noop: if the file is missing now (either the cached
 221  
              * file is gone, or the file can no longer be found)
 222  
              * then we leave modified alone (it's set to true); a 
 223  
              * reload attempt will be done, which will either use
 224  
              * a new template or fail with an appropriate message
 225  
              * about how the file couldn't be found.
 226  
              */
 227  
         }
 228  0
         else if ( currentFile.equals( file ) && file.canRead() )
 229  
         {
 230  
             /*
 231  
              * if only if currentFile is the same as file and
 232  
              * file.lastModified() is the same as
 233  
              * resource.getLastModified(), then we should use the
 234  
              * cached version.
 235  
              */
 236  0
             modified = ( file.lastModified() != resource.getLastModified() );
 237  
         }
 238  
 
 239  
         /*
 240  
          * rsvc.debug("isSourceModified for " + fileName + ": " + modified);
 241  
          */
 242  0
         return modified;
 243  
     }
 244  
 
 245  
     public long getLastModified( Resource resource )
 246  
     {
 247  2
         String path = templatePaths.get( resource.getName() );
 248  2
         File file = new File( path, resource.getName() );
 249  
 
 250  2
         if ( file.canRead() )
 251  
         {
 252  2
             return file.lastModified();
 253  
         }
 254  
         else
 255  
         {
 256  0
             return 0;
 257  
         }
 258  
     }
 259  
 }