1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package android.signature.cts; 17 18 import java.io.File; 19 import java.io.FileInputStream; 20 import java.io.IOException; 21 import java.io.InputStream; 22 import java.net.URL; 23 import java.util.zip.ZipEntry; 24 import java.util.zip.ZipFile; 25 26 /** 27 * Workaround for the lack of a zip file system provider on Android. 28 */ 29 public abstract class VirtualPath { 30 31 /** 32 * Get a path to the local file system. 33 */ get(String path)34 public static LocalFilePath get(String path) { 35 return new LocalFilePath(path); 36 } 37 38 /** 39 * Get a path to an entry in a zip file, i.e. a zip file system. 40 */ get(ZipFile zip, ZipEntry entry)41 public static ZipEntryPath get(ZipFile zip, ZipEntry entry) { 42 return new ZipEntryPath(zip, entry); 43 } 44 45 /** 46 * Get a path to a resource in a ClassLoader. 47 * 48 * @param classLoader the ClassLoader containing the resource. 49 * @param resourceName the name of the resource, must not start with a /. 50 */ get(ClassLoader classLoader, String resourceName)51 public static ResourcePath get(ClassLoader classLoader, String resourceName) 52 throws IOException { 53 return new ResourcePath(classLoader, resourceName); 54 } 55 newInputStream()56 public abstract InputStream newInputStream() throws IOException; 57 58 public static class LocalFilePath extends VirtualPath { 59 private final String path; 60 LocalFilePath(String path)61 LocalFilePath(String path) { 62 this.path = path; 63 } 64 toFile()65 public File toFile() { 66 return new File(path); 67 } 68 resolve(String relative)69 public LocalFilePath resolve(String relative) { 70 return new LocalFilePath(path + "/" + relative); 71 } 72 73 @Override newInputStream()74 public InputStream newInputStream() throws IOException { 75 return new FileInputStream(path); 76 } 77 78 @Override toString()79 public String toString() { 80 return path; 81 } 82 } 83 84 private static class ZipEntryPath extends VirtualPath { 85 86 private final ZipFile zip; 87 88 private final ZipEntry entry; 89 ZipEntryPath(ZipFile zip, ZipEntry entry)90 private ZipEntryPath(ZipFile zip, ZipEntry entry) { 91 this.zip = zip; 92 this.entry = entry; 93 } 94 95 @Override newInputStream()96 public InputStream newInputStream() throws IOException { 97 return zip.getInputStream(entry); 98 } 99 100 @Override toString()101 public String toString() { 102 return "zip:file:" + zip.getName() + "!/" + entry.getName(); 103 } 104 } 105 106 public static class ResourcePath extends VirtualPath { 107 private final URL url; 108 ResourcePath(ClassLoader classLoader, String path)109 ResourcePath(ClassLoader classLoader, String path) throws IOException { 110 this.url = classLoader.getResource(path); 111 if (url == null) { 112 throw new IOException("Could not find resource '" + path + "' in " + classLoader); 113 } 114 } 115 116 @Override newInputStream()117 public InputStream newInputStream() throws IOException { 118 return url.openStream(); 119 } 120 121 @Override toString()122 public String toString() { 123 return url.toExternalForm(); 124 } 125 } 126 } 127