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;
018    
019    import java.io.IOException;
020    import java.net.URL;
021    import java.net.URLConnection;
022    import java.net.URLStreamHandler;
023    
024    import org.apache.commons.vfs2.FileObject;
025    import org.apache.commons.vfs2.FileSystemException;
026    import org.apache.commons.vfs2.FileSystemOptions;
027    import org.apache.commons.vfs2.FileType;
028    
029    /**
030     * A default URL stream handler that will work for most file systems.
031     *
032     * @author <a href="http://commons.apache.org/vfs/team-list.html">Commons VFS team</a>
033     */
034    public class DefaultURLStreamHandler
035        extends URLStreamHandler
036    {
037        private final VfsComponentContext context;
038        private final FileSystemOptions fileSystemOptions;
039    
040        public DefaultURLStreamHandler(final VfsComponentContext context)
041        {
042            this(context, null);
043        }
044    
045        public DefaultURLStreamHandler(final VfsComponentContext context, final FileSystemOptions fileSystemOptions)
046        {
047            this.context = context;
048            this.fileSystemOptions = fileSystemOptions;
049        }
050    
051        @Override
052        protected URLConnection openConnection(final URL url)
053            throws IOException
054        {
055            final FileObject entry = context.resolveFile(url.toExternalForm(), fileSystemOptions);
056            return new DefaultURLConnection(url, entry.getContent());
057        }
058    
059        @Override
060        protected void parseURL(final URL u,
061                                final String spec,
062                                final int start,
063                                final int limit)
064        {
065            try
066            {
067                FileObject old = context.resolveFile(u.toExternalForm(), fileSystemOptions);
068    
069                FileObject newURL;
070                if (start > 0 && spec.charAt(start - 1) == ':')
071                {
072                    newURL = context.resolveFile(old, spec, fileSystemOptions);
073                }
074                else
075                {
076                    if (old.getType() == FileType.FILE && old.getParent() != null)
077                    {
078                        // for files we have to resolve relative
079                        newURL = old.getParent().resolveFile(spec);
080                    }
081                    else
082                    {
083                        newURL = old.resolveFile(spec);
084                    }
085                }
086    
087                final String url = newURL.getName().getURI();
088                final StringBuilder filePart = new StringBuilder();
089                final String protocolPart = UriParser.extractScheme(url, filePart);
090    
091                setURL(u, protocolPart, "", -1, null, null, filePart.toString(), null, null);
092            }
093            catch (FileSystemException fse)
094            {
095                // This is rethrown to MalformedURLException in URL anyway
096                throw new RuntimeException(fse.getMessage());
097            }
098        }
099    
100        @Override
101        protected String toExternalForm(final URL u)
102        {
103            return u.getProtocol() + ":" + u.getFile();
104        }
105    }