1 /*
   2  * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.tools.javac.api;
  27 
  28 import java.io.File;
  29 import java.io.IOException;
  30 import java.io.InputStream;
  31 import java.io.OutputStream;
  32 import java.io.Reader;
  33 import java.io.Writer;
  34 import java.lang.annotation.ElementType;
  35 import java.lang.annotation.Retention;
  36 import java.lang.annotation.RetentionPolicy;
  37 import java.lang.annotation.Target;
  38 import java.net.URI;
  39 import java.nio.file.Path;
  40 import java.util.ArrayList;
  41 import java.util.Collection;
  42 import java.util.Collections;
  43 import java.util.HashMap;
  44 import java.util.Iterator;
  45 import java.util.List;
  46 import java.util.Locale;
  47 import java.util.Map;
  48 import java.util.Objects;
  49 import java.util.ServiceLoader;
  50 import java.util.Set;
  51 
  52 import javax.lang.model.element.Modifier;
  53 import javax.lang.model.element.NestingKind;
  54 import javax.tools.Diagnostic;
  55 import javax.tools.DiagnosticListener;
  56 import javax.tools.FileObject;
  57 import javax.tools.JavaFileManager;
  58 import javax.tools.JavaFileManager.Location;
  59 import javax.tools.JavaFileObject;
  60 import javax.tools.JavaFileObject.Kind;
  61 import javax.tools.StandardJavaFileManager;
  62 
  63 import com.sun.source.util.TaskEvent;
  64 import com.sun.source.util.TaskListener;
  65 import com.sun.tools.javac.util.ClientCodeException;
  66 import com.sun.tools.javac.util.Context;
  67 import com.sun.tools.javac.util.DefinedBy;
  68 import com.sun.tools.javac.util.DefinedBy.Api;
  69 import com.sun.tools.javac.util.JCDiagnostic;
  70 
  71 /**
  72  *  Wrap objects to enable unchecked exceptions to be caught and handled.
  73  *
  74  *  For each method, exceptions are handled as follows:
  75  *  <ul>
  76  *  <li>Checked exceptions are left alone and propagate upwards in the
  77  *      obvious way, since they are an expected aspect of the method's
  78  *      specification.
  79  *  <li>Unchecked exceptions which have already been caught and wrapped in
  80  *      ClientCodeException are left alone to continue propagating upwards.
  81  *  <li>All other unchecked exceptions (i.e. subtypes of RuntimeException
  82  *      and Error) and caught, and rethrown as a ClientCodeException with
  83  *      its cause set to the original exception.
  84  *  </ul>
  85  *
  86  *  The intent is that ClientCodeException can be caught at an appropriate point
  87  *  in the program and can be distinguished from any unanticipated unchecked
  88  *  exceptions arising in the main body of the code (i.e. bugs.) When the
  89  *  ClientCodeException has been caught, either a suitable message can be
  90  *  generated, or if appropriate, the original cause can be rethrown.
  91  *
  92  *  <p><b>This is NOT part of any supported API.
  93  *  If you write code that depends on this, you do so at your own risk.
  94  *  This code and its internal interfaces are subject to change or
  95  *  deletion without notice.</b>
  96  */
  97 public class ClientCodeWrapper {
  98     @Retention(RetentionPolicy.RUNTIME)
  99     @Target(ElementType.TYPE)
 100     public @interface Trusted { }
 101 
 102     public static ClientCodeWrapper instance(Context context) {
 103         ClientCodeWrapper instance = context.get(ClientCodeWrapper.class);
 104         if (instance == null)
 105             instance = new ClientCodeWrapper(context);
 106         return instance;
 107     }
 108 
 109     /**
 110      * A map to cache the results of whether or not a specific classes can
 111      * be "trusted", and thus does not need to be wrapped.
 112      */
 113     Map<Class<?>, Boolean> trustedClasses;
 114 
 115     protected ClientCodeWrapper(Context context) {
 116         trustedClasses = new HashMap<>();
 117     }
 118 
 119     public JavaFileManager wrap(JavaFileManager fm) {
 120         if (isTrusted(fm))
 121             return fm;
 122         if (fm instanceof StandardJavaFileManager)
 123             return new WrappedStandardJavaFileManager((StandardJavaFileManager) fm);
 124         return new WrappedJavaFileManager(fm);
 125     }
 126 
 127     public FileObject wrap(FileObject fo) {
 128         if (fo == null || isTrusted(fo))
 129             return fo;
 130         return new WrappedFileObject(fo);
 131     }
 132 
 133     FileObject unwrap(FileObject fo) {
 134         if (fo instanceof WrappedFileObject)
 135             return ((WrappedFileObject) fo).clientFileObject;
 136         else
 137             return fo;
 138     }
 139 
 140     public JavaFileObject wrap(JavaFileObject fo) {
 141         if (fo == null || isTrusted(fo))
 142             return fo;
 143         return new WrappedJavaFileObject(fo);
 144     }
 145 
 146     public Iterable<JavaFileObject> wrapJavaFileObjects(Iterable<? extends JavaFileObject> list) {
 147         List<JavaFileObject> wrapped = new ArrayList<>();
 148         for (JavaFileObject fo : list)
 149             wrapped.add(wrap(fo));
 150         return Collections.unmodifiableList(wrapped);
 151     }
 152 
 153     JavaFileObject unwrap(JavaFileObject fo) {
 154         if (fo instanceof WrappedJavaFileObject)
 155             return ((JavaFileObject) ((WrappedJavaFileObject) fo).clientFileObject);
 156         else
 157             return fo;
 158     }
 159 
 160     public <T /*super JavaFileObject*/> DiagnosticListener<T> wrap(DiagnosticListener<T> dl) {
 161         if (isTrusted(dl))
 162             return dl;
 163         return new WrappedDiagnosticListener<>(dl);
 164     }
 165 
 166     TaskListener wrap(TaskListener tl) {
 167         if (isTrusted(tl))
 168             return tl;
 169         return new WrappedTaskListener(tl);
 170     }
 171 
 172     TaskListener unwrap(TaskListener l) {
 173         if (l instanceof WrappedTaskListener)
 174             return ((WrappedTaskListener) l).clientTaskListener;
 175         else
 176             return l;
 177     }
 178 
 179     Collection<TaskListener> unwrap(Collection<? extends TaskListener> listeners) {
 180         Collection<TaskListener> c = new ArrayList<>(listeners.size());
 181         for (TaskListener l: listeners)
 182             c.add(unwrap(l));
 183         return c;
 184     }
 185 
 186     @SuppressWarnings("unchecked")
 187     private <T> Diagnostic<T> unwrap(final Diagnostic<T> diagnostic) {
 188         if (diagnostic instanceof JCDiagnostic) {
 189             JCDiagnostic d = (JCDiagnostic) diagnostic;
 190             return (Diagnostic<T>) new DiagnosticSourceUnwrapper(d);
 191         } else {
 192             return diagnostic;
 193         }
 194     }
 195 
 196     protected boolean isTrusted(Object o) {
 197         Class<?> c = o.getClass();
 198         Boolean trusted = trustedClasses.get(c);
 199         if (trusted == null) {
 200             trusted = c.getName().startsWith("com.sun.tools.javac.")
 201                     || c.isAnnotationPresent(Trusted.class);
 202             trustedClasses.put(c, trusted);
 203         }
 204         return trusted;
 205     }
 206 
 207     private String wrappedToString(Class<?> wrapperClass, Object wrapped) {
 208         return wrapperClass.getSimpleName() + "[" + wrapped + "]";
 209     }
 210 
 211     // <editor-fold defaultstate="collapsed" desc="Wrapper classes">
 212 
 213     protected class WrappedJavaFileManager implements JavaFileManager {
 214         protected JavaFileManager clientJavaFileManager;
 215         WrappedJavaFileManager(JavaFileManager clientJavaFileManager) {
 216             this.clientJavaFileManager = Objects.requireNonNull(clientJavaFileManager);
 217         }
 218 
 219         @Override @DefinedBy(Api.COMPILER)
 220         public ClassLoader getClassLoader(Location location) {
 221             try {
 222                 return clientJavaFileManager.getClassLoader(location);
 223             } catch (ClientCodeException e) {
 224                 throw e;
 225             } catch (RuntimeException | Error e) {
 226                 throw new ClientCodeException(e);
 227             }
 228         }
 229 
 230         @Override @DefinedBy(Api.COMPILER)
 231         public Iterable<JavaFileObject> list(Location location, String packageName, Set<Kind> kinds, boolean recurse) throws IOException {
 232             try {
 233                 return wrapJavaFileObjects(clientJavaFileManager.list(location, packageName, kinds, recurse));
 234             } catch (ClientCodeException e) {
 235                 throw e;
 236             } catch (RuntimeException | Error e) {
 237                 throw new ClientCodeException(e);
 238             }
 239         }
 240 
 241         @Override @DefinedBy(Api.COMPILER)
 242         public String inferBinaryName(Location location, JavaFileObject file) {
 243             try {
 244                 return clientJavaFileManager.inferBinaryName(location, unwrap(file));
 245             } catch (ClientCodeException e) {
 246                 throw e;
 247             } catch (RuntimeException | Error e) {
 248                 throw new ClientCodeException(e);
 249             }
 250         }
 251 
 252         @Override @DefinedBy(Api.COMPILER)
 253         public boolean isSameFile(FileObject a, FileObject b) {
 254             try {
 255                 return clientJavaFileManager.isSameFile(unwrap(a), unwrap(b));
 256             } catch (ClientCodeException e) {
 257                 throw e;
 258             } catch (RuntimeException | Error e) {
 259                 throw new ClientCodeException(e);
 260             }
 261         }
 262 
 263         @Override @DefinedBy(Api.COMPILER)
 264         public boolean handleOption(String current, Iterator<String> remaining) {
 265             try {
 266                 return clientJavaFileManager.handleOption(current, remaining);
 267             } catch (ClientCodeException e) {
 268                 throw e;
 269             } catch (RuntimeException | Error e) {
 270                 throw new ClientCodeException(e);
 271             }
 272         }
 273 
 274         @Override @DefinedBy(Api.COMPILER)
 275         public boolean hasLocation(Location location) {
 276             try {
 277                 return clientJavaFileManager.hasLocation(location);
 278             } catch (ClientCodeException e) {
 279                 throw e;
 280             } catch (RuntimeException | Error e) {
 281                 throw new ClientCodeException(e);
 282             }
 283         }
 284 
 285         @Override @DefinedBy(Api.COMPILER)
 286         public JavaFileObject getJavaFileForInput(Location location, String className, Kind kind) throws IOException {
 287             try {
 288                 return wrap(clientJavaFileManager.getJavaFileForInput(location, className, kind));
 289             } catch (ClientCodeException e) {
 290                 throw e;
 291             } catch (RuntimeException | Error e) {
 292                 throw new ClientCodeException(e);
 293             }
 294         }
 295 
 296         @Override @DefinedBy(Api.COMPILER)
 297         public JavaFileObject getJavaFileForOutput(Location location, String className, Kind kind, FileObject sibling) throws IOException {
 298             try {
 299                 return wrap(clientJavaFileManager.getJavaFileForOutput(location, className, kind, unwrap(sibling)));
 300             } catch (ClientCodeException e) {
 301                 throw e;
 302             } catch (RuntimeException | Error e) {
 303                 throw new ClientCodeException(e);
 304             }
 305         }
 306 
 307         @Override @DefinedBy(Api.COMPILER)
 308         public FileObject getFileForInput(Location location, String packageName, String relativeName) throws IOException {
 309             try {
 310                 return wrap(clientJavaFileManager.getFileForInput(location, packageName, relativeName));
 311             } catch (ClientCodeException e) {
 312                 throw e;
 313             } catch (RuntimeException | Error e) {
 314                 throw new ClientCodeException(e);
 315             }
 316         }
 317 
 318         @Override @DefinedBy(Api.COMPILER)
 319         public FileObject getFileForOutput(Location location, String packageName, String relativeName, FileObject sibling) throws IOException {
 320             try {
 321                 return wrap(clientJavaFileManager.getFileForOutput(location, packageName, relativeName, unwrap(sibling)));
 322             } catch (ClientCodeException e) {
 323                 throw e;
 324             } catch (RuntimeException | Error e) {
 325                 throw new ClientCodeException(e);
 326             }
 327         }
 328 
 329         @Override @DefinedBy(Api.COMPILER)
 330         public boolean contains(Location location, FileObject file) throws IOException {
 331             try {
 332                 return clientJavaFileManager.contains(location, unwrap(file));
 333             } catch (ClientCodeException e) {
 334                 throw e;
 335             } catch (RuntimeException | Error e) {
 336                 throw new ClientCodeException(e);
 337             }
 338         }
 339 
 340         @Override @DefinedBy(Api.COMPILER)
 341         public void flush() throws IOException {
 342             try {
 343                 clientJavaFileManager.flush();
 344             } catch (ClientCodeException e) {
 345                 throw e;
 346             } catch (RuntimeException | Error e) {
 347                 throw new ClientCodeException(e);
 348             }
 349         }
 350 
 351         @Override @DefinedBy(Api.COMPILER)
 352         public void close() throws IOException {
 353             try {
 354                 clientJavaFileManager.close();
 355             } catch (ClientCodeException e) {
 356                 throw e;
 357             } catch (RuntimeException | Error e) {
 358                 throw new ClientCodeException(e);
 359             }
 360         }
 361 
 362         @Override @DefinedBy(Api.COMPILER)
 363         public Location getLocationForModule(Location location, String moduleName) throws IOException {
 364             try {
 365                 return clientJavaFileManager.getLocationForModule(location, moduleName);
 366             } catch (ClientCodeException e) {
 367                 throw e;
 368             } catch (RuntimeException | Error e) {
 369                 throw new ClientCodeException(e);
 370             }
 371         }
 372 
 373         @Override @DefinedBy(Api.COMPILER)
 374         public Location getLocationForModule(Location location, JavaFileObject fo) throws IOException {
 375             try {
 376                 return clientJavaFileManager.getLocationForModule(location, unwrap(fo));
 377             } catch (ClientCodeException e) {
 378                 throw e;
 379             } catch (RuntimeException | Error e) {
 380                 throw new ClientCodeException(e);
 381             }
 382         }
 383 
 384         @Override @DefinedBy(Api.COMPILER)
 385         public String inferModuleName(Location location) throws IOException {
 386             try {
 387                 return clientJavaFileManager.inferModuleName(location);
 388             } catch (ClientCodeException e) {
 389                 throw e;
 390             } catch (RuntimeException | Error e) {
 391                 throw new ClientCodeException(e);
 392             }
 393         }
 394 
 395         @Override @DefinedBy(Api.COMPILER)
 396         public Iterable<Set<Location>> listLocationsForModules(Location location) throws IOException {
 397             try {
 398                 return clientJavaFileManager.listLocationsForModules(location);
 399             } catch (ClientCodeException e) {
 400                 throw e;
 401             } catch (RuntimeException | Error e) {
 402                 throw new ClientCodeException(e);
 403             }
 404         }
 405 
 406         @Override @DefinedBy(Api.COMPILER)
 407         public int isSupportedOption(String option) {
 408             try {
 409                 return clientJavaFileManager.isSupportedOption(option);
 410             } catch (ClientCodeException e) {
 411                 throw e;
 412             } catch (RuntimeException | Error e) {
 413                 throw new ClientCodeException(e);
 414             }
 415         }
 416 
 417         @Override
 418         public String toString() {
 419             return wrappedToString(getClass(), clientJavaFileManager);
 420         }
 421 
 422         @Override @DefinedBy(Api.COMPILER)
 423         public <S> ServiceLoader<S> getServiceLoader(Location location, Class<S> service) throws IOException {
 424             try {
 425                 return clientJavaFileManager.getServiceLoader(location, service);
 426             } catch (ClientCodeException e) {
 427                 throw e;
 428             } catch (RuntimeException | Error e) {
 429                 throw new ClientCodeException(e);
 430             }
 431         }
 432     }
 433 
 434     protected class WrappedStandardJavaFileManager extends WrappedJavaFileManager
 435             implements StandardJavaFileManager {
 436         WrappedStandardJavaFileManager(StandardJavaFileManager clientJavaFileManager) {
 437             super(clientJavaFileManager);
 438         }
 439 
 440         @Override @DefinedBy(Api.COMPILER)
 441         public Iterable<? extends JavaFileObject> getJavaFileObjectsFromFiles(Iterable<? extends File> files) {
 442             try {
 443                 return ((StandardJavaFileManager)clientJavaFileManager).getJavaFileObjectsFromFiles(files);
 444             } catch (ClientCodeException e) {
 445                 throw e;
 446             } catch (RuntimeException | Error e) {
 447                 throw new ClientCodeException(e);
 448             }
 449         }
 450 
 451         @Override @DefinedBy(Api.COMPILER)
 452         public Iterable<? extends JavaFileObject> getJavaFileObjectsFromPaths(Collection<? extends Path> paths) {
 453             try {
 454                 return ((StandardJavaFileManager)clientJavaFileManager).getJavaFileObjectsFromPaths(paths);
 455             } catch (ClientCodeException e) {
 456                 throw e;
 457             } catch (RuntimeException | Error e) {
 458                 throw new ClientCodeException(e);
 459             }
 460         }
 461 
 462         @Deprecated(since = "13")
 463         @Override @DefinedBy(Api.COMPILER)
 464         public Iterable<? extends JavaFileObject> getJavaFileObjectsFromPaths(Iterable<? extends Path> paths) {
 465             try {
 466                 return ((StandardJavaFileManager)clientJavaFileManager).getJavaFileObjectsFromPaths(paths);
 467             } catch (ClientCodeException e) {
 468                 throw e;
 469             } catch (RuntimeException | Error e) {
 470                 throw new ClientCodeException(e);
 471             }
 472         }
 473 
 474         @Override @DefinedBy(Api.COMPILER)
 475         public Iterable<? extends JavaFileObject> getJavaFileObjects(File... files) {
 476             try {
 477                 return ((StandardJavaFileManager)clientJavaFileManager).getJavaFileObjects(files);
 478             } catch (ClientCodeException e) {
 479                 throw e;
 480             } catch (RuntimeException | Error e) {
 481                 throw new ClientCodeException(e);
 482             }
 483         }
 484 
 485         @Override @DefinedBy(Api.COMPILER)
 486         public Iterable<? extends JavaFileObject> getJavaFileObjects(Path... paths) {
 487             try {
 488                 return ((StandardJavaFileManager)clientJavaFileManager).getJavaFileObjects(paths);
 489             } catch (ClientCodeException e) {
 490                 throw e;
 491             } catch (RuntimeException | Error e) {
 492                 throw new ClientCodeException(e);
 493             }
 494         }
 495 
 496         @Override @DefinedBy(Api.COMPILER)
 497         public Iterable<? extends JavaFileObject> getJavaFileObjectsFromStrings(Iterable<String> names) {
 498             try {
 499                 return ((StandardJavaFileManager)clientJavaFileManager).getJavaFileObjectsFromStrings(names);
 500             } catch (ClientCodeException e) {
 501                 throw e;
 502             } catch (RuntimeException | Error e) {
 503                 throw new ClientCodeException(e);
 504             }
 505         }
 506 
 507         @Override @DefinedBy(Api.COMPILER)
 508         public Iterable<? extends JavaFileObject> getJavaFileObjects(String... names) {
 509             try {
 510                 return ((StandardJavaFileManager)clientJavaFileManager).getJavaFileObjects(names);
 511             } catch (ClientCodeException e) {
 512                 throw e;
 513             } catch (RuntimeException | Error e) {
 514                 throw new ClientCodeException(e);
 515             }
 516         }
 517 
 518         @Override @DefinedBy(Api.COMPILER)
 519         public void setLocation(Location location, Iterable<? extends File> files) throws IOException {
 520             try {
 521                 ((StandardJavaFileManager)clientJavaFileManager).setLocation(location, files);
 522             } catch (ClientCodeException e) {
 523                 throw e;
 524             } catch (RuntimeException | Error e) {
 525                 throw new ClientCodeException(e);
 526             }
 527         }
 528 
 529         @Override @DefinedBy(Api.COMPILER)
 530         public void setLocationFromPaths(Location location, Collection<? extends Path> paths) throws IOException {
 531             try {
 532                 ((StandardJavaFileManager)clientJavaFileManager).setLocationFromPaths(location, paths);
 533             } catch (ClientCodeException e) {
 534                 throw e;
 535             } catch (RuntimeException | Error e) {
 536                 throw new ClientCodeException(e);
 537             }
 538         }
 539 
 540         @Override @DefinedBy(Api.COMPILER)
 541         public Iterable<? extends File> getLocation(Location location) {
 542             try {
 543                 return ((StandardJavaFileManager)clientJavaFileManager).getLocation(location);
 544             } catch (ClientCodeException e) {
 545                 throw e;
 546             } catch (RuntimeException | Error e) {
 547                 throw new ClientCodeException(e);
 548             }
 549         }
 550 
 551         @Override @DefinedBy(Api.COMPILER)
 552         public Iterable<? extends Path> getLocationAsPaths(Location location) {
 553             try {
 554                 return ((StandardJavaFileManager)clientJavaFileManager).getLocationAsPaths(location);
 555             } catch (ClientCodeException e) {
 556                 throw e;
 557             } catch (RuntimeException | Error e) {
 558                 throw new ClientCodeException(e);
 559             }
 560         }
 561 
 562         @Override @DefinedBy(Api.COMPILER)
 563         public Path asPath(FileObject file) {
 564             try {
 565                 return ((StandardJavaFileManager)clientJavaFileManager).asPath(file);
 566             } catch (ClientCodeException e) {
 567                 throw e;
 568             } catch (RuntimeException | Error e) {
 569                 throw new ClientCodeException(e);
 570             }
 571         }
 572 
 573         @Override @DefinedBy(Api.COMPILER)
 574         public void setPathFactory(PathFactory f) {
 575             try {
 576                 ((StandardJavaFileManager)clientJavaFileManager).setPathFactory(f);
 577             } catch (ClientCodeException e) {
 578                 throw e;
 579             } catch (RuntimeException | Error e) {
 580                 throw new ClientCodeException(e);
 581             }
 582         }
 583 
 584         @Override @DefinedBy(Api.COMPILER)
 585         public void setLocationForModule(Location location, String moduleName, Collection<? extends Path> paths) throws IOException {
 586             try {
 587                 System.out.println("invoking wrapped setLocationForModule");
 588                 ((StandardJavaFileManager)clientJavaFileManager).setLocationForModule(location, moduleName, paths);
 589             } catch (ClientCodeException e) {
 590                 throw e;
 591             } catch (RuntimeException | Error e) {
 592                 throw new ClientCodeException(e);
 593             }
 594         }
 595     }
 596 
 597     protected class WrappedFileObject implements FileObject {
 598         protected FileObject clientFileObject;
 599         WrappedFileObject(FileObject clientFileObject) {
 600             this.clientFileObject = Objects.requireNonNull(clientFileObject);
 601         }
 602 
 603         @Override @DefinedBy(Api.COMPILER)
 604         public URI toUri() {
 605             try {
 606                 return clientFileObject.toUri();
 607             } catch (ClientCodeException e) {
 608                 throw e;
 609             } catch (RuntimeException | Error e) {
 610                 throw new ClientCodeException(e);
 611             }
 612         }
 613 
 614         @Override @DefinedBy(Api.COMPILER)
 615         public String getName() {
 616             try {
 617                 return clientFileObject.getName();
 618             } catch (ClientCodeException e) {
 619                 throw e;
 620             } catch (RuntimeException | Error e) {
 621                 throw new ClientCodeException(e);
 622             }
 623         }
 624 
 625         @Override @DefinedBy(Api.COMPILER)
 626         public InputStream openInputStream() throws IOException {
 627             try {
 628                 return clientFileObject.openInputStream();
 629             } catch (ClientCodeException e) {
 630                 throw e;
 631             } catch (RuntimeException | Error e) {
 632                 throw new ClientCodeException(e);
 633             }
 634         }
 635 
 636         @Override @DefinedBy(Api.COMPILER)
 637         public OutputStream openOutputStream() throws IOException {
 638             try {
 639                 return clientFileObject.openOutputStream();
 640             } catch (ClientCodeException e) {
 641                 throw e;
 642             } catch (RuntimeException | Error e) {
 643                 throw new ClientCodeException(e);
 644             }
 645         }
 646 
 647         @Override @DefinedBy(Api.COMPILER)
 648         public Reader openReader(boolean ignoreEncodingErrors) throws IOException {
 649             try {
 650                 return clientFileObject.openReader(ignoreEncodingErrors);
 651             } catch (ClientCodeException e) {
 652                 throw e;
 653             } catch (RuntimeException | Error e) {
 654                 throw new ClientCodeException(e);
 655             }
 656         }
 657 
 658         @Override @DefinedBy(Api.COMPILER)
 659         public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
 660             try {
 661                 return clientFileObject.getCharContent(ignoreEncodingErrors);
 662             } catch (ClientCodeException e) {
 663                 throw e;
 664             } catch (RuntimeException | Error e) {
 665                 throw new ClientCodeException(e);
 666             }
 667         }
 668 
 669         @Override @DefinedBy(Api.COMPILER)
 670         public Writer openWriter() throws IOException {
 671             try {
 672                 return clientFileObject.openWriter();
 673             } catch (ClientCodeException e) {
 674                 throw e;
 675             } catch (RuntimeException | Error e) {
 676                 throw new ClientCodeException(e);
 677             }
 678         }
 679 
 680         @Override @DefinedBy(Api.COMPILER)
 681         public long getLastModified() {
 682             try {
 683                 return clientFileObject.getLastModified();
 684             } catch (ClientCodeException e) {
 685                 throw e;
 686             } catch (RuntimeException | Error e) {
 687                 throw new ClientCodeException(e);
 688             }
 689         }
 690 
 691         @Override @DefinedBy(Api.COMPILER)
 692         public boolean delete() {
 693             try {
 694                 return clientFileObject.delete();
 695             } catch (ClientCodeException e) {
 696                 throw e;
 697             } catch (RuntimeException | Error e) {
 698                 throw new ClientCodeException(e);
 699             }
 700         }
 701 
 702         @Override
 703         public String toString() {
 704             return wrappedToString(getClass(), clientFileObject);
 705         }
 706     }
 707 
 708     protected class WrappedJavaFileObject extends WrappedFileObject implements JavaFileObject {
 709         WrappedJavaFileObject(JavaFileObject clientJavaFileObject) {
 710             super(clientJavaFileObject);
 711         }
 712 
 713         @Override @DefinedBy(Api.COMPILER)
 714         public Kind getKind() {
 715             try {
 716                 return ((JavaFileObject)clientFileObject).getKind();
 717             } catch (ClientCodeException e) {
 718                 throw e;
 719             } catch (RuntimeException | Error e) {
 720                 throw new ClientCodeException(e);
 721             }
 722         }
 723 
 724         @Override @DefinedBy(Api.COMPILER)
 725         public boolean isNameCompatible(String simpleName, Kind kind) {
 726             try {
 727                 return ((JavaFileObject)clientFileObject).isNameCompatible(simpleName, kind);
 728             } catch (ClientCodeException e) {
 729                 throw e;
 730             } catch (RuntimeException | Error e) {
 731                 throw new ClientCodeException(e);
 732             }
 733         }
 734 
 735         @Override @DefinedBy(Api.COMPILER)
 736         public NestingKind getNestingKind() {
 737             try {
 738                 return ((JavaFileObject)clientFileObject).getNestingKind();
 739             } catch (ClientCodeException e) {
 740                 throw e;
 741             } catch (RuntimeException | Error e) {
 742                 throw new ClientCodeException(e);
 743             }
 744         }
 745 
 746         @Override @DefinedBy(Api.COMPILER)
 747         public Modifier getAccessLevel() {
 748             try {
 749                 return ((JavaFileObject)clientFileObject).getAccessLevel();
 750             } catch (ClientCodeException e) {
 751                 throw e;
 752             } catch (RuntimeException | Error e) {
 753                 throw new ClientCodeException(e);
 754             }
 755         }
 756 
 757         @Override
 758         public String toString() {
 759             return wrappedToString(getClass(), clientFileObject);
 760         }
 761     }
 762 
 763     protected class WrappedDiagnosticListener<T /*super JavaFileObject*/> implements DiagnosticListener<T> {
 764         protected DiagnosticListener<T> clientDiagnosticListener;
 765         WrappedDiagnosticListener(DiagnosticListener<T> clientDiagnosticListener) {
 766             this.clientDiagnosticListener = Objects.requireNonNull(clientDiagnosticListener);
 767         }
 768 
 769         @Override @DefinedBy(Api.COMPILER)
 770         public void report(Diagnostic<? extends T> diagnostic) {
 771             try {
 772                 clientDiagnosticListener.report(unwrap(diagnostic));
 773             } catch (ClientCodeException e) {
 774                 throw e;
 775             } catch (RuntimeException | Error e) {
 776                 throw new ClientCodeException(e);
 777             }
 778         }
 779 
 780         @Override
 781         public String toString() {
 782             return wrappedToString(getClass(), clientDiagnosticListener);
 783         }
 784     }
 785 
 786     public class DiagnosticSourceUnwrapper implements Diagnostic<JavaFileObject> {
 787         public final JCDiagnostic d;
 788 
 789         DiagnosticSourceUnwrapper(JCDiagnostic d) {
 790             this.d = d;
 791         }
 792 
 793         @Override @DefinedBy(Api.COMPILER)
 794         public Diagnostic.Kind getKind() {
 795             return d.getKind();
 796         }
 797 
 798         @Override @DefinedBy(Api.COMPILER)
 799         public JavaFileObject getSource() {
 800             return unwrap(d.getSource());
 801         }
 802 
 803         @Override @DefinedBy(Api.COMPILER)
 804         public long getPosition() {
 805             return d.getPosition();
 806         }
 807 
 808         @Override @DefinedBy(Api.COMPILER)
 809         public long getStartPosition() {
 810             return d.getStartPosition();
 811         }
 812 
 813         @Override @DefinedBy(Api.COMPILER)
 814         public long getEndPosition() {
 815             return d.getEndPosition();
 816         }
 817 
 818         @Override @DefinedBy(Api.COMPILER)
 819         public long getLineNumber() {
 820             return d.getLineNumber();
 821         }
 822 
 823         @Override @DefinedBy(Api.COMPILER)
 824         public long getColumnNumber() {
 825             return d.getColumnNumber();
 826         }
 827 
 828         @Override @DefinedBy(Api.COMPILER)
 829         public String getCode() {
 830             return d.getCode();
 831         }
 832 
 833         @Override @DefinedBy(Api.COMPILER)
 834         public String getMessage(Locale locale) {
 835             return d.getMessage(locale);
 836         }
 837 
 838         @Override
 839         public String toString() {
 840             return d.toString();
 841         }
 842     }
 843 
 844     protected class WrappedTaskListener implements TaskListener {
 845         protected TaskListener clientTaskListener;
 846         WrappedTaskListener(TaskListener clientTaskListener) {
 847             this.clientTaskListener = Objects.requireNonNull(clientTaskListener);
 848         }
 849 
 850         @Override @DefinedBy(Api.COMPILER_TREE)
 851         public void started(TaskEvent ev) {
 852             try {
 853                 clientTaskListener.started(ev);
 854             } catch (ClientCodeException e) {
 855                 throw e;
 856             } catch (RuntimeException | Error e) {
 857                 throw new ClientCodeException(e);
 858             }
 859         }
 860 
 861         @Override @DefinedBy(Api.COMPILER_TREE)
 862         public void finished(TaskEvent ev) {
 863             try {
 864                 clientTaskListener.finished(ev);
 865             } catch (ClientCodeException e) {
 866                 throw e;
 867             } catch (RuntimeException | Error e) {
 868                 throw new ClientCodeException(e);
 869             }
 870         }
 871 
 872         @Override
 873         public String toString() {
 874             return wrappedToString(getClass(), clientTaskListener);
 875         }
 876     }
 877 
 878     // </editor-fold>
 879 }