Coverage Report - com.sun.tools.javafx.script.MemoryFileManager
 
Classes in this File Line Coverage Branch Coverage Complexity
MemoryFileManager
75%
43/57
70%
21/30
0
MemoryFileManager$ClassOutputBuffer
86%
6/7
N/A
0
MemoryFileManager$ClassOutputBuffer$1
100%
5/5
N/A
0
MemoryFileManager$ClassResource
0%
0/7
N/A
0
MemoryFileManager$StringInputBuffer
65%
11/17
50%
1/2
0
 
 1  
 /*
 2  
  * Copyright 2007 Sun Microsystems, Inc.  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.  Sun designates this
 8  
  * particular file as subject to the "Classpath" exception as provided
 9  
  * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 22  
  * CA 95054 USA or visit www.sun.com if you need additional information or
 23  
  * have any questions.
 24  
  */
 25  
 
 26  
 package com.sun.tools.javafx.script;
 27  
 
 28  
 import com.sun.tools.javafx.util.JavafxFileManager;
 29  
 import java.io.*;
 30  
 import java.net.URI;
 31  
 import java.nio.CharBuffer;
 32  
 import java.util.Map;
 33  
 import java.util.*;
 34  
 import java.util.HashMap;
 35  
 import java.util.Set;
 36  
 import javax.lang.model.element.NestingKind;
 37  
 import javax.tools.*;
 38  
 import javax.tools.JavaFileObject.Kind;
 39  
 import java.net.URL;
 40  
 import java.net.URI;
 41  
 
 42  
 /**
 43  
  * JavaFileManager that keeps compiled .class bytes in memory.
 44  
  *
 45  
  * @author A. Sundararajan
 46  
  */
 47  40
 public final class MemoryFileManager extends ForwardingJavaFileManager {                 
 48  
     private ClassLoader parentClassLoader;
 49  37
     List<SimpleJavaFileObject> buffers = new ArrayList<SimpleJavaFileObject>();
 50  
 
 51  
     /** JavaFX Script source file extension. */
 52  
     private final static String EXT = ".fx";
 53  
 
 54  
     private Map<String, byte[]> classBytes;
 55  
     
 56  
     public MemoryFileManager(JavaFileManager fileManager, ClassLoader cl) {
 57  37
         super(fileManager);
 58  37
         classBytes = new HashMap<String, byte[]>();
 59  37
         parentClassLoader = cl;
 60  37
     }
 61  
 
 62  
     public Map<String, byte[]> getClassBytes() {
 63  18
         return classBytes;
 64  
     }
 65  
    
 66  
     @Override
 67  
     public void close() throws IOException {
 68  18
         classBytes = new HashMap<String, byte[]>();
 69  18
     }
 70  
 
 71  
     @Override
 72  
     public void flush() throws IOException {
 73  87
     }
 74  
 
 75  
     /**
 76  
      * A file object used to represent a Java class coming from the parent class loader
 77  
      */
 78  
     private static class ClassResource extends SimpleJavaFileObject {
 79  
         URL url;
 80  
         static URI toURI(URL u) {
 81  
             try {
 82  0
                 return u.toURI();
 83  0
             } catch (Exception e) {
 84  0
                 throw new RuntimeException(e);
 85  
             }
 86  
         }
 87  
         public ClassResource(URL u) {
 88  0
             super(toURI(u), Kind.CLASS);
 89  0
             this.url = u;
 90  0
         }
 91  
 
 92  
         @Override
 93  
         public InputStream openInputStream() throws IOException {
 94  0
             return url.openStream();
 95  
         }
 96  
     }
 97  
 
 98  
     /**
 99  
      * A file object used to represent Java source coming from a string.
 100  
      */
 101  49
     private static class StringInputBuffer extends SimpleJavaFileObject {
 102  
         final String code;
 103  
         final boolean isFXSourceFile;
 104  
         String binaryName;
 105  
         
 106  
         public String getBinaryName() {
 107  216
             return binaryName.equals("__FX_SCRIPT__.fx") ? "__FX_SCRIPT__" : binaryName;
 108  
         }
 109  
 
 110  
         StringInputBuffer(String name, String code) {
 111  37
             super(toURI(name), Kind.SOURCE);
 112  37
             this.code = code;
 113  37
             binaryName = name;
 114  37
             isFXSourceFile = name.endsWith(JavafxFileManager.FX_SOURCE_SUFFIX);
 115  37
         }
 116  
         
 117  
         @Override
 118  
         public CharBuffer getCharContent(boolean ignoreEncodingErrors) {
 119  49
             return CharBuffer.wrap(code);
 120  
         }
 121  
 
 122  
         public Reader openReader() {
 123  0
             return new StringReader(code);
 124  
         }
 125  
 
 126  
         @Override
 127  
         public Kind getKind() {
 128  
             //return isFXSourceFile ? JavaFileObject.Kind.SOURCE : super.getKind();
 129  300
             return JavaFileObject.Kind.SOURCE;
 130  
         }
 131  
 
 132  
         @Override
 133  
         public String getName() {
 134  714
             return super.getName();
 135  
         }
 136  
 
 137  
         @Override
 138  
         public NestingKind getNestingKind() {
 139  0
             return super.getNestingKind();
 140  
         }
 141  
 
 142  
         @Override
 143  
         public boolean isNameCompatible(String simpleName, Kind kind) {
 144  47
             return super.isNameCompatible(simpleName, kind);
 145  
         }
 146  
 
 147  
         @Override
 148  
         public InputStream openInputStream() throws IOException {
 149  0
             return super.openInputStream();
 150  
         }
 151  
 
 152  
         @Override
 153  
         public OutputStream openOutputStream() throws IOException {
 154  0
             return super.openOutputStream();
 155  
         }
 156  
 
 157  
         @Override
 158  
         public Reader openReader(boolean ignoreEncodingErrors) throws IOException {
 159  0
             return super.openReader(ignoreEncodingErrors);
 160  
         }
 161  
 
 162  
         @Override
 163  
         public Writer openWriter() throws IOException {
 164  0
             return super.openWriter();
 165  
         }
 166  
     }
 167  
 
 168  
     /**
 169  
      * A file object that stores Java bytecode into the classBytes map.
 170  
      */
 171  40
     private class ClassOutputBuffer extends SimpleJavaFileObject {
 172  
         private String name;
 173  
 
 174  40
         ClassOutputBuffer(String name) { 
 175  40
             super(toURI(name), Kind.CLASS);
 176  40
             this.name = name;
 177  40
         }
 178  
 
 179  
         public String getBinaryName() {
 180  0
             return name;
 181  
         }
 182  
 
 183  
         @Override
 184  
         public OutputStream openOutputStream() {
 185  40
             return new FilterOutputStream(new ByteArrayOutputStream()) {
 186  
                 @Override
 187  
                 public void close() throws IOException {
 188  40
                     out.close();
 189  40
                     ByteArrayOutputStream bos = (ByteArrayOutputStream)out;
 190  40
                     classBytes.put(name, bos.toByteArray());
 191  40
                 }
 192  
             };
 193  
         }
 194  
     }
 195  
     @Override
 196  
     public FileObject getFileForInput(Location location,
 197  
                                       String packageName,
 198  
                                       String relativeName) throws IOException {
 199  
         
 200  0
         return super.getFileForInput(location, packageName, relativeName);
 201  
     }
 202  
 
 203  
     @Override
 204  
     public FileObject getFileForOutput(Location location,
 205  
                                        String packageName,
 206  
                                        String relativeName,
 207  
                                        FileObject sibling) throws IOException {
 208  
         
 209  0
         return super.getFileForOutput(location, packageName, relativeName, sibling);
 210  
     }
 211  
     
 212  
     @Override
 213  
     public JavaFileObject getJavaFileForInput(JavaFileManager.Location location,
 214  
                                               String className,
 215  
                                               Kind kind) throws IOException {
 216  0
         if (kind == Kind.CLASS) {
 217  0
             URL res = 
 218  
                 parentClassLoader.getResource(className.replace('.', '/') + ".class");
 219  0
             if (res != null) {
 220  0
                 return new ClassResource(res);
 221  
             }
 222  
         }
 223  0
         return super.getJavaFileForInput(location, className, kind);
 224  
     }
 225  
 
 226  
     @Override
 227  
     public JavaFileObject getJavaFileForOutput(JavaFileManager.Location location,
 228  
                                     String className,
 229  
                                     Kind kind,
 230  
                                     FileObject sibling) throws IOException {
 231  40
         if (kind == Kind.CLASS) {
 232  40
             ClassOutputBuffer buf = new ClassOutputBuffer(className);
 233  40
             buffers.add(buf);
 234  40
             return buf;
 235  
         } else {
 236  0
             return super.getJavaFileForOutput(location, className, kind, sibling);
 237  
         }
 238  
     }
 239  
     @Override
 240  
     public Iterable list(JavaFileManager.Location location,
 241  
                          String packageName,
 242  
                          Set kinds,
 243  
                          boolean recurse)
 244  
         throws IOException
 245  
     {
 246  696
         Iterable result = super.list(location, packageName, kinds, recurse);
 247  696
         List results = new LinkedList();
 248  696
         for (Object o : result) {
 249  35448
             results.add(o);
 250  
         }
 251  696
         String prefix = packageName.equals("") ? "" : packageName + ".";
 252  696
         for (SimpleJavaFileObject b : buffers) {
 253  712
             String name = b.getName().replace("/", ".");
 254  712
             name = name.substring(1, name.length() - (name.endsWith(EXT) ? EXT.length() : 0));
 255  712
             if (prefix.length() == 0) {
 256  112
                 if (!name.contains(".")) {
 257  108
                     results.add(b);
 258  
                 }
 259  
             } else {
 260  600
                 if (name.startsWith(prefix)) {
 261  0
                     name = name.substring(prefix.length());
 262  0
                     if (!name.contains(".")) {
 263  0
                         results.add(b);
 264  
                     }
 265  
                 }
 266  
             }
 267  712
         }
 268  696
         return results;
 269  
     }
 270  
     
 271  
     JavaFileObject makeStringSource(String name, String code) {
 272  37
         StringInputBuffer buffer = new StringInputBuffer(name, code);
 273  37
         buffers.add(buffer);
 274  37
         return buffer;
 275  
     }
 276  
 
 277  
     @Override
 278  
     public String inferBinaryName(Location location, JavaFileObject file) {
 279  71112
         if (file instanceof StringInputBuffer) {
 280  216
             return ((StringInputBuffer)file).getBinaryName();
 281  70896
         } else if (file instanceof ClassOutputBuffer) {
 282  0
             return ((ClassOutputBuffer)file).getBinaryName();
 283  
         }
 284  70896
         return super.inferBinaryName(location, file);
 285  
     }
 286  
 
 287  
     static URI toURI(String name) {
 288  77
         File file = new File(name);
 289  77
         if (file.exists()) {
 290  1
             return file.toURI();
 291  
         } else {
 292  
             try {
 293  76
                 final StringBuilder newUri = new StringBuilder();
 294  76
                 newUri.append("mfm:///");
 295  76
                 newUri.append(name.replace('.', '/'));
 296  76
                 if(name.endsWith(EXT)) newUri.replace(newUri.length() - EXT.length(), newUri.length(), EXT);
 297  76
                 return URI.create(newUri.toString());
 298  0
             } catch (Exception exp) {
 299  0
                 return URI.create("mfm:///com/sun/tools/javafx/script/javafx_source");
 300  
             }
 301  
         }
 302  
     }
 303  
 }