Home » openjdk-7 » com.sun.tools » javac » api » [javadoc | source]

    1   /*
    2    * Copyright (c) 2011, 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   
   27   package com.sun.tools.javac.api;
   28   
   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.net.URI;
   35   import java.util.ArrayList;
   36   import java.util.Collections;
   37   import java.util.HashMap;
   38   import java.util.Iterator;
   39   import java.util.List;
   40   import java.util.Map;
   41   import java.util.Set;
   42   
   43   import javax.lang.model.element.NestingKind;
   44   import javax.tools.Diagnostic;
   45   import javax.tools.FileObject;
   46   import javax.tools.JavaFileManager;
   47   import javax.tools.JavaFileManager.Location;
   48   import javax.tools.JavaFileObject;
   49   
   50   import com.sun.source.util.TaskEvent;
   51   import com.sun.source.util.TaskListener;
   52   import com.sun.tools.javac.util.ClientCodeException;
   53   import com.sun.tools.javac.util.Context;
   54   import java.lang.annotation.ElementType;
   55   import java.lang.annotation.Retention;
   56   import java.lang.annotation.RetentionPolicy;
   57   import java.lang.annotation.Target;
   58   import javax.lang.model.element.Modifier;
   59   import javax.tools.DiagnosticListener;
   60   import javax.tools.JavaFileObject.Kind;
   61   
   62   /**
   63    *  Wrap objects to enable unchecked exceptions to be caught and handled.
   64    *
   65    *  For each method, exceptions are handled as follows:
   66    *  <ul>
   67    *  <li>Checked exceptions are left alone and propogate upwards in the
   68    *      obvious way, since they are an expected aspect of the method's
   69    *      specification.
   70    *  <li>Unchecked exceptions which have already been caught and wrapped in
   71    *      ClientCodeException are left alone to continue propogating upwards.
   72    *  <li>All other unchecked exceptions (i.e. subtypes of RuntimeException
   73    *      and Error) and caught, and rethrown as a ClientCodeException with
   74    *      its cause set to the original exception.
   75    *  </ul>
   76    *
   77    *  The intent is that ClientCodeException can be caught at an appropriate point
   78    *  in the program and can be distinguished from any unanticipated unchecked
   79    *  exceptions arising in the main body of the code (i.e. bugs.) When the
   80    *  ClientCodeException has been caught, either a suitable message can be
   81    *  generated, or if appropriate, the original cause can be rethrown.
   82    *
   83    *  <p><b>This is NOT part of any supported API.
   84    *  If you write code that depends on this, you do so at your own risk.
   85    *  This code and its internal interfaces are subject to change or
   86    *  deletion without notice.</b>
   87    */
   88   public class ClientCodeWrapper {
   89       @Retention(RetentionPolicy.RUNTIME)
   90       @Target(ElementType.TYPE)
   91       public @interface Trusted { }
   92   
   93       public static ClientCodeWrapper instance(Context context) {
   94           ClientCodeWrapper instance = context.get(ClientCodeWrapper.class);
   95           if (instance == null)
   96               instance = new ClientCodeWrapper(context);
   97           return instance;
   98       }
   99   
  100       /**
  101        * A map to cache the results of whether or not a specific classes can
  102        * be "trusted", and thus does not need to be wrapped.
  103        */
  104       Map<Class<?>, Boolean> trustedClasses;
  105   
  106       protected ClientCodeWrapper(Context context) {
  107           trustedClasses = new HashMap<Class<?>, Boolean>();
  108       }
  109   
  110       public JavaFileManager wrap(JavaFileManager fm) {
  111           if (isTrusted(fm))
  112               return fm;
  113           return new WrappedJavaFileManager(fm);
  114       }
  115   
  116       public FileObject wrap(FileObject fo) {
  117           if (isTrusted(fo))
  118               return fo;
  119           return new WrappedFileObject(fo);
  120       }
  121   
  122       FileObject unwrap(FileObject fo) {
  123           if (fo instanceof WrappedFileObject)
  124               return ((WrappedFileObject) fo).clientFileObject;
  125           else
  126               return fo;
  127       }
  128   
  129       public JavaFileObject wrap(JavaFileObject fo) {
  130           if (isTrusted(fo))
  131               return fo;
  132           return new WrappedJavaFileObject(fo);
  133       }
  134   
  135       public Iterable<JavaFileObject> wrapJavaFileObjects(Iterable<? extends JavaFileObject> list) {
  136           List<JavaFileObject> wrapped = new ArrayList<JavaFileObject>();
  137           for (JavaFileObject fo : list)
  138               wrapped.add(wrap(fo));
  139           return Collections.unmodifiableList(wrapped);
  140       }
  141   
  142       JavaFileObject unwrap(JavaFileObject fo) {
  143           if (fo instanceof WrappedJavaFileObject)
  144               return ((JavaFileObject) ((WrappedJavaFileObject) fo).clientFileObject);
  145           else
  146               return fo;
  147       }
  148   
  149       <T> DiagnosticListener<T> wrap(DiagnosticListener<T> dl) {
  150           if (isTrusted(dl))
  151               return dl;
  152           return new WrappedDiagnosticListener<T>(dl);
  153       }
  154   
  155       TaskListener wrap(TaskListener tl) {
  156           if (isTrusted(tl))
  157               return tl;
  158           return new WrappedTaskListener(tl);
  159       }
  160   
  161       protected boolean isTrusted(Object o) {
  162           Class<?> c = o.getClass();
  163           Boolean trusted = trustedClasses.get(c);
  164           if (trusted == null) {
  165               trusted = c.getName().startsWith("com.sun.tools.javac.")
  166                       || c.isAnnotationPresent(Trusted.class);
  167               trustedClasses.put(c, trusted);
  168           }
  169           return trusted;
  170       }
  171   
  172       // <editor-fold defaultstate="collapsed" desc="Wrapper classes">
  173   
  174       // FIXME: all these classes should be converted to use multi-catch when
  175       // that is available in the bootstrap compiler.
  176   
  177       protected class WrappedJavaFileManager implements JavaFileManager {
  178           protected JavaFileManager clientJavaFileManager;
  179           WrappedJavaFileManager(JavaFileManager clientJavaFileManager) {
  180               clientJavaFileManager.getClass(); // null check
  181               this.clientJavaFileManager = clientJavaFileManager;
  182           }
  183   
  184           @Override
  185           public ClassLoader getClassLoader(Location location) {
  186               try {
  187                   return clientJavaFileManager.getClassLoader(location);
  188               } catch (ClientCodeException e) {
  189                   throw e;
  190               } catch (RuntimeException e) {
  191                   throw new ClientCodeException(e);
  192               } catch (Error e) {
  193                   throw new ClientCodeException(e);
  194               }
  195           }
  196   
  197           @Override
  198           public Iterable<JavaFileObject> list(Location location, String packageName, Set<Kind> kinds, boolean recurse) throws IOException {
  199               try {
  200                   return wrapJavaFileObjects(clientJavaFileManager.list(location, packageName, kinds, recurse));
  201               } catch (ClientCodeException e) {
  202                   throw e;
  203               } catch (RuntimeException e) {
  204                   throw new ClientCodeException(e);
  205               } catch (Error e) {
  206                   throw new ClientCodeException(e);
  207               }
  208           }
  209   
  210           @Override
  211           public String inferBinaryName(Location location, JavaFileObject file) {
  212               try {
  213                   return clientJavaFileManager.inferBinaryName(location, unwrap(file));
  214               } catch (ClientCodeException e) {
  215                   throw e;
  216               } catch (RuntimeException e) {
  217                   throw new ClientCodeException(e);
  218               } catch (Error e) {
  219                   throw new ClientCodeException(e);
  220               }
  221           }
  222   
  223           @Override
  224           public boolean isSameFile(FileObject a, FileObject b) {
  225               try {
  226                   return clientJavaFileManager.isSameFile(unwrap(a), unwrap(b));
  227               } catch (ClientCodeException e) {
  228                   throw e;
  229               } catch (RuntimeException e) {
  230                   throw new ClientCodeException(e);
  231               } catch (Error e) {
  232                   throw new ClientCodeException(e);
  233               }
  234           }
  235   
  236           @Override
  237           public boolean handleOption(String current, Iterator<String> remaining) {
  238               try {
  239                   return clientJavaFileManager.handleOption(current, remaining);
  240               } catch (ClientCodeException e) {
  241                   throw e;
  242               } catch (RuntimeException e) {
  243                   throw new ClientCodeException(e);
  244               } catch (Error e) {
  245                   throw new ClientCodeException(e);
  246               }
  247           }
  248   
  249           @Override
  250           public boolean hasLocation(Location location) {
  251               try {
  252                   return clientJavaFileManager.hasLocation(location);
  253               } catch (ClientCodeException e) {
  254                   throw e;
  255               } catch (RuntimeException e) {
  256                   throw new ClientCodeException(e);
  257               } catch (Error e) {
  258                   throw new ClientCodeException(e);
  259               }
  260           }
  261   
  262           @Override
  263           public JavaFileObject getJavaFileForInput(Location location, String className, Kind kind) throws IOException {
  264               try {
  265                   return wrap(clientJavaFileManager.getJavaFileForInput(location, className, kind));
  266               } catch (ClientCodeException e) {
  267                   throw e;
  268               } catch (RuntimeException e) {
  269                   throw new ClientCodeException(e);
  270               } catch (Error e) {
  271                   throw new ClientCodeException(e);
  272               }
  273           }
  274   
  275           @Override
  276           public JavaFileObject getJavaFileForOutput(Location location, String className, Kind kind, FileObject sibling) throws IOException {
  277               try {
  278                   return wrap(clientJavaFileManager.getJavaFileForOutput(location, className, kind, unwrap(sibling)));
  279               } catch (ClientCodeException e) {
  280                   throw e;
  281               } catch (RuntimeException e) {
  282                   throw new ClientCodeException(e);
  283               } catch (Error e) {
  284                   throw new ClientCodeException(e);
  285               }
  286           }
  287   
  288           @Override
  289           public FileObject getFileForInput(Location location, String packageName, String relativeName) throws IOException {
  290               try {
  291                   return wrap(clientJavaFileManager.getFileForInput(location, packageName, relativeName));
  292               } catch (ClientCodeException e) {
  293                   throw e;
  294               } catch (RuntimeException e) {
  295                   throw new ClientCodeException(e);
  296               } catch (Error e) {
  297                   throw new ClientCodeException(e);
  298               }
  299           }
  300   
  301           @Override
  302           public FileObject getFileForOutput(Location location, String packageName, String relativeName, FileObject sibling) throws IOException {
  303               try {
  304                   return wrap(clientJavaFileManager.getFileForOutput(location, packageName, relativeName, unwrap(sibling)));
  305               } catch (ClientCodeException e) {
  306                   throw e;
  307               } catch (RuntimeException e) {
  308                   throw new ClientCodeException(e);
  309               } catch (Error e) {
  310                   throw new ClientCodeException(e);
  311               }
  312           }
  313   
  314           @Override
  315           public void flush() throws IOException {
  316               try {
  317                   clientJavaFileManager.flush();
  318               } catch (ClientCodeException e) {
  319                   throw e;
  320               } catch (RuntimeException e) {
  321                   throw new ClientCodeException(e);
  322               } catch (Error e) {
  323                   throw new ClientCodeException(e);
  324               }
  325           }
  326   
  327           @Override
  328           public void close() throws IOException {
  329               try {
  330                   clientJavaFileManager.close();
  331               } catch (ClientCodeException e) {
  332                   throw e;
  333               } catch (RuntimeException e) {
  334                   throw new ClientCodeException(e);
  335               } catch (Error e) {
  336                   throw new ClientCodeException(e);
  337               }
  338           }
  339   
  340           @Override
  341           public int isSupportedOption(String option) {
  342               try {
  343                   return clientJavaFileManager.isSupportedOption(option);
  344               } catch (ClientCodeException e) {
  345                   throw e;
  346               } catch (RuntimeException e) {
  347                   throw new ClientCodeException(e);
  348               } catch (Error e) {
  349                   throw new ClientCodeException(e);
  350               }
  351           }
  352       }
  353   
  354       protected class WrappedFileObject implements FileObject {
  355           protected FileObject clientFileObject;
  356           WrappedFileObject(FileObject clientFileObject) {
  357               clientFileObject.getClass(); // null check
  358               this.clientFileObject = clientFileObject;
  359           }
  360   
  361           @Override
  362           public URI toUri() {
  363               try {
  364                   return clientFileObject.toUri();
  365               } catch (ClientCodeException e) {
  366                   throw e;
  367               } catch (RuntimeException e) {
  368                   throw new ClientCodeException(e);
  369               } catch (Error e) {
  370                   throw new ClientCodeException(e);
  371               }
  372           }
  373   
  374           @Override
  375           public String getName() {
  376               try {
  377                   return clientFileObject.getName();
  378               } catch (ClientCodeException e) {
  379                   throw e;
  380               } catch (RuntimeException e) {
  381                   throw new ClientCodeException(e);
  382               } catch (Error e) {
  383                   throw new ClientCodeException(e);
  384               }
  385           }
  386   
  387           @Override
  388           public InputStream openInputStream() throws IOException {
  389               try {
  390                   return clientFileObject.openInputStream();
  391               } catch (ClientCodeException e) {
  392                   throw e;
  393               } catch (RuntimeException e) {
  394                   throw new ClientCodeException(e);
  395               } catch (Error e) {
  396                   throw new ClientCodeException(e);
  397               }
  398           }
  399   
  400           @Override
  401           public OutputStream openOutputStream() throws IOException {
  402               try {
  403                   return clientFileObject.openOutputStream();
  404               } catch (ClientCodeException e) {
  405                   throw e;
  406               } catch (RuntimeException e) {
  407                   throw new ClientCodeException(e);
  408               } catch (Error e) {
  409                   throw new ClientCodeException(e);
  410               }
  411           }
  412   
  413           @Override
  414           public Reader openReader(boolean ignoreEncodingErrors) throws IOException {
  415               try {
  416                   return clientFileObject.openReader(ignoreEncodingErrors);
  417               } catch (ClientCodeException e) {
  418                   throw e;
  419               } catch (RuntimeException e) {
  420                   throw new ClientCodeException(e);
  421               } catch (Error e) {
  422                   throw new ClientCodeException(e);
  423               }
  424           }
  425   
  426           @Override
  427           public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
  428               try {
  429                   return clientFileObject.getCharContent(ignoreEncodingErrors);
  430               } catch (ClientCodeException e) {
  431                   throw e;
  432               } catch (RuntimeException e) {
  433                   throw new ClientCodeException(e);
  434               } catch (Error e) {
  435                   throw new ClientCodeException(e);
  436               }
  437           }
  438   
  439           @Override
  440           public Writer openWriter() throws IOException {
  441               try {
  442                   return clientFileObject.openWriter();
  443               } catch (ClientCodeException e) {
  444                   throw e;
  445               } catch (RuntimeException e) {
  446                   throw new ClientCodeException(e);
  447               } catch (Error e) {
  448                   throw new ClientCodeException(e);
  449               }
  450           }
  451   
  452           @Override
  453           public long getLastModified() {
  454               try {
  455                   return clientFileObject.getLastModified();
  456               } catch (ClientCodeException e) {
  457                   throw e;
  458               } catch (RuntimeException e) {
  459                   throw new ClientCodeException(e);
  460               } catch (Error e) {
  461                   throw new ClientCodeException(e);
  462               }
  463           }
  464   
  465           @Override
  466           public boolean delete() {
  467               try {
  468                   return clientFileObject.delete();
  469               } catch (ClientCodeException e) {
  470                   throw e;
  471               } catch (RuntimeException e) {
  472                   throw new ClientCodeException(e);
  473               } catch (Error e) {
  474                   throw new ClientCodeException(e);
  475               }
  476           }
  477       }
  478   
  479       protected class WrappedJavaFileObject extends WrappedFileObject implements JavaFileObject {
  480           WrappedJavaFileObject(JavaFileObject clientJavaFileObject) {
  481               super(clientJavaFileObject);
  482           }
  483   
  484           @Override
  485           public Kind getKind() {
  486               try {
  487                   return ((JavaFileObject)clientFileObject).getKind();
  488               } catch (ClientCodeException e) {
  489                   throw e;
  490               } catch (RuntimeException e) {
  491                   throw new ClientCodeException(e);
  492               } catch (Error e) {
  493                   throw new ClientCodeException(e);
  494               }
  495           }
  496   
  497           @Override
  498           public boolean isNameCompatible(String simpleName, Kind kind) {
  499               try {
  500                   return ((JavaFileObject)clientFileObject).isNameCompatible(simpleName, kind);
  501               } catch (ClientCodeException e) {
  502                   throw e;
  503               } catch (RuntimeException e) {
  504                   throw new ClientCodeException(e);
  505               } catch (Error e) {
  506                   throw new ClientCodeException(e);
  507               }
  508           }
  509   
  510           @Override
  511           public NestingKind getNestingKind() {
  512               try {
  513                   return ((JavaFileObject)clientFileObject).getNestingKind();
  514               } catch (ClientCodeException e) {
  515                   throw e;
  516               } catch (RuntimeException e) {
  517                   throw new ClientCodeException(e);
  518               } catch (Error e) {
  519                   throw new ClientCodeException(e);
  520               }
  521           }
  522   
  523           @Override
  524           public Modifier getAccessLevel() {
  525               try {
  526                   return ((JavaFileObject)clientFileObject).getAccessLevel();
  527               } catch (ClientCodeException e) {
  528                   throw e;
  529               } catch (RuntimeException e) {
  530                   throw new ClientCodeException(e);
  531               } catch (Error e) {
  532                   throw new ClientCodeException(e);
  533               }
  534           }
  535       }
  536   
  537       protected class WrappedDiagnosticListener<T> implements DiagnosticListener<T> {
  538           protected DiagnosticListener<T> clientDiagnosticListener;
  539           WrappedDiagnosticListener(DiagnosticListener<T> clientDiagnosticListener) {
  540               clientDiagnosticListener.getClass(); // null check
  541               this.clientDiagnosticListener = clientDiagnosticListener;
  542           }
  543   
  544           @Override
  545           public void report(Diagnostic<? extends T> diagnostic) {
  546               try {
  547                   clientDiagnosticListener.report(diagnostic);
  548               } catch (ClientCodeException e) {
  549                   throw e;
  550               } catch (RuntimeException e) {
  551                   throw new ClientCodeException(e);
  552               } catch (Error e) {
  553                   throw new ClientCodeException(e);
  554               }
  555           }
  556       }
  557   
  558       protected class WrappedTaskListener implements TaskListener {
  559           protected TaskListener clientTaskListener;
  560           WrappedTaskListener(TaskListener clientTaskListener) {
  561               clientTaskListener.getClass(); // null check
  562               this.clientTaskListener = clientTaskListener;
  563           }
  564   
  565           @Override
  566           public void started(TaskEvent ev) {
  567               try {
  568                   clientTaskListener.started(ev);
  569               } catch (ClientCodeException e) {
  570                   throw e;
  571               } catch (RuntimeException e) {
  572                   throw new ClientCodeException(e);
  573               } catch (Error e) {
  574                   throw new ClientCodeException(e);
  575               }
  576           }
  577   
  578           @Override
  579           public void finished(TaskEvent ev) {
  580               try {
  581                   clientTaskListener.finished(ev);
  582               } catch (ClientCodeException e) {
  583                   throw e;
  584               } catch (RuntimeException e) {
  585                   throw new ClientCodeException(e);
  586               } catch (Error e) {
  587                   throw new ClientCodeException(e);
  588               }
  589           }
  590       }
  591   
  592       // </editor-fold>
  593   }

Home » openjdk-7 » com.sun.tools » javac » api » [javadoc | source]