1 17 18 package org.apache.avalon.repository.util; 19 20 21 import java.io.File ; 22 import java.io.FileOutputStream ; 23 import java.io.InputStream ; 24 import java.io.IOException ; 25 import java.io.OutputStream ; 26 27 import java.net.HttpURLConnection ; 28 import java.net.URL ; 29 import java.net.URLConnection ; 30 31 import org.apache.avalon.repository.Artifact; 32 import org.apache.avalon.repository.RepositoryException; 33 34 35 42 public class LoaderUtils 43 { 44 private boolean m_online; 45 46 public LoaderUtils( boolean online ) 47 { 48 m_online = online; 49 } 50 51 63 public URL getResource( Artifact artifact, 64 String [] repositories, File root, boolean timestamping ) 65 throws RepositoryException 66 { 67 Exception cause = null; 68 69 File destination = new File ( root, artifact.getPath() ); 70 71 if( !m_online ) 72 { 73 if( destination.exists() ) 74 { 75 return getURL( destination ); 76 } 77 else 78 { 79 final String error = 80 "Artifact [" + artifact 81 + "] does not exist in local cache."; 82 throw new RepositoryException( error ); 83 } 84 } 85 86 90 for ( int i = 0; i < repositories.length; i++ ) 91 { 92 try 93 { 94 String url = artifact.getURL( repositories[i] ) ; 95 return getResource( url, destination, timestamping ) ; 96 } 97 catch ( Exception e ) 98 { 99 cause = e ; 100 } 101 } 102 103 if( destination.exists() ) return getURL( destination ); 104 105 StringBuffer buffer = new StringBuffer (); 106 buffer.append( 107 "Failed to download artifact to local cache file " 108 + destination.getAbsolutePath() 109 + " from hosts: " ); 110 for( int i=0; i<repositories.length; i++ ) 111 { 112 buffer.append( "\n " + repositories[i] ); 113 } 114 throw new RepositoryException( buffer.toString(), cause ); 115 } 116 117 130 public URL getResource( Artifact artifact, String mime, 131 String [] repositories, File root, boolean timestamping ) 132 throws RepositoryException 133 { 134 if( null == artifact ) 135 throw new NullPointerException ( "artifact" ); 136 137 if( null == mime ) 138 throw new NullPointerException ( "mime" ); 139 140 if( null == root ) 141 throw new NullPointerException ( "root" ); 142 143 if( null == repositories ) 144 throw new NullPointerException ( "repositories" ); 145 146 Exception cause = null; 147 148 File destination = 149 new File ( root, artifact.getPath() + "." + mime ); 150 151 if( !m_online ) 152 { 153 if( destination.exists() ) 154 { 155 return getURL( destination ); 156 } 157 else 158 { 159 final String error = 160 "Artifact [" 161 + artifact.getPath() + "." + mime 162 + "] does not exist in local cache."; 163 throw new RepositoryException( error ); 164 } 165 } 166 167 171 for ( int i = 0; i < repositories.length; i++ ) 172 { 173 try 174 { 175 String url = artifact.getURL( repositories[i] ) + "." + mime; 176 return getResource( url, destination, timestamping ) ; 177 } 178 catch ( Exception e ) 179 { 180 cause = e ; 181 } 182 } 183 184 if( destination.exists() ) return getURL( destination ); 185 186 StringBuffer buffer = new StringBuffer (); 187 buffer.append( 188 "Failed to download mime artifact to local cache file " 189 + destination.getAbsolutePath() 190 + " from hosts: " ); 191 for( int i=0; i<repositories.length; i++ ) 192 { 193 buffer.append( "\n " + repositories[i] ); 194 } 195 throw new RepositoryException( buffer.toString(), cause ); 196 } 197 198 207 public URL getResource( 208 String url, File destination, boolean timestamping ) 209 throws Exception 210 { 211 212 boolean update = destination.exists(); 213 long remoteTimestamp = 0; 215 221 if( timestamping && destination.exists() && url.startsWith( "file:" ) ) 222 { 223 try 224 { 225 URL sourceFileUrl = new URL ( url ); 226 String sourcePath = sourceFileUrl.getPath(); 227 File sourceFile = new File ( sourcePath ); 228 if( destination.lastModified() >= sourceFile.lastModified() ) 229 { 230 return destination.toURL(); 231 } 232 else 233 { 234 240 remoteTimestamp = sourceFile.lastModified(); 241 } 242 } 243 catch( Throwable e ) 244 { 245 e.printStackTrace(); 246 } 247 } 248 249 if( !m_online ) 250 { 251 if( destination.exists() ) 252 { 253 return getURL( destination ); 254 } 255 else 256 { 257 final String error = 258 "Cannot retrieve url [" + url + "] while disconnected."; 259 throw new RepositoryException( error ); 260 } 261 } 262 else 263 { 264 if( destination.exists() && !isSnapshot( destination ) ) 265 { 266 return getURL( destination ); 267 } 268 } 269 270 274 URL source = null ; 275 String username = null ; 276 String password = null ; 277 278 284 int atIdx = url.indexOf( "@" ) ; 285 if ( atIdx > 0 ) 286 { 287 String s = url.substring( 7, atIdx ) ; 288 int colon = s.indexOf( ":" ) ; 289 username = s.substring( 0, colon ) ; 290 password = s.substring( colon + 1 ) ; 291 source = new URL ( "http://" + url.substring( atIdx + 1 ) ) ; 292 } 293 else 294 { 295 source = new URL ( url ) ; 296 } 297 298 long timestamp = 0 ; 300 boolean hasTimestamp = false ; 301 if ( timestamping && destination.exists() ) 302 { 303 timestamp = destination.lastModified() ; 304 hasTimestamp = true ; 305 } 306 307 URLConnection connection = source.openConnection() ; 309 310 313 if ( timestamping && hasTimestamp ) 314 { 315 connection.setIfModifiedSince( timestamp ) ; 316 } 317 318 320 connection.connect() ; 321 322 324 if ( connection instanceof HttpURLConnection ) 325 { 326 HttpURLConnection httpConnection = 327 ( HttpURLConnection ) connection ; 328 329 if ( httpConnection.getResponseCode() == 330 HttpURLConnection.HTTP_NOT_MODIFIED ) 331 { 332 return destination.toURL() ; 333 } 334 335 if ( httpConnection.getResponseCode() == 337 HttpURLConnection.HTTP_UNAUTHORIZED ) 338 { 339 throw new Exception ( "Not authorized." ) ; 340 } 341 } 342 343 348 InputStream in = null ; 349 for ( int ii = 0; ii < 3; ii++ ) 350 { 351 try 352 { 353 in = connection.getInputStream() ; 354 break ; 355 } 356 catch ( IOException ex ) 357 { 358 } 360 } 361 if ( in == null ) 362 { 363 final String error = 364 "Connection returned a null input stream: " + url ; 365 throw new IOException ( error ) ; 366 } 367 368 File parent = destination.getParentFile() ; 369 parent.mkdirs() ; 370 371 File tempFile = File.createTempFile( "~avalon", ".tmp", parent ); 372 tempFile.deleteOnExit(); 375 FileOutputStream tempOut = new FileOutputStream ( tempFile ); 376 String title; 377 if( update ) 378 { 379 title = "Update from: [" + source + "] "; 380 } 381 else 382 { 383 title = "Download from: [" + source + "] "; 384 } 385 copyStream( in, tempOut, true, title ); 386 387 390 tempFile.renameTo( destination ); 391 392 396 if ( timestamping ) 397 { 398 if( remoteTimestamp == 0 ) 399 { 400 remoteTimestamp = connection.getLastModified() ; 401 } 402 403 if( remoteTimestamp < 0 ) 404 { 405 destination.setLastModified( System.currentTimeMillis() ) ; 406 } 407 else 408 { 409 destination.setLastModified( remoteTimestamp ) ; 410 } 411 } 412 return destination.toURL(); 413 } 414 415 private static boolean isSnapshot( File file ) 416 { 417 return file.getName().endsWith( "SNAPSHOT" ); 418 } 419 420 private static URL getURL( File file ) throws RepositoryException 421 { 422 try 423 { 424 return file.toURL(); 425 } 426 catch( Throwable e ) 427 { 428 final String error = 429 "Internal error while attempting to create a url from the file: " 430 + file; 431 throw new RepositoryException( error, e ); 432 } 433 } 434 435 private static void copyStream( 436 InputStream src, OutputStream dest, boolean closeStreams, 437 String title ) 438 throws IOException 439 { 440 boolean progress = title != null; 441 byte[] buffer = new byte[100 * 1024] ; 442 int length ; 443 if( title != null ) 444 System.out.println( title ); 445 try 446 { 447 while ( ( length = src.read( buffer ) ) >= 0 ) 448 { 449 dest.write( buffer, 0, length ) ; 450 if( progress ) 451 System.out.print( "." ) ; 452 } 453 } 454 finally 455 { 456 if( closeStreams ) 457 { 458 if( src != null ) 459 src.close(); 460 if( dest != null ) 461 dest.close(); 462 } 463 if( progress ) 464 System.out.println( "" ) ; 465 } 466 } 467 } 468 | Popular Tags |