mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
InstrumentationClassFinder to depend only on jdk classes
This commit is contained in:
@@ -1,365 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jps.incremental.java;
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import sun.misc.Resource;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.util.*;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
class ClassFinderClasspath {
|
||||
private static final String FILE_PROTOCOL = "file";
|
||||
|
||||
private final Stack<URL> myUrls = new Stack<URL>();
|
||||
private final List<Loader> myLoaders = new ArrayList<Loader>();
|
||||
private final Map<URL,Loader> myLoadersMap = new HashMap<URL, Loader>();
|
||||
|
||||
public ClassFinderClasspath(URL[] urls) {
|
||||
push(urls);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Resource getResource(String s, boolean flag) {
|
||||
int i = 0;
|
||||
for (Loader loader; (loader = getLoader(i)) != null; i++) {
|
||||
Resource resource = loader.getResource(s, flag);
|
||||
if (resource != null) {
|
||||
return resource;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void releaseResources() {
|
||||
for (Loader loader : myLoaders) {
|
||||
loader.releaseResources();
|
||||
}
|
||||
myLoaders.clear();
|
||||
myLoadersMap.clear();
|
||||
myUrls.clear();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private synchronized Loader getLoader(int i) {
|
||||
while (myLoaders.size() < i + 1) {
|
||||
URL url;
|
||||
synchronized (myUrls) {
|
||||
if (myUrls.empty()) {
|
||||
return null;
|
||||
}
|
||||
url = myUrls.pop();
|
||||
}
|
||||
|
||||
if (myLoadersMap.containsKey(url)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Loader loader;
|
||||
try {
|
||||
loader = getLoader(url, myLoaders.size());
|
||||
if (loader == null) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
catch (IOException ioexception) {
|
||||
continue;
|
||||
}
|
||||
|
||||
myLoaders.add(loader);
|
||||
myLoadersMap.put(url, loader);
|
||||
}
|
||||
|
||||
return myLoaders.get(i);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Loader getLoader(final URL url, int index) throws IOException {
|
||||
String s;
|
||||
try {
|
||||
s = url.toURI().getSchemeSpecificPart();
|
||||
}
|
||||
catch (URISyntaxException thisShouldNotHappen) {
|
||||
thisShouldNotHappen.printStackTrace();
|
||||
s = url.getFile();
|
||||
}
|
||||
|
||||
Loader loader = null;
|
||||
if (s != null && new File(s).isDirectory()) {
|
||||
if (FILE_PROTOCOL.equals(url.getProtocol())) {
|
||||
loader = new FileLoader(url, index);
|
||||
}
|
||||
}
|
||||
else {
|
||||
loader = new JarLoader(url, index);
|
||||
}
|
||||
|
||||
return loader;
|
||||
}
|
||||
|
||||
private void push(URL[] urls) {
|
||||
if (urls.length == 0) return;
|
||||
synchronized (myUrls) {
|
||||
for (int i = urls.length - 1; i >= 0; i--) {
|
||||
myUrls.push(urls[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private abstract static class Loader {
|
||||
protected static final String JAR_PROTOCOL = "jar";
|
||||
protected static final String FILE_PROTOCOL = "file";
|
||||
|
||||
private final URL myURL;
|
||||
private final int myIndex;
|
||||
|
||||
protected Loader(URL url, int index) {
|
||||
myURL = url;
|
||||
myIndex = index;
|
||||
}
|
||||
|
||||
|
||||
protected URL getBaseURL() {
|
||||
return myURL;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public abstract Resource getResource(final String name, boolean flag);
|
||||
|
||||
public abstract void releaseResources();
|
||||
|
||||
public int getIndex() {
|
||||
return myIndex;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class FileLoader extends Loader {
|
||||
private final File myRootDir;
|
||||
|
||||
@SuppressWarnings({"HardCodedStringLiteral"})
|
||||
FileLoader(URL url, int index) throws IOException {
|
||||
super(url, index);
|
||||
if (!FILE_PROTOCOL.equals(url.getProtocol())) {
|
||||
throw new IllegalArgumentException("url");
|
||||
}
|
||||
else {
|
||||
final String s = FileUtil.unquote(url.getFile());
|
||||
myRootDir = new File(s);
|
||||
}
|
||||
}
|
||||
|
||||
public void releaseResources() {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Resource getResource(final String name, boolean check) {
|
||||
URL url = null;
|
||||
File file = null;
|
||||
|
||||
try {
|
||||
url = new URL(getBaseURL(), name);
|
||||
if (!url.getFile().startsWith(getBaseURL().getFile())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
file = new File(myRootDir, name.replace('/', File.separatorChar));
|
||||
if (!check || file.exists()) { // check means we load or process resource so we check its existence via old way
|
||||
return new FileResource(name, url, file, !check);
|
||||
}
|
||||
}
|
||||
catch (Exception exception) {
|
||||
if (!check && file != null && file.exists()) {
|
||||
try { // we can not open the file if it is directory, Resource still can be created
|
||||
return new FileResource(name, url, file, false);
|
||||
}
|
||||
catch (IOException ex) {}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private class FileResource extends Resource {
|
||||
private final String myName;
|
||||
private final URL myUrl;
|
||||
private final File myFile;
|
||||
|
||||
public FileResource(String name, URL url, File file, boolean willLoadBytes) throws IOException {
|
||||
myName = name;
|
||||
myUrl = url;
|
||||
myFile = file;
|
||||
if (willLoadBytes) getByteBuffer(); // check for existence by creating cached file input stream
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return myName;
|
||||
}
|
||||
|
||||
public URL getURL() {
|
||||
return myUrl;
|
||||
}
|
||||
|
||||
public URL getCodeSourceURL() {
|
||||
return getBaseURL();
|
||||
}
|
||||
|
||||
public InputStream getInputStream() throws IOException {
|
||||
return new BufferedInputStream(new FileInputStream(myFile));
|
||||
}
|
||||
|
||||
public int getContentLength() throws IOException {
|
||||
return -1;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return myFile.getAbsolutePath();
|
||||
}
|
||||
}
|
||||
|
||||
@NonNls
|
||||
public String toString() {
|
||||
return "FileLoader [" + myRootDir + "]";
|
||||
}
|
||||
}
|
||||
|
||||
private class JarLoader extends Loader {
|
||||
private final URL myURL;
|
||||
private ZipFile myZipFile;
|
||||
|
||||
JarLoader(URL url, int index) throws IOException {
|
||||
super(new URL(JAR_PROTOCOL, "", -1, url + "!/"), index);
|
||||
myURL = url;
|
||||
}
|
||||
|
||||
public void releaseResources() {
|
||||
final ZipFile zipFile = myZipFile;
|
||||
if (zipFile != null) {
|
||||
myZipFile = null;
|
||||
try {
|
||||
zipFile.close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private ZipFile acquireZipFile() throws IOException {
|
||||
ZipFile zipFile = myZipFile;
|
||||
if (zipFile == null) {
|
||||
zipFile = doGetZipFile();
|
||||
myZipFile = zipFile;
|
||||
}
|
||||
return zipFile;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private ZipFile doGetZipFile() throws IOException {
|
||||
if (FILE_PROTOCOL.equals(myURL.getProtocol())) {
|
||||
String s = FileUtil.unquote(myURL.getFile());
|
||||
if (!new File(s).exists()) {
|
||||
throw new FileNotFoundException(s);
|
||||
}
|
||||
else {
|
||||
return new ZipFile(s);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Resource getResource(String name, boolean flag) {
|
||||
try {
|
||||
final ZipFile file = acquireZipFile();
|
||||
if (file != null) {
|
||||
final ZipEntry entry = file.getEntry(name);
|
||||
if (entry != null) {
|
||||
return new JarResource(entry, new URL(getBaseURL(), name));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private class JarResource extends Resource {
|
||||
private final ZipEntry myEntry;
|
||||
private final URL myUrl;
|
||||
|
||||
public JarResource(ZipEntry name, URL url) {
|
||||
myEntry = name;
|
||||
myUrl = url;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return myEntry.getName();
|
||||
}
|
||||
|
||||
public URL getURL() {
|
||||
return myUrl;
|
||||
}
|
||||
|
||||
public URL getCodeSourceURL() {
|
||||
return myURL;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public InputStream getInputStream() throws IOException {
|
||||
ZipFile file = null;
|
||||
try {
|
||||
file = acquireZipFile();
|
||||
if (file == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final InputStream inputStream = file.getInputStream(myEntry);
|
||||
if (inputStream == null) {
|
||||
return null; // if entry was not found
|
||||
}
|
||||
return new FilterInputStream(inputStream) {};
|
||||
}
|
||||
catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public int getContentLength() {
|
||||
return (int)myEntry.getSize();
|
||||
}
|
||||
}
|
||||
|
||||
@NonNls
|
||||
public String toString() {
|
||||
return "JarLoader [" + myURL + "]";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+412
-15
@@ -1,33 +1,33 @@
|
||||
package org.jetbrains.jps.incremental.java;
|
||||
|
||||
import org.jetbrains.jps.javac.OutputFileObject;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.objectweb.asm.Attribute;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.commons.EmptyVisitor;
|
||||
import sun.misc.Resource;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.*;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: 2/16/12
|
||||
*/
|
||||
class InstrumentationClassFinder {
|
||||
public class InstrumentationClassFinder {
|
||||
private static final PseudoClass[] EMPTY_PSEUDOCLASS_ARRAY = new PseudoClass[0];
|
||||
private static final String CLASS_RESOURCE_EXTENSION = ".class";
|
||||
private final Map<String, PseudoClass> myLoaded = new HashMap<String, PseudoClass>(); // className -> class object
|
||||
private final ClassFinderClasspath myPlatformClasspath;
|
||||
private final ClassFinderClasspath myClasspath;
|
||||
private final OutputFilesSink myCompiled;
|
||||
|
||||
public InstrumentationClassFinder(final URL[] platformClasspath, final URL[] classpath, OutputFilesSink compiled) {
|
||||
myCompiled = compiled;
|
||||
public InstrumentationClassFinder(final URL[] platformClasspath, final URL[] classpath) {
|
||||
myPlatformClasspath = new ClassFinderClasspath(platformClasspath);
|
||||
myClasspath = new ClassFinderClasspath(classpath);
|
||||
}
|
||||
@@ -53,10 +53,7 @@ class InstrumentationClassFinder {
|
||||
}
|
||||
// second look into memory and classspath
|
||||
if (is == null) {
|
||||
final OutputFileObject.Content content = myCompiled.lookupClassBytes(internalName.replace("/", "."));
|
||||
if (content != null) {
|
||||
is = new ByteArrayInputStream(content.getBuffer(), content.getOffset(), content.getLength());
|
||||
}
|
||||
is = lookupClassBeforeClasspath(internalName);
|
||||
}
|
||||
|
||||
if (is == null) {
|
||||
@@ -65,7 +62,11 @@ class InstrumentationClassFinder {
|
||||
is = resource.getInputStream();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (is == null) {
|
||||
is = lookupClassAfterClasspath(internalName);
|
||||
}
|
||||
|
||||
if (is == null) {
|
||||
throw new ClassNotFoundException("Class not found: " + internalName);
|
||||
}
|
||||
@@ -80,6 +81,16 @@ class InstrumentationClassFinder {
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected InputStream lookupClassBeforeClasspath(final String internalClassName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected InputStream lookupClassAfterClasspath(final String internalClassName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
private PseudoClass loadPseudoClass(InputStream is) throws IOException {
|
||||
final ClassReader reader = new ClassReader(is);
|
||||
final V visitor = new V();
|
||||
@@ -194,4 +205,390 @@ class InstrumentationClassFinder {
|
||||
myIsInterface = (access & Opcodes.ACC_INTERFACE) > 0;
|
||||
}
|
||||
}
|
||||
|
||||
static class ClassFinderClasspath {
|
||||
private static final String FILE_PROTOCOL = "file";
|
||||
|
||||
private final Stack<URL> myUrls = new Stack<URL>();
|
||||
private final List<Loader> myLoaders = new ArrayList<Loader>();
|
||||
private final Map<URL,Loader> myLoadersMap = new HashMap<URL, Loader>();
|
||||
|
||||
public ClassFinderClasspath(URL[] urls) {
|
||||
if (urls.length > 0) {
|
||||
for (int i = urls.length - 1; i >= 0; i--) {
|
||||
myUrls.push(urls[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Resource getResource(String s, boolean flag) {
|
||||
int i = 0;
|
||||
for (Loader loader; (loader = getLoader(i)) != null; i++) {
|
||||
Resource resource = loader.getResource(s, flag);
|
||||
if (resource != null) {
|
||||
return resource;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void releaseResources() {
|
||||
for (Loader loader : myLoaders) {
|
||||
loader.releaseResources();
|
||||
}
|
||||
myLoaders.clear();
|
||||
myLoadersMap.clear();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private synchronized Loader getLoader(int i) {
|
||||
while (myLoaders.size() < i + 1) {
|
||||
URL url;
|
||||
synchronized (myUrls) {
|
||||
if (myUrls.empty()) {
|
||||
return null;
|
||||
}
|
||||
url = myUrls.pop();
|
||||
}
|
||||
|
||||
if (myLoadersMap.containsKey(url)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Loader loader;
|
||||
try {
|
||||
loader = getLoader(url, myLoaders.size());
|
||||
if (loader == null) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
catch (IOException ioexception) {
|
||||
continue;
|
||||
}
|
||||
|
||||
myLoaders.add(loader);
|
||||
myLoadersMap.put(url, loader);
|
||||
}
|
||||
|
||||
return myLoaders.get(i);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Loader getLoader(final URL url, int index) throws IOException {
|
||||
String s;
|
||||
try {
|
||||
s = url.toURI().getSchemeSpecificPart();
|
||||
}
|
||||
catch (URISyntaxException thisShouldNotHappen) {
|
||||
thisShouldNotHappen.printStackTrace();
|
||||
s = url.getFile();
|
||||
}
|
||||
|
||||
Loader loader = null;
|
||||
if (s != null && new File(s).isDirectory()) {
|
||||
if (FILE_PROTOCOL.equals(url.getProtocol())) {
|
||||
loader = new FileLoader(url, index);
|
||||
}
|
||||
}
|
||||
else {
|
||||
loader = new JarLoader(url, index);
|
||||
}
|
||||
|
||||
return loader;
|
||||
}
|
||||
|
||||
|
||||
private abstract static class Loader {
|
||||
protected static final String JAR_PROTOCOL = "jar";
|
||||
protected static final String FILE_PROTOCOL = "file";
|
||||
|
||||
private final URL myURL;
|
||||
private final int myIndex;
|
||||
|
||||
protected Loader(URL url, int index) {
|
||||
myURL = url;
|
||||
myIndex = index;
|
||||
}
|
||||
|
||||
|
||||
protected URL getBaseURL() {
|
||||
return myURL;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public abstract Resource getResource(final String name, boolean flag);
|
||||
|
||||
public abstract void releaseResources();
|
||||
|
||||
public int getIndex() {
|
||||
return myIndex;
|
||||
}
|
||||
}
|
||||
|
||||
private static class FileLoader extends Loader {
|
||||
private final File myRootDir;
|
||||
|
||||
@SuppressWarnings({"HardCodedStringLiteral"})
|
||||
FileLoader(URL url, int index) throws IOException {
|
||||
super(url, index);
|
||||
if (!FILE_PROTOCOL.equals(url.getProtocol())) {
|
||||
throw new IllegalArgumentException("url");
|
||||
}
|
||||
else {
|
||||
final String s = unescapePercentSequences(url.getFile().replace('/', File.separatorChar));
|
||||
myRootDir = new File(s);
|
||||
}
|
||||
}
|
||||
|
||||
public void releaseResources() {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Resource getResource(final String name, boolean check) {
|
||||
URL url = null;
|
||||
File file = null;
|
||||
|
||||
try {
|
||||
url = new URL(getBaseURL(), name);
|
||||
if (!url.getFile().startsWith(getBaseURL().getFile())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
file = new File(myRootDir, name.replace('/', File.separatorChar));
|
||||
if (!check || file.exists()) { // check means we load or process resource so we check its existence via old way
|
||||
return new FileResource(name, url, file, !check);
|
||||
}
|
||||
}
|
||||
catch (Exception exception) {
|
||||
if (!check && file != null && file.exists()) {
|
||||
try { // we can not open the file if it is directory, Resource still can be created
|
||||
return new FileResource(name, url, file, false);
|
||||
}
|
||||
catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private class FileResource extends Resource {
|
||||
private final String myName;
|
||||
private final URL myUrl;
|
||||
private final File myFile;
|
||||
|
||||
public FileResource(String name, URL url, File file, boolean willLoadBytes) throws IOException {
|
||||
myName = name;
|
||||
myUrl = url;
|
||||
myFile = file;
|
||||
if (willLoadBytes) getByteBuffer(); // check for existence by creating cached file input stream
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return myName;
|
||||
}
|
||||
|
||||
public URL getURL() {
|
||||
return myUrl;
|
||||
}
|
||||
|
||||
public URL getCodeSourceURL() {
|
||||
return getBaseURL();
|
||||
}
|
||||
|
||||
public InputStream getInputStream() throws IOException {
|
||||
return new BufferedInputStream(new FileInputStream(myFile));
|
||||
}
|
||||
|
||||
public int getContentLength() throws IOException {
|
||||
return -1;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return myFile.getAbsolutePath();
|
||||
}
|
||||
}
|
||||
|
||||
@NonNls
|
||||
public String toString() {
|
||||
return "FileLoader [" + myRootDir + "]";
|
||||
}
|
||||
}
|
||||
|
||||
private class JarLoader extends Loader {
|
||||
private final URL myURL;
|
||||
private ZipFile myZipFile;
|
||||
|
||||
JarLoader(URL url, int index) throws IOException {
|
||||
super(new URL(JAR_PROTOCOL, "", -1, url + "!/"), index);
|
||||
myURL = url;
|
||||
}
|
||||
|
||||
public void releaseResources() {
|
||||
final ZipFile zipFile = myZipFile;
|
||||
if (zipFile != null) {
|
||||
myZipFile = null;
|
||||
try {
|
||||
zipFile.close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private ZipFile acquireZipFile() throws IOException {
|
||||
ZipFile zipFile = myZipFile;
|
||||
if (zipFile == null) {
|
||||
zipFile = doGetZipFile();
|
||||
myZipFile = zipFile;
|
||||
}
|
||||
return zipFile;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private ZipFile doGetZipFile() throws IOException {
|
||||
if (FILE_PROTOCOL.equals(myURL.getProtocol())) {
|
||||
String s = unescapePercentSequences(myURL.getFile().replace('/', File.separatorChar));
|
||||
if (!new File(s).exists()) {
|
||||
throw new FileNotFoundException(s);
|
||||
}
|
||||
else {
|
||||
return new ZipFile(s);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Resource getResource(String name, boolean flag) {
|
||||
try {
|
||||
final ZipFile file = acquireZipFile();
|
||||
if (file != null) {
|
||||
final ZipEntry entry = file.getEntry(name);
|
||||
if (entry != null) {
|
||||
return new JarResource(entry, new URL(getBaseURL(), name));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private class JarResource extends Resource {
|
||||
private final ZipEntry myEntry;
|
||||
private final URL myUrl;
|
||||
|
||||
public JarResource(ZipEntry name, URL url) {
|
||||
myEntry = name;
|
||||
myUrl = url;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return myEntry.getName();
|
||||
}
|
||||
|
||||
public URL getURL() {
|
||||
return myUrl;
|
||||
}
|
||||
|
||||
public URL getCodeSourceURL() {
|
||||
return myURL;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public InputStream getInputStream() throws IOException {
|
||||
ZipFile file = null;
|
||||
try {
|
||||
file = acquireZipFile();
|
||||
if (file == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final InputStream inputStream = file.getInputStream(myEntry);
|
||||
if (inputStream == null) {
|
||||
return null; // if entry was not found
|
||||
}
|
||||
return new FilterInputStream(inputStream) {};
|
||||
}
|
||||
catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public int getContentLength() {
|
||||
return (int)myEntry.getSize();
|
||||
}
|
||||
}
|
||||
|
||||
@NonNls
|
||||
public String toString() {
|
||||
return "JarLoader [" + myURL + "]";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
private static String unescapePercentSequences(@NotNull String s) {
|
||||
if (s.indexOf('%') == -1) {
|
||||
return s;
|
||||
}
|
||||
StringBuilder decoded = new StringBuilder();
|
||||
final int len = s.length();
|
||||
int i = 0;
|
||||
while (i < len) {
|
||||
char c = s.charAt(i);
|
||||
if (c == '%') {
|
||||
List<Integer> bytes = new ArrayList<Integer>();
|
||||
while (i + 2 < len && s.charAt(i) == '%') {
|
||||
final int d1 = decode(s.charAt(i + 1));
|
||||
final int d2 = decode(s.charAt(i + 2));
|
||||
if (d1 != -1 && d2 != -1) {
|
||||
bytes.add(((d1 & 0xf) << 4 | d2 & 0xf));
|
||||
i += 3;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!bytes.isEmpty()) {
|
||||
final byte[] bytesArray = new byte[bytes.size()];
|
||||
for (int j = 0; j < bytes.size(); j++) {
|
||||
bytesArray[j] = (byte)bytes.get(j).intValue();
|
||||
}
|
||||
try {
|
||||
decoded.append(new String(bytesArray, "UTF-8"));
|
||||
continue;
|
||||
}
|
||||
catch (UnsupportedEncodingException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
decoded.append(c);
|
||||
i++;
|
||||
}
|
||||
return decoded.toString();
|
||||
}
|
||||
|
||||
private static int decode(char c) {
|
||||
if ((c >= '0') && (c <= '9')){
|
||||
return c - '0';
|
||||
}
|
||||
if ((c >= 'a') && (c <= 'f')){
|
||||
return c - 'a' + 10;
|
||||
}
|
||||
if ((c >= 'A') && (c <= 'F')){
|
||||
return c - 'A' + 10;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -529,7 +529,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
|
||||
|
||||
private static InstrumentationClassFinder createInstrumentationClassFinder(Collection<File> platformCp,
|
||||
Collection<File> classpath,
|
||||
OutputFilesSink outputSink) throws MalformedURLException {
|
||||
final OutputFilesSink outputSink) throws MalformedURLException {
|
||||
final URL[] platformUrls = new URL[platformCp.size()];
|
||||
int index = 0;
|
||||
for (File file : platformCp) {
|
||||
@@ -544,7 +544,15 @@ public class JavaBuilder extends ModuleLevelBuilder {
|
||||
urls[index++] = getResourcePath(GridConstraints.class).toURI().toURL(); // forms_rt.jar
|
||||
//urls.add(getResourcePath(CellConstraints.class).toURI().toURL()); // jgoodies-forms
|
||||
|
||||
return new InstrumentationClassFinder(platformUrls, urls, outputSink);
|
||||
return new InstrumentationClassFinder(platformUrls, urls) {
|
||||
protected InputStream lookupClassBeforeClasspath(String internalClassName) {
|
||||
final OutputFileObject.Content content = outputSink.lookupClassBytes(internalClassName.replace("/", "."));
|
||||
if (content != null) {
|
||||
return new ByteArrayInputStream(content.getBuffer(), content.getOffset(), content.getLength());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static ClassLoader createInstrumentationClassLoader(Collection<File> platformCp, Collection<File> classpath,
|
||||
|
||||
Reference in New Issue
Block a user