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 org.crsh.util.Utils;
022    import org.crsh.vfs.spi.url.Node;
023    import org.crsh.vfs.spi.url.Resource;
024    import org.crsh.vfs.spi.url.URLDriver;
025    
026    import javax.tools.JavaFileObject;
027    import java.io.IOException;
028    import java.net.URI;
029    import java.net.URISyntaxException;
030    import java.util.ArrayList;
031    import java.util.Collections;
032    import java.util.Iterator;
033    import java.util.List;
034    
035    /** @author Julien Viet */
036    class ClasspathResolver {
037    
038      /** . */
039      final ClassLoader loader;
040    
041      /** . */
042      final URLDriver driver;
043    
044      public ClasspathResolver(ClassLoader loader) {
045    
046        URLDriver driver = null;
047        try {
048          driver = new URLDriver();
049          driver.merge(loader);
050        }
051        catch (Exception e) {
052          e.printStackTrace();
053        }
054    
055        //
056        this.loader = loader;
057        this.driver = driver;
058      }
059    
060      private void resolve(List<JavaFileObject> files, Node node, String binaryName, boolean recurse) throws IOException, URISyntaxException {
061        for (Node child : driver.children(node)) {
062          Iterator<Resource> i = child.iterator();
063          if (i.hasNext()) {
064            if (child.name.endsWith(".class")) {
065              Resource r = i.next();
066              URI uri = r.url.toURI();
067              files.add(new NodeJavaFileObject(
068                  binaryName + "." + child.name.substring(0, child.name.length() - ".class".length()),
069                  uri,
070                  r.streamFactory,
071                  r.lastModified));
072            }
073          } else {
074            if (recurse) {
075              resolve(files, child, binaryName + "." + child.name, recurse);
076            }
077          }
078        }
079      }
080    
081      public Iterable<JavaFileObject> resolve(String pkg, boolean recurse) throws IOException, URISyntaxException {
082    
083        Node current = driver.root();
084    
085        String[] elts = Utils.split(pkg, '.');
086    
087        for (String elt : elts) {
088          current = driver.child(current, elt);
089          if (current == null) {
090            return Collections.emptyList();
091          }
092        }
093    
094        //
095        List<JavaFileObject> files = new ArrayList<JavaFileObject>();
096        resolve(files, current, pkg, recurse);
097        return files;
098    
099    
100    
101    /*
102        String pkgName = pkg.replace('.', '/');
103        ArrayList<JavaFileObject> ret = new ArrayList<JavaFileObject>();
104        final Enumeration<URL> en = loader.getResources(pkgName);
105        while (en.hasMoreElements()) {
106          URL url = en.nextElement();
107          String protocol = url.getProtocol();
108          if (protocol.equals("file")) {
109            File root = new File(url.toURI());
110            resolve(pkgName, ret, root, recurse);
111          } else if ("jar".equals(protocol)) {
112            String path = url.getPath();
113            int index = path.lastIndexOf('!');
114            String containerURLs = path.substring(0, index);
115            URL containerURL = new URL(containerURLs);
116            ZipIterator i = ZipIterator.create(containerURL);
117            while (i.hasNext()) {
118              ZipEntry entry = i.next();
119              String name = entry.getName();
120              if (!entry.isDirectory() && name.startsWith(pkgName) && (name.indexOf('/', pkgName.length() + 1) == -1 || recurse)) {
121                String binaryName = name.substring(0, name.length() - ".class".length()).replace('/', '.');
122                URI entryURI = new URI("jar:" + containerURLs + "!/" + name);
123                ret.add(new URIJavaFileObject(binaryName, entryURI, i.getStreamFactory(), entry.getTime()));
124              }
125            }
126          } else {
127            throw new UnsupportedOperationException("Protocol for url " + url + " not supported");
128          }
129        }
130        return ret;
131    */
132      }
133    
134    /*
135      private void resolve(String pkgName, ArrayList<JavaFileObject> ret, File file, boolean recurse) {
136        final File[] children = file.listFiles();
137        if (children != null) {
138          Arrays.sort(children);
139          for (final File child : children) {
140            if (child.isDirectory()) {
141              if (recurse) {
142                resolve(pkgName, ret, child, recurse);
143              }
144            } else {
145              String childName = child.getName();
146              if (childName.endsWith(".class")) {
147                String binaryName = pkgName + "." + childName.substring(0, childName.length() - ".class".length());
148                InputStreamFactory streamFactory = new InputStreamFactory() {
149                  @Override
150                  public InputStream open() throws IOException {
151                    return new FileInputStream(child);
152                  }
153                };
154                ret.add(new URIJavaFileObject(binaryName, child.toURI(), streamFactory, child.lastModified()));
155              }
156            }
157          }
158        }
159      }
160    */
161    }