make/tools/classanalyzer/src/com/sun/classanalyzer/Modularizer.java

Print this page




 173                 ClassPathEntry src = cp.accept(visitor, pathname);
 174                 if (src != null) {
 175                     // cache the ClassPathEntry from which this class is copied
 176                     // Most of the files in a module likely come from the
 177                     // same jar or directory.
 178                     lastVisitedClassPath = src;
 179                     return visitor.bytes;
 180                 }
 181             }
 182             return 0;
 183         }
 184 
 185         /**
 186          * Write the resource file if not filtered
 187          *
 188          * @param res a ResourceFile
 189          * @param filter a Filter
 190          * @return the number of bytes copied
 191          */
 192         long writeResource(ResourceFile res, Filter filter) throws IOException {



 193             String pathname = res.getPathname();
 194             Copier visitor = new Copier(classDir, filter);
 195             if (lastVisitedClassPath != null) {
 196                 ClassPathEntry cp = lastVisitedClassPath.accept(visitor, pathname);
 197                 if (cp != null) {
 198                     assert cp == lastVisitedClassPath;
 199                     return visitor.bytes;
 200                 }
 201             }
 202 
 203             // locate the source of the given resource file from the classpath
 204             for (ClassPathEntry cp : cpath.entries()) {
 205                 ClassPathEntry src = cp.accept(visitor, pathname);
 206                 if (src != null) {
 207                     // cache the ClassPathEntry from which this class is copied
 208                     // Most of the files in a module likely come from the
 209                     // same jar or directory.
 210                     lastVisitedClassPath = src;
 211                     return visitor.bytes;
 212                 }
 213             }
 214             return 0;
 215         }
 216 
 217         /**



























 218          * A ClassPathEntry visitor to copy a file to the given destination
 219          * if not filtered.
 220          */
 221         class Copier implements ClassPathEntry.Visitor<ClassPathEntry, String> {
 222             final Filter filter;
 223             final File dest;

 224             long bytes = 0;
 225 
 226             Copier(File dest, Filter filter) {




 227                 this.filter = filter;
 228                 this.dest = dest;

 229             }
 230 




 231             @Override
 232             public ClassPathEntry visitFile(File src, ClassPathEntry cp, String pathname) throws IOException {
 233                 String name = pathname.replace(File.separatorChar, '/');
 234                 if (cp.getName().endsWith(File.separator + pathname)
 235                         && matches(src, name)) {
 236                     if (filter == null || filter.accept(src)) {
 237                         File dst = new File(dest, pathname);
 238                         bytes += copy(src, dst);
 239                     }
 240                     return cp;
 241                 } else {
 242                     return null;
 243                 }
 244             }
 245 
 246             @Override
 247             public ClassPathEntry visitDir(File dir, ClassPathEntry cp, String pathname) throws IOException {
 248                 File src = new File(cp.getFile(), pathname);
 249                 File dst = new File(dest, pathname);
 250                 String name = pathname.replace(File.separatorChar, '/');


 257                 } else {
 258                     return null;
 259                 }
 260             }
 261 
 262             @Override
 263             public ClassPathEntry visitJarFile(JarFile jf, ClassPathEntry cp, String pathname) throws IOException {
 264                 String name = pathname.replace(File.separatorChar, '/');
 265                 JarEntry e = jf.getJarEntry(name);
 266                 if (e != null && matches(jf, e, name)) {
 267                     if (filter == null || filter.accept(jf, e)) {
 268                         bytes += copy(jf, e);
 269                     }
 270                     return cp;
 271                 } else {
 272                     return null;
 273                 }
 274             }
 275 
 276             boolean matches(File src, String name) throws IOException {
 277                 if (!name.startsWith("META-INF/services")) {
 278                     return true;
 279                 }
 280 
 281                 BufferedInputStream in = new BufferedInputStream(new FileInputStream(src));
 282                 try {
 283                     return matches(in, name);
 284                 } finally {
 285                     in.close();
 286                 }
 287             }
 288 
 289             boolean matches(JarFile jf, JarEntry e, String name) throws IOException {
 290                 if (!name.startsWith("META-INF/services")) {
 291                     return true;
 292                 }
 293                 return matches(jf.getInputStream(e), name);
 294             }
 295 
 296             boolean matches(InputStream in, String name) throws IOException {
 297                 ServiceProviderConfigFile sp = new ServiceProviderConfigFile(name, in);
 298                 for (String p : sp.providers) {
 299                     Klass k = Klass.findKlass(p);
 300                     if (k == null) {
 301                         Trace.trace("Service %s: provider class %s not found%n", sp.service, p);
 302                         continue;
 303                     }
 304                     if (module.contains(k)) {
 305                         return true;
 306                     }
 307                 }
 308                 // return true if no provider; otherwise false
 309                 return sp.providers.isEmpty();
 310             }
 311 
 312             long copy(JarFile jf, JarEntry e) throws IOException {
 313                 File dst = new File(dest, e.getName().replace('/', File.separatorChar));
 314                 if (!dst.exists()) {
 315                     Files.createFile(dst);
 316                 }
 317 
 318                 byte[] buf = new byte[8192];
 319                 InputStream in = jf.getInputStream(e);
 320                 long bytes = 0;
 321                 try {
 322                     FileOutputStream out = new FileOutputStream(dst);
 323                     try {
 324                         int n;
 325                         while ((n = in.read(buf)) > 0) {
 326                             out.write(buf, 0, n);
 327                             bytes += n;
 328                         }
 329                     } finally {
 330                         out.close();
 331                     }
 332                 } finally {
 333                     in.close();
 334                 }
 335 
 336                 long lastModified = e.getTime();
 337                 if (lastModified > 0) {
 338                     dst.setLastModified(lastModified);
 339                 }
 340                 return bytes;
 341             }
 342 
 343             long copy(File src, File dst)
 344                     throws IOException {
 345                 assert src.exists();
 346 
 347                 if (!dst.exists()) {
 348                     Files.createFile(dst);
 349                 }
 350 
 351                 BufferedInputStream in = new BufferedInputStream(new FileInputStream(src));
 352                 byte[] buf = new byte[8192];
 353                 long bytes = 0;
 354                 try {
 355                     FileOutputStream out = new FileOutputStream(dst);
 356                     try {
 357                         int n;
 358                         while ((n = in.read(buf)) > 0) {
 359                             out.write(buf, 0, n);
 360                             bytes += n;
 361                         }
 362                     } finally {
 363                         out.close();
 364                     }
 365                 } finally {
 366                     in.close();
 367                 }
 368                 dst.setLastModified(src.lastModified());
 369                 if (src.canExecute()) {
 370                     dst.setExecutable(true, false);
 371                 }
 372                 return bytes;
 373             }
 374         }
 375     }
 376 
 377     /**
 378      * A filter that accepts files that don't exist in the given
 379      * location or modified since it's copied.
 380      */
 381     class Filter implements ClassPath.Filter {
 382         private final long timestamp;
 383         Filter(File dir, String pathname) {
 384             File destfile = new File(dir, pathname);
 385             this.timestamp = destfile.exists() ? destfile.lastModified() : -1L;
 386         }
 387 




 173                 ClassPathEntry src = cp.accept(visitor, pathname);
 174                 if (src != null) {
 175                     // cache the ClassPathEntry from which this class is copied
 176                     // Most of the files in a module likely come from the
 177                     // same jar or directory.
 178                     lastVisitedClassPath = src;
 179                     return visitor.bytes;
 180                 }
 181             }
 182             return 0;
 183         }
 184 
 185         /**
 186          * Write the resource file if not filtered
 187          *
 188          * @param res a ResourceFile
 189          * @param filter a Filter
 190          * @return the number of bytes copied
 191          */
 192         long writeResource(ResourceFile res, Filter filter) throws IOException {
 193             if (res.isService())
 194                 return writeService(res, filter);
 195 
 196             String pathname = res.getPathname();
 197             Copier visitor = new Copier(classDir, filter);
 198             if (lastVisitedClassPath != null) {
 199                 ClassPathEntry cp = lastVisitedClassPath.accept(visitor, pathname);
 200                 if (cp != null) {
 201                     assert cp == lastVisitedClassPath;
 202                     return visitor.bytes;
 203                 }
 204             }
 205 
 206             // locate the source of the given resource file from the classpath
 207             for (ClassPathEntry cp : cpath.entries()) {
 208                 ClassPathEntry src = cp.accept(visitor, pathname);
 209                 if (src != null) {
 210                     // cache the ClassPathEntry from which this class is copied
 211                     // Most of the files in a module likely come from the
 212                     // same jar or directory.
 213                     lastVisitedClassPath = src;
 214                     return visitor.bytes;
 215                 }
 216             }
 217             return 0;
 218         }
 219 
 220         /**
 221          * Write the service descriptor file if not filtered
 222          *
 223          * @param res a ResourceFile
 224          * @param filter a Filter
 225          * @return the number of bytes copied
 226          */
 227         long writeService(ResourceFile res, Filter filter) throws IOException {
 228             String pathname = res.getPathname();
 229             Copier visitor = new Copier(classDir, filter);
 230             boolean foundOne = false;
 231             int bytes = 0;
 232 
 233             // scan all class path entries for services
 234             for (ClassPathEntry cp : cpath.entries()) {
 235                 ClassPathEntry src = cp.accept(visitor, pathname);
 236                 if (src != null) {
 237                     bytes += visitor.bytes;
 238                     if (foundOne == false) {
 239                         foundOne = true;
 240                         visitor = new Copier(classDir, null, true); // append subsequent
 241                     }
 242                 }
 243             }
 244             return bytes;
 245         }
 246 
 247         /**
 248          * A ClassPathEntry visitor to copy a file to the given destination
 249          * if not filtered.
 250          */
 251         class Copier implements ClassPathEntry.Visitor<ClassPathEntry, String> {
 252             final Filter filter;
 253             final File dest;
 254             final boolean append;
 255             long bytes = 0;
 256 
 257             Copier(File dest, Filter filter) {
 258                 this(dest, filter, false);
 259             }
 260 
 261             Copier(File dest, Filter filter, boolean append) {
 262                 this.filter = filter;
 263                 this.dest = dest;
 264                 this.append = append;
 265             }
 266 
 267             private boolean isService(String name) {
 268                 return name.startsWith("META-INF/services") ? true : false;
 269             }
 270 
 271             @Override
 272             public ClassPathEntry visitFile(File src, ClassPathEntry cp, String pathname) throws IOException {
 273                 String name = pathname.replace(File.separatorChar, '/');
 274                 if (cp.getName().endsWith(File.separator + pathname)
 275                         && matches(src, name)) {
 276                     if (filter == null || filter.accept(src)) {
 277                         File dst = new File(dest, pathname);
 278                         bytes += copy(src, dst);
 279                     }
 280                     return cp;
 281                 } else {
 282                     return null;
 283                 }
 284             }
 285 
 286             @Override
 287             public ClassPathEntry visitDir(File dir, ClassPathEntry cp, String pathname) throws IOException {
 288                 File src = new File(cp.getFile(), pathname);
 289                 File dst = new File(dest, pathname);
 290                 String name = pathname.replace(File.separatorChar, '/');


 297                 } else {
 298                     return null;
 299                 }
 300             }
 301 
 302             @Override
 303             public ClassPathEntry visitJarFile(JarFile jf, ClassPathEntry cp, String pathname) throws IOException {
 304                 String name = pathname.replace(File.separatorChar, '/');
 305                 JarEntry e = jf.getJarEntry(name);
 306                 if (e != null && matches(jf, e, name)) {
 307                     if (filter == null || filter.accept(jf, e)) {
 308                         bytes += copy(jf, e);
 309                     }
 310                     return cp;
 311                 } else {
 312                     return null;
 313                 }
 314             }
 315 
 316             boolean matches(File src, String name) throws IOException {
 317                 if (!isService(name)) {
 318                     return true;
 319                 }
 320 
 321                 try (FileInputStream fis = new FileInputStream(src);
 322                      BufferedInputStream in = new BufferedInputStream(fis)) {
 323                     return matches(in, name);


 324                 }
 325             }
 326 
 327             boolean matches(JarFile jf, JarEntry e, String name) throws IOException {
 328                 if (!isService(name)) {
 329                     return true;
 330                 }
 331                 return matches(jf.getInputStream(e), name);
 332             }
 333 
 334             boolean matches(InputStream in, String name) throws IOException {
 335                 ServiceProviderConfigFile sp = new ServiceProviderConfigFile(name, in);
 336                 for (String p : sp.providers) {
 337                     Klass k = Klass.findKlass(p);
 338                     if (k == null) {
 339                         Trace.trace("Service %s: provider class %s not found%n", sp.service, p);
 340                         continue;
 341                     }
 342                     if (module.contains(k)) {
 343                         return true;
 344                     }
 345                 }
 346                 // return true if no provider; otherwise false
 347                 return sp.providers.isEmpty();
 348             }
 349 
 350             long copy(JarFile jf, JarEntry e) throws IOException {
 351                 File dst = new File(dest, e.getName().replace('/', File.separatorChar));
 352                 if (!dst.exists()) {
 353                     Files.createFile(dst);
 354                 }
 355 
 356                 byte[] buf = new byte[8192];

 357                 long bytes = 0;
 358                 try (InputStream in = jf.getInputStream(e);
 359                      FileOutputStream out = new FileOutputStream(dst, append)) {

 360                     int n;
 361                     while ((n = in.read(buf)) > 0) {
 362                         out.write(buf, 0, n);
 363                         bytes += n;
 364                     }


 365                 }



 366 
 367                 long lastModified = e.getTime();
 368                 if (lastModified > 0) {
 369                     dst.setLastModified(lastModified);
 370                 }
 371                 return bytes;
 372             }
 373 
 374             long copy(File src, File dst)
 375                     throws IOException {
 376                 assert src.exists();
 377 
 378                 if (!dst.exists()) {
 379                     Files.createFile(dst);
 380                 }
 381 

 382                 byte[] buf = new byte[8192];
 383                 long bytes = 0;
 384                 try (InputStream fin = new FileInputStream(src);
 385                      BufferedInputStream in = new BufferedInputStream(fin);
 386                      FileOutputStream out = new FileOutputStream(dst, append)) {
 387                     int n;
 388                     while ((n = in.read(buf)) > 0) {
 389                         out.write(buf, 0, n);
 390                         bytes += n;
 391                     }


 392                 }



 393                 dst.setLastModified(src.lastModified());
 394                 if (src.canExecute()) {
 395                     dst.setExecutable(true, false);
 396                 }
 397                 return bytes;
 398             }
 399         }
 400     }
 401 
 402     /**
 403      * A filter that accepts files that don't exist in the given
 404      * location or modified since it's copied.
 405      */
 406     class Filter implements ClassPath.Filter {
 407         private final long timestamp;
 408         Filter(File dir, String pathname) {
 409             File destfile = new File(dir, pathname);
 410             this.timestamp = destfile.exists() ? destfile.lastModified() : -1L;
 411         }
 412