Nyla.Solutions.Global

Nyla Solutions Global Java API provides support for basic application utilities (application configuration, data encryption, debugger and text processing).

License

License

GroupId

GroupId

com.github.nyla-solutions
ArtifactId

ArtifactId

nyla.solutions.global
Last Version

Last Version

0.0.6
Release Date

Release Date

Type

Type

jar
Description

Description

Nyla.Solutions.Global
Nyla Solutions Global Java API provides support for basic application utilities (application configuration, data encryption, debugger and text processing).
Project URL

Project URL

https://github.com/nyla-solutions/nyla
Source Code Management

Source Code Management

https://github.com/nyla-solutions/nyla.git

Download nyla.solutions.global

How to add to project

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

Dependencies

compile (20)

Group / Artifact Type Version
com.google.code.gson : gson jar 2.3.1
commons-beanutils : commons-beanutils jar 1.9.2
commons-net : commons-net jar 3.3
org.freemarker : freemarker jar 2.3.21
javax.mail : javax.mail-api jar 1.5.2
log4j : log4j jar 1.2.17
httpunit : httpunit jar 1.7
org.aspectj : aspectjrt jar 1.8.5
org.reflections : reflections jar 0.9.10
dom4j : dom4j jar 1.6.1
org.jsoup : jsoup jar 1.8.2
com.thoughtworks.xstream : xstream jar 1.4.8
org.springframework : spring-context jar 4.1.6.RELEASE
junit : junit jar 4.12
org.apache.logging.log4j : log4j-api jar 2.3
org.apache.logging.log4j : log4j-core jar 2.3
org.codehaus.groovy : groovy-all jar 2.4.4
com.fasterxml.jackson.core : jackson-databind jar 2.5.0
com.fasterxml.jackson.core : jackson-core jar 2.5.0
com.fasterxml.jackson.core : jackson-annotations jar 2.5.0

Project Modules

There are no modules declared in this project.

NYLA Solutions Core

This Java API provides support for application utilities (application configuration, data encryption, debugger, text processing and more).

This library is a collection of the design pattern implementation.

Benefits

  • Lots of implemented design patterns and utilities
  • Very cloud native friendly
  • Default settings required ZERO additional runtime dependencies
  • Used by some of the largest corporations in the US

Available in the maven central repository

See http://mvnrepository.com/artifact/com.github.nyla-solutions/nyla.solutions.core

Maven dependencies

	<dependency>
	    <groupId>com.github.nyla-solutions</groupId>
	    <artifactId>nyla.solutions.core</artifactId>
	    <version>${VERSION}</version>
	</dependency>
Add it using Maven

Gradle

compile group: 'com.github.nyla-solutions', name: 'nyla.solutions.core', version: $VERSION

Building

Download Gradle version 6.4.1 or higher

`gradle clean build`

Solutions Core Overview

Package: nyla.solutions.core.util.stats

Use the Mathematics object to calculate statistics such as the 95th percentile, standard deviation, variance, mean of set of numbers, etc.

Example Code

Mathematics math = new Mathematics();
    
//Calculate the variance 
assertEquals(700,math.variance(10, 20, 60));
  
//Calculate mean
assertEquals(30,math.mean(10, 20, 60));

//std dev
assertEquals(0.816496580927726,math.stdDev(9, 10, 11));
    
//Percentile (ex 95th)

assertEquals(323,subject.percentile(95.0,10,232,232,323,232));
assertEquals(454,subject.percentile(95.0,23,75,19,3,5,454,100000,232,23,23,2,32,32,3,2,3,4,34,3,43,43,4,3,43,43,4,3,43,4,34,3,4,3,4343));
assertEquals(98,subject.percentile(95.0,23,1,23,2,32,3,2,356,56,5,6,57,6,8,9,8,98,9,8,12,1,2,1,21,21,21));

Package: nyla.solutions.core.util

Config

This class provides a central mechanism for applications to access key/value property settings and encrypted passwords. Developer can get access to environment variable, system Java properties and other property. It also supports type conversion from property strings to numbers, booleans and arrays. There are several ways to specify the configuration properties.

1.	Add file config.properties to CLASSPATH. This file will be loaded as a Java resource bundle. 
2.	Add the JVM argument -Dconfig.properties where the value is equal to the location of the configuration file.

Example: -Dconfig.properties=/dev/configurations/files/system/config.properties

There are methods to get the String value property such as Config.getProperty(key) method. There are also methods to get an expected property value of a type such as Integer, Boolean, etc.

nyla.solutions.core.util.Config.mergeSystemProperties=false

It also supports formatting several property values into a single property by adding the following property;

nyla.solutions.core.util.Config.useFormatting=true

By default the configuration is read only once when the application is initialized. Add the following to the configuration property file to always reload the property whenever a getProperty... method is called. Note that this is a potentially an expensive operation.

nyla.solutions.core.util.Config.alwaysReloadProperties=true

