FileURLConnection.java revision f6c387128427e121477c1b32ad35cdcaa5101ba3
1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * this work for additional information regarding copyright ownership. 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (the "License"); you may not use this file except in compliance with 7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the License. You may obtain a copy of the License at 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License. 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage org.apache.harmony.luni.internal.net.www.protocol.file; 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.BufferedInputStream; 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.ByteArrayInputStream; 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.ByteArrayOutputStream; 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.File; 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.FileInputStream; 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.FilePermission; 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.IOException; 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.InputStream; 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.PrintStream; 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.net.URL; 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.net.URLConnection; 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.apache.harmony.luni.internal.net.www.MimeTable; 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.apache.harmony.luni.util.Util; 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/** 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This subclass extends <code>URLConnection</code>. 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <p> 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This class is responsible for connecting, getting content and input stream of 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the file. 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic class FileURLConnection extends URLConnection { 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String fileName; 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private InputStream is; 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int length = -1; 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private boolean isDir; 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private FilePermission permission; 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Creates an instance of <code>FileURLConnection</code> for establishing 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * a connection to the file pointed by this <code>URL<code> 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param url The URL this connection is connected to 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public FileURLConnection(URL url) { 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project super(url); 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fileName = url.getFile(); 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (url.getRef() != null) { 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fileName += "#" + url.getRef(); //$NON-NLS-1$ 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (fileName == null) { 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fileName = ""; //$NON-NLS-1$ 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String host = url.getHost(); 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (host != null && host.length() > 0) { 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fileName = "//" + host + fileName; //$NON-NLS-1$ 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fileName = Util.decode(fileName, false); 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This methods will attempt to obtain the input stream of the file pointed 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * by this <code>URL</code>. If the file is a directory, it will return 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * that directory listing as an input stream. 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IOException 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if an IO error occurs while connecting 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void connect() throws IOException { 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project File f = new File(fileName); 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (f.isDirectory()) { 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project isDir = true; 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project is = getDirectoryListing(f); 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // use -1 for the contentLength 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // BEGIN android-modified 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project is = new BufferedInputStream(new FileInputStream(f), 8192); 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // END android-modified 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project length = is.available(); 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project connected = true; 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the length of the file in bytes. 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the length of the file 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @see #getContentType() 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int getContentLength() { 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!connected) { 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project connect(); 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (IOException e) { 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // default is -1 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return length; 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the content type of the resource. Just takes a guess based on the 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * name. 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the content type 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public String getContentType() { 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!connected) { 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project connect(); 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (IOException e) { 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return MimeTable.UNKNOWN; 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (isDir) { 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return "text/html"; //$NON-NLS-1$ 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String result = guessContentTypeFromName(url.getFile()); 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result == null) { 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return MimeTable.UNKNOWN; 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the directory listing of the file component as an input stream. 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the input stream of the directory listing 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private InputStream getDirectoryListing(File f) { 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String fileList[] = f.list(); 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ByteArrayOutputStream bytes = new java.io.ByteArrayOutputStream(); 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project PrintStream out = new PrintStream(bytes); 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.print("<title>Directory Listing</title>\n"); //$NON-NLS-1$ 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.print("<base href=\"file:"); //$NON-NLS-1$ 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.print(f.getPath().replace('\\', '/') + "/\"><h1>" + f.getPath() //$NON-NLS-1$ 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project + "</h1>\n<hr>\n"); //$NON-NLS-1$ 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i; 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < fileList.length; i++) { 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.print(fileList[i] + "<br>\n"); //$NON-NLS-1$ 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.close(); 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return new ByteArrayInputStream(bytes.toByteArray()); 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the input stream of the object referred to by this 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <code>URLConnection</code> 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * File Sample : "/ZIP211/+/harmony/tools/javac/resources/javac.properties" 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Invalid File Sample: 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "/ZIP/+/harmony/tools/javac/resources/javac.properties" 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "ZIP211/+/harmony/tools/javac/resources/javac.properties" 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return input stream of the object 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IOException 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if an IO error occurs 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public InputStream getInputStream() throws IOException { 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!connected) { 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project connect(); 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return is; 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the permission, in this case the subclass, FilePermission object 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * which represents the permission necessary for this URLConnection to 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * establish the connection. 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the permission required for this URLConnection. 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IOException 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if an IO exception occurs while creating the permission. 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public java.security.Permission getPermission() throws IOException { 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (permission == null) { 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String path = fileName; 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (File.separatorChar != '/') { 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project path = path.replace('/', File.separatorChar); 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project permission = new FilePermission(path, "read"); //$NON-NLS-1$ 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return permission; 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 208