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