Dynamic properties and methods are used when the property/method name is not defined in advance, but can appear according to specific use cases. When they are dynamic, more readable and writable properties/methods names are provided.
In our script service a camera can have different settings depending on the model – brightness, contrast, saturation, zoom, etc. , so that we can handle dynamic get and set camera feature methods.
For example:
camera.setBrightness(6.0d);camera.setZoom(3.2d);double saturationValue = camera.saturation;double constrastValue = camera.contrast;Dynamic properties and methods are supported by a script service class when it implements:
• com.prosyst.mprm.backend.rules.spi.PropertyMissing – handles dynamic properties.
• com.prosyst.mprm.backend.rules.spi.MethodMissing – handles dynamic methods.
In our script service the Camera object will support dynamic properties and methods:
// extending the interfaces PropertyMissing and MethodMissingpublic interface Camera extends PropertyMissing, MethodMissing, ScriptSerializable { …}And the implementation:
package com.prosyst.mprm.demos.rules.impl;public class CameraImpl implements Camera { ... private static final String ASYNC_METHOD_PREFIX = "set"; ... // executed when no static property was found public Object propertyMissing(String propertyName) throws Exception { Object propertyValue = getFeatureValue(propertyName); if (propertyValue == null) { throw new NoSuchFieldException("Feature '" + propertyName + "' not supported!"); } return propertyValue; }// executed when no static method was found public MethodMissingMetaData methodMissingMetaData(String methodName, Object arg) throws Exception { // there are only asynchornous dynamic methods return new MethodMissingMetaData(false, true); } // the dynamic synchronous method implementation public Object methodMissing(String methodName, Object args) throws Exception { throw new NoSuchMethodException("Synchronous dynamic methods are not supported!"); } // the dynamic asynchronous method implementation public Object methodMissing(String methodName, Object args, AsyncResult asyncResult) throws Exception { if (methodName.startsWith(ASYNC_METHOD_PREFIX)) { String featureName = methodName.substring(ASYNC_METHOD_PREFIX.length()).toLowerCase(); double featureValue = (Double)args; setFeature(featureName, featureValue, asyncResult); return null; } else { throw new NoSuchMethodException("Wrong dynamic asynchronous method prefix!"); } } ...}When implementing PropertyMissing and MethodMissing interfaces these exceptions have to be thrown when needed:
• java.lang.NoSuchFieldException – thrown when the object doesn't have a property with the specified name.
• java.lang.NoSuchMethodException – thrown when the object doesn't have a method with the specified name.
The property missing method is called when no property of the object with the given static name is found.
For example, when script:
camera.saturation;or
camera.getSaturation();is called, then Object propertyMissing(String propertyName) throws Exception of the Camera object will be invoked.
When no method of the object with the given static name is found, for example:
camera.setBrightness(6.0d); Then the MethodMissing interface methods are called in specific order:
First one called is
MethodMissingMetaData methodMissingMetaData(String methodName, Object arg)throwsExceptionAfter that we have to provide the value of the argument
isAsync (true/false)depending on the script service logic and call theMethodMissingMetaDataconstructor with itMethodMissingMetaData(booleanreportResult,booleanisAsync)If the argument
isAsyncis true then the following method will be called:Object methodMissing(String methodName, Object args, AsyncResult asyncResult)throwsExceptionIf false the called method will be:
Object methodMissing(String methodName, Object args)throwsException