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 }