001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.commons.vfs2.provider.url;
018
019 import java.io.FileNotFoundException;
020 import java.io.InputStream;
021 import java.net.HttpURLConnection;
022 import java.net.MalformedURLException;
023 import java.net.URL;
024 import java.net.URLConnection;
025
026 import org.apache.commons.httpclient.URIException;
027 import org.apache.commons.vfs2.FileName;
028 import org.apache.commons.vfs2.FileObject;
029 import org.apache.commons.vfs2.FileSystemException;
030 import org.apache.commons.vfs2.FileType;
031 import org.apache.commons.vfs2.provider.AbstractFileName;
032 import org.apache.commons.vfs2.provider.AbstractFileObject;
033 import org.apache.commons.vfs2.provider.URLFileName;
034
035 /**
036 * A {@link FileObject} implementation backed by a {@link URL}.
037 *
038 * @author <a href="http://commons.apache.org/vfs/team-list.html">Commons VFS team</a>
039 * @todo Implement set lastModified and get/set attribute
040 * @todo Implement getOutputStream()
041 */
042 public class UrlFileObject extends AbstractFileObject implements FileObject
043 {
044 private URL url;
045
046 protected UrlFileObject(final UrlFileSystem fs,
047 final AbstractFileName fileName)
048 {
049 super(fileName, fs);
050 }
051
052 /**
053 * Attaches this file object to its file resource. This method is called
054 * before any of the doBlah() or onBlah() methods. Sub-classes can use
055 * this method to perform lazy initialisation.
056 */
057 @Override
058 protected void doAttach() throws Exception
059 {
060 if (url == null)
061 {
062 // url = new URL(getName().getURI());
063 url = createURL(getName());
064 }
065 }
066
067 protected URL createURL(final FileName name) throws MalformedURLException, FileSystemException, URIException
068 {
069 if (name instanceof URLFileName)
070 {
071 URLFileName urlName = (URLFileName) getName();
072
073 // TODO: charset
074 return new URL(urlName.getURIEncoded(null));
075 }
076 return new URL(getName().getURI());
077 }
078
079 /**
080 * Determines the type of the file.
081 */
082 @Override
083 protected FileType doGetType() throws Exception
084 {
085 try
086 {
087 // Attempt to connect & check status
088 final URLConnection conn = url.openConnection();
089 final InputStream in = conn.getInputStream();
090 try
091 {
092 if (conn instanceof HttpURLConnection)
093 {
094 final int status = ((HttpURLConnection) conn).getResponseCode();
095 // 200 is good, maybe add more later...
096 if (HttpURLConnection.HTTP_OK != status)
097 {
098 return FileType.IMAGINARY;
099 }
100 }
101
102 return FileType.FILE;
103 }
104 finally
105 {
106 in.close();
107 }
108 }
109 catch (final FileNotFoundException e)
110 {
111 return FileType.IMAGINARY;
112 }
113 }
114
115 /**
116 * Returns the size of the file content (in bytes).
117 */
118 @Override
119 protected long doGetContentSize() throws Exception
120 {
121 final URLConnection conn = url.openConnection();
122 final InputStream in = conn.getInputStream();
123 try
124 {
125 return conn.getContentLength();
126 }
127 finally
128 {
129 in.close();
130 }
131 }
132
133 /**
134 * Returns the last modified time of this file.
135 */
136 @Override
137 protected long doGetLastModifiedTime()
138 throws Exception
139 {
140 final URLConnection conn = url.openConnection();
141 final InputStream in = conn.getInputStream();
142 try
143 {
144 return conn.getLastModified();
145 }
146 finally
147 {
148 in.close();
149 }
150 }
151
152 /**
153 * Lists the children of the file.
154 */
155 @Override
156 protected String[] doListChildren() throws Exception
157 {
158 throw new FileSystemException("Not implemented.");
159 }
160
161 /**
162 * Creates an input stream to read the file content from.
163 */
164 @Override
165 protected InputStream doGetInputStream() throws Exception
166 {
167 return url.openStream();
168 }
169 }