Refactor downloader into FileLocator and optimize for speed.

This commit is contained in:
md_5 2013-04-20 14:00:29 +10:00
parent 6ea97c26c8
commit 2d06f11347
7 changed files with 60 additions and 51 deletions

View File

@ -28,6 +28,7 @@
*/
package net.md_5.specialsource;
import net.md_5.specialsource.util.FileLocator;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
@ -98,7 +99,7 @@ public class AccessMap {
if (filename.startsWith("pattern:")) {
addAccessChange(filename.substring("pattern:".length()));
} else {
loadAccessTransformer(URLDownloader.getLocalFile(filename));
loadAccessTransformer(FileLocator.getFile(filename));
}
}

View File

@ -28,6 +28,7 @@
*/
package net.md_5.specialsource;
import net.md_5.specialsource.util.NoDupeList;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;

View File

@ -28,6 +28,7 @@
*/
package net.md_5.specialsource;
import net.md_5.specialsource.util.FileLocator;
import net.md_5.specialsource.transformer.MavenShade;
import net.md_5.specialsource.writer.CompactSearge;
import net.md_5.specialsource.writer.Searge;
@ -108,7 +109,7 @@ public class JarMapping {
*/
private void loadMappingsDir(String dirname, boolean reverse, boolean ignoreCsv, boolean numericSrgNames) throws IOException {
File dir = new File(dirname);
if (!URLDownloader.isHTTPURL(dirname) && !dir.isDirectory()) {
if (!FileLocator.isHTTPURL(dirname) && !dir.isDirectory()) {
throw new IllegalArgumentException("loadMappingsDir(" + dir + "): not a directory");
}
@ -116,14 +117,14 @@ public class JarMapping {
List<File> srgFiles = new ArrayList<File>();
File joinedSrg = URLDownloader.getLocalFile(dirname + sep + "joined.srg");
File joinedSrg = FileLocator.getFile(dirname + sep + "joined.srg");
if (joinedSrg.exists()) {
// FML/MCP client/server joined
srgFiles.add(joinedSrg);
} else {
// vanilla MCP separated sides
File serverSrg = URLDownloader.getLocalFile(dirname + sep + "server.srg");
File clientSrg = URLDownloader.getLocalFile(dirname + sep + "client.srg");
File serverSrg = FileLocator.getFile(dirname + sep + "server.srg");
File clientSrg = FileLocator.getFile(dirname + sep + "client.srg");
if (serverSrg.exists()) {
srgFiles.add(serverSrg);
}
@ -137,9 +138,9 @@ public class JarMapping {
}
// Read output names through csv mappings, if available & enabled
File fieldsCsv = URLDownloader.getLocalFile(dirname + sep + "fields.csv");
File methodsCsv = URLDownloader.getLocalFile(dirname + sep + "methods.csv");
File packagesCsv = URLDownloader.getLocalFile(dirname + sep + "packages.csv"); // FML repackaging, optional
File fieldsCsv = FileLocator.getFile(dirname + sep + "fields.csv");
File methodsCsv = FileLocator.getFile(dirname + sep + "methods.csv");
File packagesCsv = FileLocator.getFile(dirname + sep + "packages.csv"); // FML repackaging, optional
MinecraftCodersPack outputTransformer;
MappingTransformer inputTransformer;
@ -211,7 +212,7 @@ public class JarMapping {
throw new IllegalArgumentException("loadMappings(" + filename + "): numeric only supported on directories, not files");
}
loadMappings(new BufferedReader(new FileReader(URLDownloader.getLocalFile(filename))), inputTransformer, outputTransformer, reverse);
loadMappings(new BufferedReader(new FileReader(FileLocator.getFile(filename))), inputTransformer, outputTransformer, reverse);
}
}

View File

@ -28,6 +28,8 @@
*/
package net.md_5.specialsource;
import net.md_5.specialsource.util.Pair;
import net.md_5.specialsource.util.FileLocator;
import net.md_5.specialsource.provider.JointProvider;
import net.md_5.specialsource.provider.JarProvider;
import java.io.*;
@ -129,13 +131,13 @@ public class SpecialSource {
JarMapping jarMapping;
verbose = !options.has("quiet");
URLDownloader.useCache = !options.has("force-redownload");
FileLocator.useCache = !options.has("force-redownload");
if (options.has("first-jar") && options.has("second-jar")) {
// Generate mappings from two otherwise-identical jars
log("Reading jars");
Jar jar1 = Jar.init(URLDownloader.getLocalFile((String) options.valueOf("first-jar")));
Jar jar2 = Jar.init(URLDownloader.getLocalFile((String) options.valueOf("second-jar")));
Jar jar1 = Jar.init(FileLocator.getFile((String) options.valueOf("first-jar")));
Jar jar2 = Jar.init(FileLocator.getFile((String) options.valueOf("second-jar")));
log("Creating jar compare");
JarComparer visitor1 = new JarComparer(jar1);
@ -200,7 +202,7 @@ public class SpecialSource {
List<String> filenames = (List<String>) options.valuesOf("in-jar");
List<File> files = new ArrayList<File>();
for (String filename : filenames) {
files.add(URLDownloader.getLocalFile(filename));
files.add(FileLocator.getFile(filename));
}
Jar jar3 = Jar.init(files);

View File

@ -26,31 +26,28 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package net.md_5.specialsource;
package net.md_5.specialsource.util;
import com.google.common.base.CharMatcher;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import net.md_5.specialsource.SpecialSource;
public class URLDownloader {
public class FileLocator {
private static String CACHE_FOLDER = ".ss-cache";
private URL url;
public static boolean useCache = true;
public URLDownloader(String urlString) throws MalformedURLException {
urlString = urlString.replace('\\', '/'); // Windows paths to URLs - TODO: improve this in JarMapping directory loading
this.url = new URL(urlString);
}
public File download() throws IOException {
// Cache to temporary directory
String sep = System.getProperty("file.separator");
private static File download(String url) throws IOException {
// Create temporary dir in system location
File tempDir = File.createTempFile("ss-cache", null);
// Create our own cache file here, replacing potentially invalid characters
// TODO: Maybe just store the base name or something
String id = CharMatcher.JAVA_LETTER_OR_DIGIT.or(CharMatcher.anyOf("-_.")).negate().replaceFrom(url.toString(), '_');
String cacheFilename = System.getProperty("java.io.tmpdir") + sep + CACHE_FOLDER + sep + id;
File file = new File(cacheFilename);
File file = new File(tempDir, id);
// Check cache for a hit
if (file.exists() && useCache) {
if (SpecialSource.verbose()) {
System.out.println("Using cached file " + file.getPath() + " for " + url);
@ -59,27 +56,28 @@ public class URLDownloader {
return file;
}
// Download
file.getParentFile().mkdirs();
// Nope, we need to download it ourselves
if (SpecialSource.verbose()) {
System.out.println("Downloading " + url);
}
url.openConnection();
InputStream inputStream = url.openStream();
FileOutputStream outputStream = new FileOutputStream(file);
int n;
byte[] buffer = new byte[4096];
while ((n = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, n);
ReadableByteChannel rbc = null;
FileOutputStream fos = null;
try {
// TODO: Better sollution for cleaning names
rbc = Channels.newChannel(new URL(url.replace('\\', '/')).openStream());
fos = new FileOutputStream(file);
fos.getChannel().transferFrom(rbc, 0, 1 << 24);
} finally {
if (rbc != null) {
rbc.close();
}
if (fos != null) {
fos.close();
}
}
inputStream.close();
outputStream.close();
// Success!
if (SpecialSource.verbose()) {
System.out.println("Downloaded to " + file.getPath());
}
@ -87,13 +85,19 @@ public class URLDownloader {
return file;
}
public static File getLocalFile(String string) throws IOException {
if (isHTTPURL(string)) {
URLDownloader downloader = new URLDownloader(string);
return downloader.download();
} else {
return new File(string);
/**
* Either download, or get a File object corresponding to the given URL /
* file name.
*
* @param path
* @return
* @throws IOException
*/
public static File getFile(String path) throws IOException {
if (isHTTPURL(path)) {
return download(path);
}
return new File(path);
}
public static boolean isHTTPURL(String string) {

View File

@ -26,7 +26,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package net.md_5.specialsource;
package net.md_5.specialsource.util;
import java.util.ArrayList;
import java.util.HashSet;

View File

@ -26,7 +26,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package net.md_5.specialsource;
package net.md_5.specialsource.util;
import lombok.EqualsAndHashCode;
import lombok.RequiredArgsConstructor;