Multi-functional, cross-platform, well documented framework cutting boilerplate and speeding up your software development process
Boilerplate busting framework with features found in many modern programming
environments, such as LINQ, reified collections and numerous one-liner
type utility methods, e.g. loading a file into memory.
Open source (LGPL), cross platform, cross culture, compatible with legacy
environments (e.g. JDK 1.5) and single JAR deployment.
Forked a much leaner version at -> https://github.com/nicholas22/jpropel-light
Contains only LINQ, reified generic collections and utilities.
Documented these features in the front page of that project.
Highly recommended if you don’t want extra dependencies in your libraries.
CHANGELOG 1.0.8
CHANGELOG 1.0.7
CHANGELOG 1.0.6
CHANGELOG 1.0.5
CHANGELOG 1.0.4
CHANGELOG 1.0.3
CHANGELOG 1.0.2
CHANGELOG 1.0.1
CHANGELOG 1.0.0
CHANGELOG 0.9.9
CHANGELOG 0.9.8
Ivy support
You can now resolve the jpropel dependency by using in ivysettings.xml:
BouncyCastle support removed, without compromising AES, XTEA and Blowfish
algorithms (although Rijndael was renamed to AES)
lombok-pg 0.10.4-SNAPSHOT support
Joda Period validation (see PeriodPropertyMetadata)
CHANGELOG 0.9.7
val result = StringUtils.crop(“abc123abc”, new char[] {‘a’,‘c’});
System.out.println(result); // => “bc123ab”
CHANGELOG 0.9.6
CHANGELOG 0.9.5
MapMultimap data structure
Better java.io.File extension methods
new File(“myFile.txt”).readFileToEnd().split(“\r\n”);
CHANGELOG 0.9.4
CHANGELOG 0.9.3
Using Scala-like programming-style library
(https://github.com/peichhorn/lombok-pg)
examples:
// create alphabet char[]
new Character(‘A’).to(new Character(‘Z’)).unbox();
// join two arrays and put in list
alphabet.join(numerics).toList();
// select distinct j* names, using LINQ-style statements
new String[] { “james”, “john”, “john”, “eddie” }.where(startsWith(“j”)).distinct();
** WARNING: **
If you use Eclipse or NetBeans, patch it by running lombok.jar
and selecting the executable. No patching required for javac / Ant
Full example:
import java.util.Arrays;
import lombok.ExtensionMethod;
import lombok.val;
import propel.core.utils.Linq;
import propel.core.utils.StringUtils;
import static propel.core.functional.predicates.Strings.;
//import static propel.core.functional.projections.Projections.;
@ExtensionMethod({Arrays.class, Linq.class, StringUtils.class})
public class Main
{
/**
Added commonly used Predicates and Projections see
propel.core.functional.Predicates, propel.core.functional.Projections
examples:
equal(), notEqual(), isNullOrEmpty(), startsWith(), etc.
Removed propel.core.threading.* as it has been superseded by
JDK7 fork/join framework.
CHANGELOG 0.9.2
Annotation-based method-call tracing
example: // This logs input args, result and exceptions (if any)
// with fine-grained configurability in presentation of data
@Trace(level=LogLevel.WARN)
public int add(int a, int b) {…}
Stopwatch class allowing for high-precision performance benchmarking
example: Stopwatch sw = new Stopwatch();
sw.start();
sw.stop();
long ns = sw.getNanosElapsed();
Robust resource loading by classpath, supporting loading from within
JARs, HTTP-based URLs as well as file-system, through the same API
(see FileUtils)
example: // this file could reside inside a JAR, or outside a JAR
URL url = “/java/util/test.xml”.getResourceUrl();
String xmlData = url.getResourceTextData();
// read entire file
String xmlData = FileUtils.readFileToEnd(url.toUri().toUrl());
Tuples
example: Pair<A,B> tuple1 = new Pair<A,B>(a,b);
Triple<A,B,C> tuple2 = new Triple<A,B,C>(a,b,c);
etc.
Bugfixes
CHANGELOG 0.9.1
CHANGELOG 0.8
Bouncycastle encryption/decryption support added
CryptographicString class, allows for storing strings encrypted
in memory. Accessing the string decrypts it, as char[] or byte[]
example: // stores in memory encrypted
CryptographicString cs = new CryptographicString(“my precious secret”);
// access unencrypted version
byte[] ba = cs.asByteArray();
char[] ca = cs.asCharArray();
String st = cs.asString(); // not recommended
CHANGELOG 0.7
Arrays utilities (ArrayUtils)
example: // convert primitive array to the corresponding
// wrapper type array e.g. int[] -> Integer[]
Integer[] ints = new int[] { 1,2,3}.box();
// inverse operation
int[] intsCopy = ints.unbox();
// add/remove operations
String[] strVals = new String[] { "hello", "hello2" };
strVals = strVals.add("test");
strVals = strVals.remove("test");
// resize
strVals.resize(1); // last element lost
strVals.resize(strVals, 2); // last element is null
// get part of array
strVals = strVals.subArray(strVals, 0, 1); // single element
// join and prepend
strVals = strVals.join(strVals).prepend("test");
Byte array utilities
example: // convert multi-byte arithmetic structures
ByteArrayUtils.getBytes(Long)
// support for little and big endian
ByteArrayUtils.LITTLE_ENDIAN
Conversion utilities
example: // convert various data types to BASE64
ConversionUtils.toBase64(…)
ConversionUtils.fromBase64…
// hex conversions
ConversionUtils.toHex(...)
ConversionUtils.fromHex...
// binary conversions
ConversionUtils.toBinary(...)
ConversionUtils.fromBinary...
// byte[] conversions
ConversionUtils.toByteArray(...)
ConversionUtils.toString(...)
// alphanumeric conversions (e.g. for shortening)
ConversionUtils.toAlphanumeric(...)
ConversionUtils.fromAlphanumeric...
// human-readable intervals, e.g. 2:10:23 -> 2 hours ago
ConversionUtils.toHumanReadable(...)
Escaping
example: // escape HTML
EscapingUtils.toHtml(…)
EscapingUtils.fromHtml(…)
// escape XML
EscapingUtils.toXml(...)
EscapingUtils.fromXml(...)
// URL escaping
EscapingUtils.toUrl(...)
EscapingUtils.fromUrl(...);
File utilities
example: // append text to a file, if missing it is created
FileUtils.appendText(…);
// read entire file in memory (as text)
FileUtils.readToEnd(...)
// read entire file in memory (as byte[])
FileUtils.readFileInMemory(...)
// deletion
FileUtils.delete(...) // throws exception upon failure
FileUtils.tryDelete(...) // no exceptions thrown
// touch file
FileUtils.touch(...) // create or update
// search for file, highly configurable for:
// - files/folders or both
// - hidden/normal or both
// - sorting order (ascending/descending/none)
// - traversal (depth/breadth/shallow)
FileUtils.scanPath(...)
// test read/write and access right for a path
FileUtils.tryPerformCreateReadWriteDeleteAccess("C:\\");
// forensically copy file (maintains MAC dates)
FileUtils.cloneFile(from, to);
Operating System utils
example: // OS detection
boolean tux = OsUtils.isLinux();
boolean win = OsUtils.isWindows();
boolean bsd = OsUtils.isBsd();
boolean osx = OsUtils.isOSX();
Randomisation utilities
example: // one-liner for a pseudo random
RandomUtils.getPseudoInt32(…)
RandomUtils.getPseudoInt64(…)
// one-liner for a secure random
RandomUtils.getSecureInt32(...)
RandomUtils.getSecureInt64(...)
// one-liner for pseudo alphanumeric text
RandomUtils.getPseudoAlphanumericText(...)
// one-liner for secure, arbitratily-sized byte array
RandomUtils.getSecureBytes(...)
// one-liner for a pseudorandom BASE64
RandomUtils.getPseudoBase64(...);
Reflection utilities
example: // instantiate class by name of class type
ReflectionUtils.activate(…)
// check if two methods, fields, properties or constructors
// appear to be the same (via signature comparison)
ReflectionUtils.equal(...)
// get all declared and/or inherited annotations
ReflectionUtils.findAnnotations(...)
// discover bean properties
PropertyInfo pi = ReflectionUtils.getProperty("name");
// search all fields, methods and properties
ReflectionUtils.getMember(A.class, "name", true);
// check if an interface is implemented
ReflectionUtils.isImplementing(A.class, Serializable.class);
// check if class extends another class
ReflectionUtils.isExtending(Client.class, Person.class);
// check if a class "looks like a duck" (duck-typing)
ReflectionUtils.isLookingLike(A.class, B.class);
// one-liner proxying
ReflectionUtils.proxy(myObj, MyInterfaceType.class);
Streams
example: // copy stream contents
StreamUtils.copy(inputStream, outputStream, size);
// block until read a specified number of bytes from stream
StreamUtils.readFully(inputStream, 100);
// block until read a specified number of chars from stream
StreamUtils.readAllCharacters(stream, 100);
// read stream until a byte or char is encountered
StreamUtils.readUntil(inputStream, "\r\n.\r\n");
// skip bytes
StreamUtils.skipBytes(inputStream, 100);
// skip characters
StreamUtils.skipBytes(inputStream, 100);
// chunked writing / reading from streams
byte[] data = ...
int chunkSize = 1024;
StreamUtils.writeFully(outputStream, data, chunkSize);
String utilities
example: // char range generation
StringUtils.charRange(65, 91); // chars A…Z
// String comparison implementations:
// e.g. this returns true for German locale
equal("stra�e", "strasse", StringComparison.CurrentCulture)
// and this returns true
startsWith("str", "STR", StringComparison.OrdinalIgnoreCase)
// single method to check for null or ""
isNullOrEmpty(String)
compare(...)
concat(...)
contains(...)
containsAny(...)
containsAll(...)
TODO: document more functions here
#CHANGELOG 0.6
#CHANGELOG 0.5
Validation framework
example: // validate a last name
StringPropertyMetadata strMeta = new
StringPropertyMetadata(“Last name”, 3, 50, true, true, true);
// ValidationException: "Last name cannot be null"
strMeta.validate(null);
// ValidationException: "Last name cannot be empty"
strMeta.validate("");
// "Last name cannot have fewer than 3 characters in length"
strMeta.validate("ab");
// "Last name cannot contain the null character"
strMeta.validate("abc\0def");
// "Last name cannot be over 50 characters in length"
strMeta.validate("...51 chars here...");
others: All basic data types (int, double, String, boolean, etc.)
File names and folders (cross platform)
File system paths (cross platform)
Domain names (to RFC spec)
Sub-domain names (to RFC spec)
Emails (to RFC spec)
Active Directory usernames (LDAP spec)
CreditCard
IPv4
IPv6
MAC addresses
#CHANGELOG 0.4
Transactions
example: // transactionally swap two files, by using a temp file,
// in the case that an error occurs roll back all actions
String src=“/home/test1.txt”;
String dst=“/home/test2.txt”;
// used for the swap process
String temp = "/home/temp.txt";
TransactionManager tm = new TransactionManager();
// action is to move source file to a temp location,
// rollback action is to move the temp file back to source
tm.add(moveFileAction(src, temp),
moveFileAction(temp, src));
// action is to move destination file to source,
// rollback action is to move source to destination
tm.add(moveFileAction(dst, src),
moveFileAction(src, dst));
// this is the last action, no rollback action required
tm.add(moveFileAction(temp, dst));
// safely swap files
tm.commitWithRollback();
// ... somewhere outside method scope ...
@Function
private Void moveFileAction(final String src, final String dest)
{
File file = new File(src);
file.moveTo(dest);
}
others: commit();
rollback();
commitWithRollback();
resumeCommit();
resumeRollback();
skipCommitStep();
skipRollbackStep();
#CHANGELOG 0.3
Parallel task library
example: // declare a simple printing task
ParallelAction
public void executeWith(Integer arg) {
for(int i=0; i < arg; i++)
System.out.println(i);
}
};
// background execution
pa.executeLater();
// blocking execution
pa.executeAndWait();
example: // declare a simple function
ParallelFunction<Integer, Double> pf =
new ParallelAction<Integer, Double>(){
public Double operateOn(Integer arg) {
Double dbl = new Double(arg);
return Math.exp(dbl);
}
};
// background execution
ITaskResult<Double> result = Linq.first(pf.executeLater()));
if(!result.isSuccessful())
throw new Exception("Could not perform calculation",
result.getError());
// print result
System.out.println(result.getResult());
example: // actions and functions can be grouped into collections
ParallelActionCollection
new ParallelActionCollection
pac.addAction(…);
pac.addAction(…);
// wait for all to complete
pac.executeAndWaitAll();
// background execution (e.g. reverse order)
for(ITaskResult<String> result :
pf.executeAndYield(TaskResultOrder.ReverseOrder)) {
if(!result.isSuccessful())
// tasks are identified and any errors are preserved
throw new Exception("Could not perform calculation with "
+ "ID="+result.getTaskId(), result.getError());
System.out.println(result.getResult());
}
others: Cancellable actions and functions:
These give the ability to stop a task mid-way.
Timed actions and functions:
Automatically stop if a configurable amount of time passes.
#CHANGELOG 0.2
Linq for Java
example: Iterable
int count = Linq.count(someStrings);
example: // simulate: String[] names = people.select(p=>p.toString()).reverse()
Person[] people = …
String[] peopleNames = people.select(toStringSelector()).reverse();
// ... somewhere else in code, declaration of method
@Function
private String toStringSelector(Person person) {
return person.toString();
}
others: aggregate();
all();
any();
cast();
concat();
contains();
containsAll();
containsAny();
count();
countWhere();
defaultIfEmpty();
distinct();
elementAt();
elementAtOrDefault();
except();
first();
firstOrDefault();
...
select();
...
toArray();
...
where();
zip();
// most things you expect from LINQ have been implemented
#CHANGELOG 0.1.2
CONSTANTS class
example: CONSTANT.CRLF // this equals to “\r\n”
CONSTANT.ENVIRONMENT_NEWLINE // “\r\n” on Windows, “\n” on *nix
CONSTANT.DIRECTORY_SEPARATOR // “\” for Windows, “/” for *nix
CONSTANT.EMPTY_STRING // same as “”
CONSTANT.ZERO_GUID // “00000000-0000-0000-0000-000000000000”
CONSTANT.A // “A”
CONSTANT.a // “a”
CONSTANT.ONE // “1”
// etc.
#CHANGELOG 0.1.1
More collections
example: // AVL-backed hashtable implementation.
// AVL trees are the fastest BSTs for lookups
AvlHashtable<Long, Person> idToPersonMap =
new AvlHashtable<Long, Person>(){};
idToPersonMap.add(123, new Person());
Person person = idToPersonMap.get(123);
example: Person[] arrayPeople = …
// implements Iterable
ReifiedArray
new ReifiedArray
example: // Least-Recently Used algorithm buffer
LRUBuffer
buffer.add(“1”);
buffer.add(“2”);
buffer.add(“3”); // buffer contains only “2”, “3” now (LRU)
#CHANGELOG 0.1
Reified collections
example: ReifiedList
-or- people = new ReifiedArrayList
// using plain List this would be: Object[] array = ...
Person[] array = people.toArray();
Concurrent collections
example: // queue used for message passing (MPI) between producers/consumers
SharedQueue
// another thread
queue.put(...); // this signals the other waiting thread