cl.util

Tools for the busy Java developer

License

License

GroupId

GroupId

com.github.vmazheru.codeless
ArtifactId

ArtifactId

cl-util
Last Version

Last Version

0.9.0
Release Date

Release Date

Type

Type

jar
Description

Description

cl.util
Tools for the busy Java developer
Project URL

Project URL

https://github.com/vmazheru/codeless/blob/master/README.md
Project Organization

Project Organization

com.github.vmazheru.codeless
Source Code Management

Source Code Management

https://github.com/vmazheru/codeless

Download cl-util

How to add to project

<!-- https://jarcasting.com/artifacts/com.github.vmazheru.codeless/cl-util/ -->
<dependency>
    <groupId>com.github.vmazheru.codeless</groupId>
    <artifactId>cl-util</artifactId>
    <version>0.9.0</version>
</dependency>
// https://jarcasting.com/artifacts/com.github.vmazheru.codeless/cl-util/
implementation 'com.github.vmazheru.codeless:cl-util:0.9.0'
// https://jarcasting.com/artifacts/com.github.vmazheru.codeless/cl-util/
implementation ("com.github.vmazheru.codeless:cl-util:0.9.0")
'com.github.vmazheru.codeless:cl-util:jar:0.9.0'
<dependency org="com.github.vmazheru.codeless" name="cl-util" rev="0.9.0">
  <artifact name="cl-util" type="jar" />
</dependency>
@Grapes(
@Grab(group='com.github.vmazheru.codeless', module='cl-util', version='0.9.0')
)
libraryDependencies += "com.github.vmazheru.codeless" % "cl-util" % "0.9.0"
[com.github.vmazheru.codeless/cl-util "0.9.0"]

Dependencies

compile (2)

Group / Artifact Type Version
org.scala-lang : scala-library jar 2.11.8
com.github.vmazheru.codeless : cl-serializers jar 0.9.0

test (3)

Group / Artifact Type Version
org.scalatest : scalatest_2.11 jar 2.2.1
junit : junit jar 4.12
com.novocode : junit-interface jar 0.11

Project Modules

There are no modules declared in this project.

Code Less

Tools for the busy Java developer

Highlights

  • Help remove boilerplate code from Java programs
  • Make trivial things simple, not so trivial not so simple
  • Tune the behavior of any component
  • Java interfaces, but implementations are in any JVM language (currently Scala and Java)
  • Test with Scala Spec and JUnit

Maven dependency

<dependency>
  <groupId>com.github.vmazheru.codeless</groupId>
  <artifactId>cl-util</artifactId>
  <version>0.9.0</version>
</dependency>

What's in the package?

Decorators

Imagine, you have a list of 10,000 objects which you need to run against some external API. So your Java code may look as simple as

List<Response> result = api.process(myItems);

but there are issues.

* The API throws this ugly `ApiException` which you have to catch.
* The API unstable, so you want to retry the call multiple times before giving up.
* The API imposes a request size limit of 500, so you have to make multiple calls to process you list
(and retry each one of them!).

Decorators to the rescue! Wrap you Java call as:

    List<Request> myItems = ... ;
    
    // batch by maximum request size
    // retry 3 times every minute
    // convert checked exceptions into runtime exceptions
    
    List<Response> result =
        batched(API.MAX_REQUEST_SIZE,
            retried(3, 1000 * 60,
                unchecked((List<Request> list) -> api.process(list)))).apply(myItems);

Configurable Objects

Every object is configurable, and there is a default configuration for each object!

Suppose, you need to convert your customer data to JSON. Here is your customer:

    Customer customer = new Customer("John Doe", new String[] {"212-111-9999"});

JsonMapper will help. It's use may be as simple as

    JsonMapper mapper = JsonMapper.getJsonMapper();
    mapper.toJson(customer);

    // produces
    // {"name":"John Doe","phones":["212-111-9999"]}

or

    JsonMapper mapper = JsonMapper.getJsonMapper(false)
        .with(JsonMapper.prettyPrinting, true)
        .with(JsonMapper.unwrapSingleElementArrays, true)
        .with(JsonMapper.visibility, Visibility.METHOD)
        .with(JsonMapper.wrapRootValue, true)
        .locked();
    mapper.toJson(customer);    
        
    // produces
    /*
    {
      "Customer" : {
        "name" : "John Doe",
        "phones" : "212-111-9999"
      }
    }
    */

"Configurable objects" framework is builder pattern on steroids!

Serializers and other file utilities

Serializing/de-serializing objects to/from files/streams is easy.

    // process customers stored in JSON format in a file
    try (ObjectIterator<Customer> iter = JsonIterator.fromFile(myFile, Customer.class)) {
        iter.forEachBatch(500, customers -> {
            // save them to DB in batches of 500
        });
    }

or

    List<Customer> myCustomers = ...
    
    // dump customer list to a file using Java serialization
    try (ObjectWriter<Customer> writer = JavaWriter.toFile(myFile)) {
        writer.write(myCustomers);
    }

There are also serializers, which are pairs of an object reader and an object writer sharing the same configuration settings. Use them when you need to read objects from a file, process them somehow, and put the results of processing back into a different file. For example,

    // generate a file of customer names for those customers who don't have phones
    try (Serializer<Customer, String> s = Serializer.jsonSerializer(inFile, outFile, Customer.class)) {
        s.filterAndMap(c -> c.getPhones() == null, Customer::getName);
    }

this snippet will actually write customer names (which are strings) in JSON format. If you'd like to dump them as plain strings you would do

    try (Serializer<Customer, String> s = Serializer.serializer(
            inFile, outFile, 
            SerializationType.JSON,              // input serialization type
            SerializationType.STRING,            // output serialization type
            Optional.of(Customer.class),         // object class (needed by JSON iterator)
            Optional.of(Configurable.empty())))  // no additional configuration settins necessary 
    {
        s.filterAndMap(c -> c.getPhones() == null, Customer::getName);
    }

File sorter

File sorter makes use of serializers to sort files of any size. File sorter may sort them in memory or it may sort them by using "external merge sort" if files are very large. There is a file size threshold (configurable!) which is used by the file sorter to switch from "in-memory" sorting to "external merge" sorting.

Additionally, file sorter can:

* remove duplicates while sorting
* skip one ore more header lines (when for example sorting CSV files)

The use file sorter may be as simple as:

    FileSorter.sort(myFile);

or as complex as :

    FileSorter<Customer> fileSorter = FileSorter.getFileSorter(
                inFile,                      // input file 
                outFile,                     // output (sorted) file
                SerializationType.JSON,      // what is the serialization scheme (file format)
                Customer.class,              // object class (needed by JSONMapper)
                Comparator.reverseOrder(),   // sort in descending order. 
                true);                       // remove duplicates
    fileSorter.sort();

More detailed list of features

Versions

Version
0.9.0