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.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 }