org.tango.server.build.DeviceBuilder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of JTangoServer Show documentation
Show all versions of JTangoServer Show documentation
Library for Tango Server (ie. Tango Device) in Java
/**
* Copyright (C) : 2012
*
* Synchrotron Soleil
* L'Orme des merisiers
* Saint Aubin
* BP48
* 91192 GIF-SUR-YVETTE CEDEX
*
* This file is part of Tango.
*
* Tango is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Tango is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Tango. If not, see .
*/
package org.tango.server.build;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.slf4j.ext.XLogger;
import org.slf4j.ext.XLoggerFactory;
import org.tango.server.ServerManager;
import org.tango.server.annotation.AroundInvoke;
import org.tango.server.annotation.Attribute;
import org.tango.server.annotation.ClassProperty;
import org.tango.server.annotation.Command;
import org.tango.server.annotation.Delete;
import org.tango.server.annotation.Device;
import org.tango.server.annotation.DeviceManagement;
import org.tango.server.annotation.DeviceProperties;
import org.tango.server.annotation.DeviceProperty;
import org.tango.server.annotation.DynamicManagement;
import org.tango.server.annotation.Init;
import org.tango.server.annotation.Pipe;
import org.tango.server.annotation.Schedule;
import org.tango.server.annotation.State;
import org.tango.server.annotation.Status;
import org.tango.server.annotation.TransactionType;
import org.tango.server.servant.DeviceImpl;
import org.tango.utils.DevFailedUtils;
import org.tango.utils.ReflectionScanner;
import fr.esrf.Tango.DevFailed;
/**
* Build a {@link Device}
*
* @author ABEILLE
*
*/
public final class DeviceBuilder {
private static final String MUST_BE_UNIQUE = " must be unique";
private final Logger logger = LoggerFactory.getLogger(DeviceBuilder.class);
private final XLogger xlogger = XLoggerFactory.getXLogger(DeviceBuilder.class);
private final Class> clazz;
private final String className;
private final String name;
private DeviceImpl device;
private Object businessObject;
DeviceBuilder(final Class> clazz, final String className, final String name) {
this.clazz = clazz;
this.className = className;
this.name = name;
}
public DeviceImpl createDevice() throws DevFailed {
MDC.put("deviceName", name);
xlogger.entry();
checkIsTangoDevice(clazz, name);
DeviceManagerBuilder.clear();
DynamicManagerBuilder.clear();
try {
final Device annotation = clazz.getAnnotation(Device.class);
TransactionType txType = ServerManager.getInstance().getTransactionType();
if (txType == null) {
txType = annotation.transactionType();
}
final String deviceType = annotation.deviceType();
// create the device
businessObject = clazz.newInstance();
device = new DeviceImpl(name, className, txType, businessObject, deviceType);
addSuperDevices();
// create default attributes and commands
final ReflectionScanner deviceImplScanner = new ReflectionScanner(device.getClass());
createBusinessObjectAttrField(deviceImplScanner, true);
createBusinessObjectAttrCmd(deviceImplScanner, true);
final ReflectionScanner boScanner = new ReflectionScanner(clazz);
createBusinessObjectFields(boScanner);
createBusinessObjectAttrField(boScanner, false);
createBusinessObjectAttrCmd(boScanner, false);
createBusinessObjectInitDelete(boScanner);
createBusinessObjectAroundInvoke(boScanner);
createBusinessObjectDeviceProperties(boScanner);
createBusinessObjectProps(boScanner);
createBusinessObjectPipes(boScanner);
createBusinessObjectState(boScanner);
} catch (final InstantiationException e) {
DevFailedUtils.throwDevFailed(e);
} catch (final IllegalAccessException e) {
DevFailedUtils.throwDevFailed(e);
}
device.initDevice();
xlogger.exit();
return device;
}
private void addSuperDevices() throws DevFailed {
Class> superDeviceClass = clazz.getSuperclass();
while (superDeviceClass != null && superDeviceClass.getAnnotation(Device.class) != null) {
logger.debug("adding super class to device {}", superDeviceClass.getCanonicalName());
final ReflectionScanner superClassScanner = new ReflectionScanner(superDeviceClass);
createBusinessObjectAttrCmd(superClassScanner, false);
createBusinessObjectAttrField(superClassScanner, false);
createBusinessObjectProps(superClassScanner);
createBusinessObjectFields(superClassScanner);
createBusinessObjectInitDelete(superClassScanner);
createBusinessObjectPipes(superClassScanner);
createBusinessObjectState(superClassScanner);
superDeviceClass = superDeviceClass.getSuperclass();
}
}
private void createBusinessObjectAttrCmd(final ReflectionScanner scanner, final boolean isOnDeviceImpl)
throws DevFailed {
// Command
final Set cmds = scanner.getMethodsAnnotatedWith(Command.class);
if (cmds != null) {
final CommandBuilder cmd = new CommandBuilder();
for (final Method method : cmds) {
cmd.build(device, businessObject, method, isOnDeviceImpl);
}
}
// Attribute
final Set attrs = scanner.getMethodsAnnotatedWith(Attribute.class);
if (attrs != null) {
final AttributeMethodBuilder attr = new AttributeMethodBuilder();
for (final Method method : attrs) {
attr.build(device, businessObject, method, isOnDeviceImpl);
}
}
}
private void createBusinessObjectInitDelete(final ReflectionScanner scanner) throws DevFailed {
// Init
final Set initM = scanner.getMethodsAnnotatedWith(Init.class);
if (initM != null && initM.size() > 1) {
DevFailedUtils.throwDevFailed(DevFailedUtils.TANGO_BUILD_FAILED, Init.class + MUST_BE_UNIQUE);
}
if (initM != null && initM.size() == 1) {
new InitBuilder().build(initM.iterator().next(), device, businessObject);
}
// Delete
final Set deleteM = scanner.getMethodsAnnotatedWith(Delete.class);
if (deleteM != null && deleteM.size() > 1) {
DevFailedUtils.throwDevFailed(DevFailedUtils.TANGO_BUILD_FAILED, Delete.class + MUST_BE_UNIQUE);
}
if (deleteM != null && deleteM.size() == 1) {
new DeleteBuilder().build(deleteM.iterator().next(), device);
}
// Schedule
final Set scheduleM = scanner.getMethodsAnnotatedWith(Schedule.class);
if (scheduleM != null && scheduleM.size() == 1) {
new DeviceSchedulerBuilder().build(scheduleM, device);
}
}
private void createBusinessObjectAroundInvoke(final ReflectionScanner scanner) throws DevFailed {
// AroundInvoke
final Set invokeM = scanner.getMethodsAnnotatedWith(AroundInvoke.class);
if (invokeM != null && invokeM.size() > 1) {
DevFailedUtils.throwDevFailed(DevFailedUtils.TANGO_BUILD_FAILED, AroundInvoke.class + MUST_BE_UNIQUE);
}
if (invokeM != null && invokeM.size() == 1) {
new AroundInvokeBuilder().build(invokeM.iterator().next(), device, businessObject);
}
}
private void createBusinessObjectAttrField(final ReflectionScanner scanner, final boolean isOnDeviceImpl)
throws DevFailed {
// Attribute
final Set attributeF = scanner.getFieldsAnnotatedWith(Attribute.class);
if (attributeF != null) {
final AttributeFieldBuilder attr = new AttributeFieldBuilder();
for (final Field field : attributeF) {
attr.build(device, businessObject, field, isOnDeviceImpl);
}
}
}
private void createBusinessObjectPipes(final ReflectionScanner scanner) throws DevFailed {
// Pipe
final Set fields = scanner.getFieldsAnnotatedWith(Pipe.class);
if (fields != null) {
final PipeBuilder pipe = new PipeBuilder();
for (final Field field : fields) {
pipe.build(device, businessObject, field);
}
}
}
private void createBusinessObjectFields(final ReflectionScanner scanner) throws DevFailed {
// DynamicManagement
final Set dynF = scanner.getFieldsAnnotatedWith(DynamicManagement.class);
if (dynF != null) {
if (dynF.size() > 1) {
DevFailedUtils.throwDevFailed(DevFailedUtils.TANGO_BUILD_FAILED, DynamicManagement.class
+ MUST_BE_UNIQUE);
}
if (dynF.size() == 1) {
new DynamicManagerBuilder().build(dynF.iterator().next(), device, businessObject);
}
}
// DeviceManagement
final Set deviceF = scanner.getFieldsAnnotatedWith(DeviceManagement.class);
if (deviceF != null) {
if (deviceF.size() > 1) {
DevFailedUtils.throwDevFailed(DevFailedUtils.TANGO_BUILD_FAILED, DeviceManagement.class
+ MUST_BE_UNIQUE);
}
if (deviceF.size() == 1) {
new DeviceManagerBuilder().build(deviceF.iterator().next(), device, businessObject);
}
}
}
private void createBusinessObjectState(final ReflectionScanner scanner) throws DevFailed {
// State
final Set stateF = scanner.getFieldsAnnotatedWith(State.class);
if (stateF != null) {
final StateBuilder stateB = new StateBuilder();
if (stateF.size() > 1) {
DevFailedUtils.throwDevFailed(DevFailedUtils.TANGO_BUILD_FAILED, State.class + MUST_BE_UNIQUE);
}
if (stateF.size() == 1) {
stateB.build(clazz, stateF.iterator().next(), device, businessObject);
}
}
// Status
final Set statusF = scanner.getFieldsAnnotatedWith(Status.class);
if (statusF != null) {
final StatusBuilder statusB = new StatusBuilder();
if (statusF.size() > 1) {
DevFailedUtils.throwDevFailed(DevFailedUtils.TANGO_BUILD_FAILED, Status.class + MUST_BE_UNIQUE);
}
if (statusF.size() == 1) {
statusB.build(clazz, statusF.iterator().next(), device, businessObject);
}
}
}
private void createBusinessObjectDeviceProperties(final ReflectionScanner scanner) throws DevFailed {
// DeviceProperties
final Set devicePropsF = scanner.getFieldsAnnotatedWith(DeviceProperties.class);
if (devicePropsF != null) {
final DevicePropertiesBuilder devicePropsB = new DevicePropertiesBuilder();
if (devicePropsF.size() > 1) {
DevFailedUtils.throwDevFailed(DevFailedUtils.TANGO_BUILD_FAILED, DeviceProperties.class
+ MUST_BE_UNIQUE);
}
if (devicePropsF.size() == 1) {
devicePropsB.build(clazz, devicePropsF.iterator().next(), device, businessObject);
}
}
}
private void createBusinessObjectProps(final ReflectionScanner scanner) throws DevFailed {
// DeviceProperties
final Set devicePropsF = scanner.getFieldsAnnotatedWith(DeviceProperties.class);
if (devicePropsF != null) {
final DevicePropertiesBuilder devicePropsB = new DevicePropertiesBuilder();
if (devicePropsF.size() > 1) {
DevFailedUtils.throwDevFailed(DevFailedUtils.TANGO_BUILD_FAILED, DeviceProperties.class
+ MUST_BE_UNIQUE);
}
if (devicePropsF.size() == 1) {
devicePropsB.build(clazz, devicePropsF.iterator().next(), device, businessObject);
}
}
// DeviceProperty
final Set devicePropF = scanner.getFieldsAnnotatedWith(DeviceProperty.class);
if (devicePropF != null) {
final DevicePropertyBuilder devicePropB = new DevicePropertyBuilder();
for (final Field field : devicePropF) {
devicePropB.build(clazz, field, device, businessObject);
}
}
// ClassProperty
final Set classPropF = scanner.getFieldsAnnotatedWith(ClassProperty.class);
if (classPropF != null) {
final ClassPropertyBuilder classPropB = new ClassPropertyBuilder();
for (final Field field : classPropF) {
classPropB.build(clazz, field, device, businessObject);
}
}
}
private void checkIsTangoDevice(final Class> clazz, final String name) throws DevFailed {
if (clazz == null) {
DevFailedUtils.throwDevFailed("INIT_FAILED", "create device " + name + " - is not a tango device");
}
if (clazz.getAnnotation(Device.class) == null) {
DevFailedUtils.throwDevFailed("INIT_FAILED", "create device " + name + " of class " + clazz.getName()
+ " - is not a tango device");
}
}
}