Note the following is a property file used for the sample usage code below.

application.name=JUNIT
debug=true
nyla.solutions.core.util.ConfigTest.integerProperty=24
password={cryption}102 42 -22 24 12 66 -35 89 50 -15 21 9 -67 73 -128 -105
	
nyla.solutions.core.util.Config.mergeSystemProperties=true	
nyla.solutions.core.util.Config.useFormatting=true
application.name.debug=${application.name}.${debug}.${user.dir}

USAGE

 //Get a default string property
  //The following assumes;
  //application.name=JUNIT
  String property = Config.getProperty("application.name");
  Assert.assertEquals("JUNIT",property);
  
  //An exception will be thrown if the referenced property does not exist in the property file
  //in this case the ConfigException will be thrown
  try
  {
   property = Config.getProperty("missing.property");
  }
  catch(ConfigException e)
  {
   //valid configuration exception
  }
  
  //Provide a default value if the default value is missing
  property = Config.getProperty("missing.property","default");
  Assert.assertEquals("default", property);
  
  //Properties can be retrieved by type (boolean, Integer, Character, Long, Bytes)
  //The following assumes;
  //debug=true
  boolean propertyBoolean = Config.getPropertyBoolean("debug");
  Assert.assertTrue(propertyBoolean);
  
  //Each getProperty<Type> accepts a default value
  //The following assumes;
  //missing.boolean.property=false
   propertyBoolean = Config.getPropertyBoolean("missing.boolean.property",false);
   Assert.assertFalse(propertyBoolean);
   
   //Config has a user friendly way to associate properties with classes
   //The properties can be prefixed with the class name
   //Each getProperty<Type> optional accept the class name as the first argument
   //The following assumes the property 
   //nyla.solutions.core.util.ConfigTest.integerProperty=24
   int integerProperty = Config.getPropertyInteger(nyla.solutions.core.util.ConfigTest.class, "integerProperty");
   Assert.assertEquals(24, integerProperty);
   
   
   //Passwords encrypted with the nyla.solutions.core.util.Cryption object 
   //can be retrieved with the Config.getPassword(key) method
   //An exception will be thrown if the password is not encrypted correctly in the property file
   //The following is example encrypted password stored in the property file
   //password={cryption} 2 -21 23 12 2 -21 23 12 2 -21 23 12 2 -21 23 12 2 -21 23 12
   char[] password = Config.getPropertyPassword("password");
   Assert.assertNotNull(password);
   
   
   //Properties in the System.getProperties() can be merged with the Config's object properties
   //This is done by setting the property
   //nyla.solutions.core.util.Config.mergeSystemProperties=true
   String jvmSystemPropertyName = "user.dir";
   property = Config.getProperty(jvmSystemPropertyName); 
   Assert.assertNotNull(property);
   
   
   //solutions.globa.util.Config.useFormatting property can be used to dynamically combine properties.
   //This feature uses the nyla.solutions.core.patterns.decorator.style  package (see Styles interface)
   //The value of property surrounded with ${property.name} will be formatted by replacing it with the
   //actual value from another property.
   
   //The following is based on the following properties (note this combines the system property "user.dir")
   //nyla.solutions.core.util.Config.useFormatting=true
   //application.name.debug=${application.name}.${debug}.${user.dir}

   property = Config.getProperty("application.name.debug");
   Debugger.println(this,"property="+property);
  
  Assert.assertTrue("All values formatted:"+property, property.indexOf("${") < 0);

Supports observer pattern for file configuration changes.

Note that this requires two configuration properties.

Property Example Is Required
CONFIG_FILE_WATCH_POLLING_INTERVAL_MS 1000 true
CONFIG_FILE_WATCH_DELAY_MS 10 false (default is 5 seconds)
		File config = Paths.get("src/test/resources/config/configTest.properties").toFile();
		
		System.setProperty(Config.SYS_PROPERTY, config.getAbsolutePath());
		
		SubjectObserver<Settings> settingsObserver = new SubjectObserver<Settings>()
		{
			private String name = "test";
			
			@Override
			public String getId()
			{
				return name;
			}
			
			@Override
			public void update(String subjectName, Settings data)
			{
				System.out.println("subjectNAme:"+subjectName+" data:"+data);
				isCalled = true;
			}
		};
		
		Config.registerObserver(settingsObserver);
		IO.touch(config);
		// observer will be called

Cryption

Cryption provides a set of functions to encrypt and decrypt bytes and text. It uses the javax.crypto package.

The default encryption algorithm is the Advanced Encryption Standard (AES).

The default algorithm can be changed with a configuration property named nyla.solutions.core.util.Cryption.alogorithm.

# The following sets the encryption algorithm to Data Encryption Standard (DES)
nyla.solutions.core.util.Cryption.algorithm=DES

