jdk/src/share/classes/sun/security/provider/SeedGenerator.java
changeset 4176 bf303f38f727
parent 2175 7d7e238cb41a
child 5506 202f599c92aa
equal deleted inserted replaced
4175:3bbed32a84ee 4176:bf303f38f727
    61  *
    61  *
    62  * @author Joshua Bloch
    62  * @author Joshua Bloch
    63  * @author Gadi Guy
    63  * @author Gadi Guy
    64  */
    64  */
    65 
    65 
       
    66 import java.lang.reflect.Method;
       
    67 import java.lang.reflect.InvocationTargetException;
    66 import java.security.*;
    68 import java.security.*;
    67 import java.io.*;
    69 import java.io.*;
    68 import java.util.Properties;
    70 import java.util.Properties;
    69 import java.util.Enumeration;
    71 import java.util.Enumeration;
    70 import java.net.*;
    72 import java.net.*;
    71 import java.nio.file.DirectoryStream;
       
    72 import java.nio.file.Path;
       
    73 import java.util.Random;
    73 import java.util.Random;
    74 import sun.security.util.Debug;
    74 import sun.security.util.Debug;
    75 
    75 
    76 abstract class SeedGenerator {
    76 abstract class SeedGenerator {
    77 
    77 
   181                         md.update
   181                         md.update
   182                             (InetAddress.getLocalHost().toString().getBytes());
   182                             (InetAddress.getLocalHost().toString().getBytes());
   183 
   183 
   184                         // The temporary dir
   184                         // The temporary dir
   185                         File f = new File(p.getProperty("java.io.tmpdir"));
   185                         File f = new File(p.getProperty("java.io.tmpdir"));
   186                         int count = 0;
   186 
   187                         DirectoryStream<Path> ds
   187                         // Go thru files in the tmp dir using NIO's
   188                                 = f.toPath().newDirectoryStream();
   188                         // DirectoryStream. Fallback to File.list()
   189                         try {
   189                         // if NIO is not available.
       
   190                         if (NIODirectoryStream.isAvailable()) {
       
   191                             int count = 0;
       
   192                             Iterable<?> stream =
       
   193                                     NIODirectoryStream.newDirectoryStream(f);
   190                             // We use a Random object to choose what file names
   194                             // We use a Random object to choose what file names
   191                             // should be used. Otherwise on a machine with too
   195                             // should be used. Otherwise on a machine with too
   192                             // many files, the same first 1024 files always get
   196                             // many files, the same first 1024 files always get
   193                             // used. Any, We make sure the first 512 files are
   197                             // used. Any, We make sure the first 512 files are
   194                             // always used.
   198                             // always used.
   195                             Random r = new Random();
   199                             Random r = new Random();
   196                             for (Path path: ds) {
   200                             try {
   197                                 if (count < 512 || r.nextBoolean()) {
   201                                 for (Object entry: stream) {
   198                                     md.update(path.getName().toString().getBytes());
   202                                     if (count < 512 || r.nextBoolean()) {
       
   203                                         md.update(NIODirectoryStream.getName(
       
   204                                                 entry).getBytes());
       
   205                                     }
       
   206                                     if (count++ > 1024) {
       
   207                                         break;
       
   208                                     }
   199                                 }
   209                                 }
   200                                 if (count++ > 1024) {
   210                             } finally {
   201                                     break;
   211                                 ((Closeable)stream).close();
   202                                 }
       
   203                             }
   212                             }
   204                         } finally {
   213                         } else {
   205                             ds.close();
   214                             String[] sa = f.list();
       
   215                             for(int i = 0; i < sa.length; i++) {
       
   216                                 md.update(sa[i].getBytes());
       
   217                             }
   206                         }
   218                         }
   207                     } catch (Exception ex) {
   219                     } catch (Exception ex) {
   208                         md.update((byte)ex.hashCode());
   220                         md.update((byte)ex.hashCode());
   209                     }
   221                     }
   210 
   222 
   503             }
   515             }
   504         }
   516         }
   505 
   517 
   506     }
   518     }
   507 
   519 
       
   520     /**
       
   521      * A wrapper of NIO DirectoryStream using reflection.
       
   522      */
       
   523     private static class NIODirectoryStream {
       
   524         private static final Class<?> pathClass =
       
   525                 getClass("java.nio.file.Path");
       
   526 
       
   527         private static final Method toPathMethod =
       
   528                 (pathClass == null) ? null : getMethod(File.class, "toPath");
       
   529         private static final Method getNameMethod =
       
   530                 getMethod(pathClass, "getName");
       
   531         private static final Method newDirectoryStreamMethod =
       
   532                 getMethod(pathClass, "newDirectoryStream");
       
   533 
       
   534         private static Class<?> getClass(String name) {
       
   535             try {
       
   536                 return Class.forName(name, true, null);
       
   537             } catch (ClassNotFoundException e) {
       
   538                 return null;
       
   539             }
       
   540         }
       
   541 
       
   542         private static Method getMethod(Class<?> clazz,
       
   543                                         String name,
       
   544                                         Class<?>... paramTypes) {
       
   545             if (clazz != null) {
       
   546                 try {
       
   547                     return clazz.getMethod(name, paramTypes);
       
   548                 } catch (NoSuchMethodException e) {
       
   549                     throw new AssertionError(e);
       
   550                 }
       
   551             } else {
       
   552                 return null;
       
   553             }
       
   554         }
       
   555 
       
   556         static boolean isAvailable() {
       
   557             return pathClass != null;
       
   558         }
       
   559 
       
   560         static Iterable<?> newDirectoryStream(File dir) throws IOException {
       
   561             assert pathClass != null;
       
   562             try {
       
   563                 Object path = toPathMethod.invoke(dir);
       
   564                 return (Iterable<?>)newDirectoryStreamMethod.invoke(path);
       
   565             } catch (InvocationTargetException e) {
       
   566                 Throwable cause = e.getCause();
       
   567                 if (cause instanceof IOException)
       
   568                     throw (IOException)cause;
       
   569                 if (cause instanceof RuntimeException)
       
   570                     throw (RuntimeException)cause;
       
   571                 if (cause instanceof Error)
       
   572                     throw (Error)cause;
       
   573                 throw new AssertionError(e);
       
   574             } catch (IllegalAccessException iae) {
       
   575                 throw new AssertionError(iae);
       
   576             }
       
   577         }
       
   578 
       
   579         static String getName(Object path) {
       
   580             assert pathClass != null;
       
   581             try {
       
   582                 Object name = getNameMethod.invoke(path);
       
   583                 return name.toString();
       
   584             } catch (InvocationTargetException e) {
       
   585                 throw new AssertionError(e);
       
   586             } catch (IllegalAccessException iae) {
       
   587                 throw new AssertionError(iae);
       
   588             }
       
   589         }
       
   590     }
   508 }
   591 }
       
   592