Skip to content

Multi-functional, cross-platform, well documented framework cutting boilerplate and speeding up your software development process

Notifications You must be signed in to change notification settings

redundent/jpropel

 
 

Repository files navigation

Description
-------------
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, cross platform, cross culture, compatible with legacy 
environments (e.g. JDK 1.5) and single JAR deployment.


News
------
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.


Change logs
------------
CHANGELOG 1.0.7
- StringUtils faster replace with StringBuilder
- FileUtils methods for checking if a file exists
- ConversionUtils support for Period and DateTime
- XmlUtils faster compaction
- ArrayUtils copy helper method
- Nullable method for NPE check
- StackTraceLogger remove trailing CRLF chars

CHANGELOG 1.0.6
- ReifiedArrayList fix (thanks to Redudent!)
- syntax in readme

CHANGELOG 1.0.5
- Bugfix for ReflectionUtils getSetters and getProperties
- Block iterator for per-line file reading

CHANGELOG 1.0.4
- Bugfixing
- Minor improvements

CHANGELOG 1.0.3
- Upgraded dependency lombok-pg to v0.11.0
- Upgraded dependency slf4j-api to v1.6.4
- ThreadUtils methods for sleep, busy-spin, yield waiting
- Added methods getSetter and getGetter in ReflectionUtils
- Added FileUtils directory methods accepting File as arg
- NPE cleanup, using Validate.NotNull in most Util classes
- Bugfixing Linq (type constraints)
- Bugfixing in ArrayUtils (reverse method)
- Breaking changes:
  - Moved some ArrayUtils methods to Linq for consistency
  - Projections organised as Arrays, Objects, Files, etc.
  - Removed duplicates

CHANGELOG 1.0.2
- Bugfixing validators and logger

CHANGELOG 1.0.1
- Added EnvironmentUtils utility class, allows for altering JVM env. vars at run-time
- Added Stopwatch.restart() convenience method
- Added Iterable validator (IterablePropertyMetadata)
- Added URL validator (URLPropertyMetadata)
- Added a few commonly used predicates (propel.core.functional.predicates.*)
- StackTraceLogger now has configurable level, showing minimal, abbreviated or full trace
- Fixed inaccurate comments in NumericUtils, StringUtils, Linq, etc.
- Linq unzip() and partition() methods added. Bug-fixing (ofType, orderByThenBy, skip)
- Using lombok-pg 0.10.8-SNAPSHOT dependency
- Using slf4j-api 1.6.4 dependency
- Included Eclipse project in sources JAR

CHANGELOG 1.0.0
- LongHashMap now has *very* fast lookup performance and smaller memory footprint
- Added ReflectionUtils.proxy() overload allowing you to "seal" certain class methods
  (via proxying) and as such guaranteeing immutability for things like collections.
- Using these two features together (i.e. a long->T map and immutability), you can 
  create a hash map that is ~500% faster than ConcurrentHashMap (during lookups).
  This is due to absence of locking. See ImmutableUtils.toReadOnly().  
- Improved InitGuard interface / comments.
- Extracted interface for MapMultimaps
- Removed SharedLongHashMap implementation.

CHANGELOG 0.9.9
- Support for primitive (long-based) collections (buffers, maps)
- Generic Frozen object container, can only be set once
- StringUtils.replace() bugfix
- Validation error message improvement when min & max length are equal
- Replaced usages of StringBuffer with StringBuilder instead
- Fixed StringUtils padLeft/padRight comments
- Added projections: getClassType(), getClassName(), getClassNameSimple()
- Updated Objects.* predicates to use Object instead of T where a type is not needed
  (this is to alleviate some type inferencing woes with javac/ecj)
- Added print() predicate to Objects and Strings 
- Added min() and max() to Linq
- Added minOccurring() and maxOccurring() to Linq
  (using non-parallel map/reduce which needs to be optimised in a next version)
- LocalDatePropertyMetadata

CHANGELOG 0.9.8
- Ivy support
  You can now resolve the jpropel dependency by using in ivysettings.xml:

  <resolvers>
    <url name="jpropel-github">
      <ivy pattern="https://github.com/nicholas22/jpropel/raw/master/ivy-[revision].xml"/>
      <artifact pattern="https://github.com/nicholas22/jpropel/raw/master/[module]-[revision].[ext]"/>
    </url>
  </resolvers>
