mirror of
https://github.com/jenkinsci/jenkins.git
synced 2026-11-11 11:06:25 +00:00
Annotate hudson.Util methods.
The change adds annotations for all methods inside the class. The initial idea - enforce checks of symlink methods to prevent NPEs on Windows platforms. Signed-off-by: Oleg Nenashev <o.v.nenashev@gmail.com>
This commit is contained in:
1 parent
1568a8bc24
commit
48cc7e03d4
1 file changed
+120
-66
@@ -73,6 +73,8 @@ import hudson.util.jna.Kernel32Utils;
|
||||
|
||||
import static hudson.util.jna.GNUCLibrary.LIBC;
|
||||
import java.security.DigestInputStream;
|
||||
import javax.annotation.CheckForNull;
|
||||
import javax.annotation.Nonnull;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
|
||||
/**
|
||||
@@ -94,7 +96,8 @@ public class Util {
|
||||
* Creates a filtered sublist.
|
||||
* @since 1.176
|
||||
*/
|
||||
public static <T> List<T> filter( Iterable<?> base, Class<T> type ) {
|
||||
@Nonnull
|
||||
public static <T> List<T> filter( @Nonnull Iterable<?> base, @Nonnull Class<T> type ) {
|
||||
List<T> r = new ArrayList<T>();
|
||||
for (Object i : base) {
|
||||
if(type.isInstance(i))
|
||||
@@ -106,7 +109,8 @@ public class Util {
|
||||
/**
|
||||
* Creates a filtered sublist.
|
||||
*/
|
||||
public static <T> List<T> filter( List<?> base, Class<T> type ) {
|
||||
@Nonnull
|
||||
public static <T> List<T> filter( @Nonnull List<?> base, @Nonnull Class<T> type ) {
|
||||
return filter((Iterable)base,type);
|
||||
}
|
||||
|
||||
@@ -122,7 +126,8 @@ public class Util {
|
||||
* Unlike shell, undefined variables are left as-is (this behavior is the same as Ant.)
|
||||
*
|
||||
*/
|
||||
public static String replaceMacro(String s, Map<String,String> properties) {
|
||||
@CheckForNull
|
||||
public static String replaceMacro( @CheckForNull String s, @Nonnull Map<String,String> properties) {
|
||||
return replaceMacro(s,new VariableResolver.ByMap<String>(properties));
|
||||
}
|
||||
|
||||
@@ -132,7 +137,8 @@ public class Util {
|
||||
* <p>
|
||||
* Unlike shell, undefined variables are left as-is (this behavior is the same as Ant.)
|
||||
*/
|
||||
public static String replaceMacro(String s, VariableResolver<String> resolver) {
|
||||
@CheckForNull
|
||||
public static String replaceMacro(@CheckForNull String s, @Nonnull VariableResolver<String> resolver) {
|
||||
if (s == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -165,11 +171,13 @@ public class Util {
|
||||
/**
|
||||
* Loads the contents of a file into a string.
|
||||
*/
|
||||
public static String loadFile(File logfile) throws IOException {
|
||||
@Nonnull
|
||||
public static String loadFile(@Nonnull File logfile) throws IOException {
|
||||
return loadFile(logfile, Charset.defaultCharset());
|
||||
}
|
||||
|
||||
public static String loadFile(File logfile,Charset charset) throws IOException {
|
||||
@Nonnull
|
||||
public static String loadFile(@Nonnull File logfile, @Nonnull Charset charset) throws IOException {
|
||||
if(!logfile.exists())
|
||||
return "";
|
||||
|
||||
@@ -195,7 +203,7 @@ public class Util {
|
||||
* @throws IOException
|
||||
* if the operation fails.
|
||||
*/
|
||||
public static void deleteContentsRecursive(File file) throws IOException {
|
||||
public static void deleteContentsRecursive(@Nonnull File file) throws IOException {
|
||||
File[] files = file.listFiles();
|
||||
if(files==null)
|
||||
return; // the directory didn't exist in the first place
|
||||
@@ -208,7 +216,7 @@ public class Util {
|
||||
* @param f a file to delete
|
||||
* @throws IOException if it exists but could not be successfully deleted
|
||||
*/
|
||||
public static void deleteFile(File f) throws IOException {
|
||||
public static void deleteFile(@Nonnull File f) throws IOException {
|
||||
if (!f.delete()) {
|
||||
if(!f.exists())
|
||||
// we are trying to delete a file that no longer exists, so this is not an error
|
||||
@@ -259,7 +267,7 @@ public class Util {
|
||||
/**
|
||||
* Makes the given file writable by any means possible.
|
||||
*/
|
||||
private static void makeWritable(File f) {
|
||||
private static void makeWritable(@Nonnull File f) {
|
||||
if (f.setWritable(true)) {
|
||||
return;
|
||||
}
|
||||
@@ -287,7 +295,7 @@ public class Util {
|
||||
|
||||
}
|
||||
|
||||
public static void deleteRecursive(File dir) throws IOException {
|
||||
public static void deleteRecursive(@Nonnull File dir) throws IOException {
|
||||
if(!isSymlink(dir))
|
||||
deleteContentsRecursive(dir);
|
||||
try {
|
||||
@@ -321,7 +329,7 @@ public class Util {
|
||||
* Checks if the given file represents a symlink.
|
||||
*/
|
||||
//Taken from http://svn.apache.org/viewvc/maven/shared/trunk/file-management/src/main/java/org/apache/maven/shared/model/fileset/util/FileSetManager.java?view=markup
|
||||
public static boolean isSymlink(File file) throws IOException {
|
||||
public static boolean isSymlink(@Nonnull File file) throws IOException {
|
||||
Boolean r = isSymlinkJava7(file);
|
||||
if (r != null) {
|
||||
return r;
|
||||
@@ -350,7 +358,7 @@ public class Util {
|
||||
}
|
||||
|
||||
@SuppressWarnings("NP_BOOLEAN_RETURN_NULL")
|
||||
private static Boolean isSymlinkJava7(File file) throws IOException {
|
||||
private static Boolean isSymlinkJava7(@Nonnull File file) throws IOException {
|
||||
try {
|
||||
Object path = File.class.getMethod("toPath").invoke(file);
|
||||
return (Boolean) Class.forName("java.nio.file.Files").getMethod("isSymbolicLink", Class.forName("java.nio.file.Path")).invoke(null, path);
|
||||
@@ -379,13 +387,14 @@ public class Util {
|
||||
* On Windows, error messages for IOException aren't very helpful.
|
||||
* This method generates additional user-friendly error message to the listener
|
||||
*/
|
||||
public static void displayIOException( IOException e, TaskListener listener ) {
|
||||
public static void displayIOException(@Nonnull IOException e, @Nonnull TaskListener listener ) {
|
||||
String msg = getWin32ErrorMessage(e);
|
||||
if(msg!=null)
|
||||
listener.getLogger().println(msg);
|
||||
}
|
||||
|
||||
public static String getWin32ErrorMessage(IOException e) {
|
||||
@CheckForNull
|
||||
public static String getWin32ErrorMessage(@Nonnull IOException e) {
|
||||
return getWin32ErrorMessage((Throwable)e);
|
||||
}
|
||||
|
||||
@@ -395,6 +404,7 @@ public class Util {
|
||||
* @return
|
||||
* null if there seems to be no error code or if the platform is not Win32.
|
||||
*/
|
||||
@CheckForNull
|
||||
public static String getWin32ErrorMessage(Throwable e) {
|
||||
String msg = e.getMessage();
|
||||
if(msg!=null) {
|
||||
@@ -420,6 +430,7 @@ public class Util {
|
||||
* @return
|
||||
* null if no such message is available.
|
||||
*/
|
||||
@CheckForNull
|
||||
public static String getWin32ErrorMessage(int n) {
|
||||
try {
|
||||
ResourceBundle rb = ResourceBundle.getBundle("/hudson/win32errors");
|
||||
@@ -433,6 +444,7 @@ public class Util {
|
||||
/**
|
||||
* Guesses the current host name.
|
||||
*/
|
||||
@Nonnull
|
||||
public static String getHostName() {
|
||||
try {
|
||||
return InetAddress.getLocalHost().getHostName();
|
||||
@@ -441,21 +453,21 @@ public class Util {
|
||||
}
|
||||
}
|
||||
|
||||
public static void copyStream(InputStream in,OutputStream out) throws IOException {
|
||||
public static void copyStream(@Nonnull InputStream in,@Nonnull OutputStream out) throws IOException {
|
||||
byte[] buf = new byte[8192];
|
||||
int len;
|
||||
while((len=in.read(buf))>=0)
|
||||
out.write(buf,0,len);
|
||||
}
|
||||
|
||||
public static void copyStream(Reader in, Writer out) throws IOException {
|
||||
public static void copyStream(@Nonnull Reader in, @Nonnull Writer out) throws IOException {
|
||||
char[] buf = new char[8192];
|
||||
int len;
|
||||
while((len=in.read(buf))>0)
|
||||
out.write(buf,0,len);
|
||||
}
|
||||
|
||||
public static void copyStreamAndClose(InputStream in,OutputStream out) throws IOException {
|
||||
public static void copyStreamAndClose(@Nonnull InputStream in, @Nonnull OutputStream out) throws IOException {
|
||||
try {
|
||||
copyStream(in,out);
|
||||
} finally {
|
||||
@@ -464,7 +476,7 @@ public class Util {
|
||||
}
|
||||
}
|
||||
|
||||
public static void copyStreamAndClose(Reader in,Writer out) throws IOException {
|
||||
public static void copyStreamAndClose(@Nonnull Reader in, @Nonnull Writer out) throws IOException {
|
||||
try {
|
||||
copyStream(in,out);
|
||||
} finally {
|
||||
@@ -483,18 +495,21 @@ public class Util {
|
||||
* @since 1.145
|
||||
* @see QuotedStringTokenizer
|
||||
*/
|
||||
public static String[] tokenize(String s,String delimiter) {
|
||||
@Nonnull
|
||||
public static String[] tokenize(@Nonnull String s, @CheckForNull String delimiter) {
|
||||
return QuotedStringTokenizer.tokenize(s,delimiter);
|
||||
}
|
||||
|
||||
public static String[] tokenize(String s) {
|
||||
@Nonnull
|
||||
public static String[] tokenize(@Nonnull String s) {
|
||||
return tokenize(s," \t\n\r\f");
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the map format of the environment variables to the K=V format in the array.
|
||||
*/
|
||||
public static String[] mapToEnv(Map<String,String> m) {
|
||||
@Nonnull
|
||||
public static String[] mapToEnv(@Nonnull Map<String,String> m) {
|
||||
String[] r = new String[m.size()];
|
||||
int idx=0;
|
||||
|
||||
@@ -504,7 +519,7 @@ public class Util {
|
||||
return r;
|
||||
}
|
||||
|
||||
public static int min(int x, int... values) {
|
||||
public static int min(int x, @Nonnull int... values) {
|
||||
for (int i : values) {
|
||||
if(i<x)
|
||||
x=i;
|
||||
@@ -512,11 +527,13 @@ public class Util {
|
||||
return x;
|
||||
}
|
||||
|
||||
public static String nullify(String v) {
|
||||
@CheckForNull
|
||||
public static String nullify(@CheckForNull String v) {
|
||||
return fixEmpty(v);
|
||||
}
|
||||
|
||||
public static String removeTrailingSlash(String s) {
|
||||
@Nonnull
|
||||
public static String removeTrailingSlash(@Nonnull String s) {
|
||||
if(s.endsWith("/")) return s.substring(0,s.length()-1);
|
||||
else return s;
|
||||
}
|
||||
@@ -531,7 +548,8 @@ public class Util {
|
||||
* case subject was null and subject + suffix otherwise.
|
||||
* @since 1.505
|
||||
*/
|
||||
public static String ensureEndsWith(String subject, String suffix) {
|
||||
@CheckForNull
|
||||
public static String ensureEndsWith(@CheckForNull String subject, @CheckForNull String suffix) {
|
||||
|
||||
if (subject == null) return null;
|
||||
|
||||
@@ -549,7 +567,8 @@ public class Util {
|
||||
* 32-char wide string
|
||||
* @see DigestUtils#md5Hex(InputStream)
|
||||
*/
|
||||
public static String getDigestOf(InputStream source) throws IOException {
|
||||
@Nonnull
|
||||
public static String getDigestOf(@Nonnull InputStream source) throws IOException {
|
||||
try {
|
||||
MessageDigest md5 = MessageDigest.getInstance("MD5");
|
||||
|
||||
@@ -574,7 +593,8 @@ public class Util {
|
||||
*/
|
||||
}
|
||||
|
||||
public static String getDigestOf(String text) {
|
||||
@Nonnull
|
||||
public static String getDigestOf(@Nonnull String text) {
|
||||
try {
|
||||
return getDigestOf(new ByteArrayInputStream(text.getBytes("UTF-8")));
|
||||
} catch (IOException e) {
|
||||
@@ -589,7 +609,8 @@ public class Util {
|
||||
* @throws IOException in case reading fails
|
||||
* @since 1.525
|
||||
*/
|
||||
public static String getDigestOf(File file) throws IOException {
|
||||
@Nonnull
|
||||
public static String getDigestOf(@Nonnull File file) throws IOException {
|
||||
InputStream is = new FileInputStream(file);
|
||||
try {
|
||||
return getDigestOf(new BufferedInputStream(is));
|
||||
@@ -602,7 +623,8 @@ public class Util {
|
||||
* Converts a string into 128-bit AES key.
|
||||
* @since 1.308
|
||||
*/
|
||||
public static SecretKey toAes128Key(String s) {
|
||||
@Nonnull
|
||||
public static SecretKey toAes128Key(@Nonnull String s) {
|
||||
try {
|
||||
// turn secretKey into 256 bit hash
|
||||
MessageDigest digest = MessageDigest.getInstance("SHA-256");
|
||||
@@ -618,7 +640,8 @@ public class Util {
|
||||
}
|
||||
}
|
||||
|
||||
public static String toHexString(byte[] data, int start, int len) {
|
||||
@Nonnull
|
||||
public static String toHexString(@Nonnull byte[] data, int start, int len) {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
for( int i=0; i<len; i++ ) {
|
||||
int b = data[start+i]&0xFF;
|
||||
@@ -628,11 +651,13 @@ public class Util {
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public static String toHexString(byte[] bytes) {
|
||||
@Nonnull
|
||||
public static String toHexString(@Nonnull byte[] bytes) {
|
||||
return toHexString(bytes,0,bytes.length);
|
||||
}
|
||||
|
||||
public static byte[] fromHexString(String data) {
|
||||
@Nonnull
|
||||
public static byte[] fromHexString(@Nonnull String data) {
|
||||
byte[] r = new byte[data.length() / 2];
|
||||
for (int i = 0; i < data.length(); i += 2)
|
||||
r[i / 2] = (byte) Integer.parseInt(data.substring(i, i + 2), 16);
|
||||
@@ -646,6 +671,7 @@ public class Util {
|
||||
* @param duration
|
||||
* number of milliseconds.
|
||||
*/
|
||||
@Nonnull
|
||||
public static String getTimeSpanString(long duration) {
|
||||
// Break the duration up in to units.
|
||||
long years = duration / ONE_YEAR_MS;
|
||||
@@ -692,10 +718,11 @@ public class Util {
|
||||
* So 13 minutes and 43 seconds returns just "13 minutes", but 3 minutes
|
||||
* and 43 seconds is "3 minutes 43 seconds".
|
||||
*/
|
||||
@Nonnull
|
||||
private static String makeTimeSpanString(long bigUnit,
|
||||
String bigLabel,
|
||||
@Nonnull String bigLabel,
|
||||
long smallUnit,
|
||||
String smallLabel) {
|
||||
@Nonnull String smallLabel) {
|
||||
String text = bigLabel;
|
||||
if (bigUnit < 10)
|
||||
text += ' ' + smallLabel;
|
||||
@@ -707,6 +734,7 @@ public class Util {
|
||||
* Get a human readable string representing strings like "xxx days ago",
|
||||
* which should be used to point to the occurrence of an event in the past.
|
||||
*/
|
||||
@Nonnull
|
||||
public static String getPastTimeString(long duration) {
|
||||
return Messages.Util_pastTime(getTimeSpanString(duration));
|
||||
}
|
||||
@@ -720,7 +748,8 @@ public class Util {
|
||||
* See {@link Messages#Util_year(Object)} for an example.
|
||||
* Deprecated since 2009-06-24, remove method after 2009-12-24.
|
||||
*/
|
||||
public static String combine(long n, String suffix) {
|
||||
@Nonnull
|
||||
public static String combine(long n, @Nonnull String suffix) {
|
||||
String s = Long.toString(n)+' '+suffix;
|
||||
if(n!=1)
|
||||
// Just adding an 's' won't work in most natural languages, even English has exception to the rule (e.g. copy/copies).
|
||||
@@ -731,7 +760,8 @@ public class Util {
|
||||
/**
|
||||
* Create a sub-list by only picking up instances of the specified type.
|
||||
*/
|
||||
public static <T> List<T> createSubList( Collection<?> source, Class<T> type ) {
|
||||
@Nonnull
|
||||
public static <T> List<T> createSubList(@Nonnull Collection<?> source, @Nonnull Class<T> type ) {
|
||||
List<T> r = new ArrayList<T>();
|
||||
for (Object item : source) {
|
||||
if(type.isInstance(item))
|
||||
@@ -749,7 +779,8 @@ public class Util {
|
||||
* {@link #rawEncode(String)} should generally be used instead, though be careful to pass only
|
||||
* a single path component to that method (it will encode /, but this method does not).
|
||||
*/
|
||||
public static String encode(String s) {
|
||||
@Nonnull
|
||||
public static String encode(@Nonnull String s) {
|
||||
try {
|
||||
boolean escaped = false;
|
||||
|
||||
@@ -806,7 +837,8 @@ public class Util {
|
||||
* single path component used in constructing a URL.
|
||||
* Method name inspired by PHP's rawurlencode.
|
||||
*/
|
||||
public static String rawEncode(String s) {
|
||||
@Nonnull
|
||||
public static String rawEncode(@Nonnull String s) {
|
||||
boolean escaped = false;
|
||||
StringBuilder out = null;
|
||||
CharsetEncoder enc = null;
|
||||
@@ -855,7 +887,8 @@ public class Util {
|
||||
/**
|
||||
* Escapes HTML unsafe characters like <, & to the respective character entities.
|
||||
*/
|
||||
public static String escape(String text) {
|
||||
@Nonnull
|
||||
public static String escape(@Nonnull String text) {
|
||||
if (text==null) return null;
|
||||
StringBuilder buf = new StringBuilder(text.length()+64);
|
||||
for( int i=0; i<text.length(); i++ ) {
|
||||
@@ -888,7 +921,8 @@ public class Util {
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public static String xmlEscape(String text) {
|
||||
@Nonnull
|
||||
public static String xmlEscape(@Nonnull String text) {
|
||||
StringBuilder buf = new StringBuilder(text.length()+64);
|
||||
for( int i=0; i<text.length(); i++ ) {
|
||||
char ch = text.charAt(i);
|
||||
@@ -906,14 +940,14 @@ public class Util {
|
||||
/**
|
||||
* Creates an empty file.
|
||||
*/
|
||||
public static void touch(File file) throws IOException {
|
||||
public static void touch(@Nonnull File file) throws IOException {
|
||||
new FileOutputStream(file).close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies a single file by using Ant.
|
||||
*/
|
||||
public static void copyFile(File src, File dst) throws BuildException {
|
||||
public static void copyFile(@Nonnull File src, @Nonnull File dst) throws BuildException {
|
||||
Copy cp = new Copy();
|
||||
cp.setProject(new org.apache.tools.ant.Project());
|
||||
cp.setTofile(dst);
|
||||
@@ -925,7 +959,8 @@ public class Util {
|
||||
/**
|
||||
* Convert null to "".
|
||||
*/
|
||||
public static String fixNull(String s) {
|
||||
@Nonnull
|
||||
public static String fixNull(@CheckForNull String s) {
|
||||
if(s==null) return "";
|
||||
else return s;
|
||||
}
|
||||
@@ -933,7 +968,8 @@ public class Util {
|
||||
/**
|
||||
* Convert empty string to null.
|
||||
*/
|
||||
public static String fixEmpty(String s) {
|
||||
@CheckForNull
|
||||
public static String fixEmpty(@CheckForNull String s) {
|
||||
if(s==null || s.length()==0) return null;
|
||||
return s;
|
||||
}
|
||||
@@ -943,31 +979,37 @@ public class Util {
|
||||
*
|
||||
* @since 1.154
|
||||
*/
|
||||
public static String fixEmptyAndTrim(String s) {
|
||||
@CheckForNull
|
||||
public static String fixEmptyAndTrim(@CheckForNull String s) {
|
||||
if(s==null) return null;
|
||||
return fixEmpty(s.trim());
|
||||
}
|
||||
|
||||
public static <T> List<T> fixNull(List<T> l) {
|
||||
@Nonnull
|
||||
public static <T> List<T> fixNull(@CheckForNull List<T> l) {
|
||||
return l!=null ? l : Collections.<T>emptyList();
|
||||
}
|
||||
|
||||
public static <T> Set<T> fixNull(Set<T> l) {
|
||||
@Nonnull
|
||||
public static <T> Set<T> fixNull(@CheckForNull Set<T> l) {
|
||||
return l!=null ? l : Collections.<T>emptySet();
|
||||
}
|
||||
|
||||
public static <T> Collection<T> fixNull(Collection<T> l) {
|
||||
@Nonnull
|
||||
public static <T> Collection<T> fixNull(@CheckForNull Collection<T> l) {
|
||||
return l!=null ? l : Collections.<T>emptySet();
|
||||
}
|
||||
|
||||
public static <T> Iterable<T> fixNull(Iterable<T> l) {
|
||||
@Nonnull
|
||||
public static <T> Iterable<T> fixNull(@CheckForNull Iterable<T> l) {
|
||||
return l!=null ? l : Collections.<T>emptySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Cuts all the leading path portion and get just the file name.
|
||||
*/
|
||||
public static String getFileName(String filePath) {
|
||||
@Nonnull
|
||||
public static String getFileName(@Nonnull String filePath) {
|
||||
int idx = filePath.lastIndexOf('\\');
|
||||
if(idx>=0)
|
||||
return getFileName(filePath.substring(idx+1));
|
||||
@@ -980,7 +1022,8 @@ public class Util {
|
||||
/**
|
||||
* Concatenate multiple strings by inserting a separator.
|
||||
*/
|
||||
public static String join(Collection<?> strings, String separator) {
|
||||
@Nonnull
|
||||
public static String join(@Nonnull Collection<?> strings, @Nonnull String separator) {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
boolean first=true;
|
||||
for (Object s : strings) {
|
||||
@@ -994,7 +1037,8 @@ public class Util {
|
||||
/**
|
||||
* Combines all the given collections into a single list.
|
||||
*/
|
||||
public static <T> List<T> join(Collection<? extends T>... items) {
|
||||
@Nonnull
|
||||
public static <T> List<T> join(@Nonnull Collection<? extends T>... items) {
|
||||
int size = 0;
|
||||
for (Collection<? extends T> item : items)
|
||||
size += item.size();
|
||||
@@ -1021,7 +1065,8 @@ public class Util {
|
||||
* Can be null.
|
||||
* @since 1.172
|
||||
*/
|
||||
public static FileSet createFileSet(File baseDir, String includes, String excludes) {
|
||||
@Nonnull
|
||||
public static FileSet createFileSet(@Nonnull File baseDir, @Nonnull String includes, @CheckForNull String excludes) {
|
||||
FileSet fs = new FileSet();
|
||||
fs.setDir(baseDir);
|
||||
fs.setProject(new Project());
|
||||
@@ -1043,7 +1088,8 @@ public class Util {
|
||||
return fs;
|
||||
}
|
||||
|
||||
public static FileSet createFileSet(File baseDir, String includes) {
|
||||
@Nonnull
|
||||
public static FileSet createFileSet(@Nonnull File baseDir, @Nonnull String includes) {
|
||||
return createFileSet(baseDir,includes,null);
|
||||
}
|
||||
|
||||
@@ -1059,7 +1105,8 @@ public class Util {
|
||||
* @param symlinkPath
|
||||
* Where to create a symlink in (relative to {@code baseDir})
|
||||
*/
|
||||
public static void createSymlink(File baseDir, String targetPath, String symlinkPath, TaskListener listener) throws InterruptedException {
|
||||
public static void createSymlink(@Nonnull File baseDir, @Nonnull String targetPath,
|
||||
@Nonnull String symlinkPath, @Nonnull TaskListener listener) throws InterruptedException {
|
||||
try {
|
||||
if (createSymlinkJava7(baseDir, targetPath, symlinkPath)) {
|
||||
return;
|
||||
@@ -1131,7 +1178,7 @@ public class Util {
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean createSymlinkJava7(File baseDir, String targetPath, String symlinkPath) throws IOException {
|
||||
private static boolean createSymlinkJava7(@Nonnull File baseDir, @Nonnull String targetPath, @Nonnull String symlinkPath) throws IOException {
|
||||
try {
|
||||
Object path = File.class.getMethod("toPath").invoke(new File(baseDir, symlinkPath));
|
||||
Object target = Class.forName("java.nio.file.Paths").getMethod("get", String.class, String[].class).invoke(null, targetPath, new String[0]);
|
||||
@@ -1201,7 +1248,8 @@ public class Util {
|
||||
* @return null
|
||||
* if the specified file is not a symlink.
|
||||
*/
|
||||
public static File resolveSymlinkToFile(File link) throws InterruptedException, IOException {
|
||||
@CheckForNull
|
||||
public static File resolveSymlinkToFile(@Nonnull File link) throws InterruptedException, IOException {
|
||||
String target = resolveSymlink(link);
|
||||
if (target==null) return null;
|
||||
|
||||
@@ -1221,7 +1269,8 @@ public class Util {
|
||||
* If the symlink is relative, the returned string is that relative representation.
|
||||
* The relative path is meant to be resolved from the location of the symlink.
|
||||
*/
|
||||
public static String resolveSymlink(File link) throws InterruptedException, IOException {
|
||||
@CheckForNull
|
||||
public static String resolveSymlink(@Nonnull File link) throws InterruptedException, IOException {
|
||||
try { // Java 7
|
||||
Object path = File.class.getMethod("toPath").invoke(link);
|
||||
return Class.forName("java.nio.file.Files").getMethod("readSymbolicLink", Class.forName("java.nio.file.Path")).invoke(null, path).toString();
|
||||
@@ -1306,7 +1355,8 @@ public class Util {
|
||||
* Wraps with the error icon and the CSS class to render error message.
|
||||
* @since 1.173
|
||||
*/
|
||||
public static String wrapToErrorSpan(String s) {
|
||||
@Nonnull
|
||||
public static String wrapToErrorSpan(@Nonnull String s) {
|
||||
s = "<span class=error style='display:inline-block'>"+s+"</span>";
|
||||
return s;
|
||||
}
|
||||
@@ -1319,7 +1369,8 @@ public class Util {
|
||||
* @param defaultNumber number to return if the string can not be parsed
|
||||
* @return returns the parsed string; otherwise the default number
|
||||
*/
|
||||
public static Number tryParseNumber(String numberStr, Number defaultNumber) {
|
||||
@CheckForNull
|
||||
public static Number tryParseNumber(@CheckForNull String numberStr, @CheckForNull Number defaultNumber) {
|
||||
if ((numberStr == null) || (numberStr.length() == 0)) {
|
||||
return defaultNumber;
|
||||
}
|
||||
@@ -1334,7 +1385,7 @@ public class Util {
|
||||
* Checks if the public method defined on the base type with the given arguments
|
||||
* are overridden in the given derived type.
|
||||
*/
|
||||
public static boolean isOverridden(Class base, Class derived, String methodName, Class... types) {
|
||||
public static boolean isOverridden(@Nonnull Class base, @Nonnull Class derived, @Nonnull String methodName, @Nonnull Class... types) {
|
||||
try {
|
||||
return !base.getMethod(methodName, types).equals(
|
||||
derived.getMethod(methodName,types));
|
||||
@@ -1349,7 +1400,8 @@ public class Util {
|
||||
* @param ext
|
||||
* For example, ".zip"
|
||||
*/
|
||||
public static File changeExtension(File dst, String ext) {
|
||||
@Nonnull
|
||||
public static File changeExtension(@Nonnull File dst, @Nonnull String ext) {
|
||||
String p = dst.getPath();
|
||||
int pos = p.lastIndexOf('.');
|
||||
if (pos<0) return new File(p+ext);
|
||||
@@ -1359,7 +1411,8 @@ public class Util {
|
||||
/**
|
||||
* Null-safe String intern method.
|
||||
*/
|
||||
public static String intern(String s) {
|
||||
@CheckForNull
|
||||
public static String intern(@CheckForNull String s) {
|
||||
return s==null ? s : s.intern();
|
||||
}
|
||||
|
||||
@@ -1370,7 +1423,7 @@ public class Util {
|
||||
* implementing this by ourselves allow it to be more lenient about
|
||||
* escaping of URI.
|
||||
*/
|
||||
public static boolean isAbsoluteUri(String uri) {
|
||||
public static boolean isAbsoluteUri(@Nonnull String uri) {
|
||||
int idx = uri.indexOf(':');
|
||||
if (idx<0) return false; // no ':'. can't be absolute
|
||||
|
||||
@@ -1382,7 +1435,7 @@ public class Util {
|
||||
* Works like {@link String#indexOf(int)} but 'not found' is returned as s.length(), not -1.
|
||||
* This enables more straight-forward comparison.
|
||||
*/
|
||||
private static int _indexOf(String s, char ch) {
|
||||
private static int _indexOf(@Nonnull String s, char ch) {
|
||||
int idx = s.indexOf(ch);
|
||||
if (idx<0) return s.length();
|
||||
return idx;
|
||||
@@ -1392,7 +1445,8 @@ public class Util {
|
||||
* Loads a key/value pair string as {@link Properties}
|
||||
* @since 1.392
|
||||
*/
|
||||
public static Properties loadProperties(String properties) throws IOException {
|
||||
@Nonnull
|
||||
public static Properties loadProperties(@Nonnull String properties) throws IOException {
|
||||
Properties p = new Properties();
|
||||
p.load(new StringReader(properties));
|
||||
return p;
|
||||
|
||||
Reference in new issue
Block a user