1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.commons.vfs2; 18 19 import java.io.IOException; 20 import java.util.regex.Matcher; 21 import java.util.regex.Pattern; 22 23 import org.apache.commons.lang3.ArrayUtils; 24 import org.apache.commons.vfs2.util.Messages; 25 26 /** 27 * Thrown for file system errors. 28 */ 29 public class FileSystemException extends IOException { 30 31 /** 32 * serialVersionUID format is YYYYMMDD for the date of the last binary change. 33 */ 34 private static final long serialVersionUID = 20101208L; 35 36 /** URL pattern */ 37 private static final Pattern URL_PATTERN = Pattern.compile("[a-z]+://.*"); 38 39 /** Password pattern */ 40 private static final Pattern PASSWORD_PATTERN = Pattern.compile(":(?:[^/]+)@"); 41 42 /** 43 * Throws a FileSystemException when the given object is null. 44 * 45 * @param obj 46 * the object reference to check for null. 47 * @param code 48 * message used when {@code 49 * FileSystemException} is thrown 50 * @param <T> 51 * the type of the reference 52 * @return {@code obj} if not {@code null} 53 * @throws FileSystemException 54 * if {@code obj} is {@code null} 55 * @since 2.3 56 */ 57 public static <T> T requireNonNull(final T obj, final String code) throws FileSystemException { 58 if (obj == null) { 59 throw new FileSystemException(code); 60 } 61 return obj; 62 } 63 64 /** 65 * Throws a FileSystemException when the given object is null. 66 * 67 * @param obj 68 * the object reference to check for null. 69 * @param code 70 * message used when {@code 71 * FileSystemException} is thrown 72 * @param info 73 * one context information. 74 * @param <T> 75 * the type of the reference 76 * @return {@code obj} if not {@code null} 77 * @throws FileSystemException 78 * if {@code obj} is {@code null} 79 * @since 2.3 80 */ 81 public static <T> T requireNonNull(final T obj, final String code, final Object... info) throws FileSystemException { 82 if (obj == null) { 83 throw new FileSystemException(code, info); 84 } 85 return obj; 86 } 87 88 /** 89 * Array of complementary info (context). 90 */ 91 private final String[] info; 92 93 /** 94 * Constructs exception with the specified detail message. 95 * 96 * @param code the error code of the message. 97 */ 98 public FileSystemException(final String code) { 99 this(code, null, (Object[]) null); 100 } 101 102 /** 103 * Constructs exception with the specified detail message. 104 * 105 * @param code the error code of the message. 106 * @param info one context information. 107 */ 108 public FileSystemException(final String code, final Object info) { 109 this(code, null, new Object[] {info}); 110 } 111 112 /** 113 * Constructs exception with the specified detail message. 114 * 115 * @param code the error code of the message. 116 * @param info array of complementary info (context). 117 */ 118 public FileSystemException(final String code, final Object... info) { 119 this(code, null, info); 120 } 121 122 /** 123 * Constructs exception with the specified detail message and cause. 124 * 125 * @param code the error code of the message. 126 * @param info one context information. 127 * @param cause the cause. 128 */ 129 public FileSystemException(final String code, final Object info, final Throwable cause) { 130 this(code, cause, info); 131 } 132 133 /** 134 * Constructs exception with the specified detail message. 135 * 136 * @param code the error code of the message. 137 * @param info array of complementary info (context). 138 * @param cause the cause. 139 * @deprecated Use instead {@link #FileSystemException(String, Throwable, Object[])}. Will be removed in 3.0. 140 */ 141 @Deprecated 142 public FileSystemException(final String code, final Object[] info, final Throwable cause) { 143 this(code, cause, info); 144 } 145 146 /** 147 * Constructs exception with the specified detail message. 148 * 149 * @param code the error code of the message. 150 * @param cause the original cause 151 */ 152 public FileSystemException(final String code, final Throwable cause) { 153 this(code, cause, (Object[]) null); 154 } 155 156 /** 157 * Constructs exception with the specified detail message. 158 * 159 * @param code the error code of the message. 160 * @param info array of complementary info (context). 161 * @param cause the cause. 162 */ 163 public FileSystemException(final String code, final Throwable cause, final Object... info) { 164 super(code, cause); 165 166 if (info == null) { 167 this.info = ArrayUtils.EMPTY_STRING_ARRAY; 168 } else { 169 this.info = new String[info.length]; 170 for (int i = 0; i < info.length; i++) { 171 String value = String.valueOf(info[i]); 172 // mask passwords (VFS-169) 173 final Matcher urlMatcher = URL_PATTERN.matcher(value); 174 if (urlMatcher.find()) { 175 value = PASSWORD_PATTERN.matcher(value).replaceFirst(":***@"); 176 } 177 this.info[i] = value; 178 } 179 } 180 } 181 182 /** 183 * Constructs wrapper exception. 184 * 185 * @param cause the root cause to wrap. 186 */ 187 public FileSystemException(final Throwable cause) { 188 this(cause.getMessage(), cause, (Object[]) null); 189 } 190 191 /** 192 * Retrieves error code of the exception. Could be used as key for internationalization. 193 * 194 * @return the code. 195 */ 196 public String getCode() { 197 return super.getMessage(); 198 } 199 200 /** 201 * Retrieves array of complementary info (context). Could be used as parameter for internationalization. 202 * 203 * @return the context info. 204 */ 205 public String[] getInfo() { 206 return info; 207 } 208 209 /** 210 * Retrieves message from bundle. 211 * 212 * @return The exception message. 213 */ 214 @Override 215 public String getMessage() { 216 return Messages.getString(super.getMessage(), (Object[]) getInfo()); 217 } 218 }