The Cryption object is used by nyla.solutions.core.util.Config object to decrypt properties prefixed with {cryption}. The Cryption class can be used to generate encrypted passwords that can be added to the config.properties file. The Cryption main method accepts a password and will print the encrypted password that can be added to the property file.

The printed password will be prefixed with the value “{cryption}”. Any properties prefixed with {cryption} in the config.properties is an indicator that content is encrypted.

The follow is a sample Cryption UNIX script:

export LIB_DIR=put correct directory here
export CP="$LIB_DIR/solution.global.jar"
java -classpath $CP nyla.solutions.core.util.Cryption $1

The following is a sample output of an encrypted password generated by the Cryption main method.

{cryption}23 4 -3 -77 -128 -88 -34 -105 23 4 -3 -77 -128 -88 -34 -105

USAGE

//The cryption default constructor using the 
//AES algorithm with a default key
Cryption cryption = new Cryption();

//Use the encryptText method to encrypt strings
String original = "Text to encrypt";
String encrypted = cryption.encryptText(original);
Assert.assertTrue(!original.equals(encrypted));

//Use the decryptText method to decrypt strings
String decrypted = cryption.decryptText(encrypted);
Assert.assertEquals(decrypted, original);

//Use encrypt for bytes
byte[] orginalBytes = original.getBytes();
byte[] encryptedBytes = cryption.encrypt(orginalBytes);

//Use decrypt 
byte[] decryptedBytes = cryption.decrypt(encryptedBytes);
Assert.assertTrue(Arrays.equals(orginalBytes, decryptedBytes));


//Create crypt with a specific key and algorithm
byte[] keyBytes = {0x22, 0x15, 0x27, 0x36, 0x41, 0x11, 0x79, 0x76};
Cryption desCryption = new Cryption(keyBytes,"DES"); 

String desEncrypted = desCryption.encryptText(original);
Assert.assertTrue(!original.equals(encrypted) && !desEncrypted.equals(encrypted));
decrypted = desCryption.decryptText(desEncrypted);
Assert.assertEquals(decrypted, original);

Debugger

Debugger provides useful methods for obtaining exception stack traces. It can build reader friendly strings for objects that do not implement their toString method.

It also provides a set of print functions to log DEBUG, INFO, WARN and FATAL level messages using the Debugger.println(...), Debugger.printInfo(...),Debugger.printWarn(...) and Debugger.printFatal(...) methods respectively.

The default log object implementation is nyla.solutions.core.operations.Log4J.

Set the configuration property to plug-in another logger (@see Config more information);

nyla.solutions.core.util.Debugger.logClass=className

The logClass class name indicated must implement the nyla.solutions.core.operations.Log interface.

USAGE

//The Debugger toString(Object) can be used to debug objects where the toString method is not implemented.
String[] arraysNicely = { "first","second"};
String text = Debugger.toString(arraysNicely); 
Assert.assertEquals("{[0]=first ,[1]=second}", text);

//The print method wraps log levels of DEBUG,INFO,WARN and FATAL
Debugger.printInfo("This is a INFO level message");

//Two arguments can be passed where the first is the calling object
//The debugger will prepend the calling objects class name to the logged output
Debugger.println(this, "This is a DEBUG level message");

//Debugger can be used to efficiently print exception information
text = null;
try{
text.toString(); //causes a null pointer exception
}
catch(NullPointerException e)
{
//Use the stackTrace method to get the string version of the exception call stack
String stackTrace = Debugger.stackTrace(e);

//Print warn level
Debugger.printWarn(this,stackTrace);

//stack trace will be automatically created if the exception object is passed
Debugger.printError(e); 

Debugger.printFatal(this,"Stack trace will not be printed, because this is not an exception object.");
}

BeanComparator

BeanComparator is a generic Bean property java.util.Comparator implementation. It compares specified property beans using reflection. This object is internally used by the Organizer.sortByJavaBeanProperty(String,Collection) method.

USAGE

//The constructor accepts a JavaBean property name
BeanComparator beanComparator = new BeanComparator("firstName");

//The following are two sample user profile beans
UserProfile josiah = new UserProfile();
josiah.setFirstName("Josiah");
		
UserProfile nyla = new UserProfile();
nyla.setFirstName("Nyla");
		 
//Reflection is used to compare the properties of the beans
Assert.assertTrue(beanComparator.compare(josiah, nyla) < 0);
		 
//The following shows how the BeanComparator.sort method can be used
		 
//This method can be used to sort an given collection based on the JavaBean properties 
//of objects in the collection
ArrayList<UserProfile> unSorted = new ArrayList<UserProfile>();
unSorted.add(0, nyla);
unSorted.add(1, josiah);
		 
//Setting the descending will determine the sort order
beanComparator.setDescending(true);
beanComparator.sort(unSorted);

Assert.assertTrue(unSorted.get(0) == nyla);
		 
//Changing the descending flag changes the output of the sort method
beanComparator.setDescending(false);
beanComparator.sort(unSorted);
Assert.assertTrue(unSorted.get(0) == josiah);

