org.apache.beehive.controls.runtime.generator.ControlBean.vm Maven / Gradle / Ivy
The newest version!
##
## The Velocity code generation template for the JavaBean generated from a Control public
## or extension interface.
##
## Licensed to the Apache Software Foundation (ASF) under one or more
## contributor license agreements. See the NOTICE file distributed with
## this work for additional information regarding copyright ownership.
## The ASF licenses this file to You under the Apache License, Version 2.0
## (the "License"); you may not use this file except in compliance with
## the License. You may obtain a copy of the License at
##
## http://www.apache.org/licenses/LICENSE-2.0
##
## Unless required by applicable law or agreed to in writing, software
## distributed under the License is distributed on an "AS IS" BASIS,
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
## See the License for the specific language governing permissions and
## limitations under the License.
##
## $Header:$
##
## The following context variables are used by this template:
## $bean - a ControlBean instance that defines the attributes of the bean
## $intf - a ControlInterface instance that defines the attributes of the public interface
##
## The actual class template apears at the end of this file, and is preceded by a number of
## supporting macros that define elements of the template.
##
## LOCAL SUPPORTING MACROS
##
## This macro declares the template for defining bean constructors
##
#macro (declareConstructors)
/**
* This is the public constructor for the class. A client-defined control ID may
* be provided. This ID must be unique within the nesting ControlBeanContext.
* @param context The containing ControlBeanContext
* @param id The control identifier (or null to autogenerate a unique value)
* @param props The initialization Properties for the new instance (or null for defaults)
*/
public ${bean.shortName}(ControlBeanContext context, String id, PropertyMap props)
{
this(context, id, props, ${intf.className}.class);
}
/**
* This is the public null-arg constructor for this ControlBean. If a control id
* is not provided, a unique value will be auto-generated.
*/
public ${bean.shortName}()
{
this(null, null, null);
}
/**
* This is the protected version that is used by any ControlBean subclass
*/
protected ${bean.shortName}(ControlBeanContext context, String id, PropertyMap props, Class controlClass)
{
super(context, id, props, controlClass);
#foreach ($eventSet in $intf.eventSets)
#if ($velocityCount == 1)
//
// Register event notifier instances for any EventSets
//
#end
setEventNotifier(${eventSet.className}.class, new ${eventSet.notifierClass}());
#end
}
#end
##
## This macro defines the implementation of of the getParameterNames helper method
##
#macro (declareGetParameterNames)
/**
* Returns an array of parameter names for the request method, or null if no parameter
* data is available.
*/
protected String [] getParameterNames(Method m)
{
// Check the local map for operations on this bean type
if (_methodParamMap.containsKey(m))
{
return _methodParamMap.get(m);
}
// Delegate up if not found locally
return super.getParameterNames(m);
}
#end
##
## This macro defines the implementation of an operation
##
#macro (declareOperationImpl $operation)
#set ($returnType = $operation.returnType)
/**
* Implements ${intf.className}.${operation.name}
*/
@SuppressWarnings({"unchecked"}) // for __bc_retval cast
public $operation.formalTypes $returnType ${operation.name}($operation.argDecl) $operation.throwsClause
{
Object [] __bc_argArray = new Object[] { $operation.argList };
Throwable __bc_thrown = null;
#if (!$intf.isExtension())
$intf.formalClassName __bc_target = ($intf.formalClassName)ensureControl();
#else
Extensible __bc_target = (Extensible)ensureControl();
#end
#if ($returnType != "void")
$returnType __bc_retval = ${operation.defaultReturnValue};
#end
#if ($operation.interceptorServiceNames.size() > 0)
String __bc_pivotedInterceptor = null;
#end
try
{
#if ($operation.interceptorServiceNames.size() == 0)
preInvoke(${operation.methodField}, __bc_argArray);
#else
preInvoke(${operation.methodField}, __bc_argArray, ${operation.methodField}Interceptors);
#end
##
## There are two basic generation patterns:
## - standard invoke (declared on a ControlInterface)
## - extensible invoke (declared on a ControlExtension)
##
#if ($returnType != "void")
__bc_retval =
#end
#if (!$intf.isExtension())
__bc_target.${operation.name}($operation.argList)
#else
#if ($returnType != "void")
(#toObject ($returnType))
#end
__bc_target.invoke(${operation.methodField}, __bc_argArray)
#end
;
}
#if ($operation.interceptorServiceNames.size() > 0)
catch (org.apache.beehive.controls.spi.svc.InterceptorPivotException __bc_ipe)
{
__bc_pivotedInterceptor = __bc_ipe.getInterceptorName();
#if ($returnType != "void")
__bc_retval = (#toObject ($returnType))__bc_ipe.getReturnValue();
#end
}
#end
catch (Throwable __bc_t)
{
//
// All exceptions are caught here, so postInvoke processing has visibility into
// the exception status. Errors, RuntimExceptions, or declared checked exceptions will
// be rethrown.
//
__bc_thrown = __bc_t;
if (__bc_t instanceof Error) throw (Error)__bc_t;
else if (__bc_t instanceof RuntimeException) throw (RuntimeException)__bc_t;
#foreach ($thrownException in $operation.throwsList)
else if (__bc_t instanceof $thrownException) throw ($thrownException)__bc_t;
#end
throw new UndeclaredThrowableException(__bc_t);
}
finally
{
#if ($returnType == "void")
Object __bc_rv = null;
#else
Object __bc_rv = __bc_retval;
#end
#if ($operation.interceptorServiceNames.size() == 0)
postInvoke(${operation.methodField}, __bc_argArray, __bc_rv, __bc_thrown);
#else
postInvoke(${operation.methodField}, __bc_argArray, __bc_rv, __bc_thrown, ${operation.methodField}Interceptors, __bc_pivotedInterceptor);
#end
}
#if ($returnType != "void")
return __bc_retval;
#end
}
#end
##
## This macro defines the property accessor methods for a bean property
##
#macro (declarePropertyAccessors $property)
/**
* A PropertyKey that can be used to access the $property.name property of the
* $property.propertySet.shortName PropertySet
*/
public static final PropertyKey $property.keyName = new PropertyKey(${property.propertySet.className}.class, "$property.name");
#if ($property.propertySet.hasSetters())
public synchronized void ${property.writeMethod}($property.type value)
#if ($property.constrained)
throws java.beans.PropertyVetoException
#end
{
#if ($property.bound || $property.constrained)
// Ensure the control impl exists, since it may want to receive property events
ensureControl();
Object __bc_oldValue = getRawControlProperty($property.keyName);
#end
#if ($property.constrained)
fireVetoableChange($property.keyName, __bc_oldValue, value);
#end
setControlProperty($property.keyName, value);
#if ($property.bound)
firePropertyChange($property.keyName, __bc_oldValue, value);
#end
}
#end
#if (!$property.propertySet.isOptional())
public $property.type ${property.readMethod}()
{
return (#toObject($property.type))getControlProperty($property.keyName);
}
#end
#end
##
## This macro declares the registration methods supporting a PropertyChangeListener
##
#macro (declareBoundPropertySupport)
/**
* Adds a new PropertyChangeListener for listening to changes on bound properties of this
* control.
*/
public void addPropertyChangeListener(PropertyChangeListener pcl)
{
getPropertyChangeSupport().addPropertyChangeListener(pcl);
}
/**
* Adds a new PropertyChangeListener for listening to changes to a specific bound
* property of this control.
*/
public void addPropertyChangeListener(String propertyName, PropertyChangeListener pcl)
{
getPropertyChangeSupport().addPropertyChangeListener(propertyName, pcl);
}
/**
* Removes a registered PropertyChangeListener listening to changes on bound properties of
* this control.
*/
public void removePropertyChangeListener(PropertyChangeListener pcl)
{
getPropertyChangeSupport().removePropertyChangeListener(pcl);
}
/**
* Removes a registered PropertyChangeListener listening to changes on a specific bound
* property of this control.
*/
public void removePropertyChangeListener(String propertyName, PropertyChangeListener pcl)
{
getPropertyChangeSupport().removePropertyChangeListener(propertyName, pcl);
}
#end
##
## This macro declares the registration methods supporting a VetoableChangeListener
##
#macro (declareConstrainedPropertySupport)
/**
* Adds a new PropertyChangeListener for listening to changes on bound properties of this
* control.
*/
public void addVetoableChangeListener(VetoableChangeListener vcl)
{
getVetoableChangeSupport().addVetoableChangeListener(vcl);
}
/**
* Adds a new PropertyChangeListener for listening to changes to a specific constrained
* property of this control.
*/
public void addVetoableChangeListener(String propertyName, VetoableChangeListener vcl)
{
getVetoableChangeSupport().addVetoableChangeListener(propertyName, vcl);
}
/**
* Removes a registered PropertyChangeListener listening to changes on constrained properties
* of this control.
*/
public void removeVetoableChangeListener(VetoableChangeListener vcl)
{
getVetoableChangeSupport().removeVetoableChangeListener(vcl);
}
/**
* Removes a registered PropertyChangeListener listening to changes to a specific constrained
* property of this control.
*/
public void removeVetoableChangeListener(String propertyName, VetoableChangeListener vcl)
{
getVetoableChangeSupport().removeVetoableChangeListener(propertyName, vcl);
}
#end
##
## This macro defines the implementation of an event routing method
##
#macro (declareEventImpl $event)
#set ($returnType = $event.returnType)
public $returnType ${event.name}($event.argDecl) $event.throwsClause
{
Throwable __bc_thrown = null;
#if ($returnType != "void")
$returnType __bc_retval = ${event.defaultReturnValue};
#end
$eventSet.notifierClass __bc_notifier = ($eventSet.notifierClass)getEventNotifier(${eventSet.className}.class);
#if ($event.eventSet.unicast)
$event.eventSet.formalClassName __bc_listener = ($event.eventSet.formalClassName)__bc_notifier.getListener();
//
// If an event listener has been registered, then deliver the event
//
if (__bc_listener != null)
{
Object [] __bc_argArray = new Object[] {$event.argList};
#if ($event.interceptorServiceNames.size() != 0)
String __bc_pivotedInterceptor = null;
#end
try
{
#if ($event.interceptorServiceNames.size() != 0)
preEvent($event.methodField, __bc_argArray, ${event.methodField}Interceptors);
#end
#if ($returnType != "void")
__bc_retval = __bc_listener.${event.name}($event.argList);
#else
__bc_listener.${event.name}($event.argList);
#end
}
#if ($event.interceptorServiceNames.size() != 0)
catch (org.apache.beehive.controls.spi.svc.InterceptorPivotException __bc_ipe)
{
__bc_pivotedInterceptor = __bc_ipe.getInterceptorName();
#if ($returnType != "void")
__bc_retval = (#toObject ($returnType))__bc_ipe.getReturnValue();
#end
}
#end
catch (Throwable __bc_t)
{
//
// All exceptions are caught here, so postEvent processing has visibility into
// the exception status. Errors, RuntimExceptions, or declared checked exceptions will
// be rethrown.
//
__bc_thrown = __bc_t;
if (__bc_t instanceof Error) throw (Error)__bc_t;
else if (__bc_t instanceof RuntimeException) throw (RuntimeException)__bc_t;
#foreach ($thrownException in $event.throwsList)
else if (__bc_t instanceof $thrownException) throw ($thrownException)__bc_t;
#end
throw new UndeclaredThrowableException(__bc_t);
}
#if ($event.interceptorServiceNames.size() != 0)
finally
{
#if ($returnType == "void")
Object __bc_rv = null;
#else
Object __bc_rv = __bc_retval;
#end
postEvent($event.methodField, __bc_argArray, __bc_rv, __bc_thrown, ${event.methodField}Interceptors, __bc_pivotedInterceptor);
}
#end
}
#if ($returnType != "void")
return __bc_retval;
#end
#else
Object [] __bc_argArray = new Object[] {$event.argList};
#if ($event.interceptorServiceNames.size() != 0)
String __bc_pivotedInterceptor = null;
#end
java.util.Iterator __bc_listenerIter = __bc_notifier.listenerIterator();
try
{
#if ($event.interceptorServiceNames.size() != 0)
preEvent($event.methodField, __bc_argArray, ${event.methodField}Interceptors);
#end
while (__bc_listenerIter.hasNext())
{
$event.eventSet.formalClassName __bc_listener = ($eventSet.formalClassName)__bc_listenerIter.next();
__bc_listener.${event.name}($event.argList);
}
}
#if ($event.interceptorServiceNames.size() != 0)
catch (org.apache.beehive.controls.spi.svc.InterceptorPivotException __bc_ipe)
{
__bc_pivotedInterceptor = __bc_ipe.getInterceptorName();
}
#end
catch (Throwable __bc_t)
{
//
// All exceptions are caught here, so postEvent processing has visibility into
// the exception status. Errors, RuntimExceptions, or declared checked exceptions will
// be rethrown.
//
__bc_thrown = __bc_t;
if (__bc_t instanceof Error) throw (Error)__bc_t;
else if (__bc_t instanceof RuntimeException) throw (RuntimeException)__bc_t;
#foreach ($thrownException in $event.throwsList)
else if (__bc_t instanceof $thrownException) throw ($thrownException)__bc_t;
#end
throw new UndeclaredThrowableException(__bc_t);
}
#if ($event.interceptorServiceNames.size() != 0)
finally
{
postEvent($event.methodField, __bc_argArray, null, __bc_thrown, ${event.methodField}Interceptors, __bc_pivotedInterceptor);
}
#end
#end
}
#end
##
## This macro defines the implementation of a preEvent method
##
#macro (declarePreEvent $eventSet)
private void preEvent(Method method, Object[] argArray, String[] interceptors)
throws org.apache.beehive.controls.spi.svc.InterceptorPivotException
{
for ( String __bc_n : interceptors )
{
org.apache.beehive.controls.spi.svc.Interceptor __bc_i = ensureInterceptor( __bc_n );
try
{
__bc_i.preEvent( ${bean.shortName}.this, ${eventSet.formalClassName}.class , method, argArray );
}
catch (org.apache.beehive.controls.spi.svc.InterceptorPivotException __bc_ipe)
{
__bc_ipe.setInterceptorName(__bc_n);
throw __bc_ipe;
}
}
}
#end
##
## This macro defines the implementation of a postEvent method
##
#macro (declarePostEvent $eventSet)
private void postEvent(Method method, Object[] argArray, Object retval, Throwable t, String[] interceptors, String pivotedInterceptor)
{
for (int __bc_cnt = interceptors.length - 1; __bc_cnt >= 0; __bc_cnt--)
{
String __bc_n = interceptors[__bc_cnt];
if (pivotedInterceptor == null || __bc_n.equals(pivotedInterceptor))
{
pivotedInterceptor = null;
org.apache.beehive.controls.spi.svc.Interceptor __bc_i = ensureInterceptor( __bc_n );
__bc_i.postEvent( ${bean.shortName}.this, ${eventSet.formalClassName}.class , method, argArray, retval, t );
}
}
}
#end
##
## This macro defines an EventSet proxy implementation for routing events
##
#macro (declareEventSetImpl $eventSet)
/**
* This inner class implements a simple proxy to deliver $eventSet.shortName events
* back to a register listener.
*/
protected class $eventSet.notifierClass
#if ($eventSet.extendsNotifierBase)
extends $eventSet.notifierExtends
#else
extends ${bean.superClass.className}.${eventSet.notifierExtendsShortName}
#end
implements ${eventSet.formalClassName}, java.io.Serializable
{
private static final long serialVersionUID = 1L;
#set ( $interceptor = false )
#foreach ($event in $eventSet.events)
#declareEventImpl($event)
#if ($event.interceptorServiceNames.size() != 0)
#set ( $interceptor = true )
#end
#end
#if ( $interceptor )
#declarePreEvent ($eventSet)
#declarePostEvent ($eventSet)
#end
}
#end
##
## This macros defines the EventSet listener registration methods
##
#macro (declaredListenerMethods $eventSet)
/**
* Registers a new listener for ${eventSet.shortName} events on the bean.
*/
public synchronized void ${eventSet.addListenerMethod}($eventSet.formalClassName listener)
#if ($eventSet.unicast)
throws java.util.TooManyListenersException
#end
{
$eventSet.notifierClass __bc_notifier = ($eventSet.notifierClass)getEventNotifier(${eventSet.className}.class);
__bc_notifier.addListener(listener);
}
/**
* Unregisters an existing listener for ${eventSet.shortName} events on the bean.
*/
public synchronized void ${eventSet.removeListenerMethod}($eventSet.formalClassName listener)
{
$eventSet.notifierClass __bc_notifier = ($eventSet.notifierClass)getEventNotifier(${eventSet.className}.class);
__bc_notifier.removeListener(listener);
}
/**
* Returns the array of registered listeners for ${eventSet.shortName} events on the bean, or
* an empty array if no listener has been registered
*/
public synchronized $eventSet.formalClassName [] ${eventSet.getListenersMethod}()
{
$eventSet.notifierClass __bc_notifier = ($eventSet.notifierClass)getEventNotifier(${eventSet.className}.class);
$eventSet.formalClassName [] __bc_listeners = new ${eventSet.className}[__bc_notifier.getListenerCount()];
__bc_notifier.getListeners(__bc_listeners);
return __bc_listeners;
}
#end
##
## This macro declares the local (bean class) cache that is used for shared PropertyMaps
##
#macro (declarePropertyCache)
/**
* The _annotCache maintains a lookup cache from AnnotatedElements to an associated
* PropertyMap. This enables these maps to be shared across multiple beans.
*/
static private HashMap __bc_annotCache = new HashMap();
protected Map getPropertyMapCache() { return __bc_annotCache; }
#end
##
## This macro enforces the VersionRequired annotation semantics
##
#macro (enforceVersionRequired)
/*
* Enforce VersionRequired
*/
Class __bc_controlIntf = null;
#if ($intf.getMostDerivedInterface())
__bc_controlIntf = ${intf.getMostDerivedInterface().className}.class;
#end
Version __bc_versionPresent = (Version)__bc_controlIntf.getAnnotation(Version.class);
VersionRequired __bc_versionRequired = (${bean.shortName}.class).getAnnotation(VersionRequired.class);
org.apache.beehive.controls.runtime.bean.ControlBean.enforceVersionRequired("${intf.className}", __bc_versionPresent, __bc_versionRequired);
#end
##
## This macro declares the interceptor arrays for operations and eventsets
##
#macro (declareMethodInterceptors)
#foreach ($operation in $intf.operations)
#if ($operation.interceptorServiceNames.size() != 0)
private static String[] ${operation.methodField}Interceptors = ${operation.interceptorDecl};
#end
#end
#foreach ($eventSet in $intf.eventSets)
#foreach ($event in $eventSet.events)
#if ($event.interceptorServiceNames.size() != 0)
private static String[] ${event.methodField}Interceptors = ${event.interceptorDecl};
#end
#end
#end
#end
##
## This macro declares the code that prioritizes interceptor arrays for operations
##
#macro (prioritizeInterceptors)
#foreach ($operation in $intf.operations)
#if ($operation.interceptorServiceNames.size() != 0)
${operation.methodField}Interceptors = org.apache.beehive.controls.runtime.bean.InterceptorUtils.prioritizeInterceptors( ${operation.methodField}Interceptors );
#end
#end
#foreach ($eventSet in $intf.eventSets)
#foreach ($event in $eventSet.events)
#if ($event.interceptorServiceNames.size() != 0)
${event.methodField}Interceptors = org.apache.beehive.controls.runtime.bean.InterceptorUtils.prioritizeInterceptors(${event.methodField}Interceptors);
#end
#end
#end
#end
##
## THE CONTROLBEAN CLASS TEMPLATE
##
#if (!$bean.isRootPackage())
package $bean.package;
#end
import java.beans.*;
import java.lang.reflect.Method;
import java.lang.reflect.UndeclaredThrowableException;
import java.util.HashMap;
import java.util.Map;
import org.apache.beehive.controls.api.bean.*;
import org.apache.beehive.controls.api.context.ControlBeanContext;
import org.apache.beehive.controls.api.properties.PropertyKey;
import org.apache.beehive.controls.api.properties.PropertyMap;
import org.apache.beehive.controls.api.versioning.*;
@SuppressWarnings("all")
public class ${bean.classDeclaration}
extends ${bean.superClass.className}${bean.superTypeBinding}
implements ${intf.formalClassName}
{
#if ($intf.operations.size() != 0 || $intf.localEventSetCount != 0)
#declareMethodStatics()
static
{
#initMethodStatics()
}
#declareMethodInterceptors()
static
{
#prioritizeInterceptors()
}
#end
#if ($intf.getVersionRequired())
static
{
#enforceVersionRequired()
}
#end
#declareConstructors()
#if ($intf.operations.size() != 0)
#declareGetParameterNames()
#foreach ($operation in $intf.operations)
#declareOperationImpl ($operation)
#end
#end
#foreach ($propertySet in $intf.propertySets)
#foreach ($property in $propertySet.properties)
#declarePropertyAccessors ($property)
#end
#end
#if ($intf.addsBoundPropertySupport())
#declareBoundPropertySupport()
#end
#if ($intf.addsConstrainedPropertySupport())
#declareConstrainedPropertySupport()
#end
#foreach ($eventSet in $intf.eventSets)
#declareEventSetImpl ($eventSet)
#declaredListenerMethods($eventSet)
#end
#declarePropertyCache()
private static final long serialVersionUID = 1L;
}