diff --git a/Dorkbox-Util/.classpath b/Dorkbox-Util/.classpath
index e7d4eb3..ad0537e 100644
--- a/Dorkbox-Util/.classpath
+++ b/Dorkbox-Util/.classpath
@@ -11,7 +11,6 @@
-
@@ -25,5 +24,6 @@
+
diff --git a/Dorkbox-Util/LICENSE b/Dorkbox-Util/LICENSE
index cef1190..70133b9 100644
--- a/Dorkbox-Util/LICENSE
+++ b/Dorkbox-Util/LICENSE
@@ -66,6 +66,12 @@
+ - jOOU, Unsigned Numbers for Java - Apache 2.0 License
+ https://github.com/jOOQ/jOOU/tree/master/jOOU
+ Copyright 2011-2013, Lukas Eder, lukas.eder@gmail.com
+
+
+
- Kryo - New BSD License
https://github.com/EsotericSoftware/kryo
Copyright 2008, Nathan Sweet, All rights reserved.
@@ -93,7 +99,8 @@
- - jOOU, Unsigned Numbers for Java - Apache 2.0 License
- https://github.com/jOOQ/jOOU/tree/master/jOOU
- Copyright 2011-2013, Lukas Eder, lukas.eder@gmail.com
+ - migbase64 - High performance base64 encoder & decoder - BSD License
+ http://migbase64.sourceforge.net/
+ Copyright 2004, Mikael Grev, MiG InfoCom AB. (base64@miginfocom.com)
+
diff --git a/Dorkbox-Util/src/dorkbox/util/FileUtil.java b/Dorkbox-Util/src/dorkbox/util/FileUtil.java
index 87a3064..0b4e55d 100644
--- a/Dorkbox-Util/src/dorkbox/util/FileUtil.java
+++ b/Dorkbox-Util/src/dorkbox/util/FileUtil.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2010 dorkbox, llc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package dorkbox.util;
import java.io.BufferedInputStream;
@@ -20,7 +35,6 @@ import java.util.zip.ZipInputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
/**
* File related utilities.
*
@@ -158,6 +172,12 @@ public class FileUtil {
String normalizedIn = normalize(in.getAbsolutePath());
String normalizedout = normalize(out.getAbsolutePath());
+ if (normalizedIn.equalsIgnoreCase(normalizedout)) {
+ logger.warn("Source equals destination! " + normalizedIn);
+ return out;
+ }
+
+
// if out doesn't exist, then create it.
File parentOut = out.getParentFile();
if (!parentOut.canWrite()) {
@@ -174,6 +194,11 @@ public class FileUtil {
try {
sourceChannel = new FileInputStream(normalizedIn).getChannel();
destinationChannel = new FileOutputStream(normalizedout).getChannel();
+
+ if (sourceChannel.size() == 0) {
+ logger2.warn("Source size is ZERO: " + normalizedIn);
+ }
+
sourceChannel.transferTo(0, sourceChannel.size(), destinationChannel);
} finally {
try {
@@ -252,7 +277,7 @@ public class FileUtil {
/**
* Moves a file, overwriting any existing file at the destination.
*/
- public static File moveFile(String in, String out) {
+ public static File moveFile(String in, String out) throws IOException {
if (in == null || in.isEmpty()) {
throw new IllegalArgumentException("in cannot be null.");
}
@@ -266,7 +291,7 @@ public class FileUtil {
/**
* Moves a file, overwriting any existing file at the destination.
*/
- public static File moveFile(File in, File out) {
+ public static File moveFile(File in, File out) throws IOException {
if (in == null) {
throw new IllegalArgumentException("in cannot be null.");
}
@@ -274,17 +299,13 @@ public class FileUtil {
throw new IllegalArgumentException("out cannot be null.");
}
- System.err.println("\t\t: Moving file");
- System.err.println("\t\t: " + in.getAbsolutePath());
- System.err.println("\t\t: " + out.getAbsolutePath());
-
if (out.canRead()) {
out.delete();
}
boolean renameSuccess = renameTo(in, out);
if (!renameSuccess) {
- throw new RuntimeException("Unable to move file: '" + in.getAbsolutePath() + "' -> '" + out.getAbsolutePath() + "'");
+ throw new IOException("Unable to move file: '" + in.getAbsolutePath() + "' -> '" + out.getAbsolutePath() + "'");
}
return out;
}
@@ -300,7 +321,10 @@ public class FileUtil {
/**
* Copies a directory from one location to another
*/
- public static void copyDirectory(File src, File dest, String... dirNamesToIgnore) throws IOException {
+ public static void copyDirectory(File src_, File dest_, String... dirNamesToIgnore) throws IOException {
+ File src = FileUtil.normalize(src_);
+ File dest = FileUtil.normalize(dest_);
+
if (dirNamesToIgnore.length > 0) {
String name = src.getName();
for (String ignore : dirNamesToIgnore) {
@@ -388,37 +412,80 @@ public class FileUtil {
/**
* Deletes a file or directory and all files and sub-directories under it.
+ * @param namesToIgnore if prefaced with a '/', it will ignore as a directory instead of file
*/
- public static boolean delete(String fileName) {
+ public static boolean delete(String fileName, String... namesToIgnore) {
if (fileName == null) {
throw new IllegalArgumentException("fileName cannot be null.");
}
- return delete(new File(fileName));
+ return delete(new File(fileName), namesToIgnore);
}
/**
* Deletes a file or directory and all files and sub-directories under it.
+ * @param namesToIgnore if prefaced with a '/', it will ignore as a directory instead of file
*/
- public static boolean delete(File file) {
+ public static boolean delete(File file, String... namesToIgnore) {
+ boolean ignored = false;
Logger logger2 = logger;
if (file.exists() && file.isDirectory()) {
File[] files = file.listFiles();
for (int i = 0, n = files.length; i < n; i++) {
+ boolean delete = true;
+ String name2 = files[i].getName();
+
if (files[i].isDirectory()) {
- delete(files[i].getAbsolutePath());
- } else {
- if (logger2.isTraceEnabled()) {
- logger2.trace("Deleting file: {}", files[i]);
+ for (String name : namesToIgnore) {
+ if (name.startsWith("/") && name.equals(name2)) {
+ if (logger2.isTraceEnabled()) {
+ logger2.trace("Skipping delete dir: {}", files[i]);
+ }
+ ignored = true;
+ delete = false;
+ break;
+ }
+ }
+
+ if (delete) {
+ if (logger2.isTraceEnabled()) {
+ logger2.trace("Deleting dir: {}", files[i]);
+ }
+ delete(files[i], namesToIgnore);
+ }
+ } else {
+ for (String name : namesToIgnore) {
+ if (!name.startsWith("/") && name.equals(name2)) {
+ if (logger2.isTraceEnabled()) {
+ logger2.trace("Skipping delete file: {}", files[i]);
+ }
+ ignored = true;
+ delete = false;
+ break;
+ }
+ }
+
+ if (delete) {
+ if (logger2.isTraceEnabled()) {
+ logger2.trace("Deleting file: {}", files[i]);
+ }
+ files[i].delete();
}
- files[i].delete();
}
}
}
+
+ // don't try to delete the dir if there was an ignored file in it
+ if (ignored) {
+ if (logger2.isTraceEnabled()) {
+ logger2.trace("Skipping deleting file: {}", file);
+ }
+ return true;
+ }
+
if (logger2.isTraceEnabled()) {
logger2.trace("Deleting file: {}", file);
}
-
return file.delete();
}
@@ -703,7 +770,7 @@ public class FileUtil {
* This is different, in that it returns ALL FILES, instead of ones that just match a specific extension.
* @return the list of all files in the root+sub-dirs.
*/
- public static List parseDir(String rootDirectory) {
+ public static List parseDir(String rootDirectory) throws IOException {
if (rootDirectory == null) {
throw new IllegalArgumentException("rootDirectory cannot be null");
}
@@ -716,7 +783,7 @@ public class FileUtil {
* This is different, in that it returns ALL FILES, instead of ones that just match a specific extension.
* @return the list of all files in the root+sub-dirs.
*/
- public static List parseDir(File rootDirectory) {
+ public static List parseDir(File rootDirectory) throws IOException {
return parseDir(rootDirectory, (String) null);
}
@@ -724,10 +791,12 @@ public class FileUtil {
* Parses the specified root directory for files that end in the extension to match. All of the sub-directories are searched as well.
* @return the list of all files in the root+sub-dirs that match the given extension.
*/
- public static List parseDir(File rootDirectory, String... extensionsToMatch) {
+ public static List parseDir(File rootDirectory, String... extensionsToMatch) throws IOException {
List jarList = new LinkedList();
LinkedList directories = new LinkedList();
+ rootDirectory = FileUtil.normalize(rootDirectory.getAbsoluteFile());
+
if (rootDirectory.isDirectory()) {
directories.add(rootDirectory);
@@ -753,7 +822,7 @@ public class FileUtil {
}
}
} else {
- System.err.println("Cannot search directory children if the dir is a file name: " + rootDirectory.getAbsolutePath());
+ throw new IOException("Cannot search directory children if the dir is a file name: " + rootDirectory.getAbsolutePath());
}
@@ -1133,7 +1202,7 @@ public class FileUtil {
return null;
}
- return new File(asString);
+ return new File(asString).getAbsoluteFile();
}
/*
diff --git a/Dorkbox-Util/src/dorkbox/util/Sys.java b/Dorkbox-Util/src/dorkbox/util/Sys.java
index 26be7a5..78c121c 100644
--- a/Dorkbox-Util/src/dorkbox/util/Sys.java
+++ b/Dorkbox-Util/src/dorkbox/util/Sys.java
@@ -17,39 +17,30 @@ package dorkbox.util;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
-import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
-import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.net.InetAddress;
-import java.net.JarURLConnection;
import java.net.NetworkInterface;
import java.net.URL;
-import java.net.URLConnection;
import java.net.UnknownHostException;
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
-import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.bouncycastle.crypto.digests.SHA256Digest;
-import dorkbox.urlHandler.BoxURLConnection;
-
public class Sys {
public static final int javaVersion = getJavaVersion();
public static final boolean isAndroid = getIsAndroid();
@@ -682,189 +673,6 @@ public class Sys {
System.err.println(builder.toString());
}
- /**
- * Finds a list of classes that are annotated with the specified annotation.
- */
- public static final List> findAnnotatedClasses(Class extends Annotation> annotation) {
- return findAnnotatedClasses("", annotation);
- }
-
- /**
- * Finds a list of classes in the specific package that are annotated with the specified annotation.
- */
- public static final List> findAnnotatedClasses(String packageName, Class extends Annotation> annotation) {
- // find ALL ServerLoader classes and use reflection to load them.
- ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
-
- String noDotsPackageName = packageName;
- boolean isEmpty = true;
- if (packageName != null && !packageName.isEmpty()) {
- noDotsPackageName = packageName.replace('.', '/');
- isEmpty = false;
- } else {
- noDotsPackageName = ""; // cannot be null!
- }
-
- // look for all annotated classes in the projects package.
- try {
- LinkedList> annotatedClasses = new LinkedList>();
-
- URL url;
- Enumeration resources = classLoader.getResources(noDotsPackageName);
-
- // lengthy, but it will traverse how we want.
- while (resources.hasMoreElements()) {
- url = resources.nextElement();
- if (url.getProtocol().equals("file")) {
- File file = new File(url.getFile());
- if (!isEmpty) {
- String relativeToDir = FileUtil.getParentRelativeToDir(file, noDotsPackageName);
- if (relativeToDir != null) {
- findAnnotatedClassesRecursive(classLoader, noDotsPackageName, annotation, file, relativeToDir, annotatedClasses);
- }
- } else {
- findAnnotatedClassesRecursive(classLoader, noDotsPackageName, annotation, file, file.getAbsolutePath(), annotatedClasses);
- }
- } else {
- findModulesInJar(classLoader, noDotsPackageName, annotation, url, annotatedClasses);
- }
- }
-
- return annotatedClasses;
- } catch (Exception e) {
- System.err.println("Problem finding annotated classes for: " + annotation.getSimpleName());
- System.exit(-1);
- }
-
- return null;
- }
-
- private static final void findAnnotatedClassesRecursive(ClassLoader classLoader, String packageName,
- Class extends Annotation> annotation, File directory,
- String rootPath,
- List> annotatedClasses) throws ClassNotFoundException {
-
- File[] files = directory.listFiles();
-
- if (files != null) {
- for (File file : files) {
- String absolutePath = file.getAbsolutePath();
- String fileName = file.getName();
-
- if (file.isDirectory()) {
- findAnnotatedClassesRecursive(classLoader, packageName , annotation, file, rootPath, annotatedClasses);
- }
- else if (isValid(fileName)) {
- String classPath = absolutePath.substring(rootPath.length() + 1, absolutePath.length() - 6);
-
- if (!packageName.isEmpty()) {
- if (!classPath.startsWith(packageName)) {
- return;
- }
- }
-
- String toDots = classPath.replaceAll(File.separator, ".");
-
- Class> clazz = Class.forName(toDots, false, classLoader);
- if (clazz.getAnnotation(annotation) != null) {
- annotatedClasses.add(clazz);
- }
- }
- }
- }
- }
-
-
- private static final void findModulesInJar(ClassLoader classLoader, String searchLocation,
- Class extends Annotation> annotation, URL resource, List> annotatedClasses)
- throws IOException, ClassNotFoundException {
-
- URLConnection connection = resource.openConnection();
-
- // Regular JAR
- if (connection instanceof JarURLConnection) {
- JarURLConnection jarURLConnection = (JarURLConnection) connection;
-
- JarFile jarFile = jarURLConnection.getJarFile();
-
- Enumeration entries = jarFile.entries();
-
- // read all the jar entries.
- while (entries.hasMoreElements()) {
- JarEntry jarEntry = entries.nextElement();
- String name = jarEntry.getName();
-
- if (name.startsWith(searchLocation) && // make sure it's at least the correct package
- isValid(name)) {
-
- String classPath = name.replace(File.separatorChar, '.').substring(0, name.lastIndexOf("."));
-
- String toDots = classPath.replaceAll(File.separator, ".");
-
- Class> clazz = Class.forName(toDots, false, classLoader);
- if (clazz.getAnnotation(annotation) != null) {
- annotatedClasses.add(clazz);
- }
- }
- }
- jarFile.close();
- }
- // Files inside of box deployment
- else if (connection instanceof BoxURLConnection) {
- BoxURLConnection hiveJarURLConnection = (BoxURLConnection) connection;
-
- // class files will not have an entry name, which is reserved for resources only
- String name = hiveJarURLConnection.getResourceName();
-
- if (name.startsWith(searchLocation) && // make sure it's at least the correct package
- isValid(name)) {
-
- String classPath = name.substring(0, name.lastIndexOf('.'));
- classPath = classPath.replace('/', '.');
-
- Class> clazz = Class.forName(classPath, false, classLoader);
- if (clazz.getAnnotation(annotation) != null) {
- annotatedClasses.add(clazz);
- }
- }
- }
- else {
- return;
- }
- }
-
- /**
- * remove directories from the search. make sure it's a class file shortcut so we don't load ALL .class files!
- *
- **/
- private static boolean isValid(String name) {
-
- if (name == null) {
- return false;
- }
-
- int length = name.length();
-
- if (name.charAt(length-1) == '/') { // remove directories from the search.)
- return false;
- }
-
- // ALSO, cannot use classes such as "ServerBloah$4.class".
- int newLength = length-6;
- for (int i=0;iInetAddress object encapsulating what is most likely the machine's LAN IP address.
*
diff --git a/Dorkbox-Util/src/dorkbox/util/crypto/Crypto.java b/Dorkbox-Util/src/dorkbox/util/crypto/Crypto.java
index e637cbd..c0616ba 100644
--- a/Dorkbox-Util/src/dorkbox/util/crypto/Crypto.java
+++ b/Dorkbox-Util/src/dorkbox/util/crypto/Crypto.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2010 dorkbox, llc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package dorkbox.util.crypto;
diff --git a/Dorkbox-Util/src/dorkbox/util/crypto/CryptoX509.java b/Dorkbox-Util/src/dorkbox/util/crypto/CryptoX509.java
index 7deef19..f5342a1 100644
--- a/Dorkbox-Util/src/dorkbox/util/crypto/CryptoX509.java
+++ b/Dorkbox-Util/src/dorkbox/util/crypto/CryptoX509.java
@@ -1,7 +1,20 @@
+/*
+ * Copyright 2010 dorkbox, llc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package dorkbox.util.crypto;
-
-
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.FileWriter;
diff --git a/Dorkbox-Util/src/dorkbox/util/crypto/signers/BcECDSAContentSignerBuilder.java b/Dorkbox-Util/src/dorkbox/util/crypto/signers/BcECDSAContentSignerBuilder.java
index bb51756..6c11b1d 100644
--- a/Dorkbox-Util/src/dorkbox/util/crypto/signers/BcECDSAContentSignerBuilder.java
+++ b/Dorkbox-Util/src/dorkbox/util/crypto/signers/BcECDSAContentSignerBuilder.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2013 dorkbox, llc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package dorkbox.util.crypto.signers;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
diff --git a/Dorkbox-Util/src/dorkbox/util/crypto/signers/BcECDSAContentVerifierProviderBuilder.java b/Dorkbox-Util/src/dorkbox/util/crypto/signers/BcECDSAContentVerifierProviderBuilder.java
index 6a3051a..ac43807 100644
--- a/Dorkbox-Util/src/dorkbox/util/crypto/signers/BcECDSAContentVerifierProviderBuilder.java
+++ b/Dorkbox-Util/src/dorkbox/util/crypto/signers/BcECDSAContentVerifierProviderBuilder.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2013 dorkbox, llc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package dorkbox.util.crypto.signers;
import java.io.IOException;
diff --git a/Dorkbox-Util/src/dorkbox/util/gwt/GwtSymbolMapParser.java b/Dorkbox-Util/src/dorkbox/util/gwt/GwtSymbolMapParser.java
index 68e9c69..6bef7c9 100644
--- a/Dorkbox-Util/src/dorkbox/util/gwt/GwtSymbolMapParser.java
+++ b/Dorkbox-Util/src/dorkbox/util/gwt/GwtSymbolMapParser.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2011 dorkbox, llc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package dorkbox.util.gwt;
import io.netty.util.CharsetUtil;
@@ -13,7 +28,7 @@ public class GwtSymbolMapParser {
private final Map symbolMap;
public GwtSymbolMapParser() {
- symbolMap = new HashMap();
+ this.symbolMap = new HashMap();
}
/**
@@ -56,7 +71,7 @@ public class GwtSymbolMapParser {
}
public Map getSymbolMap() {
- return symbolMap;
+ return this.symbolMap;
}
public void processLine(String line) {
@@ -107,12 +122,12 @@ public class GwtSymbolMapParser {
// also, ignore if the source/dest name are the same, since that doesn't do any good for obfuscated names anyways.
if (memberName.isEmpty() && !jsName.equals(className)) {
// System.err.println(jsName + " : " + memberName + " : " + className);
- symbolMap.put(jsName, className);
+ this.symbolMap.put(jsName, className);
}
} else {
// version 2
// The list has already been pruned, so always put everything into the symbol map
- symbolMap.put(symbolInfo[0], symbolInfo[1]);
+ this.symbolMap.put(symbolInfo[0], symbolInfo[1]);
}
}
}
diff --git a/Dorkbox-Util/src/dorkbox/util/properties/PropertiesProvider.java b/Dorkbox-Util/src/dorkbox/util/properties/PropertiesProvider.java
index 28b71ed..dd4914b 100644
--- a/Dorkbox-Util/src/dorkbox/util/properties/PropertiesProvider.java
+++ b/Dorkbox-Util/src/dorkbox/util/properties/PropertiesProvider.java
@@ -23,17 +23,28 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
+import dorkbox.util.FileUtil;
+
public class PropertiesProvider {
// the basePath for properties based settings. In JAVA proper, this is by default relative to the jar location.
// in ANDROID dalvik, this must be specified to be the location of the APK plus some extra info. This must be set by the android app.
public static String basePath = "";
+ private String comments = "Settings and configuration file. Strings must be escape formatted!";
private final Properties properties = new SortedProperties();
private final File propertiesFile;
+ public PropertiesProvider(String propertiesFile) {
+ this(new File(propertiesFile));
+ }
+
public PropertiesProvider(File propertiesFile) {
- propertiesFile = propertiesFile.getAbsoluteFile();
+ if (propertiesFile == null) {
+ throw new NullPointerException("propertiesFile");
+ }
+
+ propertiesFile = FileUtil.normalize(propertiesFile);
// make sure the parent dir exists...
File parentFile = propertiesFile.getParentFile();
if (parentFile != null) {
@@ -45,6 +56,10 @@ public class PropertiesProvider {
_load();
}
+ public void setComments(String comments) {
+ this.comments = comments;
+ }
+
private final void _load() {
if (!this.propertiesFile.canRead() || !this.propertiesFile.exists()) {
// in this case, our properties file doesn't exist yet... create one!
@@ -69,7 +84,7 @@ public class PropertiesProvider {
private final void _save() {
try {
FileOutputStream fos = new FileOutputStream(this.propertiesFile);
- this.properties.store(fos, "Settings and configuration file. Strings must be escape formatted!");
+ this.properties.store(fos, this.comments);
fos.flush();
fos.close();