/** * */ package alma.ACS.impl; import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import alma.ACS.CBDescIn; import alma.ACS.CBvoid; import alma.ACS.TimeSeqHolder; import alma.ACS.jbaci.CompletionUtil; import alma.ACS.jbaci.DataAccess; import alma.ACS.jbaci.PropertyInitializationFailed; import alma.ACSErr.Completion; import alma.ACSErrTypeCommon.wrappers.AcsJCouldntPerformActionEx; import alma.acs.exceptions.AcsJException; /** * Base RW enum class. * @author msekoranja */ public class CommonRWEnumPropertyImpl extends CommonROEnumPropertyImpl { /** * @param name * @param parentComponent * @throws PropertyInitializationFailed */ CommonRWEnumPropertyImpl(Class enumClass, String name, CharacteristicComponentImpl parentComponent) throws PropertyInitializationFailed { super(enumClass, name, parentComponent); } /** * @param name * @param parentComponent * @param dataAccess * @throws PropertyInitializationFailed */ CommonRWEnumPropertyImpl(Class enumClass, String name, CharacteristicComponentImpl parentComponent, DataAccess dataAccess) throws PropertyInitializationFailed { super(enumClass, name, parentComponent, dataAccess); } public Completion set_sync(Object value) { try { return setSync(value); } catch (AcsJException acsex) { AcsJCouldntPerformActionEx cpa = new AcsJCouldntPerformActionEx("Failed to set value", acsex); return CompletionUtil.generateCompletion(cpa); } } /** * Create RW enum structure. * Example: * <code> * BasicStatesOperations basicStatesEnumImpl = * (BasicStatesOperations)CommonRWEnumPropertyImpl.createEnumProperty( * BasicStatesOperations.class, * BasicStates.class, * "state", * parentComponent, * dataAccess); * </code> * @param operationsIF CORBA <enum type>Operations class. * @param propertyType CORBA enum class. * @param name name of the property. * @param parentComponent property component. * @param dataAccess data access to be used. * @return CORBA <enum type>Operations instance. * @throws PropertyInitializationFailed */ public static Object createEnumProperty( Class operationsIF, Class propertyType, String name, CharacteristicComponentImpl parentComponent, DataAccess dataAccess) throws PropertyInitializationFailed { CommonRWEnumPropertyImpl propertyImpl; if (dataAccess == null) propertyImpl = new CommonRWEnumPropertyImpl(propertyType, name, parentComponent); else propertyImpl = new CommonRWEnumPropertyImpl(propertyType, name, parentComponent, dataAccess); return Proxy.newProxyInstance( propertyImpl.getClass().getClassLoader(), new Class[] { operationsIF, Destroyable.class }, new RWEnumProxy(propertyImpl)); } /** * RW enum proxy class. */ public static class RWEnumProxy implements InvocationHandler { private final CommonRWEnumPropertyImpl delegate; RWEnumProxy(CommonRWEnumPropertyImpl delegate) { this.delegate = delegate; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { final String methodName = method.getName(); if (methodName.equals("set_sync")) { return delegate.set_sync(args[0]); } else if (methodName.equals("set_nonblocking")) { delegate.setNonblocking(args[0]); return null; } else if (methodName.equals("set_async")) { delegate.setAsync(args[0], (CBvoid)args[1], (CBDescIn)args[2]); return null; } else if (methodName.equals("get_history")) { int n_last_values = ((Integer)args[0]).intValue(); Object seqHolder = args[1]; TimeSeqHolder ts = (TimeSeqHolder)args[2]; Object historyArray = delegate.getHistory(n_last_values, ts); Field valueField = seqHolder.getClass().getField("value"); valueField.set(seqHolder, historyArray); return Array.getLength(historyArray); } else { // delegate try { // TODO cache final Method localMethod = delegate.getClass().getMethod(method.getName(), method.getParameterTypes()); return localMethod.invoke(delegate, args); } catch (InvocationTargetException e) { throw e.getTargetException(); } catch (Throwable e) { throw e; } } } } }