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 (fileName == null) { 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fileName = ""; //$NON-NLS-1$ 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fileName = Util.decode(fileName, false); 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This methods will attempt to obtain the input stream of the file pointed 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * by this <code>URL</code>. If the file is a directory, it will return 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * that directory listing as an input stream. 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IOException 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if an IO error occurs while connecting 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void connect() throws IOException { 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project File f = new File(fileName); 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (f.isDirectory()) { 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project isDir = true; 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project is = getDirectoryListing(f); 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // use -1 for the contentLength 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // BEGIN android-modified 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project is = new BufferedInputStream(new FileInputStream(f), 8192); 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // END android-modified 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project length = is.available(); 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project connected = true; 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the length of the file in bytes. 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the length of the file 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @see #getContentType() 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int getContentLength() { 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!connected) { 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project connect(); 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (IOException e) { 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // default is -1 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return length; 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the content type of the resource. Just takes a guess based on the 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * name. 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the content type 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public String getContentType() { 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!connected) { 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project connect(); 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (IOException e) { 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return MimeTable.UNKNOWN; 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (isDir) { 1273819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson return "text/plain"; //$NON-NLS-1$ 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String result = guessContentTypeFromName(url.getFile()); 1303819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson if (result != null) { 1313819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson return result; 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1333819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson 1343819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson try { 1353819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson result = guessContentTypeFromStream(is); 1363819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson } catch (IOException e) { 1373819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson // Ignore 1383819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson } 1393819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson if (result != null) { 1403819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson return result; 1413819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson } 1423819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson 1433819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson return MimeTable.UNKNOWN; 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the directory listing of the file component as an input stream. 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the input stream of the directory listing 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private InputStream getDirectoryListing(File f) { 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String fileList[] = f.list(); 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ByteArrayOutputStream bytes = new java.io.ByteArrayOutputStream(); 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project PrintStream out = new PrintStream(bytes); 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.print("<title>Directory Listing</title>\n"); //$NON-NLS-1$ 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.print("<base href=\"file:"); //$NON-NLS-1$ 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.print(f.getPath().replace('\\', '/') + "/\"><h1>" + f.getPath() //$NON-NLS-1$ 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project + "</h1>\n<hr>\n"); //$NON-NLS-1$ 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i; 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < fileList.length; i++) { 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.print(fileList[i] + "<br>\n"); //$NON-NLS-1$ 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.close(); 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return new ByteArrayInputStream(bytes.toByteArray()); 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the input stream of the object referred to by this 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <code>URLConnection</code> 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * File Sample : "/ZIP211/+/harmony/tools/javac/resources/javac.properties" 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Invalid File Sample: 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "/ZIP/+/harmony/tools/javac/resources/javac.properties" 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "ZIP211/+/harmony/tools/javac/resources/javac.properties" 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return input stream of the object 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IOException 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if an IO error occurs 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public InputStream getInputStream() throws IOException { 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!connected) { 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project connect(); 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return is; 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the permission, in this case the subclass, FilePermission object 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * which represents the permission necessary for this URLConnection to 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * establish the connection. 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the permission required for this URLConnection. 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IOException 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if an IO exception occurs while creating the permission. 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public java.security.Permission getPermission() throws IOException { 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (permission == null) { 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String path = fileName; 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (File.separatorChar != '/') { 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project path = path.replace('/', File.separatorChar); 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project permission = new FilePermission(path, "read"); //$NON-NLS-1$ 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return permission; 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 211