- 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
- Added lock-free thread-safe initialisation guards, for preventing classes
  from being used without being initialised first (MultiInitGuard) and for
  preventing classes from being initialised multiple times (SingleInitGuard)
- String crop() trim-like function allows for strings to be cropped of
  one or more specified characters. Example:
  
val result = StringUtils.crop("abc123abc", new char[] {'a','c'});
System.out.println(result); // => "bc123ab"  

- Linq.single() get a single element of a collection, throwing an exception
  if zero, two or more elements exist in the collection.
- Cleaner functional invocation with InvokeOneArg and InvokeNoArgs classes.


CHANGELOG 0.9.6
- Split up Predicates class into Objects, Strings, Arrays and Iterables
  for modularization
- Function1<?, Boolean> -> Predicate1<?> 
  Breaking change using the more appropriate annotation @Predicate instead
  of having to specify the return type for predicate-style functions
- MapMultimap uses yield() when iterating
- SharedMapMultimap: thread-safe version of MapMultimap


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
- Added a lot of new predicates and projections.
  e.g. instanceOf(), appendToFile(), copyFile(), deleteFile(), etc.


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
{

  /**
   * @param args
   */
  public static void main(String[] args)
  {
    val names = new String[] { "john", "james", "john", "eddie" }.where(startsWith("j")).distinct().all(println());    
  }
}


- 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
  1) StringUtils: split() ignoring last character when using 
     multi-char array separator
  2) SharedModuloCounterLight: getValue() always returned 0
  3) FileUtils: readFileToEnd() Windows memory leak fixed


CHANGELOG 0.9.1
- ~100% code coverage
- ~100% documentation & full checked Exception documentation


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
- SLF4J logging


#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<Integer> pa = new ParallelAction<Integer>(){
               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<String> pac = 
             new ParallelActionCollection<String>();
           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<String> someStrings = ...
           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<Person>
           ReifiedArray<Person> people = 
             new ReifiedArray<Person>(arrayPeople); 

  example: // Least-Recently Used algorithm buffer
           LRUBuffer<String> buffer = new LRUBuffer<String>(2){};
           buffer.add("1");
           buffer.add("2");
           buffer.add("3"); // buffer contains only "2", "3" now (LRU)


#CHANGELOG 0.1
- Reified collections

  example: ReifiedList<Person> people = new ReifiedArrayList<Person>() {};
           -or- people = new ReifiedArrayList<Person>(Person.class);

           // 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<Object> queue = new SharedQueue<Object>();
           queue.get(...);

           // another thread
           queue.put(...);  // this signals the other waiting thread
               

Summary of CORE Features
-------------------------
- Reified collections, arrays and iterables, inheriting from a single
  interface, using the super-type token approach
- Linq-like functionality for Java, overloaded methods for arrays and 
  iterables, the latter using "yield" generators
- Parallel task-oriented library, supporting single & collection of tasks,
  time-expiring and cancellable tasks, blocking and background tasks,
  pipelining, thread re-use, etc.
- Support for functional programming e.g. actions, functions, predicates   
- Many collection types, e.g. concurrent collections, buffers and queues,
  support for producer/consumer message passing
- Further collection types include AVL hashtable, LRU buffer, time 
  expiring session, bi-map, circular buffer and others
- Tons of conversion helpers such as hex, binary, octal, byte array, 
  string, UTF8, Base64, etc.
- Constants class, holding most common constants used e.g. letters, 
  numbers, unicode symbols, newlines, OS-dependent stuff such as 
  directory & path separators, etc.
- Validation framework, extensible and easy to use. Support of common 
  types out of the box, e.g. date/time, string, numeric, etc.
- Tracing tools for automatic argument and return-type logging.
- Profiling helper classes with nanosecond precision
- Counters of all kinds, e.g. thread-safe, lock-free, single-threaded
- Observer pattern implementation with support for auto de-registration 
  upon the event of notification failure
- Stack trace logging helper
- Convention over configuration, but highly configurable

About

Multi-functional, cross-platform, well documented framework cutting boilerplate and speeding up your software development process

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Java 100.0%