Coverage Report - org.apache.tomcat.maven.common.run.ExternalRepositoriesReloadableWebappLoader
 
Classes in this File Line Coverage Branch Coverage Complexity
ExternalRepositoriesReloadableWebappLoader
0 %
0/43
0 %
0/26
3,5
 
 1  
 package org.apache.tomcat.maven.common.run;
 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 org.apache.catalina.loader.WebappLoader;
 23  
 import org.apache.maven.plugin.logging.Log;
 24  
 
 25  
 import java.io.File;
 26  
 import java.net.MalformedURLException;
 27  
 import java.net.URL;
 28  
 import java.util.Date;
 29  
 import java.util.HashMap;
 30  
 import java.util.Map;
 31  
 
 32  
 /**
 33  
  * A {@linkplain WebappLoader} implementation that allows scanning for changes to project classpath in support of
 34  
  * context reloads.
 35  
  *
 36  
  * @author Ryan Connolly
 37  
  * @since 2.0
 38  
  */
 39  
 public class ExternalRepositoriesReloadableWebappLoader
 40  
     extends WebappLoader
 41  
 {
 42  
 
 43  
     /**
 44  
      * Last modification times of all jar and class files.
 45  
      */
 46  0
     private Map<String, Long> modificationTimeMap = new HashMap<String, Long>();
 47  
 
 48  
     private Log log;
 49  
 
 50  
     /**
 51  
      * Default Constructor.
 52  
      */
 53  
     public ExternalRepositoriesReloadableWebappLoader()
 54  
     {
 55  0
         super();
 56  0
     }
 57  
 
 58  
 
 59  
     /**
 60  
      * Convenience Constructor allows setting of a parent ClassLoader.
 61  
      *
 62  
      * @param parent the ClassLoader instance to set as this Loader's parent ClassLoader.
 63  
      */
 64  
     public ExternalRepositoriesReloadableWebappLoader( ClassLoader parent, Log log )
 65  
     {
 66  0
         super( parent );
 67  0
         this.log = log;
 68  0
     }
 69  
 
 70  
     /**
 71  
      * {@inheritDoc}
 72  
      */
 73  
     @Override
 74  
     public void addRepository( String repository )
 75  
     {
 76  0
         super.addRepository( repository );
 77  
         try
 78  
         {
 79  0
             File file = new File( new URL( repository ).getPath().replaceAll( "%20", " " ) );
 80  0
             if ( file.isDirectory() )
 81  
             {
 82  0
                 addClassDirectory( file );
 83  
             }
 84  0
             else if ( file.isFile() && file.getName().endsWith( ".jar" ) )
 85  
             {
 86  0
                 addFile( file );
 87  
             }
 88  
         }
 89  0
         catch ( MalformedURLException muex )
 90  
         {
 91  0
             throw new RuntimeException( muex );
 92  0
         }
 93  0
     }
 94  
 
 95  
     /**
 96  
      * Tracks modification times of files in the given class directory.
 97  
      *
 98  
      * @param directory the File directory to track modification times for.
 99  
      */
 100  
     private void addClassDirectory( File directory )
 101  
     {
 102  0
         for ( File file : directory.listFiles() )
 103  
         {
 104  0
             if ( file.isDirectory() )
 105  
             {
 106  
                 //remember also directory last modification time
 107  0
                 addFile( file );
 108  0
                 addClassDirectory( file );
 109  
             }
 110  0
             else if ( file.isFile() )
 111  
             {
 112  0
                 addFile( file );
 113  
             }
 114  
         }
 115  0
     }
 116  
 
 117  
     /**
 118  
      * Tracks last modification time of the given File.
 119  
      *
 120  
      * @param file the File for which to track last modification time.
 121  
      */
 122  
     private void addFile( File file )
 123  
     {
 124  0
         modificationTimeMap.put( file.getAbsolutePath(), file.lastModified() );
 125  0
     }
 126  
 
 127  
     /**
 128  
      * Check if {@link WebappLoader} says modified(), if not then check files from added repositories.
 129  
      */
 130  
     @Override
 131  
     public boolean modified()
 132  
     {
 133  0
         boolean modified = super.modified();
 134  0
         if ( !modified )
 135  
         {
 136  0
             if ( log != null )
 137  
             {
 138  0
                 log.debug( "classPath scanning started at " + new Date().toString() );
 139  
             }
 140  0
             for ( Map.Entry<String, Long> entry : modificationTimeMap.entrySet() )
 141  
             {
 142  0
                 String key = entry.getKey();
 143  0
                 File file = new File( key );
 144  0
                 if ( file.exists() )
 145  
                 {
 146  
                     // file could be deleted.
 147  0
                     Long savedLastModified = modificationTimeMap.get( key );
 148  0
                     if ( file.lastModified() > savedLastModified )
 149  
                     {
 150  0
                         modified = true;
 151  0
                         modificationTimeMap.put( key, file.lastModified() );
 152  
 
 153  
                         // directory last modification time can change when some class,
 154  
                         // jar or subdirectory was added or deleted.
 155  0
                         if ( file.isDirectory() )
 156  
                         {
 157  0
                             addClassDirectory( file );
 158  
                         }
 159  
                     }
 160  
                 }
 161  0
             }
 162  
         }
 163  0
         if ( log != null )
 164  
         {
 165  0
             log.debug( "context " + modified + " at " + new Date().toString() );
 166  
         }
 167  0
         return modified;
 168  
     }
 169  
 
 170  
 }