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 * Array of complementary info (context). 44 */ 45 private final String[] info; 46 47 /** 48 * Throws a FileSystemException when the given object is null. 49 * 50 * @param obj 51 * the object reference to check for null. 52 * @param code 53 * message used when {@code 54 * FileSystemException} is thrown 55 * @param <T> 56 * the type of the reference 57 * @return {@code obj} if not {@code null} 58 * @throws FileSystemException 59 * if {@code obj} is {@code null} 60 * @since 2.3 61 */ 62 public static <T> T requireNonNull(final T obj, final String code) throws FileSystemException { 63 if (obj == null) { 64 throw new FileSystemException(code); 65 } 66 return obj; 67 } 68 69 /** 70 * Throws a FileSystemException when the given object is null. 71 * 72 * @param obj 73 * the object reference to check for null. 74 * @param code 75 * message used when {@code 76 * FileSystemException} is thrown 77 * @param info 78 * one context information. 79 * @param <T> 80 * the type of the reference 81 * @return {@code obj} if not {@code null} 82 * @throws FileSystemException 83 * if {@code obj} is {@code null} 84 * @since 2.3 85 */ 86 public static <T> T requireNonNull(final T obj, final String code, final Object... info) throws FileSystemException { 87 if (obj == null) { 88 throw new FileSystemException(code, info); 89 } 90 return obj; 91 } 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 info0 one context information. 107 */ 108 public FileSystemException(final String code, final Object info0) { 109 this(code, null, new Object[] { info0 }); 110 } 111 112 /** 113 * Constructs exception with the specified detail message. 114 * 115 * @param code the error code of the message. 116 * @param info0 one context information. 117 * @param throwable the cause. 118 */ 119 public FileSystemException(final String code, final Object info0, final Throwable throwable) { 120 this(code, throwable, new Object[] { info0 }); 121 } 122 123 /** 124 * Constructs exception with the specified detail message. 125 * 126 * @param code the error code of the message. 127 * @param info array of complementary info (context). 128 */ 129 public FileSystemException(final String code, final Object... info) { 130 this(code, null, info); 131 } 132 133 /** 134 * Constructs exception with the specified detail message. 135 * 136 * @param code the error code of the message. 137 * @param throwable the original cause 138 */ 139 public FileSystemException(final String code, final Throwable throwable) { 140 this(code, throwable, (Object[]) null); 141 } 142 143 /** 144 * Constructs exception with the specified detail message. 145 * 146 * @param code the error code of the message. 147 * @param info array of complementary info (context). 148 * @param throwable the cause. 149 * @deprecated Use instead {@link #FileSystemException(String, Throwable, Object[])}. Will be removed in 3.0. 150 */ 151 @Deprecated 152 public FileSystemException(final String code, final Object[] info, final Throwable throwable) { 153 this(code, throwable, info); 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 throwable the cause. 162 */ 163 public FileSystemException(final String code, final Throwable throwable, final Object... info) { 164 super(code, throwable); 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 throwable the root cause to wrap. 186 */ 187 public FileSystemException(final Throwable throwable) { 188 this(throwable.getMessage(), throwable, (Object[]) null); 189 } 190 191 /** 192 * Retrieves message from bundle. 193 * 194 * @return The exception message. 195 */ 196 @Override 197 public String getMessage() { 198 return Messages.getString(super.getMessage(), (Object[]) getInfo()); 199 } 200 201 /** 202 * Retrieves error code of the exception. Could be used as key for internationalization. 203 * 204 * @return the code. 205 */ 206 public String getCode() { 207 return super.getMessage(); 208 } 209 210 /** 211 * Retrieves array of complementary info (context). Could be used as parameter for internationalization. 212 * 213 * @return the context info. 214 */ 215 public String[] getInfo() { 216 return info; 217 } 218 }