/*
* This file is protected by Copyright. Please refer to the COPYRIGHT file
* distributed with this source distribution.
*
* This file is part of REDHAWK core.
*
* REDHAWK core 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.
*
* REDHAWK core 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 this program. If not, see http://www.gnu.org/licenses/.
*/
package org.ossie.component;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.apache.log4j.Logger;
import org.omg.CORBA.Any;
import org.omg.CORBA.ORB;
import org.omg.CORBA.Object;
import org.omg.CORBA.TCKind;
import org.omg.CORBA.TypeCode;
import org.omg.CORBA.ORBPackage.InvalidName;
import org.omg.PortableServer.POA;
import org.omg.PortableServer.POAHelper;
import org.omg.PortableServer.Servant;
import org.omg.PortableServer.POAManagerPackage.AdapterInactive;
import org.omg.PortableServer.POAPackage.ServantNotActive;
import org.omg.PortableServer.POAPackage.WrongPolicy;
import org.ossie.properties.AnyUtils;
import org.ossie.properties.IProperty;
import org.ossie.logging.logging;
import org.ossie.redhawk.DomainManagerContainer;
import org.ossie.redhawk.DeviceManagerContainer;
import org.ossie.corba.utils.*;
import CF.AggregateDevice;
import CF.AggregateDeviceHelper;
import CF.DataType;
import CF.DeviceHelper;
import CF.DeviceManager;
import CF.DomainManager;
import CF.DeviceManagerHelper;
import CF.DeviceOperations;
import CF.DevicePOATie;
import CF.InvalidObjectReference;
import CF.DevicePackage.AdminType;
import CF.DevicePackage.InvalidCapacity;
import CF.DevicePackage.InvalidState;
import CF.DevicePackage.OperationalType;
import CF.DevicePackage.UsageType;
import CF.LifeCyclePackage.ReleaseError;
import CF.PropertySetPackage.InvalidConfiguration;
import CF.PropertySetPackage.PartialConfiguration;
import org.omg.CosEventComm.Disconnected;
import org.omg.CosEventChannelAdmin.AlreadyConnected;
import org.omg.CosEventChannelAdmin.EventChannel;
import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*;
import org.omg.CosNaming.NamingContextExt;
import org.omg.CosNaming.NamingContextExtHelper;
import org.ossie.events.*;
import org.ossie.events.Manager.*;
import CF.EventChannelManagerPackage.*;
import StandardEvent.StateChangeCategoryType;
import StandardEvent.StateChangeEventType;
import StandardEvent.StateChangeType;
public abstract class Device extends Resource implements DeviceOperations {
protected DeviceManager devMgr;
protected DeviceManagerContainer _devMgr = null;
protected AggregateDevice compositeDevice;
protected CF.Device device;
protected String label;
protected AdminType adminState = AdminType.UNLOCKED;
protected UsageType usageState = UsageType.IDLE;
protected OperationalType operationState = OperationalType.ENABLED;
private boolean firstTime = true;
private Publisher idm_publisher=null;
/**
* Deprecated old-style allocation callbacks. Use the Allocator interface and
* setAllocator() on the desired property to implement custom allocation
* behavior.
*
* NB: To be removed when backwards compatibility with pre-1.9 devices is no
* longer required.
*
* @deprecated
*/
protected HashMap <String, AllocCapacity> callbacks = new HashMap<String,AllocCapacity>();
/**
* Track legacy allocation properties so that backwards-compatible allocation
* behavior can be maintained as much as possible. If it is null, no legacy
* allocation properties have been registered and no emulation of legacy
* behavior is required.
*
* NB: To be removed when backwards compatibility with pre-1.9 devices is no
* longer required.
*
* @deprecated
*/
private List<IProperty> legacyAllocProps = null;
private boolean warnedLegacyAllocProps = false;
public final static Logger logger = Logger.getLogger(Device.class.getName());
enum AnyComparisonType {
FIRST_BIGGER,
SECOND_BIGGER,
BOTH_EQUAL,
POSITIVE,
NEGATIVE,
ZERO,
UNKNOWN
};
/**
* Constructor intendend to be used by start_device
*/
protected Device() {
super();
}
public Device(final DeviceManager devMgr, final String compId, final String label, final String softwareProfile, final ORB orb, final POA poa) throws InvalidObjectReference, ServantNotActive, WrongPolicy {
this();
setup(devMgr, null, compId, label, softwareProfile, "", orb, poa);
}
public Device(final DeviceManager devMgr, final AggregateDevice compositeDevice, final String compId, final String label, final String softwareProfile, final ORB orb, final POA poa) throws InvalidObjectReference, ServantNotActive, WrongPolicy {
this();
setup(devMgr, compositeDevice, compId, label, softwareProfile, "", orb, poa);
}
public String label() {
return label;
}
public UsageType usageState() {
return usageState;
}
public AdminType adminState() {
return adminState;
}
public void adminState(AdminType newAdminState) {
adminState = newAdminState;
}
public OperationalType operationalState() {
return operationState;
}
public AggregateDevice compositeDevice() {
return compositeDevice;
}
public void releaseObject() throws ReleaseError {
if (adminState == AdminType.UNLOCKED) {
setAdminState(AdminType.SHUTTING_DOWN);
}
try {
// Release all registered childDevices
if (compositeDevice != null) {
compositeDevice.removeDevice(device);
}
// Unregister device
if (devMgr != null) {
devMgr.unregisterDevice(device);
}
} catch (Exception e) {
e.printStackTrace();
throw new ReleaseError(new String[] {e.toString()});
}
super.releaseObject();
setAdminState(AdminType.LOCKED);
if ( idm_publisher != null ) {
idm_publisher.terminate();
idm_publisher = null;
}
org.ossie.events.Manager.Terminate();
}
public void connectIDMChannel(final String idm_channel_ior){
if ( (idm_channel_ior != null && !idm_channel_ior.equals("")) || idm_channel_ior.length() > 0 ) {
EventChannel idm_channel=null;
// Get DomainManager incoming event channel and connect the device to it, where applicable
try {
logger.debug("connectIDMChannel: idm_channel_ior:" + idm_channel_ior);
Object idm_channel_obj = orb.string_to_object(idm_channel_ior);
idm_channel = org.omg.CosEventChannelAdmin.EventChannelHelper.narrow(idm_channel_obj);
idm_publisher = new org.ossie.events.Publisher(idm_channel);
}
catch (Exception e){
logger.warn("Error connecting to IDM channel.");
}
}
else {
try {
Manager evt_mgr = Manager.GetManager(this);
idm_publisher = evt_mgr.Publisher( Manager.IDM_CHANNEL_SPEC );
}
catch( Manager.OperationFailed e) {
logger.warn("Failed to connect to IDM channel.");
}
catch( RegistrationExists e) {
logger.warn("Failed to connect to IDM channel.");
}
catch( RegistrationFailed e) {
logger.warn("Failed to connect to IDM channel.");
}
}
}
/**
* The setup() function exists to make it easy for start_device to invoke the no-arg constructor.
*
* @param devMgr
* @param compositeDevice
* @param compId
* @param label
* @param softwareProfile
* @param orb
* @throws InvalidObjectReference
* @throws WrongPolicy
* @throws ServantNotActive
*/
protected CF.Device setup(final DeviceManager devMgr,
final AggregateDevice compositeDevice,
final String compId,
final String label,
final String softwareProfile,
final String idm_channel_ior,
final ORB orb,
final POA poa) throws InvalidObjectReference, ServantNotActive, WrongPolicy {
super.setup(compId, label, softwareProfile, orb, poa);
this.label = label;
DevicePOATie tie = new DevicePOATie(this, poa);
tie._this(orb);
device = DeviceHelper.narrow(poa.servant_to_reference((Servant)tie));
this.devMgr = devMgr;
if (devMgr != null) {
this._devMgr = new DeviceManagerContainer(devMgr);
this._domMgr = new DomainManagerContainer(devMgr.domMgr());
devMgr.registerDevice(device);
}
this.compositeDevice = compositeDevice;
if (compositeDevice != null) {
compositeDevice.addDevice(device);
}
connectIDMChannel( idm_channel_ior );
// this needs to be established before device saves logging context
// incase event channels are used
if ( this._domMgr != null ) {
try {
this._ecm = org.ossie.events.Manager.GetManager(this);
}catch( Manager.OperationFailed e){
logger.warn("Unable to resolve EventChannelManager");
}
}
return device;
}
public DeviceManagerContainer getDeviceManager() {
return this._devMgr;
}
/**
* Start-up function to be used from a main() function.
*
* @param clazz
* @param args
* @param builtInORB
* @param fragSize
* @param bufSize
* @throws InstantiationException
* @throws IllegalAccessException
* @throws InvalidObjectReference
*/
public static void start_device(final Class<? extends Device> clazz, final String[] args, final boolean builtInORB, final int fragSize, final int bufSize)
throws InstantiationException, IllegalAccessException, InvalidObjectReference, ServantNotActive, WrongPolicy
{
final Properties props = new Properties();
if (!builtInORB) {
props.put("org.omg.CORBA.ORBClass", "org.jacorb.orb.ORB");
props.put("org.omg.CORBA.ORBSingletonClass", "org.jacorb.orb.ORBSingleton");
props.put("jacorb.fragment_size", Integer.toString(fragSize));
props.put("jacorb.outbuf_size", Integer.toString(bufSize));
props.put("jacorb.maxManagedBufSize", "23");
} else {
props.put("com.sun.CORBA.giop.ORBFragmentSize", Integer.toString(fragSize));
props.put("com.sun.CORBA.giop.ORBBufferSize", Integer.toString(bufSize));
}
start_device(clazz, args, props);
}
/**
* Start-up function to be used from a main() function.
*
* @param clazz
* @param args
* @param builtInORB
* @param fragSize
* @param bufSize
* @throws InstantiationException
* @throws IllegalAccessException
* @throws InvalidObjectReference
* @throws WrongPolicy
* @throws ServantNotActive
*/
public static void start_device(final Class<? extends Device> clazz, final String[] args, final Properties props)
throws InstantiationException, IllegalAccessException, InvalidObjectReference, ServantNotActive, WrongPolicy
{
// initialize middleware with command line/properties..
final org.omg.CORBA.ORB orb = org.ossie.corba.utils.Init( args, props );
final POA rootpoa = org.ossie.corba.utils.RootPOA();
if (args.length == 1) {
if (args[0].equals("-i")) {
System.out.println("Interactive mode (-i) no longer supported. Please use the sandbox to run Components/Devices/Services outside the scope of a Domain");
System.exit(-1);
}
}
Map<String, String> execparams = parseArgs(args);
DeviceManager devMgr = null;
String devMgr_ior=null;
if (execparams.containsKey("DEVICE_MGR_IOR")) {
devMgr_ior=execparams.get("DEVICE_MGR_IOR");
devMgr = DeviceManagerHelper.narrow(orb.string_to_object(execparams.get("DEVICE_MGR_IOR")));
}
AggregateDevice compositeDevice = null;
String composite_ior=null;
if (execparams.containsKey("COMPOSITE_DEVICE_IOR")) {
composite_ior=execparams.get("COMPOSITE_DEVICE_IOR");
compositeDevice = AggregateDeviceHelper.narrow(orb.string_to_object(execparams.get("COMPOSITE_DEVICE_IOR")));
}
String identifier = null;
if (execparams.containsKey("DEVICE_ID")) {
identifier = execparams.get("DEVICE_ID");
}
String label = null;
if (execparams.containsKey("DEVICE_LABEL")) {
label = execparams.get("DEVICE_LABEL");
}
String profile = null;
if (execparams.containsKey("PROFILE_NAME")) {
profile = execparams.get("PROFILE_NAME");
}
String dom_path = "";
if (execparams.containsKey("DOM_PATH")) {
dom_path = execparams.get("DOM_PATH");
}
String logcfg_uri = "";
if (execparams.containsKey("LOGGING_CONFIG_URI")) {
logcfg_uri = execparams.get("LOGGING_CONFIG_URI");
}
int debugLevel = -1; // use logging config URI if specified
if (execparams.containsKey("DEBUG_LEVEL")) {
debugLevel = Integer.parseInt(execparams.get("DEBUG_LEVEL"));
}
String idm_channel_ior=""; // idm channel ior
if (execparams.containsKey("IDM_CHANNEL_IOR")) {
idm_channel_ior = execparams.get("IDM_CHANNEL_IOR");
}
if ( debugLevel > 3 ) {
System.out.println("Device Args: " );
System.out.println(" DEVICE_LABEL:"+ label );
System.out.println(" DEVICE_ID:"+ identifier );
System.out.println(" PROFILE_NAME:"+ profile );
System.out.println(" COMPONENT_IDENTIFIER:"+ identifier );
System.out.println(" COMPOSITE_IOR:"+ composite_ior );
System.out.println(" DEVICE_MGR_IOR:"+ devMgr_ior );
System.out.println(" DOM_PATH:"+ dom_path );
System.out.println(" LOG_CONFIG_URI:"+ logcfg_uri );
System.out.println(" DEBUG_LEVEL:"+ debugLevel );
}
// initialize logging library with a device context
logging.DeviceCtx ctx = new logging.DeviceCtx( label, identifier, dom_path );
logging.Configure( logcfg_uri, debugLevel, ctx );
final Device device_i = clazz.newInstance();
device_i.initializeProperties(execparams);
final CF.Device device = device_i.setup(devMgr,
compositeDevice,
identifier,
label,
profile,
idm_channel_ior,
orb,
rootpoa);
// save off logging context
device_i.saveLoggingContext( logcfg_uri, debugLevel, ctx );
// Create a thread that watches for the device to be deactivated
Thread shutdownWatcher = new Thread(new Runnable() {
public void run() {
device_i.waitDisposed();
shutdownORB(orb);
}
});
shutdownWatcher.start();
orb.run();
// Destroy the ORB, otherwise the JVM shutdown will take an unusually
// long time (~300ms).
orb.destroy();
try {
shutdownWatcher.join();
} catch (InterruptedException e) {
// PASS
}
}
/**
* Checks that all of the properties given are valid and allocatable.
*
* @throws InvalidCapacity
*/
private void validateAllocProps(final DataType[] capacities) throws InvalidCapacity {
for (final DataType capacity : capacities) {
if (AnyUtils.isNull(capacity.value)) {
throw new InvalidCapacity("Invalid null value", new DataType[]{capacity});
}
final IProperty property = this.propSet.get(capacity.id);
if (property == null) {
throw new InvalidCapacity("Unknown property", new DataType[]{capacity});
} else if (!property.isAllocatable()) {
throw new InvalidCapacity("Property is not allocatable", new DataType[]{capacity});
}
}
}
/**
* Attempts to allocate a list of capacities on a device
*
* @param capacities
* @throws InvalidCapacity
* @throws InvalidState
*/
public boolean allocateCapacity(DataType[] capacities) throws InvalidCapacity, InvalidState {
logger.debug("allocateCapacity : " + capacities.toString());
// Checks for empty
if (capacities.length == 0){
logger.trace("No capacities to allocate.");
return true;
}
// Verify that the device is in a valid state
if (!isUnlocked() || isDisabled()) {
String invalidState;
if (isLocked()) {
invalidState = "LOCKED";
} else if (isDisabled()) {
invalidState = "DISABLED";
} else {
invalidState = "SHUTTING_DOWN";
}
logger.debug("Cannot allocate capacity: System is " + invalidState);
throw new InvalidState(invalidState);
}
// Check for obviously invalid properties up front.
validateAllocProps(capacities);
// Track successful allocations in case they need to be undone.
List<DataType> allocations = new ArrayList<DataType>();
// Loops through all requested capacities
try {
for (DataType cap : capacities){
// Checks to see if the device has a call back function registered
if (callbacks.containsKey(cap.id) && callbacks.get(cap.id).allocate(cap)){
// If it does, use it
logger.trace("Capacity allocated by user-defined function.");
allocations.add(cap);
} else {
// Otherwise defer to the property's allocator.
final IProperty property = this.propSet.get(cap.id);
try {
if (property.allocate(cap.value)) {
allocations.add(cap);
} else {
logger.debug("Cannot allocate capacity. Insufficient capacity for property '" + cap.id + "'");
return false;
}
} catch (final RuntimeException ex) {
throw new InvalidCapacity(ex.getMessage(), new DataType[]{cap});
}
}
}
} finally {
// If not all allocations were successful, deallocate any that were.
// The usage state is implicitly updated by deallocateCapacity.
if (allocations.size() < capacities.length) {
deallocateCapacity(allocations.toArray(new DataType[allocations.size()]));
}
}
updateUsageState();
return true;
}
/**
* Attempts to deallocate a list of capacities on a device
*
* @param capacities
* @throws InvalidCapacity
* @throws InvalidState
*/
public void deallocateCapacity(DataType[] capacities) throws InvalidCapacity, InvalidState {
/* Verify that the device is in a valid state */
if (adminState == AdminType.LOCKED || operationState == OperationalType.DISABLED){
logger.warn("Cannot deallocate capacity. System is either LOCKED or DISABLED.");
throw new InvalidState("Cannot deallocate capacity. System is either LOCKED or DISABLED.");
}
// Check for obviously invalid properties to avoid partial deallocation.
validateAllocProps(capacities);
for (DataType cap : capacities){
// Checks to see if the device has a call back function registered
if (callbacks.containsKey(cap.id) && callbacks.get(cap.id).deallocate(cap)){
// If it does, use it
logger.trace("Capacity allocated by user-defined function.");
} else {
// Otherwise defer to the property's deallocator.
final IProperty property = this.propSet.get(cap.id);
try {
property.deallocate(cap.value);
} catch (final RuntimeException ex) {
throw new InvalidCapacity(ex.getMessage(), new DataType[]{cap});
}
}
}
updateUsageState();
}
/**
* Determine the current usage state of the device.
*
* Override if your device has a more sophisticated way of determining the
* usage state.
*/
protected void updateUsageState() {
// Do nothing, unless the device contains legacy allocation properties.
if (this.legacyAllocProps != null) {
updateUsageStateLegacy();
}
}
/**
* Internal method for updating the device's usage state based on the current
* values of the legacy allocation properties.
*
* NB: To be removed when backwards compatibility with pre-1.9 devices is no
* longer required.
*
* @deprecated
*/
@SuppressWarnings("deprecation")
private void updateUsageStateLegacy() {
boolean active = false;
boolean busy = true;
for (IProperty property : this.legacyAllocProps) {
org.ossie.properties.SimpleProperty simple = (org.ossie.properties.SimpleProperty)property;
if (compareAnyToZero(property.toAny()) == AnyComparisonType.POSITIVE) {
busy = false;
}
if (!simple.isFull()) {
active = true;
}
}
if (busy) {
setUsageState(UsageType.BUSY);
} else if (active) {
setUsageState(UsageType.ACTIVE);
} else {
setUsageState(UsageType.IDLE);
}
}
// compareAnyToZero function compares the any type input to zero
// returns POSITIVE if the first argument is bigger
// returns NEGATIVE is the second argument is bigger
// and ZERO if they are equal
public AnyComparisonType compareAnyToZero(Any first){
TypeCode tc1 = first.type();
switch (tc1.kind().value()){
case TCKind._tk_ulong: {
long frst;
frst = (Long) AnyUtils.convertAny(first);
if (frst > 0){
return AnyComparisonType.POSITIVE;
} else if (frst == 0){
return AnyComparisonType.ZERO;
} else {
return AnyComparisonType.NEGATIVE;
}
}
case TCKind._tk_long: {
int frst;
frst = (Integer) AnyUtils.convertAny(first);
if (frst > 0){
return AnyComparisonType.POSITIVE;
} else if (frst == 0){
return AnyComparisonType.ZERO;
} else {
return AnyComparisonType.NEGATIVE;
}
}
case TCKind._tk_short: {
short frst = 0;
frst = (Short) AnyUtils.convertAny(first);
if (frst > 0){
return AnyComparisonType.POSITIVE;
} else if (frst == 0){
return AnyComparisonType.ZERO;
} else {
return AnyComparisonType.NEGATIVE;
}
}
default:
return AnyComparisonType.UNKNOWN;
}
}
// compareAnys function compares both Any type inputs
// returns FIRST_BIGGER if the first argument is bigger
// returns SECOND_BIGGER is the second argument is bigger
// and BOTH_EQUAL if they are equal
public AnyComparisonType compareAnys (Any first, Any second) {
TypeCode tc1 = first.type ();
switch (tc1.kind().value()) {
case TCKind._tk_ulong: {
long frst, scnd;
frst = (Long) AnyUtils.convertAny(first);
scnd = (Long) AnyUtils.convertAny(second);
if (frst > scnd) {
return AnyComparisonType.FIRST_BIGGER;
} else if (frst == scnd) {
return AnyComparisonType.BOTH_EQUAL;
} else {
return AnyComparisonType.SECOND_BIGGER;
}
}
case TCKind._tk_long: {
int frst, scnd;
frst = (Integer) AnyUtils.convertAny(first);
scnd = (Integer) AnyUtils.convertAny(second);
if (frst > scnd) {
return AnyComparisonType.FIRST_BIGGER;
} else if (frst == scnd) {
return AnyComparisonType.BOTH_EQUAL;
} else {
return AnyComparisonType.SECOND_BIGGER;
}
}
case TCKind._tk_short: {
short frst, scnd;
frst = (Short) AnyUtils.convertAny(first);
scnd = (Short) AnyUtils.convertAny(second);
if (frst > scnd) {
return AnyComparisonType.FIRST_BIGGER;
} else if (frst == scnd) {
return AnyComparisonType.BOTH_EQUAL;
} else {
return AnyComparisonType.SECOND_BIGGER;
}
}
default:
return AnyComparisonType.UNKNOWN;
}
}
/**
* Sets a new usage state and sends an event if it has changed
*
* @param newUsageState
*/
protected void setUsageState(UsageType newUsageState){
/* Checks to see if the usageState has change */
if (newUsageState.value() != this.usageState().value()){
/* Keep a copy of the actual usage state */
StateChangeType current_state = StandardEvent.StateChangeType.BUSY;
StateChangeType new_state = StandardEvent.StateChangeType.BUSY;
switch (usageState.value()){
case UsageType._IDLE:
current_state = StandardEvent.StateChangeType.IDLE;
break;
case UsageType._ACTIVE:
current_state = StandardEvent.StateChangeType.ACTIVE;
break;
case UsageType._BUSY:
current_state = StandardEvent.StateChangeType.BUSY;
break;
}
switch (newUsageState.value()){
case UsageType._IDLE:
new_state = StandardEvent.StateChangeType.IDLE;
break;
case UsageType._ACTIVE:
new_state = StandardEvent.StateChangeType.ACTIVE;
break;
case UsageType._BUSY:
new_state = StandardEvent.StateChangeType.BUSY;
break;
}
StateChangeEventType event = new StateChangeEventType(identifier(), identifier(),
StandardEvent.StateChangeCategoryType.USAGE_STATE_EVENT, current_state, new_state);
try {
if ( idm_publisher != null ) {
idm_publisher.push(AnyUtils.toAny(event, TCKind.tk_objref) );
logger.debug("Sent device StateChangeEvent - USAGE ");
}
}
catch (Exception e) {
logger.warn("Error sending event.");
}
usageState = newUsageState;
}
}
/*
* NB: This method is overridden to support tracking of legacy (pre-1.9)
* allocation properties. When backwards-compatibility is no longer
* required, this method should be removed, deferring entirely to
* the superclass method.
*/
@SuppressWarnings("deprecation")
public void addProperty(IProperty prop) {
// Perform normal bookkeeping.
super.addProperty(prop);
// Ignore non-allocation properties.
if (!prop.isAllocatable()) {
return;
}
// If true, for a mix of legacy and new-style allocation properties.
boolean isMixed = false;
if (prop instanceof org.ossie.properties.SimpleProperty) {
if (this.legacyAllocProps == null) {
// First instance of a legacy property; create the list. This
// allows the allocation/deallocation methods to determine whether
// to try to maintain legacy behavior.
this.legacyAllocProps = new ArrayList<IProperty>();
}
this.legacyAllocProps.add(prop);
// If no warning has been issued, check whether the number of legacy
// allocation properties is the same as the total number of allocation
// properties.
if (!this.warnedLegacyAllocProps) {
int allocPropCount = 0;
for (IProperty ip : this.propSet.values()) {
if (ip.isAllocatable()) {
allocPropCount++;
}
}
isMixed = (this.legacyAllocProps.size() != allocPropCount);
}
} else if (this.legacyAllocProps != null) {
// This is a new-style property, and legacy properties are registered.
// Issue a warning if needed.
isMixed = true;
}
// Warn about mixed legacy and new-style properties, if we have not already.
if (isMixed && !this.warnedLegacyAllocProps) {
this.warnedLegacyAllocProps = true;
logger.warn("Device uses mix of deprecated and new-style allocation properties. Allocation behavior may be inconsistent.");
}
}
/**
* Sets a new admin state and sends an event if it has changed
*
* @param newAdminState
*/
protected void setAdminState(AdminType newAdminState){
/* Checks to see if the admin state has changed */
if (newAdminState.value() != this.adminState().value()){
/* Keep a copy of the actual admin state */
StateChangeType current_state = StateChangeType.UNLOCKED;
StateChangeType new_state = StateChangeType.UNLOCKED;
switch(adminState.value()){
case AdminType._LOCKED:
current_state = StateChangeType.LOCKED;
break;
case AdminType._UNLOCKED:
current_state = StateChangeType.UNLOCKED;
break;
case AdminType._SHUTTING_DOWN:
current_state = StateChangeType.SHUTTING_DOWN;
break;
}
switch (newAdminState.value()){
case AdminType._LOCKED:
new_state = StateChangeType.LOCKED;
break;
case AdminType._UNLOCKED:
new_state = StateChangeType.UNLOCKED;
break;
case AdminType._SHUTTING_DOWN:
new_state = StateChangeType.SHUTTING_DOWN;
break;
}
StateChangeEventType event = new StateChangeEventType(identifier(), identifier(),
StateChangeCategoryType.ADMINISTRATIVE_STATE_EVENT, current_state, new_state);
try {
if ( idm_publisher != null ) {
idm_publisher.push(AnyUtils.toAny(event, TCKind.tk_objref) );
logger.debug("Sent device StateChangeEvent - ADMIN ");
}
}
catch (Exception e) {
logger.warn("Error sending event.");
}
adminState = newAdminState;
}
}
/**
* Sets a new operation state and sends an event if it has changed
* @param newOperationState
*/
protected void setOperationState(OperationalType newOperationState){
/* Checks to see if the operational state has changed */
if (newOperationState.value() != this.operationalState().value()){
/* Keep a copy of the actual operational state */
StateChangeType current_state= StateChangeType.ENABLED;
StateChangeType new_state = StateChangeType.ENABLED;
switch (operationState.value()){
case OperationalType._DISABLED:
current_state = StateChangeType.DISABLED;
break;
case OperationalType._ENABLED:
current_state = StateChangeType.ENABLED;
break;
}
switch (newOperationState.value()){
case OperationalType._DISABLED:
new_state = StateChangeType.DISABLED;
break;
case OperationalType._ENABLED:
new_state = StateChangeType.ENABLED;
break;
}
StateChangeEventType event = new StateChangeEventType(identifier(), identifier(),
StateChangeCategoryType.OPERATIONAL_STATE_EVENT, current_state, new_state);
try {
if ( idm_publisher != null ) {
idm_publisher.push(AnyUtils.toAny(event, TCKind.tk_objref) );
logger.debug("Sent device StateChangeEvent - OPERATIONAL ");
}
}
catch (Exception e) {
logger.warn("Error sending event.");
}
operationState = newOperationState;
}
}
/**
* Returns whether this device's administrative state is UNLOCKED
*
* @returns true if admin state is UNLOCKED, false otherwise
*/
public boolean isUnlocked() {
return adminState.equals(AdminType.UNLOCKED);
}
/**
* Returns whether this device's administrative state is LOCKED
*
* @returns true if admin state is LOCKED, false otherwise
*/
public boolean isLocked() {
return adminState.equals(AdminType.LOCKED);
}
/**
* Returns whether this device's operational state is DISABLED
*
* @returns true if operational state is DISABLED, false otherwise
*/
public boolean isDisabled() {
return operationState.equals(OperationalType.DISABLED);
}
}