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 */ 017package org.apache.commons.vfs2.provider.local; 018 019import org.apache.commons.vfs2.FileName; 020import org.apache.commons.vfs2.FileSystemException; 021import org.apache.commons.vfs2.FileType; 022import org.apache.commons.vfs2.provider.AbstractFileName; 023import org.apache.commons.vfs2.provider.UriParser; 024 025/** 026 * A local file URI. 027 */ 028public class LocalFileName extends AbstractFileName { 029 // URI Characters that are possible in local filenames, but must be escaped 030 // for proper URI handling. 031 // 032 // How reserved URI chars were selected: 033 // 034 // URIs can contain :, /, ?, #, @ 035 // See http://download.oracle.com/javase/6/docs/api/java/net/URI.html 036 // http://tools.ietf.org/html/rfc3986#section-2.2 037 // 038 // Since : and / occur before the path, only chars after path are escaped (i.e., # and ?) 039 // ? is a reserved filesystem character for Windows and Unix, so can't be part of a filename. 040 // Therefore only # is a reserved char in a URI as part of the path that can be in the filename. 041 private static final char[] RESERVED_URI_CHARS = { '#' }; 042 043 private final String rootFile; 044 045 protected LocalFileName(final String scheme, final String rootFile, final String path, final FileType type) { 046 super(scheme, path, type); 047 this.rootFile = rootFile; 048 } 049 050 /** 051 * Returns the root file for this file. 052 * 053 * @return The root file name. 054 */ 055 public String getRootFile() { 056 return rootFile; 057 } 058 059 /** 060 * Factory method for creating name instances. 061 * 062 * @param path The file path. 063 * @param type The file type. 064 * @return The FileName. 065 */ 066 @Override 067 public FileName createName(final String path, final FileType type) { 068 return new LocalFileName(getScheme(), rootFile, path, type); 069 } 070 071 /** 072 * Returns the absolute URI of the file. 073 * 074 * @return The absolute URI of the file. 075 */ 076 @Override 077 public String getURI() { 078 String uri = super.getURI(); 079 080 if (uri != null && uri.length() > 0) { 081 try { 082 // VFS-325: Handle URI special characters in filename 083 // Decode the base uri and re-encode with URI special characters 084 uri = UriParser.decode(uri); 085 086 uri = UriParser.encode(uri, RESERVED_URI_CHARS); 087 } catch (final FileSystemException e) { 088 // Default to base uri value 089 } 090 } 091 092 return uri; 093 } 094 095 /** 096 * returns a "friendly path", this is a path without a password. 097 * 098 * @return The "friendly" URI. 099 */ 100 @Override 101 public String getFriendlyURI() { 102 String uri = super.getFriendlyURI(); 103 104 if (uri != null && uri.length() > 0) { 105 try { 106 // VFS-325: Handle URI special characters in filename 107 // Decode the base uri and re-encode with URI special characters 108 uri = UriParser.decode(uri); 109 110 uri = UriParser.encode(uri, RESERVED_URI_CHARS); 111 } catch (final FileSystemException e) { 112 // Default to base uri value 113 } 114 } 115 116 return uri; 117 } 118 119 /** 120 * Returns the decoded URI of the file. 121 * 122 * @return the FileName as a URI. 123 */ 124 @Override 125 public String toString() { 126 try { 127 return UriParser.decode(super.getURI()); 128 } catch (final FileSystemException e) { 129 return super.getURI(); 130 } 131 } 132 133 /** 134 * Builds the root URI for this file name. 135 */ 136 @Override 137 protected void appendRootUri(final StringBuilder buffer, final boolean addPassword) { 138 buffer.append(getScheme()); 139 buffer.append("://"); 140 buffer.append(rootFile); 141 } 142}