001    /*
002     * Copyright (C) 2012 eXo Platform SAS.
003     *
004     * This is free software; you can redistribute it and/or modify it
005     * under the terms of the GNU Lesser General Public License as
006     * published by the Free Software Foundation; either version 2.1 of
007     * the License, or (at your option) any later version.
008     *
009     * This software is distributed in the hope that it will be useful,
010     * but WITHOUT ANY WARRANTY; without even the implied warranty of
011     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012     * Lesser General Public License for more details.
013     *
014     * You should have received a copy of the GNU Lesser General Public
015     * License along with this software; if not, write to the Free
016     * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
017     * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
018     */
019    package org.crsh.lang.impl.java;
020    
021    import javax.tools.FileObject;
022    import javax.tools.ForwardingJavaFileManager;
023    import javax.tools.JavaFileObject;
024    import javax.tools.StandardJavaFileManager;
025    import javax.tools.StandardLocation;
026    import java.io.IOException;
027    import java.net.URISyntaxException;
028    import java.util.Collection;
029    import java.util.Collections;
030    import java.util.LinkedHashMap;
031    import java.util.Set;
032    
033    /** @author Julien Viet */
034    class JavaFileManagerImpl extends ForwardingJavaFileManager<StandardJavaFileManager> {
035    
036      /** . */
037      private final LinkedHashMap<String, JavaClassFileObject> classes = new LinkedHashMap<String, JavaClassFileObject>();
038    
039      /** . */
040      private final ClasspathResolver finder;
041    
042      JavaFileManagerImpl(StandardJavaFileManager fileManager, ClasspathResolver finder) {
043        super(fileManager);
044    
045        //
046        this.finder = finder;
047      }
048    
049      Collection<JavaClassFileObject> getClasses() {
050        return classes.values();
051      }
052    
053      @Override
054      public boolean hasLocation(Location location) {
055        return location == StandardLocation.CLASS_PATH || location == StandardLocation.PLATFORM_CLASS_PATH;
056      }
057    
058      @Override
059      public String inferBinaryName(Location location, JavaFileObject file) {
060        if (file instanceof NodeJavaFileObject) {
061          return ((NodeJavaFileObject)file).binaryName;
062        }
063        else {
064          return fileManager.inferBinaryName(location, file);
065        }
066      }
067    
068      @Override
069      public Iterable<JavaFileObject> list(Location location, String packageName, Set<JavaFileObject.Kind> kinds, boolean recurse) throws IOException {
070        if (location == StandardLocation.PLATFORM_CLASS_PATH) {
071          return fileManager.list(location, packageName, kinds, recurse);
072        }
073        else if (location == StandardLocation.CLASS_PATH && kinds.contains(JavaFileObject.Kind.CLASS)) {
074          if (packageName.startsWith("java")) {
075            return fileManager.list(location, packageName, kinds, recurse);
076          }
077          else {
078            try {
079              Iterable<JavaFileObject> ret = finder.resolve(packageName, recurse);
080              return ret;
081            }
082            catch (URISyntaxException e) {
083              throw new IOException(e);
084            }
085          }
086        } else {
087          return Collections.emptyList();
088        }
089      }
090    
091      @Override
092      public JavaFileObject getJavaFileForOutput(Location location, String className, JavaFileObject.Kind kind, FileObject sibling) throws IOException {
093    
094        if (location != StandardLocation.CLASS_OUTPUT) {
095          throw new IOException("Location " + location + " not supported");
096        }
097        if (kind != JavaFileObject.Kind.CLASS) {
098          throw new IOException("Kind " + kind + " not supported");
099        }
100    
101        //
102        JavaClassFileObject clazz = classes.get(className);
103        if (clazz == null) {
104          try {
105            classes.put(className, clazz = new JavaClassFileObject(className));
106          }
107          catch (URISyntaxException e) {
108            throw new IOException(e);
109          }
110        }
111        return clazz;
112      }
113    }