Text

nyla.solutions.core.util.Text is geared toward string based processing. It includes template engine support like Free Marker that builds composite strings/values dynamically at runtime (see http://freemarker.sourceforge.net/). There are also methods to support complex regular expressions with Boolean AND, OR and NOT logic, numerous string conversions, general text manipulation and parsing methods.

Note that the default implementation uses the class

nyla.solutions.core.patterns.decorator.BasicTextStyles

To use Free Marker directory add a configuration properties

	nyla.solutions.core.util.Text.textStyles=nyla.solutions.global.patterns.decorator.style.FreeMarkerTextStyles

Note: You must add the freemarker JARs to the classpath to use this implementation.

USAGE

//Format text replacing template place-holders prefixed with ${ and suffixed by } 
//with the corresponding values in a map.
String text = "${company} A2D2 Solution Global Application Testings";
Map<String,String> map = new HashMap<String,String>();
map.put("company", "MyCompany");
text = Text.formatText(text,map);
Assert.assertEquals("MyCompany Solution Global Application Testings", text);


//Use complex text matching boolean logic to regular expressions by adding ${AND}, ${NOT} and $OR} tags
Assert.assertTrue(Text.matches("Kenya Africa", ".*Kenya.*"));
Assert.assertFalse(Text.matches("Kenya", "${NOT}.*Kenya.*"));
Assert.assertTrue(Text.matches("Kenya", "${NOT}${NOT}.*Kenya.*"));
Assert.assertFalse(Text.matches("America, Kenya, Paris", ".*Paris.*${AND}.${NOT}.*Kenya.*"));
Assert.assertFalse(Text.matches("America, Kenya, Paris", "(.*Paris.*${AND}.${NOT}.*Kenya.*)${OR}(.*Paris.*${AND}.${NOT}.*Kenya.*)"));
Assert.assertTrue(Text.matches("United States, Kenya, France", "${NOT}.*America.*${AND}.*Kenya.${NOT}.*Paris.*"));
Assert.assertTrue(Text.matches("United States, Kenya, France", "${NOT}.*America.*${AND}.*Kenya.${NOT}.*Paris.*"));

//Use the parse method to retrieve one or more token between a start and end strings
//Note the parse method can be used with non-regular expressions
String start = "Color:";
String end = ";";
Collection collection = Text.parse("Color:green; Weight:155oz; Color:Blue; Weight:23oz", start, end);
Assert.assertEquals(2,collection.size()); //two color
Iterator i  = collection.iterator();
Assert.assertEquals("green", i.next()); //first is green
Assert.assertEquals("Blue", i.next()); //second is Blue

//There methods to count of a given character
int count = Text.characterCount('A', "All Apples");
Assert.assertEquals(2, count);

//There are methods the get digit counts
count = Text.digitCount(text);
Assert.assertEquals(2, count);

//Format text numbers/decimals
String format = "#,###,###.###";
String formattedText = Text.formatNumber(123443243240.033423,format);
Assert.assertEquals("123,443,243,240.033",formattedText);

//Format text currency
formattedText = Text.formatCurrency("1000.33");
Assert.assertEquals("$1,000.33",formattedText);

//format text percentages
formattedText = Text.formatPercent("2.3");
Assert.assertEquals("2.3%",formattedText);

//Use grep to search for expressions across multiple lines in a string
text = "Greg on line 1\nGreen on line two";
String results = Text.grepText("Green", text);
Assert.assertEquals("Green on line two",results);

PROXY

Use the nyla.solutions.core.util.PROXY method to execute methods generically.

		Object response = PROXY.executeMethod(this, "verifyNoArgs", null);
		assertNull(response);
		assertTrue(verifyNoArgsCalled);
		
		response = PROXY.executeMethod(this, "verifyWityArgs", Arrays.asList("test").toArray());
		assertNull(response);
		assertTrue(verifyWityArgs);
		
		response = PROXY.executeMethod(this, "verifyWityArgsWithReturn", Arrays.asList("test").toArray());
		assertEquals("test", response);
		assertTrue(verifyWityArgsWithReturn);
	
	void verifyNoArgs()
	{
		System.out.println("verifyNoArgs");
		verifyNoArgsCalled = true;
	}
	void verifyWityArgs(String text)
	{
		System.out.println("verifyWityArgs:"+text);
		verifyWityArgs = true;
	}
	String verifyWityArgsWithReturn(String text)
	{
		System.out.println("verifyWityArgsWithReturn:"+text);
		verifyWityArgsWithReturn = true;
		return text;
	}

Package: nyla.solutions.core.util.stats

Use the Mathematics object to calculate statistics such as the 95th percentile, standard deviation, variance, mean of set of numbers.

Example Code

Mathematics math = new Mathematics();
    
//Calculate the variance 
assertEquals(700,subject.variance(10, 20, 60));
  
//Calculate mean
assertEquals(30,subject.mean(10, 20, 60));

//std dev
assertEquals(0.816496580927726,subject.stdDev(9, 10, 11));
    
//Percentile (ex 95th)

assertEquals(323,subject.percentile(95.0,10,232,232,323,232));
assertEquals(454,subject.percentile(95.0,23,75,19,3,5,454,100000,232,23,23,2,32,32,3,2,3,4,34,3,43,43,4,3,43,43,4,3,43,4,34,3,4,3,4343));
assertEquals(98,subject.percentile(95.0,23,1,23,2,32,3,2,356,56,5,6,57,6,8,9,8,98,9,8,12,1,2,1,21,21,21));

IO

See package nyla.solutions.core.io

FileMonitor

You can use the nyla.solutions.core.io.FileMonitor observer pattern to notify object that implement the Observer interface.

	//Create the file monitoring
	FileMonitor fileMonitor = new FileMonitor();
		
		//Create an observer to be called for a file appears
		Observer printFileObserver = new Observer()
		{
			@Override
			public void update(Observable o, Object arg)
			{
				//Each argment is an instance of FileEvent
				FileEvent fileEvent = (FileEvent)arg;
				
				//Note that file with assert the file is nto changing (ex: FTP files)
				File file = fileEvent.getFile();
				
				//PRint file
				System.out.println("file:"+file);
				
				//Set flag for test case
				called = true;
			}
		};
		
		//Register the observer with the file monitor
		fileMonitor.addObserver(printFileObserver);
		
		//Set the file, pattern and whether current files should trigger event
		fileMonitor.monitor("runtime/", "*.txt", false);
		
		//Write file to trigger observer
		String filePath = "runtime/"+Text.generateId()+".txt"; 
		IO.writeFile(filePath, "Hello");
		Thread.sleep(100);
		
		//Check if observer was trigger
		assertTrue(called);
		
		//Cleanup file
		IO.delete(Paths.get(filePath).toFile());

Patterns

JDBC

See nyla.solutions.core.patterns.jdbc.

Getting a connection

        String driver = Config.getProperty("test.sql.driver","org.h2.Driver");
        String connectionURL = Config.getProperty("test.sql.connectionURL");
        String user = Config.getProperty("test.sql.user");
        char[] password = Config.getPropertyPassword("test.sql.password");
        Connection connection = Sql.createConnection(driver,connectionURL,user,password);
        

Query with results as a Java Map

 ResultSetToMapConverter converter = ...;
 Map<String,?> actual = new Sql().queryForMap(connection,converter,sql);

Query with results as a Java Map using the default converter.

Map<String,?> actual = new Sql().queryForMap(connection,sql);

Execute a statement

new Sql().execute(connection,"insert into table values(1,2)");

query For a single Column value

int actualCount = new Sql().queryForColumn(connection,"select 3 from dual",1, Integer.class);

Batch Patterns

BatchJob

See nyla.solutions.core.patterns.batch.

The BatchJob class handles reading, processing and writing records in a batch fashion. The readings, procesors and writers are based on java.util.function.Supplier, java.util.function.Function and java.util.function.Consumer. This allows this framework to be used with simple Lamba expressions.

Sample usage.

  BatchJob batchJob = BatchJob.builder().supplier(supplier)
                                         .consumer(consumer)
                                         .batchChunkSize(batchChunkSize).processor(
                             processor).build();
 
            BatchReport batchRecord = batchJob.execute()

JdbcBatch

See package nyla.solutions.core.patterns.jdbc.batch


String sql = "select * from test";
PreparedStatementMapConsumer preparedStatementMapConsumer = new PreparedStatementMapConsumer(bindVariableInterpreter,preparedStatementCreator);
                                                                    Map<String, Object> map = new HashMap<>(); 

SelectResultSetConverterSupplier resultSetSupplier = new SelectResultSetConverterSupplier(
          () -> Sql.createConnection(driver, 
                connectionURL, 
                user, password),
          new ResultSetToMapConverter(), 
          sql);

        JdbcBatch jdbcBatch = new JdbcBatch(resultSetSupplier,
                new ResultSetToMapConverter(),
                preparedStatementMapConsumer,
                batchChunkSize);

Search Patterns

See package nyla.solutions.core.patterns.search

ReLookup

ReLookup is a map that supports searching for values using a complex regular expression syntax. The key is a regular expression. This operation is similar to the lookup operation. The RELookup will iterate through the given expressions looking for a match on the corresponding source attribute. The value of the lookup is used if the regular expression matches the source attribute value.

  • Complex Regular Expression (And/Not) * By default, regular expressions do not have an easy way to chain expressions together using AND/NOT logic. The OR logical expression is supported with the character “|”. The RELookup operation combines regular expressions with a special syntax to support AND/NOT logic.

AND Operation

The RELookup supports chaining expressions together with “AND” logic. This is accomplished by chaining expressions together with “${AND}”. The string “${AND}” can be used to separate two regular expressions. If any of the regular expressions return false then the entire regular expression is false. In the following example, the regular expression “.USA.${AND}.Greece.”, only returns true if the text contains both “USA” and “Greece”.

Complex RE Value Matches
.USA.${AND}.Greece. USA and Greece True
.USA.${AND}.Greece. USA False
.USA.${AND}.Greece. Greece False
.USA.${AND}.Greece. Greece USA True

NOT Operation

The RELookup supports negative logic (NOT) for expressions. This is accomplished by prefixing the expressions with “${NOT}”. In the following example, the regular expression “.USA.” only returns true if the text does not contain the word “USA”. Note that multiple “${NOT}”(s) can be chained together with “${AND}”(s) (see table below).

Complex RE Value Matches
${NOT}.USA. USA and Greece False
${NOT}.USA. USA False
${NOT}.USA. Greece True
${NOT}.USA. Greece USA False
.Greece.${AND}${NOT}.USA. ${AND}${NOT}.Turkey. Greece Turkey False
.Greece.${AND}${NOT}.USA. ${AND}${NOT}.Turkey. Greece Africa True

USAGE

	ReLookup<FaultError> lookup = new ReLookup<FaultError>();

	assertTrue(lookup instanceof Map);
		
	lookup.put("(001)*.*Green.*${AND}${NOT}.*Blue.*", new FaultError("0001","ERROR"));
	lookup.put("(002)*.*Green.*${AND}.*Blue.*", new FaultError("0002","GB"));
	lookup.put("(003)*.*Blue.*", new FaultError("0003","BLUE"));
		
	assertEquals(lookup.get("Green").getCode(), "0001");
	assertEquals(lookup.get("Blue Green").getCode(), "0002");
	assertEquals(lookup.get("Blue with Live of pure").getCode(), "0003");

Fault Pattern

See package nyla.solutions.core.exception.fault

Use the FaultsHtmlTextDecorator to get HTML summary of the FaultException or just objects the implement the nyla.solutions.core.exception.fault.Fault interface.

		Collection<Fault> faults = new ArrayList<Fault>();
		faults.add(faultException);
		FaultsHtmlTextDecorator decorator = new FaultsHtmlTextDecorator(faults);

		String faultsSummaryHtml = decorator.getText();

You can override the HTML template by putting the following files first in the classpath:

templates/FaultsHtmlTextDecorator_ROW.txt
templates/FaultsHtmlTextDecorator.txt

You can also override the default template classpath locator from "template" by setting the following config property.

 nyla.solutions.core.util.Text.TEMPLATE_CLASSPATH_ROOT=myclassPathRoot

Example

	nyla.solutions.core.util.Text.TEMPLATE_CLASSPATH_ROOT=/com/company/templates

Example HTML output:

	<html>	<body>
			<div>
				<table>
					<tr>
						<thead>
							<td>code</td>
							<td>message</td>
							<td>category</td>
							<td>module</td>
							<td>errorStackTrace</td>
						</thead>
					</tr>
					<tr>	<td>001</td>
		<td>test_message</td>
		<td></td>
		<td></td>
		<td>nyla.solutions.core.exception.fault.FaultException: test_message
		at nyla.solutions.core.exception.fault.FaultsHtmlDecoratorTest.testGetText(FaultsHtmlDecoratorTest.java:34)
		at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
		at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
		at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
		at java.lang.reflect.Method.invoke(Method.java:498)
		at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
		at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
		at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
		at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
		at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
		at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
		at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
		at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
		at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
		at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
		at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
		at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
		at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
		at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
		at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
		at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
		at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
		at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
		at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
	</td>
	</tr>
	
				</table>	
			</div>
		</body>
	</html>

MappedTextFormatDecorator Pattern

The class nyla.solutions.core.patterns.decorator.MappedTextFormatDecorator

can be used to generator dynamic based on template text based on the Textable/TextDecorator

MappedTextFormatDecorator subject = .new MappedTextFormatDecorator();
String url = "http://localhost:8080/template/MappedTextFormatDecoratorTest.txt";
Map<String, Textable> map = new HashMap<>();
map.put("fn", new StringText(new FirstNameCreator().create()));
map.put("ln", new StringText(new LastNameCreator().create()));

subject.setTemplateUrl(url);
String text = subject.getText();

The following is an example template at a URL:

Hello ${fn} ${ln}

You also set the template without using a URL.

subject.setTemplate("I love ${fn} ${ln}");

Java Bean Generator Creator

See package nyla.solutions.core.patterns.creational.generator

JavaBeanGeneratorCreator can be used to auto generate properties for any object.

The following will auto generate random data for the "email" property.

		JavaBeanGeneratorCreator<UserProfile> creator = new JavaBeanGeneratorCreator<UserProfile>(UserProfile.class);
		creator.randomizeProperty("email");
					
		UserProfile userProfile = creator.create();
		assertNotNull(userProfile);
					
		assertTrue(userProfile.getEmail() != null && userProfile.getEmail().length() > 0 );

The following auto generate all supported properties in the provided object.

		JavaBeanGeneratorCreator<UserProfile> creator = new JavaBeanGeneratorCreator<UserProfile>(UserProfile.class);
				creator.randomizeAll();
		
		JavaBeanGeneratorCreator<UserProfile> creator = new JavaBeanGeneratorCreator<UserProfile>(UserProfile.class);
		creator.randomizeAll();
		
		assertTrue(creator.getRandomizeProperties().contains("firstName"));
		
		assertTrue(creator.create().getEmail().length() > 0);

The following uses a proxy to generate new objects. The proxy is copied with only the indicated properties auto generated with each create method.

		UserProfile protoype = new UserProfile();
				protoype.setFirstName("Imani");
				protoype.setLastName("Green");
		
		JavaBeanGeneratorCreator<UserProfile> creator = new JavaBeanGeneratorCreator<UserProfile>(protoype);
		
		creator.randomizeProperty("email");
		
		UserProfile u1 = creator.create();
		assertEquals(u1.getFirstName(),protoype.getFirstName());
		assertEquals(u1.getLastName(),protoype.getLastName());
		assertNotNull(u1.getEmail());
		assertTrue(u1.getEmail().length() > 0);

If you have a fairly complex object with multiple nested objects, you can use the generateNestedAll in addition to the randomizeAll to create random data for nested objects.

    JavaBeanGeneratorCreator<ComplexObject> creator = new
                    JavaBeanGeneratorCreator<ComplexObject>(ComplexObject.class)
                    .randomizeAll()
                    .generateNestedAll();

		ComplexObject complexObject = creator.create();

JavaBeanGenerator will also generator reasonably valid values for fields such as "firstName", "lastName", "phone", "mobile", "fax" and "email" based on the provided objects properties names.

For example, the following code

	UserProfile userProfile  = new JavaBeanGeneratorCreator<UserProfile>(UserProfile.class)
						.randomizeAll().create();
				System.out.println(userProfile);

Results in the following output. Notice, the random generated values for first, last name, email and phone.

nyla.solutions.core.security.user.
data.UserProfile[[email protected],
loginID=467230864,
firstName=Walter,lastName=Neal,
title=20200524224944759144752447,
phone=555-555-5708,
...

JSON Generation

The class JsonGeneratorCreator is creational implementation to generator example JSON output similar to the JavaBeanGenerator.

See nyla.solutions.core.patterns.creational.generator.json.JsonGeneratorCreator

It will also generator reasonably valid values for fields such as "firstName", "lastName", "phone", "mobile", "fax" and "email" based on the provided type properties names.

The supported data types are base on the JsonPropertyType object (ex: String, Integer, Number and Boolean).

Example Usage using the Properties object.

  
        
         Properties properties = new Properties();
         properties.setProperty("firstName","String");
         properties.setProperty("lastName","String");
         properties.setProperty("updateDate","String");
         properties.setProperty("cost","Number");
         properties.setProperty("count","Integer");

         JsonGeneratorCreator c =
                 new JsonGeneratorCreator(DateTimeFormatter.ISO_DATE,
                         properties);

         String json = c.create();

Example JSON output

  {"firstName":"Keith","lastName":"Jackson","updateDate":"2020-07-04","cost":0.011549557733887772,"count":119629238}
   

You can also use a JsonSchemaBluePrint object to create the JsonGeneratorCreator.

        sJsonSchemaBluePrint jsonSchemaBluePrint = new JsonSchemaBluePrint(DateTimeFormatter.ISO_DATE);

        jsonSchemaBluePrint.addPropertySchema(new JsonPropertySchema("isTrue", JsonPropertyType.Boolean));
        jsonSchemaBluePrint.addPropertySchema(new JsonPropertySchema("cost", JsonPropertyType.Number));
        jsonSchemaBluePrint.addPropertySchema(new JsonPropertySchema("count", JsonPropertyType.Integer));
        jsonSchemaBluePrint.addPropertySchema(new JsonPropertySchema("name", JsonPropertyType.String));
        jsonSchemaBluePrint.addPropertySchema(new JsonPropertySchema("date", JsonPropertyType.String));
        jsonSchemaBluePrint.addPropertySchema(new JsonPropertySchema("firstName", JsonPropertyType.String));
        jsonSchemaBluePrint.addPropertySchema(new JsonPropertySchema("lastName", JsonPropertyType.String));

        JsonGeneratorCreator c =
                new JsonGeneratorCreator(jsonSchemaBluePrint);

        String json = c.create();

Cache Farm

See package nyla.solutions.core.patterns.cache

Cache Farm is a simple singleton implementation of cached key/value pairs.

	Cache<Object,Object> cacheFarm = CacheFarm.getCache();
	cacheFarm.put("key",myObject);

CSV

See package nyla.solutions.core.io.csv

The following is used to parse CSV lines nyla.solutions.core.io.csv.CsvReader

		List<String> results = CsvReader.parse("1,2");
		assertNotNull(results);
		assertEquals("1", results.get(0));
		assertEquals("2", results.get(1));
		
		results = CsvReader.parse("\"1,2\"");
		assertEquals("1,2", results.get(0));
		
		
		results = CsvReader.parse("0,\"1,2\"");
		assertEquals("0", results.get(0));
		assertEquals("1,2", results.get(1));
		
		results = CsvReader.parse("0,\"1,2\",\"Greg's\"");
		assertEquals("0", results.get(0));
		assertEquals("1,2", results.get(1));
		assertEquals("Greg's", results.get(2));
		
		results = CsvReader.parse("0,\"1,2\",\"Greg's\",\"last");
		assertEquals("last", results.get(3));
		
		
		results = CsvReader.parse("\"0\",\"The \"\"GOOD\"\"\",2");
		
		assertEquals("0", results.get(0));
		assertEquals("The \"GOOD\"", results.get(1));
		assertEquals("2", results.get(2));

LDAP

See package nyla.solutions.core.ds

The object nyla.solutions.core.ds.LDAP provides a simple wrapper for LDAP authentication and searching.

		String adminDN = "uid=admin,ou=system";
		char[] adminPwd  ="secret".toCharArray();
		String user = "imani";
		char[] pwd = "password".toCharArray();
	  
	     try(LDAP ldap = new LDAP("ldap://localhost", adminDN, adminPwd))
		{
			Principal principal = ldap.authenicate(user,pwd,"ou=system","uid","memberOf","CN",100);
			assertEquals(user,principal.getName());
		}

LDAPS (or LDAP over SSL/TLS support)

Set the following configuration properties in order to enable secure LDAP communication.

Property Notes
LDAP_USE_SSL_CONFIG_FACTORY (true or false) Boolean value to determine if LDAPS is used with the following configurations properties
"LDAP_SSL_KEYSTORE" The SSL KEYSTORE file path location
"LDAP_SSL_TRUSTSTORE" The SSL KEYSTORE file path location
"LDAP_SSL_KEYSTORE_PASSWORD" The password for the key store
"LDAP_SSL_TRUSTSTORE_PASSSWORD" The password for the trust store

Security

See package nyla.solutions.core.security.data

Access Control List

	 Principal caller = null;
	    Principal principal = null;
	    
		SecurityAcl securityAcl = new SecurityAcl();
		
		principal = new SecurityGroup("group");
		caller = new SecurityClient("admin");
		securityAcl.addEntry(caller,principal, false,"CLUSTER");
		assertTrue(securityAcl.checkPermission(principal, "CLUSTER"));
		
		securityAcl.addEntry(caller,principal, true,"CLUSTER");
		assertFalse(securityAcl.checkPermission(principal, "CLUSTER"));	

Graphics

See package nyla.solutions.core.media

Capture screen shots

Graphics graphics = new Graphics();
graphics.printScreen(0, 0, 1000, 800, "png", new File("runtime/tmp/output/screenshot.png"));

Rotate images

Example rotate 45 degrees

Graphics graphics = new Graphics();
graphics.rotateImage(Paths.get("test-in.png").toFile(),Paths.get("test-out.png"),toFile(),Graphics.Format.PNG,45);

Expirations

See package nyla.solutions.core.data.expiration

ExpiringKeyValueLookup

The ExpiringKeyValueLookup class can be used for simple hash based look ups with expiring content. This is a good class to use for implementing caching.

Example Code

		ExpiringKeyValueLookup<String,String> bag = ExpiringKeyValueLookup.withExpirationMS(1000);
		assertNotNull(bag);
		bag.putEntry("1","1");
		
		assertEquals("1",bag.getValue("1"));
		Thread.sleep(1001);
		
		assertNull(bag.getValue("1"));

ExpiringItem

The ExpiringItem class can be used for a single value with expiring content.

Example Code

	ExpiringItem<String> e = new ExpiringItem<>("hello",
			LocalDateTime.now().plusSeconds(1));
		
		assertEquals("hello",e.value());
		
		Thread.sleep(1050);
		
		assertNull(e.value());

Building

Set your ossrUsername and ossrhPassword in the ~/.gradle

ossrhUsername=userName
ossrhPassword=<password>
  1. Change directory to the root directory
  2. $gradle install

FAQ

Add the following to gradle.properties

signing.keyId=KEYID
#ossrh
signing.password=PASSWORD
signing.secretKeyRingFile=<HOME>/secring.gpg

Versions

Version
0.0.6
0.0.5
0.0.4
0.0.3
0.0.2
0.0.1