| Creating you own PropertyType | 
|---|
| Rules | |
|---|---|
| You can always make a new Property Type, the RULES are: 
 | |
| Description of tests | |
| 
 | 
| Abstract | 
|---|
| 
	@Test
	public void testPropertyTypeDefinition() {
		//Declaration of PropertyType
		PropertyType t = null;
				
		//Values
		final String name = "name";
		final String validStrings[] = {};   //Array of valid values
		final String invalidStrings[] = {}; //Array of invalid values.
		final String emptyStrings[]={"","  "};     //invalid in most cases. Customize that bit of code
		final String nullString = null; //undefined		
		T defaultValue=<not null default value>;		
		
		//Valid values -----------------------------------------------------------
		//instance of PropertType.
		t = new PropertyType(); 
		for (String value : validStrings) {
			try {
				T validT  = t.validate(name,value);
				assertNotNull(validT);			
				assertEquals(value,t.toString(name,validT));
			} catch (PropertyException e) {
				fail(e.getMessage());
			}
		}
		
		//Invalid values -----------------------------------------------------------
		//instance of PropertType.
		t = new PropertyType(); 
		for (String value : invalidStrings) {
			try {
				t.validate(name,value);
				fail("Should not validate ["+value+"]");
			} catch (PropertyException e) {
				assertNull(t.toType(name, value));
			}
		}
				
		//Null Undefined, with default value ----------------------------------------
		//instance of PropertType with default value.
		t = new PropertyType(defaultValue); 
		try {
			t.validate(name,nullString);
			fail();		
		} catch (PropertyException e) {
			assertEquals(defaultValue,t.toType(name, nullString));
		}	
			
		//Null Undefined, no default value. ------------------------------------------
		//instance of PropertType.
		t = new PropertyType();
		try {
			t.validate(name,nullString);
			fail();
		} catch (PropertyException e) {
			assertNull(t.toType(name, nullString));
		}
		
		
		//invalid in most cases. Customize ------------------------------------------
		//Empty values, can vary in PropertyTypes.
		//instance of PropertType.
		t = new PropertyType();
		for (String value : emptyStrings) {
			try {
				t.validate(name,value);
				fail("Should not validate ["+value+"]");
			} catch (PropertyException e) {
				assertNull(t.toType(name, value));
			}
		}		
	}
 | 
| Example with IntegerPropertyType | 
|---|
| 
	@Test
	public void testPropertyTypeDefinition() {
		//Declaration of PropertyType
		IntegerPropertyType t = null;
				
		//Values
		final String name = "name";
		final String validStrings[] = {123,-123};   //Array of valid values
		final String invalidStrings[] = {"cow","1.2"}; //Array of invalid values.
		final String emptyStrings[]={"","  "};     //invalid 
		final String nullString = null; //undefined		
		Integer defaultValue=42;			
		
		
		//Valid values -----------------------------------------------------------
		//instance of PropertType.
		t = new IntegerPropertyType(); 
		for (String value : validStrings) {
			try {
				T validT  = t.validate(name,value);
				assertNotNull(validT);			
				assertEquals(value,t.toString(name,validT));
			} catch (PropertyException e) {
				fail(e.getMessage());
			}
		}
		
		//Invalid values -----------------------------------------------------------
		//instance of PropertType.
		t = new IntegerPropertyType(); 
		for (String value : invalidStrings) {
			try {
				t.validate(name,value);
				fail("Should not validate ["+value+"]");
			} catch (PropertyException e) {
				assertNull(t.toType(name, value));
			}
		}
				
		//Null Undefined, with default value ----------------------------------------
		//instance of PropertType with default value.
		t = new IntegerPropertyType(defaultValue); 
		try {
			t.validate(name,nullString);
			fail();		
		} catch (PropertyException e) {
			assertEquals(defaultValue,t.toType(name, nullString));
		}	
			
		//Null Undefined, no default value. ------------------------------------------
		//instance of PropertType.
		t = new IntegerPropertyType();
		try {
			t.validate(name,nullString);
			fail();
		} catch (PropertyException e) {
			assertNull(t.toType(name, nullString));
		}
		
		
		//invalid in most cases. Customize ------------------------------------------
		//Empty values, can vary in PropertyTypes.
		//instance of PropertType.
		t = new IntegerPropertyType();
		for (String value : emptyStrings) {
			try {
				t.validate(name,value);
				fail("Should not validate ["+value+"]");
			} catch (PropertyException e) {
				assertNull(t.toType(name, value));
			}
		}		
	}
 | 
| Example with Quartz CronTrigger | 
|---|
| A property type which could easily be made, is for the cron pattern. So in the property list we can define when triggers/timers shall run. Take the Quartz implementation http://quartz-scheduler.org/. There is a CronTrigger - http://quartz-scheduler.org/documentation/quartz-1.x/tutorials/crontrigger. To make a PropertyType for CronTrigger will look like this. 
public class CronTriggerPropertyType extends PropertyType<String> {
	
