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 */
019package org.crsh.lang.impl.java;
020
021import org.crsh.util.Utils;
022import org.crsh.vfs.spi.url.Node;
023import org.crsh.vfs.spi.url.Resource;
024import org.crsh.vfs.spi.url.URLDriver;
025
026import javax.tools.JavaFileObject;
027import java.io.IOException;
028import java.net.URI;
029import java.net.URISyntaxException;
030import java.util.ArrayList;
031import java.util.Collections;
032import java.util.Iterator;
033import java.util.List;
034
035/** @author Julien Viet */
036class 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}