	public CronTriggerPropertyType() {
		super("CronTrigger",null);
	}
	
	public CronTriggerPropertyType(String defaultValue) {
		super("CronTrigger",defaultValue);
	}	
	@Override
	public List<String> getRestrictions() {
		List<String> list = new ArrayList<String>();
		list.add("A CronTrigger value.");
		list.add("Validates a String to a valid CronExpression used by a CronTrigger.");
		list.add(getDefaultValueDescription());
		return list;
	}
	@Override
	public String validateValue(String name, String value) throws PropertyException {
		validateNullType(name,value);
		value = value.trim();
		try {
			new CronExpression(value);
			return value;			
		} catch (ParseException e) {
			throw new PropertyException("Property ["+name+"] with value ["+value+"] is not a legal CronTrigger value, with message ["+e.getMessage()+"]");
		}
	}
}
The test class for this will be. 
	@Test
	public void testPropertyTypeDefinition() {
		//Declaration of PropertyType
		QuartzCronTriggerPropertyType t = null;		
				
		//Values
		final String name = "name";
		final String validStrings[] = {"0 15 10 * * ? 2005","0 15 10 ? * 6L 2002-2005"};   //Array of valid values
		final String invalidStrings[] = {"cow","1.2"}; //Array of invalid values.
		final String emptyStrings[]={"","  "};     //invalid 
		final String nullString = null; //undefined		
		String defaultValue="0 0 12 1/5 * ?";		
		
		
		//Valid values -----------------------------------------------------------
		//instance of PropertType.
		t = new QuartzCronTriggerPropertyType(); 
		for (String value : validStrings) {
			try {
				String validT  = t.validate(name,value);
				assertNotNull(validT);			
				assertEquals(value,t.toString(name,validT));
			} catch (PropertyException e) {
				fail(e.getMessage());
			}
		}
		
		//Invalid values -----------------------------------------------------------
		//instance of PropertType.
		t = new QuartzCronTriggerPropertyType(); 
		for (String value : invalidStrings) {
			try {
				t.validate(name,value);
				fail("Should not validate ["+value+"]");
			} catch (PropertyException e) {
				assertNull(t.toType(name, value));
			}
		}
				
		//Null Undefined, with default value ----------------------------------------		
		t = new QuartzCronTriggerPropertyType(defaultValue);
		try {
			t.validate(name,nullString);
			fail();
		} catch (PropertyException e) {
			assertEquals(defaultValue,t.toType(name, nullString));
		}
			
		//Null Undefined, no default value. ------------------------------------------
		//instance of PropertType.
		t = new QuartzCronTriggerPropertyType();
		try {
			t.validate(name,nullString);
			fail();
		} catch (PropertyException e) {
			assertNull(t.toType(name, nullString));
		}
		
		
		//invalid in most cases. Customize ------------------------------------------
		//Empty values, can vary in PropertyTypes.
		//instance of PropertType.
		t = new QuartzCronTriggerPropertyType();
		for (String value : emptyStrings) {
			try {
				t.validate(name,value);
				fail("Should not validate ["+value+"]");
			} catch (PropertyException e) {
				assertNull(t.toType(name, value));
			}
		}		
	}
And used like this. 
    Trigger trigger = TriggerBuilder.newTrigger()
    .withIdentity("trigger3", "group1")
    .withSchedule(cronSchedule(MyAppProperties.APP_TIMER1_CRON.getTypedValue()));
    .build();
Than again you could extend the QuartzCronTriggerPropertyType with a method. 
	public Trigger buildTrigger(String triggerName,String triggerGroup) {
	    return TriggerBuilder.newTrigger()
	    .withIdentity(triggerName, triggerGroup)
	    .withSchedule(cronSchedule(getTypedValue()))
	    .build();
	}
 | 
| Example with your own Enum | 
|---|
| If your have your own Enum definition. 
public enum MyColors {	
	RED,
	GREEN,
	BLUE
}
It is pretty easy to make your on type, there is two ways to do this.1. Use the EnumPropertyType: public final static Property<MyColors> P_ENUM_MYCOLORS 	= new Property<MyColors>("p.enum.mycolors",new EnumPropertyType<MyColors>(MyColors.class));2. Make your own PropertyType 
public class MyColorsPropertyType extends EnumPropertyType<MyColors> {
	public MyColorsPropertyType() {
		super(MyColors.class);
	}
	public MyColorsPropertyType(MyColors defaultValue) {
		super(MyColors.class,defaultValue);
	}
}
And use it like:public final static Property<MyColors> P_ENUM_MYCOLORS 	= new Property<MyColors>("p.enum.mycolors",new MyColorsPropertyType()); |