]> git.basschouten.com Git - openhab-addons.git/commitdiff
[insteon] remove all @SuppressWarnings("null") (#8937)
authorrobnielsen <rob.nielsen@yahoo.com>
Wed, 4 Nov 2020 20:05:01 +0000 (14:05 -0600)
committerGitHub <noreply@github.com>
Wed, 4 Nov 2020 20:05:01 +0000 (21:05 +0100)
Signed-off-by: Rob Nielsen <rob.nielsen@yahoo.com>
29 files changed:
bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/InsteonBinding.java
bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/command/InsteonCommandExtension.java
bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/device/CommandHandler.java
bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/device/DeviceFeature.java
bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/device/DeviceType.java
bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/device/DeviceTypeLoader.java
bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/device/FeatureTemplate.java
bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/device/InsteonDevice.java
bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/device/MessageDispatcher.java
bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/device/MessageHandler.java
bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/device/ModemDBBuilder.java
bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/device/PollHandler.java
bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/device/RequestQueueManager.java
bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/device/X10.java
bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/driver/IOStream.java
bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/driver/Poller.java
bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/driver/Port.java
bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/driver/SerialIOStream.java
bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/driver/TcpIOStream.java
bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/driver/hub/HubIOStream.java
bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/handler/InsteonDeviceHandler.java
bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/handler/InsteonNetworkHandler.java
bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/message/DataType.java
bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/message/Field.java
bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/message/Msg.java
bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/message/MsgDefinition.java
bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/message/XMLMessageReader.java
bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/utils/Utils.java
bundles/org.openhab.binding.insteon/src/main/resources/device_features.xml

index ff6e5a0a9dd585e1c8816d7c1c3a9e3794f092ca..593dc6782c893a6a59a1efb0c211ba29b8a58747 100644 (file)
@@ -106,15 +106,14 @@ import org.xml.sax.SAXException;
  * @author Rob Nielsen - Port to openHAB 2 insteon binding
  */
 @NonNullByDefault
-@SuppressWarnings({ "null", "unused" })
 public class InsteonBinding {
     private static final int DEAD_DEVICE_COUNT = 10;
 
     private final Logger logger = LoggerFactory.getLogger(InsteonBinding.class);
 
     private Driver driver;
-    private ConcurrentHashMap<InsteonAddress, InsteonDevice> devices = new ConcurrentHashMap<>();
-    private ConcurrentHashMap<String, InsteonChannelConfiguration> bindingConfigs = new ConcurrentHashMap<>();
+    private Map<InsteonAddress, InsteonDevice> devices = new ConcurrentHashMap<>();
+    private Map<String, InsteonChannelConfiguration> bindingConfigs = new ConcurrentHashMap<>();
     private PortListener portListener = new PortListener();
     private int devicePollIntervalMilliseconds = 300000;
     private int deadDeviceTimeout = -1;
@@ -123,8 +122,8 @@ public class InsteonBinding {
     private int x10HouseUnit = -1;
     private InsteonNetworkHandler handler;
 
-    public InsteonBinding(InsteonNetworkHandler handler, @Nullable InsteonNetworkConfiguration config,
-            @Nullable SerialPortManager serialPortManager, ScheduledExecutorService scheduler) {
+    public InsteonBinding(InsteonNetworkHandler handler, InsteonNetworkConfiguration config,
+            SerialPortManager serialPortManager, ScheduledExecutorService scheduler) {
         this.handler = handler;
 
         String port = config.getPort();
@@ -142,8 +141,13 @@ public class InsteonBinding {
         String additionalDevices = config.getAdditionalDevices();
         if (additionalDevices != null) {
             try {
-                DeviceTypeLoader.instance().loadDeviceTypesXML(additionalDevices);
-                logger.debug("read additional device definitions from {}", additionalDevices);
+                DeviceTypeLoader instance = DeviceTypeLoader.instance();
+                if (instance != null) {
+                    instance.loadDeviceTypesXML(additionalDevices);
+                    logger.debug("read additional device definitions from {}", additionalDevices);
+                } else {
+                    logger.warn("device type loader instance is null");
+                }
             } catch (ParserConfigurationException | SAXException | IOException e) {
                 logger.warn("error reading additional devices from {}", additionalDevices, e);
             }
@@ -201,6 +205,10 @@ public class InsteonBinding {
 
         InsteonAddress address = bindingConfig.getAddress();
         InsteonDevice dev = getDevice(address);
+        if (dev == null) {
+            logger.warn("device for address {} is null", address);
+            return;
+        }
         @Nullable
         DeviceFeature f = dev.getFeature(bindingConfig.getFeature());
         if (f == null || f.isFeatureGroup()) {
@@ -209,7 +217,7 @@ public class InsteonBinding {
             Collections.sort(names);
             for (String name : names) {
                 DeviceFeature feature = dev.getFeature(name);
-                if (!feature.isFeatureGroup()) {
+                if (feature != null && !feature.isFeatureGroup()) {
                     if (buf.length() > 0) {
                         buf.append(", ");
                     }
@@ -249,8 +257,16 @@ public class InsteonBinding {
         handler.updateState(channelUID, state);
     }
 
-    public InsteonDevice makeNewDevice(InsteonAddress addr, String productKey, Map<String, Object> deviceConfigMap) {
-        DeviceType dt = DeviceTypeLoader.instance().getDeviceType(productKey);
+    public @Nullable InsteonDevice makeNewDevice(InsteonAddress addr, String productKey,
+            Map<String, Object> deviceConfigMap) {
+        DeviceTypeLoader instance = DeviceTypeLoader.instance();
+        if (instance == null) {
+            return null;
+        }
+        DeviceType dt = instance.getDeviceType(productKey);
+        if (dt == null) {
+            return null;
+        }
         InsteonDevice dev = InsteonDevice.makeDevice(dt);
         dev.setAddress(addr);
         dev.setProductKey(productKey);
@@ -361,10 +377,16 @@ public class InsteonBinding {
 
     private String getLinkInfo(Map<InsteonAddress, ModemDBEntry> dbes, InsteonAddress a, boolean prefix) {
         ModemDBEntry dbe = dbes.get(a);
+        if (dbe == null) {
+            return "";
+        }
         List<Byte> controls = dbe.getControls();
         List<Byte> responds = dbe.getRespondsTo();
 
         Port port = dbe.getPort();
+        if (port == null) {
+            return "";
+        }
         String deviceName = port.getDeviceName();
         String s = deviceName.startsWith("/hub") ? "hub" : "plm";
         StringBuilder buf = new StringBuilder();
@@ -433,7 +455,6 @@ public class InsteonBinding {
      * Handles messages that come in from the ports.
      * Will only process one message at a time.
      */
-    @NonNullByDefault
     private class PortListener implements MsgListener, DriverListener {
         @Override
         public void msg(Msg msg) {
index e782894a96c811b03b33be808fecf6ccc591d444..ea626c56738808e29ee2b8f036d6d75449bfe01d 100644 (file)
@@ -182,6 +182,7 @@ public class InsteonCommandExtension extends AbstractConsoleCommandExtension imp
     public void msg(Msg msg) {
         if (monitorAllDevices || monitoredAddresses.contains(msg.getAddr("fromAddress"))) {
             String date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date());
+            Console console = this.console;
             if (console != null) {
                 console.println(date + " " + msg.toString());
             }
@@ -218,7 +219,7 @@ public class InsteonCommandExtension extends AbstractConsoleCommandExtension imp
 
     private void startMonitoring(Console console, String addr) {
         if (addr.equalsIgnoreCase("all")) {
-            if (monitorAllDevices != true) {
+            if (!monitorAllDevices) {
                 monitorAllDevices = true;
                 monitoredAddresses.clear();
                 console.println("Started monitoring all devices.");
@@ -240,7 +241,7 @@ public class InsteonCommandExtension extends AbstractConsoleCommandExtension imp
             }
         }
 
-        if (monitoring == false) {
+        if (!monitoring) {
             getInsteonBinding().getDriver().addMsgListener(this);
 
             this.console = console;
@@ -249,7 +250,7 @@ public class InsteonCommandExtension extends AbstractConsoleCommandExtension imp
     }
 
     private void stopMonitoring(Console console, String addr) {
-        if (monitoring == false) {
+        if (!monitoring) {
             console.println("Not mointoring any devices.");
             return;
         }
@@ -277,7 +278,7 @@ public class InsteonCommandExtension extends AbstractConsoleCommandExtension imp
             }
         }
 
-        if (monitorAllDevices == false && monitoredAddresses.isEmpty()) {
+        if (!monitorAllDevices && monitoredAddresses.isEmpty()) {
             getInsteonBinding().getDriver().removeListener(this);
             this.console = null;
             monitoring = false;
@@ -335,18 +336,12 @@ public class InsteonCommandExtension extends AbstractConsoleCommandExtension imp
         }
     }
 
-    @SuppressWarnings("null")
     private InsteonBinding getInsteonBinding() {
+        InsteonNetworkHandler handler = this.handler;
         if (handler == null) {
             throw new IllegalArgumentException("No Insteon network bridge configured.");
         }
 
-        @Nullable
-        InsteonBinding insteonBinding = handler.getInsteonBinding();
-        if (insteonBinding == null) {
-            throw new IllegalArgumentException("Insteon binding is null.");
-        }
-
-        return insteonBinding;
+        return handler.getInsteonBinding();
     }
 }
index d5d0072d3406da3dd3c625a578f37b354a7b1a3e..cb2e871aafb925456e4875873d6c6c342c7ed3d0 100644 (file)
@@ -44,11 +44,9 @@ import org.slf4j.LoggerFactory;
  * @author Rob Nielsen - Port to openHAB 2 insteon binding
  */
 @NonNullByDefault
-@SuppressWarnings("null")
 public abstract class CommandHandler {
     private static final Logger logger = LoggerFactory.getLogger(CommandHandler.class);
     DeviceFeature feature; // related DeviceFeature
-    @Nullable
     Map<String, String> parameters = new HashMap<>();
 
     /**
@@ -114,22 +112,24 @@ public abstract class CommandHandler {
 
     protected int getMaxLightLevel(InsteonChannelConfiguration conf, int defaultLevel) {
         Map<String, String> params = conf.getParameters();
-        if (conf.getFeature().contains("dimmer") && params.containsKey("dimmermax")) {
-            String item = conf.getChannelName();
+        if (conf.getFeature().contains("dimmer")) {
             String dimmerMax = params.get("dimmermax");
-            try {
-                int i = Integer.parseInt(dimmerMax);
-                if (i > 1 && i <= 99) {
-                    int level = (int) Math.ceil((i * 255.0) / 100); // round up
-                    if (level < defaultLevel) {
-                        logger.debug("item {}: using dimmermax value of {}", item, dimmerMax);
-                        return level;
+            if (dimmerMax != null) {
+                String item = conf.getChannelName();
+                try {
+                    int i = Integer.parseInt(dimmerMax);
+                    if (i > 1 && i <= 99) {
+                        int level = (int) Math.ceil((i * 255.0) / 100); // round up
+                        if (level < defaultLevel) {
+                            logger.debug("item {}: using dimmermax value of {}", item, dimmerMax);
+                            return level;
+                        }
+                    } else {
+                        logger.warn("item {}: dimmermax must be between 1-99 inclusive: {}", item, dimmerMax);
                     }
-                } else {
-                    logger.warn("item {}: dimmermax must be between 1-99 inclusive: {}", item, dimmerMax);
+                } catch (NumberFormatException e) {
+                    logger.warn("item {}: invalid int value for dimmermax: {}", item, dimmerMax);
                 }
-            } catch (NumberFormatException e) {
-                logger.warn("item {}: invalid int value for dimmermax: {}", item, dimmerMax);
             }
         }
 
@@ -157,7 +157,6 @@ public abstract class CommandHandler {
         return iv;
     }
 
-    @NonNullByDefault
     public static class WarnCommandHandler extends CommandHandler {
         WarnCommandHandler(DeviceFeature f) {
             super(f);
@@ -169,7 +168,6 @@ public abstract class CommandHandler {
         }
     }
 
-    @NonNullByDefault
     public static class NoOpCommandHandler extends CommandHandler {
         NoOpCommandHandler(DeviceFeature f) {
             super(f);
@@ -181,7 +179,6 @@ public abstract class CommandHandler {
         }
     }
 
-    @NonNullByDefault
     public static class LightOnOffCommandHandler extends CommandHandler {
         LightOnOffCommandHandler(DeviceFeature f) {
             super(f);
@@ -227,7 +224,6 @@ public abstract class CommandHandler {
         }
     }
 
-    @NonNullByDefault
     public static class FastOnOffCommandHandler extends CommandHandler {
         FastOnOffCommandHandler(DeviceFeature f) {
             super(f);
@@ -256,7 +252,6 @@ public abstract class CommandHandler {
         }
     }
 
-    @NonNullByDefault
     public static class RampOnOffCommandHandler extends RampCommandHandler {
         RampOnOffCommandHandler(DeviceFeature f) {
             super(f);
@@ -296,7 +291,6 @@ public abstract class CommandHandler {
         }
     }
 
-    @NonNullByDefault
     public static class ManualChangeCommandHandler extends CommandHandler {
         ManualChangeCommandHandler(DeviceFeature f) {
             super(f);
@@ -327,7 +321,6 @@ public abstract class CommandHandler {
     /**
      * Sends ALLLink broadcast commands to group
      */
-    @NonNullByDefault
     public static class GroupBroadcastCommandHandler extends CommandHandler {
         GroupBroadcastCommandHandler(DeviceFeature f) {
             super(f);
@@ -358,7 +351,6 @@ public abstract class CommandHandler {
         }
     }
 
-    @NonNullByDefault
     public static class LEDOnOffCommandHandler extends CommandHandler {
         LEDOnOffCommandHandler(DeviceFeature f) {
             super(f);
@@ -386,7 +378,6 @@ public abstract class CommandHandler {
         }
     }
 
-    @NonNullByDefault
     public static class X10OnOffCommandHandler extends CommandHandler {
         X10OnOffCommandHandler(DeviceFeature f) {
             super(f);
@@ -415,7 +406,6 @@ public abstract class CommandHandler {
         }
     }
 
-    @NonNullByDefault
     public static class X10PercentCommandHandler extends CommandHandler {
         X10PercentCommandHandler(DeviceFeature f) {
             super(f);
@@ -454,7 +444,6 @@ public abstract class CommandHandler {
         private final int[] x10CodeForLevel = { 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15 };
     }
 
-    @NonNullByDefault
     public static class X10IncreaseDecreaseCommandHandler extends CommandHandler {
         X10IncreaseDecreaseCommandHandler(DeviceFeature f) {
             super(f);
@@ -484,7 +473,6 @@ public abstract class CommandHandler {
         }
     }
 
-    @NonNullByDefault
     public static class IOLincOnOffCommandHandler extends CommandHandler {
         IOLincOnOffCommandHandler(DeviceFeature f) {
             super(f);
@@ -526,7 +514,6 @@ public abstract class CommandHandler {
         }
     }
 
-    @NonNullByDefault
     public static class IncreaseDecreaseCommandHandler extends CommandHandler {
         IncreaseDecreaseCommandHandler(DeviceFeature f) {
             super(f);
@@ -552,7 +539,6 @@ public abstract class CommandHandler {
         }
     }
 
-    @NonNullByDefault
     public static class PercentHandler extends CommandHandler {
         PercentHandler(DeviceFeature f) {
             super(f);
@@ -582,7 +568,6 @@ public abstract class CommandHandler {
         }
     }
 
-    @NonNullByDefault
     private abstract static class RampCommandHandler extends CommandHandler {
         private static double[] halfRateRampTimes = new double[] { 0.1, 0.3, 2, 6.5, 19, 23.5, 28, 32, 38.5, 47, 90,
                 150, 210, 270, 360, 480 };
@@ -647,7 +632,6 @@ public abstract class CommandHandler {
         }
     }
 
-    @NonNullByDefault
     public static class RampPercentHandler extends RampCommandHandler {
 
         RampPercentHandler(DeviceFeature f) {
@@ -681,7 +665,6 @@ public abstract class CommandHandler {
         }
     }
 
-    @NonNullByDefault
     public static class PowerMeterCommandHandler extends CommandHandler {
         PowerMeterCommandHandler(DeviceFeature f) {
             super(f);
@@ -728,7 +711,6 @@ public abstract class CommandHandler {
      * First used for setting thermostat parameters.
      */
 
-    @NonNullByDefault
     public static class NumberCommandHandler extends CommandHandler {
         NumberCommandHandler(DeviceFeature f) {
             super(f);
@@ -792,7 +774,6 @@ public abstract class CommandHandler {
     /**
      * Handler to set the thermostat system mode
      */
-    @NonNullByDefault
     public static class ThermostatSystemModeCommandHandler extends NumberCommandHandler {
         ThermostatSystemModeCommandHandler(DeviceFeature f) {
             super(f);
@@ -821,7 +802,6 @@ public abstract class CommandHandler {
     /**
      * Handler to set the thermostat fan mode
      */
-    @NonNullByDefault
     public static class ThermostatFanModeCommandHandler extends NumberCommandHandler {
         ThermostatFanModeCommandHandler(DeviceFeature f) {
             super(f);
@@ -844,7 +824,6 @@ public abstract class CommandHandler {
     /**
      * Handler to set the fanlinc fan mode
      */
-    @NonNullByDefault
     public static class FanLincFanCommandHandler extends NumberCommandHandler {
         FanLincFanCommandHandler(DeviceFeature f) {
             super(f);
@@ -883,6 +862,7 @@ public abstract class CommandHandler {
             Class<?> c = Class.forName(cname);
             @SuppressWarnings("unchecked")
             Class<? extends T> dc = (Class<? extends T>) c;
+            @Nullable
             T ch = dc.getDeclaredConstructor(DeviceFeature.class).newInstance(f);
             ch.setParameters(params);
             return ch;
index 0d1f20e9aceb3a0c7a308a57cbfdcc54caa13ef8..76d3404254a449933f53c8a9d378fc2c0cb39239 100644 (file)
@@ -62,7 +62,6 @@ import org.slf4j.LoggerFactory;
  * @author Rob Nielsen - Port to openHAB 2 insteon binding
  */
 @NonNullByDefault
-@SuppressWarnings("null")
 public class DeviceFeature {
     public static enum QueryStatus {
         NEVER_QUERIED,
@@ -80,8 +79,8 @@ public class DeviceFeature {
     private int directAckTimeout = 6000;
     private QueryStatus queryStatus = QueryStatus.NEVER_QUERIED;
 
-    private @Nullable MessageHandler defaultMsgHandler = new MessageHandler.DefaultMsgHandler(this);
-    private @Nullable CommandHandler defaultCommandHandler = new CommandHandler.WarnCommandHandler(this);
+    private MessageHandler defaultMsgHandler = new MessageHandler.DefaultMsgHandler(this);
+    private CommandHandler defaultCommandHandler = new CommandHandler.WarnCommandHandler(this);
     private @Nullable PollHandler pollHandler = null;
     private @Nullable MessageDispatcher dispatcher = null;
 
@@ -135,7 +134,7 @@ public class DeviceFeature {
         return directAckTimeout;
     }
 
-    public @Nullable MessageHandler getDefaultMsgHandler() {
+    public MessageHandler getDefaultMsgHandler() {
         return defaultMsgHandler;
     }
 
@@ -164,11 +163,11 @@ public class DeviceFeature {
         dispatcher = md;
     }
 
-    public void setDefaultCommandHandler(@Nullable CommandHandler ch) {
+    public void setDefaultCommandHandler(CommandHandler ch) {
         defaultCommandHandler = ch;
     }
 
-    public void setDefaultMsgHandler(@Nullable MessageHandler mh) {
+    public void setDefaultMsgHandler(MessageHandler mh) {
         defaultMsgHandler = mh;
     }
 
@@ -264,11 +263,12 @@ public class DeviceFeature {
      * @return true if dispatch successful
      */
     public boolean handleMessage(Msg msg) {
+        MessageDispatcher dispatcher = this.dispatcher;
         if (dispatcher == null) {
             logger.warn("{} no dispatcher for msg {}", name, msg);
             return false;
         }
-        return (dispatcher.dispatch(msg));
+        return dispatcher.dispatch(msg);
     }
 
     /**
@@ -280,9 +280,11 @@ public class DeviceFeature {
     public void handleCommand(InsteonChannelConfiguration c, Command cmd) {
         Class<? extends Command> key = cmd.getClass();
         CommandHandler h = commandHandlers.containsKey(key) ? commandHandlers.get(key) : defaultCommandHandler;
-        logger.trace("{} uses {} to handle command {} for {}", getName(), h.getClass().getSimpleName(),
-                key.getSimpleName(), getDevice().getAddress());
-        h.handleCommand(c, cmd, getDevice());
+        if (h != null) {
+            logger.trace("{} uses {} to handle command {} for {}", getName(), h.getClass().getSimpleName(),
+                    key.getSimpleName(), getDevice().getAddress());
+            h.handleCommand(c, cmd, getDevice());
+        }
     }
 
     /**
@@ -291,6 +293,7 @@ public class DeviceFeature {
      * @return the poll message
      */
     public @Nullable Msg makePollMsg() {
+        PollHandler pollHandler = this.pollHandler;
         if (pollHandler == null) {
             return null;
         }
@@ -387,8 +390,9 @@ public class DeviceFeature {
     public static DeviceFeature makeDeviceFeature(String s) {
         DeviceFeature f = null;
         synchronized (features) {
-            if (features.containsKey(s)) {
-                f = features.get(s).build();
+            FeatureTemplate ft = features.get(s);
+            if (ft != null) {
+                f = ft.build();
             } else {
                 logger.warn("unimplemented feature requested: {}", s);
             }
@@ -436,6 +440,8 @@ public class DeviceFeature {
     static {
         // read features from xml file and store them in a map
         InputStream input = DeviceFeature.class.getResourceAsStream("/device_features.xml");
-        readFeatureTemplates(input);
+        if (input != null) {
+            readFeatureTemplates(input);
+        }
     }
 }
index da2f3fd7b84fa6be50c1c56b456aea2637ecb026..0a92f7845e24bb984fa0b0f9b70a8d8210b67248 100644 (file)
@@ -14,6 +14,7 @@ package org.openhab.binding.insteon.internal.device;
 
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.Map;
 import java.util.Map.Entry;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
@@ -26,13 +27,12 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
  * @author Rob Nielsen - Port to openHAB 2 insteon binding
  */
 @NonNullByDefault
-@SuppressWarnings("null")
 public class DeviceType {
     private String productKey;
     private String model = "";
     private String description = "";
-    private HashMap<String, String> features = new HashMap<>();
-    private HashMap<String, FeatureGroup> featureGroups = new HashMap<>();
+    private Map<String, String> features = new HashMap<>();
+    private Map<String, FeatureGroup> featureGroups = new HashMap<>();
 
     /**
      * Constructor
@@ -48,7 +48,7 @@ public class DeviceType {
      *
      * @return all features that this device type supports
      */
-    public HashMap<String, String> getFeatures() {
+    public Map<String, String> getFeatures() {
         return features;
     }
 
@@ -57,7 +57,7 @@ public class DeviceType {
      *
      * @return all feature groups of this device type
      */
-    public HashMap<String, FeatureGroup> getFeatureGroups() {
+    public Map<String, FeatureGroup> getFeatureGroups() {
         return featureGroups;
     }
 
@@ -127,7 +127,6 @@ public class DeviceType {
      *
      * @author Bernd Pfrommer - Initial contribution
      */
-    @NonNullByDefault
     public static class FeatureGroup {
         private String name;
         private String type;
index 295985a1c34165da5acc30a6318978228fcde758..79b368dd210226faf14b91999eb86c0aea171dbd 100644 (file)
@@ -17,6 +17,7 @@ import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.HashMap;
+import java.util.Map;
 import java.util.Map.Entry;
 
 import javax.xml.parsers.DocumentBuilder;
@@ -42,11 +43,10 @@ import org.xml.sax.SAXException;
  * @author Rob Nielsen - Port to openHAB 2 insteon binding
  */
 @NonNullByDefault
-@SuppressWarnings("null")
 public class DeviceTypeLoader {
     private static final Logger logger = LoggerFactory.getLogger(DeviceTypeLoader.class);
-    private HashMap<String, DeviceType> deviceTypes = new HashMap<>();
-    private @Nullable static DeviceTypeLoader deviceTypeLoader = null;
+    private Map<String, DeviceType> deviceTypes = new HashMap<>();
+    private static DeviceTypeLoader deviceTypeLoader = new DeviceTypeLoader();
 
     private DeviceTypeLoader() {
     } // private so nobody can call it
@@ -66,7 +66,7 @@ public class DeviceTypeLoader {
      *
      * @return currently known device types
      */
-    public HashMap<String, DeviceType> getDeviceTypes() {
+    public Map<String, DeviceType> getDeviceTypes() {
         return (deviceTypes);
     }
 
@@ -202,20 +202,23 @@ public class DeviceTypeLoader {
      */
     @Nullable
     public static synchronized DeviceTypeLoader instance() {
-        if (deviceTypeLoader == null) {
-            deviceTypeLoader = new DeviceTypeLoader();
+        if (deviceTypeLoader.getDeviceTypes().isEmpty()) {
             InputStream input = DeviceTypeLoader.class.getResourceAsStream("/device_types.xml");
-            try {
-                deviceTypeLoader.loadDeviceTypesXML(input);
-            } catch (ParserConfigurationException e) {
-                logger.warn("parser config error when reading device types xml file: ", e);
-            } catch (SAXException e) {
-                logger.warn("SAX exception when reading device types xml file: ", e);
-            } catch (IOException e) {
-                logger.warn("I/O exception when reading device types xml file: ", e);
+            if (input != null) {
+                try {
+                    deviceTypeLoader.loadDeviceTypesXML(input);
+                } catch (ParserConfigurationException e) {
+                    logger.warn("parser config error when reading device types xml file: ", e);
+                } catch (SAXException e) {
+                    logger.warn("SAX exception when reading device types xml file: ", e);
+                } catch (IOException e) {
+                    logger.warn("I/O exception when reading device types xml file: ", e);
+                }
+                logger.debug("loaded {} devices: ", deviceTypeLoader.getDeviceTypes().size());
+                deviceTypeLoader.logDeviceTypes();
+            } else {
+                logger.warn("unable to get device types xml file as a resource");
             }
-            logger.debug("loaded {} devices: ", deviceTypeLoader.getDeviceTypes().size());
-            deviceTypeLoader.logDeviceTypes();
         }
         return deviceTypeLoader;
     }
index 28d55dd039b3bfffbd886cf4664fa6e5dc6ab605..5ac39d07ef9c6fcf1eee5f68a7055b2957e01a9f 100644 (file)
@@ -13,6 +13,7 @@
 package org.openhab.binding.insteon.internal.device;
 
 import java.util.HashMap;
+import java.util.Map;
 import java.util.Map.Entry;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
@@ -28,7 +29,6 @@ import org.openhab.core.types.Command;
  * @author Rob Nielsen - Port to openHAB 2 insteon binding
  */
 @NonNullByDefault
-@SuppressWarnings("null")
 public class FeatureTemplate {
     private String name;
     private String timeout;
@@ -37,8 +37,8 @@ public class FeatureTemplate {
     private @Nullable HandlerEntry pollHandler = null;
     private @Nullable HandlerEntry defaultMsgHandler = null;
     private @Nullable HandlerEntry defaultCmdHandler = null;
-    private HashMap<Integer, HandlerEntry> messageHandlers = new HashMap<>();
-    private HashMap<Class<? extends Command>, HandlerEntry> commandHandlers = new HashMap<>();
+    private Map<Integer, HandlerEntry> messageHandlers = new HashMap<>();
+    private Map<Class<? extends Command>, HandlerEntry> commandHandlers = new HashMap<>();
 
     public FeatureTemplate(String name, boolean isStatus, String timeout) {
         this.name = name;
@@ -80,7 +80,7 @@ public class FeatureTemplate {
      *
      * @return a Hashmap from Integer to String representing the command codes and the associated message handlers
      */
-    public HashMap<Integer, HandlerEntry> getMessageHandlers() {
+    public Map<Integer, HandlerEntry> getMessageHandlers() {
         return messageHandlers;
     }
 
@@ -91,7 +91,7 @@ public class FeatureTemplate {
      * @see #getMessageHandlers()
      * @return a HashMap from Command Classes to CommandHandler names
      */
-    public HashMap<Class<? extends Command>, HandlerEntry> getCommandHandlers() {
+    public Map<Class<? extends Command>, HandlerEntry> getCommandHandlers() {
         return commandHandlers;
     }
 
@@ -141,19 +141,29 @@ public class FeatureTemplate {
         DeviceFeature f = new DeviceFeature(name);
         f.setStatusFeature(isStatus);
         f.setTimeout(timeout);
+        HandlerEntry dispatcher = this.dispatcher;
         if (dispatcher != null) {
             f.setMessageDispatcher(MessageDispatcher.makeHandler(dispatcher.getName(), dispatcher.getParams(), f));
         }
+        HandlerEntry pollHandler = this.pollHandler;
         if (pollHandler != null) {
             f.setPollHandler(PollHandler.makeHandler(pollHandler, f));
         }
+        HandlerEntry defaultCmdHandler = this.defaultCmdHandler;
         if (defaultCmdHandler != null) {
-            f.setDefaultCommandHandler(
-                    CommandHandler.makeHandler(defaultCmdHandler.getName(), defaultCmdHandler.getParams(), f));
+            CommandHandler h = CommandHandler.makeHandler(defaultCmdHandler.getName(), defaultCmdHandler.getParams(),
+                    f);
+            if (h != null) {
+                f.setDefaultCommandHandler(h);
+            }
         }
+        HandlerEntry defaultMsgHandler = this.defaultMsgHandler;
         if (defaultMsgHandler != null) {
-            f.setDefaultMsgHandler(
-                    MessageHandler.makeHandler(defaultMsgHandler.getName(), defaultMsgHandler.getParams(), f));
+            MessageHandler h = MessageHandler.makeHandler(defaultMsgHandler.getName(), defaultMsgHandler.getParams(),
+                    f);
+            if (h != null) {
+                f.setDefaultMsgHandler(h);
+            }
         }
         for (Entry<Integer, HandlerEntry> mH : messageHandlers.entrySet()) {
             f.addMessageHandler(mH.getKey(),
index aafe924c150199d84295106f9917ae5a86bc8c04..c101e54f30c825ff463474b193c36eb6c54ad8c5 100644 (file)
@@ -46,7 +46,6 @@ import org.slf4j.LoggerFactory;
  * @author Rob Nielsen - Port to openHAB 2 insteon binding
  */
 @NonNullByDefault
-@SuppressWarnings("null")
 public class InsteonDevice {
     private final Logger logger = LoggerFactory.getLogger(InsteonDevice.class);
 
@@ -134,6 +133,7 @@ public class InsteonDevice {
     }
 
     public boolean hasProductKey(String key) {
+        String productKey = this.productKey;
         return productKey != null && productKey.equals(key);
     }
 
@@ -275,7 +275,12 @@ public class InsteonDevice {
                 mrequestQueue.add(e);
             }
         }
-        RequestQueueManager.instance().addQueue(this, now + delay);
+        RequestQueueManager instance = RequestQueueManager.instance();
+        if (instance != null) {
+            instance.addQueue(this, now + delay);
+        } else {
+            logger.warn("request queue manager is null");
+        }
 
         if (!l.isEmpty()) {
             lastTimePolled = now;
@@ -440,6 +445,7 @@ public class InsteonDevice {
             if (mrequestQueue.isEmpty()) {
                 return 0L;
             }
+            DeviceFeature featureQueried = this.featureQueried;
             if (featureQueried != null) {
                 // A feature has been queried, but
                 // the response has not been digested yet.
@@ -453,6 +459,9 @@ public class InsteonDevice {
                 }
             }
             QEntry qe = mrequestQueue.poll(); // take it off the queue!
+            if (qe == null) {
+                return 0L;
+            }
             if (!qe.getMsg().isBroadcast()) {
                 logger.debug("qe taken off direct: {} {}", qe.getFeature(), qe.getMsg());
                 lastQueryTime = timeNow;
@@ -505,14 +514,22 @@ public class InsteonDevice {
             m.setQuietTime(QUIET_TIME_DIRECT_MESSAGE);
         }
         logger.trace("enqueing direct message with delay {}", delay);
-        RequestQueueManager.instance().addQueue(this, now + delay);
+        RequestQueueManager instance = RequestQueueManager.instance();
+        if (instance != null) {
+            instance.addQueue(this, now + delay);
+        } else {
+            logger.warn("request queue manger instance is null");
+        }
     }
 
     private void writeMessage(Msg m) throws IOException {
-        driver.writeMessage(m);
+        Driver driver = this.driver;
+        if (driver != null) {
+            driver.writeMessage(m);
+        }
     }
 
-    private void instantiateFeatures(@Nullable DeviceType dt) {
+    private void instantiateFeatures(DeviceType dt) {
         for (Entry<String, String> fe : dt.getFeatures().entrySet()) {
             DeviceFeature f = DeviceFeature.makeDeviceFeature(fe.getValue());
             if (f == null) {
@@ -596,7 +613,7 @@ public class InsteonDevice {
      * @param dt device type after which to model the device
      * @return newly created device
      */
-    public static InsteonDevice makeDevice(@Nullable DeviceType dt) {
+    public static InsteonDevice makeDevice(DeviceType dt) {
         InsteonDevice dev = new InsteonDevice();
         dev.instantiateFeatures(dt);
         return dev;
@@ -607,7 +624,6 @@ public class InsteonDevice {
      *
      * @author Bernd Pfrommer - Initial contribution
      */
-    @NonNullByDefault
     public static class QEntry implements Comparable<QEntry> {
         private DeviceFeature feature;
         private Msg msg;
index b83dd75b574cd3c6b64874aac193b9d546cac3cf..1c7486aa546f0303bec579c7f3c33215ae101d55 100644 (file)
@@ -31,7 +31,6 @@ import org.slf4j.LoggerFactory;
  * @author Rob Nielsen - Port to openHAB 2 insteon binding
  */
 @NonNullByDefault
-@SuppressWarnings("null")
 public abstract class MessageDispatcher {
     private static final Logger logger = LoggerFactory.getLogger(MessageDispatcher.class);
 
@@ -128,7 +127,6 @@ public abstract class MessageDispatcher {
     //
     //
 
-    @NonNullByDefault
     public static class DefaultDispatcher extends MessageDispatcher {
         DefaultDispatcher(DeviceFeature f) {
             super(f);
@@ -194,7 +192,6 @@ public abstract class MessageDispatcher {
         }
     }
 
-    @NonNullByDefault
     public static class DefaultGroupDispatcher extends MessageDispatcher {
         DefaultGroupDispatcher(DeviceFeature f) {
             super(f);
@@ -263,7 +260,6 @@ public abstract class MessageDispatcher {
         }
     }
 
-    @NonNullByDefault
     public static class PollGroupDispatcher extends MessageDispatcher {
         PollGroupDispatcher(DeviceFeature f) {
             super(f);
@@ -290,7 +286,6 @@ public abstract class MessageDispatcher {
         }
     }
 
-    @NonNullByDefault
     public static class SimpleDispatcher extends MessageDispatcher {
         SimpleDispatcher(DeviceFeature f) {
             super(f);
@@ -328,7 +323,6 @@ public abstract class MessageDispatcher {
         }
     }
 
-    @NonNullByDefault
     public static class X10Dispatcher extends MessageDispatcher {
         X10Dispatcher(DeviceFeature f) {
             super(f);
@@ -355,7 +349,6 @@ public abstract class MessageDispatcher {
         }
     }
 
-    @NonNullByDefault
     public static class PassThroughDispatcher extends MessageDispatcher {
         PassThroughDispatcher(DeviceFeature f) {
             super(f);
@@ -376,7 +369,6 @@ public abstract class MessageDispatcher {
     /**
      * Drop all incoming messages silently
      */
-    @NonNullByDefault
     public static class NoOpDispatcher extends MessageDispatcher {
         NoOpDispatcher(DeviceFeature f) {
             super(f);
@@ -404,6 +396,7 @@ public abstract class MessageDispatcher {
             Class<?> c = Class.forName(cname);
             @SuppressWarnings("unchecked")
             Class<? extends T> dc = (Class<? extends T>) c;
+            @Nullable
             T ch = dc.getDeclaredConstructor(DeviceFeature.class).newInstance(f);
             ch.setParameters(params);
             return ch;
index 625d4ad409907def3e7c9a6c603037a6124fcc71..62e61c74f10aa8974d15f7cd9cbdd82e62190916 100644 (file)
@@ -50,7 +50,6 @@ import org.slf4j.LoggerFactory;
  * @author Rob Nielsen - Port to openHAB 2 insteon binding
  */
 @NonNullByDefault
-@SuppressWarnings("null")
 public abstract class MessageHandler {
     private static final Logger logger = LoggerFactory.getLogger(MessageHandler.class);
 
@@ -147,7 +146,8 @@ public abstract class MessageHandler {
      * @return value of parameter (or default if not found)
      */
     protected @Nullable String getStringParameter(String key, @Nullable String def) {
-        return (parameters.get(key) == null ? def : parameters.get(key));
+        String str = parameters.get(key);
+        return str != null ? str : def;
     }
 
     /**
@@ -334,7 +334,6 @@ public abstract class MessageHandler {
     //
     //
 
-    @NonNullByDefault
     public static class DefaultMsgHandler extends MessageHandler {
         DefaultMsgHandler(DeviceFeature p) {
             super(p);
@@ -346,7 +345,6 @@ public abstract class MessageHandler {
         }
     }
 
-    @NonNullByDefault
     public static class NoOpMsgHandler extends MessageHandler {
         NoOpMsgHandler(DeviceFeature p) {
             super(p);
@@ -358,7 +356,6 @@ public abstract class MessageHandler {
         }
     }
 
-    @NonNullByDefault
     public static class LightOnDimmerHandler extends MessageHandler {
         LightOnDimmerHandler(DeviceFeature p) {
             super(p);
@@ -388,7 +385,6 @@ public abstract class MessageHandler {
         }
     }
 
-    @NonNullByDefault
     public static class LightOffDimmerHandler extends MessageHandler {
         LightOffDimmerHandler(DeviceFeature p) {
             super(p);
@@ -404,7 +400,6 @@ public abstract class MessageHandler {
         }
     }
 
-    @NonNullByDefault
     public static class LightOnSwitchHandler extends MessageHandler {
         LightOnSwitchHandler(DeviceFeature p) {
             super(p);
@@ -422,7 +417,6 @@ public abstract class MessageHandler {
         }
     }
 
-    @NonNullByDefault
     public static class LightOffSwitchHandler extends MessageHandler {
         LightOffSwitchHandler(DeviceFeature p) {
             super(p);
@@ -445,7 +439,6 @@ public abstract class MessageHandler {
      * handler and the command handler will need to be extended to support
      * those devices.
      */
-    @NonNullByDefault
     public static class RampDimmerHandler extends MessageHandler {
         private int onCmd;
         private int offCmd;
@@ -505,7 +498,6 @@ public abstract class MessageHandler {
      * else if command2 == 0x00 then the light has been turned off
      */
 
-    @NonNullByDefault
     public static class SwitchRequestReplyHandler extends MessageHandler {
         SwitchRequestReplyHandler(DeviceFeature p) {
             super(p);
@@ -573,7 +565,6 @@ public abstract class MessageHandler {
      * Handles Dimmer replies to status requests.
      * In the dimmers case the command2 byte represents the light level from 0-255
      */
-    @NonNullByDefault
     public static class DimmerRequestReplyHandler extends MessageHandler {
         DimmerRequestReplyHandler(DeviceFeature p) {
             super(p);
@@ -609,7 +600,6 @@ public abstract class MessageHandler {
         }
     }
 
-    @NonNullByDefault
     public static class DimmerStopManualChangeHandler extends MessageHandler {
         DimmerStopManualChangeHandler(DeviceFeature p) {
             super(p);
@@ -631,7 +621,6 @@ public abstract class MessageHandler {
         }
     }
 
-    @NonNullByDefault
     public static class StartManualChangeHandler extends MessageHandler {
         StartManualChangeHandler(DeviceFeature p) {
             super(p);
@@ -658,7 +647,6 @@ public abstract class MessageHandler {
         }
     }
 
-    @NonNullByDefault
     public static class StopManualChangeHandler extends MessageHandler {
         StopManualChangeHandler(DeviceFeature p) {
             super(p);
@@ -678,7 +666,6 @@ public abstract class MessageHandler {
         }
     }
 
-    @NonNullByDefault
     public static class InfoRequestReplyHandler extends MessageHandler {
         InfoRequestReplyHandler(DeviceFeature p) {
             super(p);
@@ -714,7 +701,6 @@ public abstract class MessageHandler {
         }
     }
 
-    @NonNullByDefault
     public static class MotionSensorDataReplyHandler extends MessageHandler {
         MotionSensorDataReplyHandler(DeviceFeature p) {
             super(p);
@@ -780,7 +766,6 @@ public abstract class MessageHandler {
         }
     }
 
-    @NonNullByDefault
     public static class MotionSensor2AlternateHeartbeatHandler extends MessageHandler {
         MotionSensor2AlternateHeartbeatHandler(DeviceFeature p) {
             super(p);
@@ -792,6 +777,10 @@ public abstract class MessageHandler {
             try {
                 // group 0x0B (11) - alternate heartbeat group
                 InsteonAddress toAddr = msg.getAddr("toAddress");
+                if (toAddr == null) {
+                    logger.warn("toAddr is null");
+                    return;
+                }
                 int batteryLevel = toAddr.getHighByte() & 0xff;
                 int lightLevel = toAddr.getMiddleByte() & 0xff;
                 int temperatureLevel = msg.getByte("command2") & 0xff;
@@ -823,7 +812,6 @@ public abstract class MessageHandler {
         }
     }
 
-    @NonNullByDefault
     public static class HiddenDoorSensorDataReplyHandler extends MessageHandler {
         HiddenDoorSensorDataReplyHandler(DeviceFeature p) {
             super(p);
@@ -859,7 +847,6 @@ public abstract class MessageHandler {
         }
     }
 
-    @NonNullByDefault
     public static class PowerMeterUpdateHandler extends MessageHandler {
         PowerMeterUpdateHandler(DeviceFeature p) {
             super(p);
@@ -899,7 +886,6 @@ public abstract class MessageHandler {
         }
     }
 
-    @NonNullByDefault
     public static class PowerMeterResetHandler extends MessageHandler {
         PowerMeterResetHandler(DeviceFeature p) {
             super(p);
@@ -918,7 +904,6 @@ public abstract class MessageHandler {
         }
     }
 
-    @NonNullByDefault
     public static class LastTimeHandler extends MessageHandler {
         LastTimeHandler(DeviceFeature p) {
             super(p);
@@ -930,7 +915,6 @@ public abstract class MessageHandler {
         }
     }
 
-    @NonNullByDefault
     public static class ContactRequestReplyHandler extends MessageHandler {
         ContactRequestReplyHandler(DeviceFeature p) {
             super(p);
@@ -955,7 +939,6 @@ public abstract class MessageHandler {
         }
     }
 
-    @NonNullByDefault
     public static class ClosedContactHandler extends MessageHandler {
         ClosedContactHandler(DeviceFeature p) {
             super(p);
@@ -967,7 +950,6 @@ public abstract class MessageHandler {
         }
     }
 
-    @NonNullByDefault
     public static class OpenedContactHandler extends MessageHandler {
         OpenedContactHandler(DeviceFeature p) {
             super(p);
@@ -979,7 +961,6 @@ public abstract class MessageHandler {
         }
     }
 
-    @NonNullByDefault
     public static class OpenedOrClosedContactHandler extends MessageHandler {
         OpenedOrClosedContactHandler(DeviceFeature p) {
             super(p);
@@ -1020,7 +1001,6 @@ public abstract class MessageHandler {
         }
     }
 
-    @NonNullByDefault
     public static class ClosedSleepingContactHandler extends MessageHandler {
         ClosedSleepingContactHandler(DeviceFeature p) {
             super(p);
@@ -1039,7 +1019,6 @@ public abstract class MessageHandler {
         }
     }
 
-    @NonNullByDefault
     public static class OpenedSleepingContactHandler extends MessageHandler {
         OpenedSleepingContactHandler(DeviceFeature p) {
             super(p);
@@ -1066,7 +1045,6 @@ public abstract class MessageHandler {
      * Then connect this handler to the ACK, such that the device will be polled, and
      * the settings updated.
      */
-    @NonNullByDefault
     public static class TriggerPollMsgHandler extends MessageHandler {
         TriggerPollMsgHandler(DeviceFeature p) {
             super(p);
@@ -1081,7 +1059,6 @@ public abstract class MessageHandler {
     /**
      * Flexible handler to extract numerical data from messages.
      */
-    @NonNullByDefault
     public static class NumberMsgHandler extends MessageHandler {
         NumberMsgHandler(DeviceFeature p) {
             super(p);
@@ -1120,8 +1097,8 @@ public abstract class MessageHandler {
         }
 
         private int extractValue(Msg msg, int group) throws FieldException {
-            String lowByte = getStringParameter("low_byte", "");
-            if (lowByte.equals("")) {
+            String lowByte = getStringParameter("low_byte", null);
+            if (lowByte == null) {
                 logger.warn("{} handler misconfigured, missing low_byte!", nm());
                 return 0;
             }
@@ -1131,8 +1108,8 @@ public abstract class MessageHandler {
             } else {
                 value = msg.getByte(lowByte) & 0xFF;
             }
-            String highByte = getStringParameter("high_byte", "");
-            if (!highByte.equals("")) {
+            String highByte = getStringParameter("high_byte", null);
+            if (highByte != null) {
                 value |= (msg.getByte(highByte) & 0xFF) << 8;
             }
             return (value);
@@ -1143,7 +1120,6 @@ public abstract class MessageHandler {
      * Convert system mode field to number 0...4. Insteon has two different
      * conventions for numbering, we use the one of the status update messages
      */
-    @NonNullByDefault
     public static class ThermostatSystemModeMsgHandler extends NumberMsgHandler {
         ThermostatSystemModeMsgHandler(DeviceFeature p) {
             super(p);
@@ -1172,7 +1148,6 @@ public abstract class MessageHandler {
     /**
      * Handle reply to system mode change command
      */
-    @NonNullByDefault
     public static class ThermostatSystemModeReplyHandler extends NumberMsgHandler {
         ThermostatSystemModeReplyHandler(DeviceFeature p) {
             super(p);
@@ -1201,7 +1176,6 @@ public abstract class MessageHandler {
     /**
      * Handle reply to fan mode change command
      */
-    @NonNullByDefault
     public static class ThermostatFanModeReplyHandler extends NumberMsgHandler {
         ThermostatFanModeReplyHandler(DeviceFeature p) {
             super(p);
@@ -1224,7 +1198,6 @@ public abstract class MessageHandler {
     /**
      * Handle reply to fanlinc fan speed change command
      */
-    @NonNullByDefault
     public static class FanLincFanReplyHandler extends NumberMsgHandler {
         FanLincFanReplyHandler(DeviceFeature p) {
             super(p);
@@ -1252,7 +1225,6 @@ public abstract class MessageHandler {
      * Process X10 messages that are generated when another controller
      * changes the state of an X10 device.
      */
-    @NonNullByDefault
     public static class X10OnHandler extends MessageHandler {
         X10OnHandler(DeviceFeature p) {
             super(p);
@@ -1266,7 +1238,6 @@ public abstract class MessageHandler {
         }
     }
 
-    @NonNullByDefault
     public static class X10OffHandler extends MessageHandler {
         X10OffHandler(DeviceFeature p) {
             super(p);
@@ -1280,7 +1251,6 @@ public abstract class MessageHandler {
         }
     }
 
-    @NonNullByDefault
     public static class X10BrightHandler extends MessageHandler {
         X10BrightHandler(DeviceFeature p) {
             super(p);
@@ -1293,7 +1263,6 @@ public abstract class MessageHandler {
         }
     }
 
-    @NonNullByDefault
     public static class X10DimHandler extends MessageHandler {
         X10DimHandler(DeviceFeature p) {
             super(p);
@@ -1306,7 +1275,6 @@ public abstract class MessageHandler {
         }
     }
 
-    @NonNullByDefault
     public static class X10OpenHandler extends MessageHandler {
         X10OpenHandler(DeviceFeature p) {
             super(p);
@@ -1320,7 +1288,6 @@ public abstract class MessageHandler {
         }
     }
 
-    @NonNullByDefault
     public static class X10ClosedHandler extends MessageHandler {
         X10ClosedHandler(DeviceFeature p) {
             super(p);
@@ -1349,6 +1316,7 @@ public abstract class MessageHandler {
             Class<?> c = Class.forName(cname);
             @SuppressWarnings("unchecked")
             Class<? extends T> dc = (Class<? extends T>) c;
+            @Nullable
             T mh = dc.getDeclaredConstructor(DeviceFeature.class).newInstance(f);
             mh.setParameters(params);
             return mh;
index 0029dcb63e04dd952a50a1ce465ce8110e352ac3..712e43031a41a9d09830180a03b0b554544ef25f 100644 (file)
@@ -39,7 +39,6 @@ import org.slf4j.LoggerFactory;
  * @author Rob Nielsen - Port to openHAB 2 insteon binding
  */
 @NonNullByDefault
-@SuppressWarnings("null")
 public class ModemDBBuilder implements MsgListener {
     private static final int MESSAGE_TIMEOUT = 30000;
 
@@ -65,8 +64,11 @@ public class ModemDBBuilder implements MsgListener {
         job = scheduler.scheduleWithFixedDelay(() -> {
             if (isComplete()) {
                 logger.trace("modem db builder finished");
-                job.cancel(false);
-                job = null;
+                ScheduledFuture<?> job = this.job;
+                if (job != null) {
+                    job.cancel(false);
+                }
+                this.job = null;
             } else {
                 if (System.currentTimeMillis() - lastMessageTimestamp > MESSAGE_TIMEOUT) {
                     String s = "";
index 14464b221411780711e90596e48dca68f1621278..1f677c584f25d3306fcc0a432bb927bb8a3adf06 100644 (file)
@@ -33,7 +33,6 @@ import org.slf4j.LoggerFactory;
  * @author Rob Nielsen - Port to openHAB 2 insteon binding
  */
 @NonNullByDefault
-@SuppressWarnings("null")
 public abstract class PollHandler {
     private static final Logger logger = LoggerFactory.getLogger(PollHandler.class);
     DeviceFeature feature;
@@ -87,7 +86,6 @@ public abstract class PollHandler {
      * most query messages. Provide the suitable parameters in
      * the device features file.
      */
-    @NonNullByDefault
     public static class FlexPollHandler extends PollHandler {
         FlexPollHandler(DeviceFeature f) {
             super(f);
@@ -124,7 +122,6 @@ public abstract class PollHandler {
         }
     }
 
-    @NonNullByDefault
     public static class NoPollHandler extends PollHandler {
         NoPollHandler(DeviceFeature f) {
             super(f);
@@ -144,12 +141,13 @@ public abstract class PollHandler {
      * @return the handler which was created
      */
     @Nullable
-    public static <T extends PollHandler> T makeHandler(@Nullable HandlerEntry ph, DeviceFeature f) {
+    public static <T extends PollHandler> T makeHandler(HandlerEntry ph, DeviceFeature f) {
         String cname = PollHandler.class.getName() + "$" + ph.getName();
         try {
             Class<?> c = Class.forName(cname);
             @SuppressWarnings("unchecked")
             Class<? extends T> dc = (Class<? extends T>) c;
+            @Nullable
             T phc = dc.getDeclaredConstructor(DeviceFeature.class).newInstance(f);
             phc.setParameters(ph.getParams());
             return phc;
index 4b9f29ff0306aba1cb3cbf0e5d398ad4b2a1efb6..0d2dfbb7c99512d27de333d618431dd6c479e384 100644 (file)
@@ -15,6 +15,7 @@ package org.openhab.binding.insteon.internal.device;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.PriorityQueue;
+import java.util.Queue;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
@@ -36,20 +37,25 @@ import org.slf4j.LoggerFactory;
  * @author Rob Nielsen - Port to openHAB 2 insteon binding
  */
 @NonNullByDefault
-@SuppressWarnings("null")
 public class RequestQueueManager {
     private static @Nullable RequestQueueManager instance = null;
     private final Logger logger = LoggerFactory.getLogger(RequestQueueManager.class);
     private @Nullable Thread queueThread = null;
-    private PriorityQueue<RequestQueue> requestQueues = new PriorityQueue<>();
+    private Queue<RequestQueue> requestQueues = new PriorityQueue<>();
     private Map<InsteonDevice, RequestQueue> requestQueueHash = new HashMap<>();
     private boolean keepRunning = true;
 
     private RequestQueueManager() {
         queueThread = new Thread(new RequestQueueReader());
-        queueThread.setName("Insteon Request Queue Reader");
-        queueThread.setDaemon(true);
-        queueThread.start();
+        setParamsAndStart(queueThread);
+    }
+
+    private void setParamsAndStart(@Nullable Thread thread) {
+        if (thread != null) {
+            thread.setName("Insteon Request Queue Reader");
+            thread.setDaemon(true);
+            thread.start();
+        }
     }
 
     /**
@@ -90,6 +96,7 @@ public class RequestQueueManager {
      */
     private void stopThread() {
         logger.debug("stopping thread");
+        Thread queueThread = this.queueThread;
         if (queueThread != null) {
             synchronized (requestQueues) {
                 keepRunning = false;
@@ -102,11 +109,10 @@ public class RequestQueueManager {
             } catch (InterruptedException e) {
                 logger.warn("got interrupted waiting for thread exit ", e);
             }
-            queueThread = null;
+            this.queueThread = null;
         }
     }
 
-    @NonNullByDefault
     class RequestQueueReader implements Runnable {
         @Override
         public void run() {
@@ -114,8 +120,8 @@ public class RequestQueueManager {
             synchronized (requestQueues) {
                 while (keepRunning) {
                     try {
-                        while (keepRunning && !requestQueues.isEmpty()) {
-                            RequestQueue q = requestQueues.peek();
+                        RequestQueue q;
+                        while (keepRunning && (q = requestQueues.peek()) != null) {
                             long now = System.currentTimeMillis();
                             long expTime = q.getExpirationTime();
                             InsteonDevice dev = q.getDevice();
@@ -161,7 +167,6 @@ public class RequestQueueManager {
         }
     }
 
-    @NonNullByDefault
     public static class RequestQueue implements Comparable<RequestQueue> {
         private InsteonDevice device;
         private long expirationTime;
@@ -189,18 +194,18 @@ public class RequestQueueManager {
         }
     }
 
-    @NonNullByDefault
     public static synchronized @Nullable RequestQueueManager instance() {
         if (instance == null) {
             instance = new RequestQueueManager();
         }
-        return (instance);
+        return instance;
     }
 
     public static synchronized void destroyInstance() {
+        RequestQueueManager instance = RequestQueueManager.instance;
         if (instance != null) {
             instance.stopThread();
-            instance = null;
+            RequestQueueManager.instance = null;
         }
     }
 }
index 90b8317fb015458630379ec76bf5fc8c6a021e51..3b7af60e5b677350f18fa357dd4ffe7744232235 100644 (file)
@@ -17,7 +17,6 @@ import java.util.Map;
 import java.util.Map.Entry;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
 
 /**
  * This class has utilities related to the X10 protocol.
@@ -26,7 +25,6 @@ import org.eclipse.jdt.annotation.Nullable;
  * @author Rob Nielsen - Port to openHAB 2 insteon binding
  */
 @NonNullByDefault
-@SuppressWarnings("null")
 public class X10 {
     /**
      * Enumerates the X10 command codes.
@@ -120,8 +118,12 @@ public class X10 {
      * @return coded house byte
      */
     public static int houseStringToCode(String s) {
-        Integer i = findKey(houseCodeToString, s);
-        return (i == null) ? 0xf : i;
+        for (Entry<Integer, String> entry : houseCodeToString.entrySet()) {
+            if (s.equals(entry.getValue())) {
+                return entry.getKey();
+            }
+        }
+        return 0xf;
     }
 
     /**
@@ -132,23 +134,17 @@ public class X10 {
      */
     public static int unitStringToCode(String s) {
         try {
-            Integer key = Integer.parseInt(s);
-            Integer i = findKey(unitCodeToInt, key);
-            return i;
+            int i = Integer.parseInt(s);
+            for (Entry<Integer, Integer> entry : unitCodeToInt.entrySet()) {
+                if (i == entry.getValue()) {
+                    return entry.getKey();
+                }
+            }
         } catch (NumberFormatException e) {
         }
         return 0xf;
     }
 
-    private static @Nullable <T, E> T findKey(Map<T, E> map, E value) {
-        for (Entry<T, E> entry : map.entrySet()) {
-            if (value.equals(entry.getValue())) {
-                return entry.getKey();
-            }
-        }
-        return null;
-    }
-
     /**
      * Map between 4-bit X10 code and the house code.
      */
index 34fc953ceb8d5fcea0ee565cb18ec1630a3e2beb..1ad3781070b363f9e49be9841bf161f6fedf8ad2 100644 (file)
@@ -33,7 +33,6 @@ import org.slf4j.LoggerFactory;
  * @author Rob Nielsen - Port to openHAB 2 insteon binding
  */
 @NonNullByDefault
-@SuppressWarnings("null")
 public abstract class IOStream {
     private static final Logger logger = LoggerFactory.getLogger(IOStream.class);
     protected @Nullable InputStream in = null;
@@ -59,7 +58,12 @@ public abstract class IOStream {
     public int read(byte[] b, int offset, int readSize) throws InterruptedException, IOException {
         int len = 0;
         while (!stopped && len < 1) {
-            len = in.read(b, offset, readSize);
+            InputStream in = this.in;
+            if (in != null) {
+                len = in.read(b, offset, readSize);
+            } else {
+                throw new IOException("in is null");
+            }
             if (len == -1) {
                 throw new EOFException();
             }
@@ -77,7 +81,12 @@ public abstract class IOStream {
      * @param b byte array to write
      */
     public void write(byte @Nullable [] b) throws IOException {
-        out.write(b);
+        OutputStream out = this.out;
+        if (out != null) {
+            out.write(b);
+        } else {
+            throw new IOException("out is null");
+        }
     }
 
     /**
@@ -156,7 +165,6 @@ public abstract class IOStream {
         return new TcpIOStream(hp.host, hp.port);
     }
 
-    @NonNullByDefault
     private static class HostPort {
         public String host = "localhost";
         public int port = -1;
index e675f1c834e49e7c448277e7f62d512bddbb4c0e..ba44bd5b8085b8f1e1f3911d155b3fe715caa700 100644 (file)
@@ -41,7 +41,6 @@ import org.slf4j.LoggerFactory;
  * @author Rob Nielsen - Port to openHAB 2 insteon binding
  */
 @NonNullByDefault
-@SuppressWarnings("null")
 public class Poller {
     private static final long MIN_MSEC_BETWEEN_POLLS = 2000L;
 
@@ -107,9 +106,15 @@ public class Poller {
     public void start() {
         if (pollThread == null) {
             pollThread = new Thread(new PollQueueReader());
-            pollThread.setName("Insteon Poll Queue Reader");
-            pollThread.setDaemon(true);
-            pollThread.start();
+            setParamsAndStart(pollThread);
+        }
+    }
+
+    private void setParamsAndStart(@Nullable Thread thread) {
+        if (thread != null) {
+            thread.setName("Insteon Poll Queue Reader");
+            thread.setDaemon(true);
+            thread.start();
         }
     }
 
@@ -124,9 +129,10 @@ public class Poller {
             pollQueue.notify();
         }
         try {
+            Thread pollThread = this.pollThread;
             if (pollThread != null) {
                 pollThread.join();
-                pollThread = null;
+                this.pollThread = null;
             }
             keepRunning = true;
         } catch (InterruptedException e) {
@@ -194,7 +200,6 @@ public class Poller {
         return expTime;
     }
 
-    @NonNullByDefault
     private class PollQueueReader implements Runnable {
         @Override
         public void run() {
@@ -246,9 +251,14 @@ public class Poller {
          * @param now the current time
          */
         private void processQueue(long now) {
-            PQEntry pqe = pollQueue.pollFirst();
-            pqe.getDevice().doPoll(0);
-            addToPollQueue(pqe.getDevice(), now + pqe.getDevice().getPollInterval());
+            processQueue(now, pollQueue.pollFirst());
+        }
+
+        private void processQueue(long now, @Nullable PQEntry pqe) {
+            if (pqe != null) {
+                pqe.getDevice().doPoll(0);
+                addToPollQueue(pqe.getDevice(), now + pqe.getDevice().getPollInterval());
+            }
         }
     }
 
@@ -259,7 +269,6 @@ public class Poller {
      * @author Bernd Pfrommer - Initial contribution
      *
      */
-    @NonNullByDefault
     private static class PQEntry implements Comparable<PQEntry> {
         private InsteonDevice dev;
         private long expirationTime;
index f803183e2968a83980e50002ccf07cb95d7f9b8f..86c09adfe4795a5df41ccb55ba4ec083ff427256 100644 (file)
@@ -15,7 +15,7 @@ package org.openhab.binding.insteon.internal.driver;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Map;
-import java.util.Random;
+import java.util.Map.Entry;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.atomic.AtomicBoolean;
@@ -57,7 +57,6 @@ import org.slf4j.LoggerFactory;
  * @author Rob Nielsen - Port to openHAB 2 insteon binding
  */
 @NonNullByDefault
-@SuppressWarnings("null")
 public class Port {
     private final Logger logger = LoggerFactory.getLogger(Port.class);
 
@@ -153,9 +152,9 @@ public class Port {
     public void clearModemDB() {
         logger.debug("clearing modem db!");
         Map<InsteonAddress, ModemDBEntry> dbes = getDriver().lockModemDBEntries();
-        for (InsteonAddress addr : dbes.keySet()) {
-            if (!dbes.get(addr).isModem()) {
-                dbes.remove(addr);
+        for (Entry<InsteonAddress, ModemDBEntry> entry : dbes.entrySet()) {
+            if (!entry.getValue().isModem()) {
+                dbes.remove(entry.getKey());
             }
         }
         getDriver().unlockModemDBEntries();
@@ -178,13 +177,9 @@ public class Port {
         }
         ioStream.start();
         readThread = new Thread(reader);
-        readThread.setName("Insteon " + logName + " Reader");
-        readThread.setDaemon(true);
-        readThread.start();
+        setParamsAndStart(readThread, "Reader");
         writeThread = new Thread(writer);
-        writeThread.setName("Insteon " + logName + " Writer");
-        writeThread.setDaemon(true);
-        writeThread.start();
+        setParamsAndStart(writeThread, "Writer");
 
         if (!mdbb.isComplete()) {
             modem.initialize();
@@ -195,6 +190,14 @@ public class Port {
         disconnected.set(false);
     }
 
+    private void setParamsAndStart(@Nullable Thread thread, String type) {
+        if (thread != null) {
+            thread.setName("Insteon " + logName + " " + type);
+            thread.setDaemon(true);
+            thread.start();
+        }
+    }
+
     /**
      * Stops all threads
      */
@@ -208,9 +211,11 @@ public class Port {
         ioStream.stop();
         ioStream.close();
 
+        Thread readThread = this.readThread;
         if (readThread != null) {
             readThread.interrupt();
         }
+        Thread writeThread = this.writeThread;
         if (writeThread != null) {
             writeThread.interrupt();
         }
@@ -230,8 +235,8 @@ public class Port {
         } catch (InterruptedException e) {
             logger.debug("got interrupted waiting for write thread to exit.");
         }
-        readThread = null;
-        writeThread = null;
+        this.readThread = null;
+        this.writeThread = null;
 
         logger.debug("all threads for port {} stopped.", logName);
     }
@@ -286,12 +291,10 @@ public class Port {
      *
      * @author Bernd Pfrommer - Initial contribution
      */
-    @NonNullByDefault
     class IOStreamReader implements Runnable {
 
         private ReplyType reply = ReplyType.GOT_ACK;
         private Object replyLock = new Object();
-        private boolean dropRandomBytes = false; // set to true for fault injection
 
         /**
          * Helper function for implementing synchronization between reader and writer
@@ -306,12 +309,8 @@ public class Port {
         public void run() {
             logger.debug("starting reader...");
             byte[] buffer = new byte[2 * readSize];
-            Random rng = new Random();
             try {
                 for (int len = -1; (len = ioStream.read(buffer, 0, readSize)) > 0;) {
-                    if (dropRandomBytes && rng.nextInt(100) < 20) {
-                        len = dropBytes(buffer, len);
-                    }
                     msgFactory.addData(buffer, len);
                     processMessages();
                 }
@@ -365,29 +364,6 @@ public class Port {
             }
         }
 
-        /**
-         * Drops bytes randomly from buffer to simulate errors seen
-         * from the InsteonHub using the raw interface
-         *
-         * @param buffer byte buffer from which to drop bytes
-         * @param len original number of valid bytes in buffer
-         * @return length of byte buffer after dropping from it
-         */
-        private int dropBytes(byte[] buffer, int len) {
-            final int dropRate = 2; // in percent
-            Random rng = new Random();
-            ArrayList<Byte> l = new ArrayList<>();
-            for (int i = 0; i < len; i++) {
-                if (rng.nextInt(100) >= dropRate) {
-                    l.add(buffer[i]);
-                }
-            }
-            for (int i = 0; i < l.size(); i++) {
-                buffer[i] = l.get(i);
-            }
-            return (l.size());
-        }
-
         @SuppressWarnings("unchecked")
         private void toAllListeners(Msg msg) {
             // When we deliver the message, the recipient
@@ -442,7 +418,6 @@ public class Port {
      *
      * @author Bernd Pfrommer - Initial contribution
      */
-    @NonNullByDefault
     class IOStreamWriter implements Runnable {
         private static final int WAIT_TIME = 200; // milliseconds
 
@@ -492,11 +467,11 @@ public class Port {
     /**
      * Class to get info about the modem
      */
-    @NonNullByDefault
     class Modem implements MsgListener {
         private @Nullable InsteonDevice device = null;
 
         InsteonAddress getAddress() {
+            InsteonDevice device = this.device;
             return (device == null) ? new InsteonAddress() : (device.getAddress());
         }
 
@@ -514,18 +489,19 @@ public class Port {
                 if (msg.getByte("Cmd") == 0x60) {
                     // add the modem to the device list
                     InsteonAddress a = new InsteonAddress(msg.getAddress("IMAddress"));
-                    DeviceType dt = DeviceTypeLoader.instance().getDeviceType(InsteonDeviceHandler.PLM_PRODUCT_KEY);
-                    if (dt == null) {
-                        logger.warn("unknown modem product key: {} for modem: {}.",
-                                InsteonDeviceHandler.PLM_PRODUCT_KEY, a);
+                    DeviceTypeLoader instance = DeviceTypeLoader.instance();
+                    if (instance != null) {
+                        DeviceType dt = instance.getDeviceType(InsteonDeviceHandler.PLM_PRODUCT_KEY);
+                        if (dt == null) {
+                            logger.warn("unknown modem product key: {} for modem: {}.",
+                                    InsteonDeviceHandler.PLM_PRODUCT_KEY, a);
+                        } else {
+                            device = InsteonDevice.makeDevice(dt);
+                            initDevice(a, device);
+                            mdbb.updateModemDB(a, Port.this, null, true);
+                        }
                     } else {
-                        device = InsteonDevice.makeDevice(dt);
-                        device.setAddress(a);
-                        device.setProductKey(InsteonDeviceHandler.PLM_PRODUCT_KEY);
-                        device.setDriver(driver);
-                        device.setIsModem(true);
-                        logger.debug("found modem {} in device_types: {}", a, device.toString());
-                        mdbb.updateModemDB(a, Port.this, null, true);
+                        logger.warn("device type loader instance is null");
                     }
                     // can unsubscribe now
                     removeListener(this);
@@ -535,6 +511,18 @@ public class Port {
             }
         }
 
+        private void initDevice(InsteonAddress a, @Nullable InsteonDevice device) {
+            if (device != null) {
+                device.setAddress(a);
+                device.setProductKey(InsteonDeviceHandler.PLM_PRODUCT_KEY);
+                device.setDriver(driver);
+                device.setIsModem(true);
+                logger.debug("found modem {} in device_types: {}", a, device.toString());
+            } else {
+                logger.warn("device is null");
+            }
+        }
+
         public void initialize() {
             try {
                 Msg m = Msg.makeMessage("GetIMInfo");
index e417a2836c66524965e163ec86b278ad524713bf..7965f119fc85bb4e4c6ce950a7eabcd08b4152eb 100644 (file)
@@ -13,6 +13,8 @@
 package org.openhab.binding.insteon.internal.driver;
 
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
@@ -32,7 +34,6 @@ import org.slf4j.LoggerFactory;
  * @author Rob Nielsen - Port to openHAB 2 insteon binding
  */
 @NonNullByDefault
-@SuppressWarnings("null")
 public class SerialIOStream extends IOStream {
     private final Logger logger = LoggerFactory.getLogger(SerialIOStream.class);
     private @Nullable SerialPort port = null;
@@ -82,6 +83,11 @@ public class SerialIOStream extends IOStream {
         }
 
         try {
+            SerialPortManager serialPortManager = this.serialPortManager;
+            if (serialPortManager == null) {
+                logger.warn("serial port manager is null.");
+                return false;
+            }
             SerialPortIdentifier spi = serialPortManager.getIdentifier(devName);
             if (spi == null) {
                 logger.warn("{} is not a valid serial port.", devName);
@@ -89,13 +95,7 @@ public class SerialIOStream extends IOStream {
             }
 
             port = spi.open(appName, 1000);
-            port.setSerialPortParams(baudRate, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
-            port.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);
-            logger.debug("setting {} baud rate to {}", devName, baudRate);
-            port.enableReceiveThreshold(1);
-            port.enableReceiveTimeout(1000);
-            in = port.getInputStream();
-            out = port.getOutputStream();
+            open(port);
             logger.debug("successfully opened port {}", devName);
             return true;
         } catch (IOException e) {
@@ -109,29 +109,46 @@ public class SerialIOStream extends IOStream {
         return false;
     }
 
+    private void open(@Nullable SerialPort port) throws UnsupportedCommOperationException, IOException {
+        if (port != null) {
+            port.setSerialPortParams(baudRate, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
+            port.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);
+            logger.debug("setting {} baud rate to {}", devName, baudRate);
+            port.enableReceiveThreshold(1);
+            port.enableReceiveTimeout(1000);
+            in = port.getInputStream();
+            out = port.getOutputStream();
+        } else {
+            logger.warn("port is null");
+        }
+    }
+
     @Override
     public void close() {
+        InputStream in = this.in;
         if (in != null) {
             try {
                 in.close();
             } catch (IOException e) {
                 logger.warn("failed to close input stream", e);
             }
-            in = null;
+            this.in = null;
         }
 
+        OutputStream out = this.out;
         if (out != null) {
             try {
                 out.close();
             } catch (IOException e) {
                 logger.warn("failed to close output stream", e);
             }
-            out = null;
+            this.out = null;
         }
 
+        SerialPort port = this.port;
         if (port != null) {
             port.close();
-            port = null;
+            this.port = null;
         }
     }
 }
index 792e449d0153d2e7ff4f111dc73c8a98efdcd6c5..fa9e91d3e67c19d2bc6741de1de73dd22033bd38 100644 (file)
@@ -13,6 +13,8 @@
 package org.openhab.binding.insteon.internal.driver;
 
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.net.Socket;
 import java.net.UnknownHostException;
 
@@ -30,7 +32,6 @@ import org.slf4j.LoggerFactory;
  *
  */
 @NonNullByDefault
-@SuppressWarnings("null")
 public class TcpIOStream extends IOStream {
     private final Logger logger = LoggerFactory.getLogger(TcpIOStream.class);
 
@@ -57,8 +58,7 @@ public class TcpIOStream extends IOStream {
         }
         try {
             socket = new Socket(host, port);
-            in = socket.getInputStream();
-            out = socket.getOutputStream();
+            open(socket);
         } catch (UnknownHostException e) {
             logger.warn("unknown host name: {}", host);
             return (false);
@@ -69,33 +69,43 @@ public class TcpIOStream extends IOStream {
         return true;
     }
 
+    private void open(@Nullable Socket socket) throws IOException {
+        if (socket != null) {
+            in = socket.getInputStream();
+            out = socket.getOutputStream();
+        }
+    }
+
     @Override
     public void close() {
+        InputStream in = this.in;
         if (in != null) {
             try {
                 in.close();
             } catch (IOException e) {
                 logger.warn("failed to close input stream", e);
             }
-            in = null;
+            this.in = null;
         }
 
+        OutputStream out = this.out;
         if (out != null) {
             try {
                 out.close();
             } catch (IOException e) {
                 logger.warn("failed to close output stream", e);
             }
-            out = null;
+            this.out = null;
         }
 
+        Socket socket = this.socket;
         if (socket != null) {
             try {
                 socket.close();
             } catch (IOException e) {
                 logger.warn("failed to close the socket", e);
             }
-            socket = null;
+            this.socket = null;
         }
     }
 }
index ad8d0cd9d8cc15743d066f63b27f0866000f32ca..83b3f7a60d7d88ac1046f9936857f9c5176bbafa 100644 (file)
@@ -37,7 +37,6 @@ import org.slf4j.LoggerFactory;
  *
  */
 @NonNullByDefault
-@SuppressWarnings("null")
 public class HubIOStream extends IOStream implements Runnable {
     private final Logger logger = LoggerFactory.getLogger(HubIOStream.class);
 
@@ -96,13 +95,19 @@ public class HubIOStream extends IOStream implements Runnable {
 
         polling = true;
         pollThread = new Thread(this);
-        pollThread.setName("Insteon Hub Poller");
-        pollThread.setDaemon(true);
-        pollThread.start();
+        setParamsAndStart(pollThread);
 
         return true;
     }
 
+    private void setParamsAndStart(@Nullable Thread thread) {
+        if (thread != null) {
+            thread.setName("Insteon Hub Poller");
+            thread.setDaemon(true);
+            thread.start();
+        }
+    }
+
     @Override
     public void close() {
         polling = false;
@@ -111,22 +116,24 @@ public class HubIOStream extends IOStream implements Runnable {
             pollThread = null;
         }
 
+        InputStream in = this.in;
         if (in != null) {
             try {
                 in.close();
             } catch (IOException e) {
                 logger.warn("failed to close input stream", e);
             }
-            in = null;
+            this.in = null;
         }
 
+        OutputStream out = this.out;
         if (out != null) {
             try {
                 out.close();
             } catch (IOException e) {
                 logger.warn("failed to close output stream", e);
             }
-            out = null;
+            this.out = null;
         }
     }
 
@@ -235,7 +242,12 @@ public class HubIOStream extends IOStream implements Runnable {
         }
         if (msg.length() != 0) {
             ByteBuffer buf = ByteBuffer.wrap(hexStringToByteArray(msg.toString()));
-            ((HubInputStream) in).handle(buf);
+            InputStream in = this.in;
+            if (in != null) {
+                ((HubInputStream) in).handle(buf);
+            } else {
+                logger.warn("in is null");
+            }
         }
         bufferIdx = nIdx;
     }
@@ -344,7 +356,6 @@ public class HubIOStream extends IOStream implements Runnable {
      * @author Daniel Pfrommer - Initial contribution
      *
      */
-    @NonNullByDefault
     public class HubInputStream extends InputStream {
 
         // A buffer to keep bytes while we are waiting for the inputstream to read
@@ -381,7 +392,6 @@ public class HubIOStream extends IOStream implements Runnable {
      * @author Daniel Pfrommer - Initial contribution
      *
      */
-    @NonNullByDefault
     public class HubOutputStream extends OutputStream {
         private ByteArrayOutputStream out = new ByteArrayOutputStream();
 
index 7cca65d20bc3c26c7e3da1a8e2a8d874333c83e6..d1505fb0ad2a6b63418595aa4c6dcfda5f2fccea 100644 (file)
@@ -34,12 +34,14 @@ import org.openhab.binding.insteon.internal.device.DeviceFeature;
 import org.openhab.binding.insteon.internal.device.DeviceTypeLoader;
 import org.openhab.binding.insteon.internal.device.InsteonAddress;
 import org.openhab.binding.insteon.internal.device.InsteonDevice;
+import org.openhab.core.thing.Bridge;
 import org.openhab.core.thing.Channel;
 import org.openhab.core.thing.ChannelUID;
 import org.openhab.core.thing.Thing;
 import org.openhab.core.thing.ThingStatus;
 import org.openhab.core.thing.ThingStatusDetail;
 import org.openhab.core.thing.binding.BaseThingHandler;
+import org.openhab.core.thing.binding.ThingHandlerCallback;
 import org.openhab.core.thing.type.ChannelTypeUID;
 import org.openhab.core.types.Command;
 import org.slf4j.Logger;
@@ -56,7 +58,6 @@ import com.google.gson.reflect.TypeToken;
  * @author Rob Nielsen - Initial contribution
  */
 @NonNullByDefault
-@SuppressWarnings("null")
 public class InsteonDeviceHandler extends BaseThingHandler {
 
     private static final Set<String> ALL_CHANNEL_IDS = Collections.unmodifiableSet(Stream.of(
@@ -142,6 +143,14 @@ public class InsteonDeviceHandler extends BaseThingHandler {
                 return;
             }
 
+            InsteonDeviceConfiguration config = this.config;
+            if (config == null) {
+                String msg = "Insteon device configuration is null.";
+                logger.warn("{} {}", thing.getUID().getAsString(), msg);
+
+                updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, msg);
+                return;
+            }
             String address = config.getAddress();
             if (!InsteonAddress.isValid(address)) {
                 String msg = "Unable to start Insteon device, the insteon or X10 address '" + address
@@ -152,8 +161,17 @@ public class InsteonDeviceHandler extends BaseThingHandler {
                 return;
             }
 
+            DeviceTypeLoader instance = DeviceTypeLoader.instance();
+            if (instance == null) {
+                String msg = "Device type loader is null.";
+                logger.warn("{} {}", thing.getUID().getAsString(), msg);
+
+                updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, msg);
+                return;
+            }
+
             String productKey = config.getProductKey();
-            if (DeviceTypeLoader.instance().getDeviceType(productKey) == null) {
+            if (instance.getDeviceType(productKey) == null) {
                 String msg = "Unable to start Insteon device, invalid product key '" + productKey + "'.";
                 logger.warn("{} {}", thing.getUID().getAsString(), msg);
 
@@ -190,6 +208,23 @@ public class InsteonDeviceHandler extends BaseThingHandler {
             }
 
             InsteonDevice device = insteonBinding.makeNewDevice(insteonAddress, productKey, deviceConfigMap);
+            if (device == null) {
+                String msg = "Unable to create a device with the product key '" + productKey + "' with the address'"
+                        + address + "'.";
+                logger.warn("{} {}", thing.getUID().getAsString(), msg);
+
+                updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, msg);
+                return;
+            }
+
+            ThingHandlerCallback callback = getCallback();
+            if (callback == null) {
+                String msg = "Unable to get thing handler callback.";
+                logger.warn("{} {}", thing.getUID().getAsString(), msg);
+
+                updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, msg);
+                return;
+            }
 
             StringBuilder channelList = new StringBuilder();
             List<Channel> channels = new ArrayList<>();
@@ -256,7 +291,7 @@ public class InsteonDeviceHandler extends BaseThingHandler {
                                                 ChannelTypeUID channelTypeUID = new ChannelTypeUID(
                                                         InsteonBindingConstants.BINDING_ID,
                                                         InsteonBindingConstants.SWITCH);
-                                                Channel channel = getCallback()
+                                                Channel channel = callback
                                                         .createChannelBuilder(channelUID, channelTypeUID).withLabel(id)
                                                         .build();
 
@@ -285,7 +320,7 @@ public class InsteonDeviceHandler extends BaseThingHandler {
                                     channelId);
                             Channel channel = thing.getChannel(channelUID);
                             if (channel == null) {
-                                channel = getCallback().createChannelBuilder(channelUID, channelTypeUID).build();
+                                channel = callback.createChannelBuilder(channelUID, channelTypeUID).build();
                             }
 
                             addChannel(channel, channelId, channels, channelList);
@@ -343,14 +378,17 @@ public class InsteonDeviceHandler extends BaseThingHandler {
 
     @Override
     public void dispose() {
-        String address = config.getAddress();
-        if (getBridge() != null && InsteonAddress.isValid(address)) {
-            getInsteonBinding().removeDevice(new InsteonAddress(address));
+        InsteonDeviceConfiguration config = this.config;
+        if (config != null) {
+            String address = config.getAddress();
+            if (getBridge() != null && InsteonAddress.isValid(address)) {
+                getInsteonBinding().removeDevice(new InsteonAddress(address));
 
-            logger.debug("removed {} address = {}", getThing().getUID().getAsString(), address);
-        }
+                logger.debug("removed {} address = {}", getThing().getUID().getAsString(), address);
+            }
 
-        getInsteonNetworkHandler().disposed(getThing().getUID());
+            getInsteonNetworkHandler().disposed(getThing().getUID());
+        }
 
         super.dispose();
     }
@@ -370,6 +408,10 @@ public class InsteonDeviceHandler extends BaseThingHandler {
 
         Map<String, String> params = new HashMap<>();
         Channel channel = getThing().getChannel(channelUID.getId());
+        if (channel == null) {
+            logger.warn("channel is null");
+            return;
+        }
 
         Map<String, Object> channelProperties = channel.getConfiguration().getProperties();
         for (String key : channelProperties.keySet()) {
@@ -381,11 +423,16 @@ public class InsteonDeviceHandler extends BaseThingHandler {
                 params.put(key, s);
             } else {
                 logger.warn("not a string or big decimal value key '{}' value '{}' {}", key, value,
-                        value.getClass().getName());
+                        value != null ? value.getClass().getName() : "unknown");
             }
         }
 
         String feature = channelUID.getId().toLowerCase();
+        InsteonDeviceConfiguration config = this.config;
+        if (config == null) {
+            logger.warn("insteon device config is null");
+            return;
+        }
         String productKey = config.getProductKey();
         if (productKey.equals(HIDDEN_DOOR_SENSOR_PRODUCT_KEY)) {
             if (feature.equalsIgnoreCase(InsteonBindingConstants.BATTERY_LEVEL)) {
@@ -461,11 +508,19 @@ public class InsteonDeviceHandler extends BaseThingHandler {
         logger.debug("channel {} unlinked ", channelUID.getAsString());
     }
 
-    private @Nullable InsteonNetworkHandler getInsteonNetworkHandler() {
-        return (InsteonNetworkHandler) getBridge().getHandler();
+    private InsteonNetworkHandler getInsteonNetworkHandler() {
+        Bridge bridge = getBridge();
+        if (bridge == null) {
+            throw new IllegalArgumentException("insteon network bridge is null");
+        }
+        InsteonNetworkHandler handler = (InsteonNetworkHandler) bridge.getHandler();
+        if (handler == null) {
+            throw new IllegalArgumentException("insteon network handler is null");
+        }
+        return handler;
     }
 
-    private @Nullable InsteonBinding getInsteonBinding() {
+    private InsteonBinding getInsteonBinding() {
         return getInsteonNetworkHandler().getInsteonBinding();
     }
 }
index 25b7163608512bb9dad6671a89f1ff6dd030a7af..3f9d18880af657d2a69303c2300d970770758edc 100644 (file)
@@ -45,7 +45,6 @@ import org.slf4j.LoggerFactory;
  * @author Rob Nielsen - Initial contribution
  */
 @NonNullByDefault
-@SuppressWarnings("null")
 public class InsteonNetworkHandler extends BaseBridgeHandler {
     private static final int LOG_DEVICE_STATISTICS_DELAY_IN_SECONDS = 600;
     private static final int RETRY_DELAY_IN_SECONDS = 30;
@@ -82,6 +81,23 @@ public class InsteonNetworkHandler extends BaseBridgeHandler {
         updateStatus(ThingStatus.UNKNOWN);
 
         scheduler.execute(() -> {
+            InsteonNetworkConfiguration config = this.config;
+            if (config == null) {
+                String msg = "Initialization failed, configuration is null.";
+                logger.warn(msg);
+
+                updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, msg);
+                return;
+            }
+            SerialPortManager serialPortManager = this.serialPortManager;
+            if (serialPortManager == null) {
+                String msg = "Initialization failed, serial port manager is null.";
+                logger.warn(msg);
+
+                updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, msg);
+
+                return;
+            }
             insteonBinding = new InsteonBinding(this, config, serialPortManager, scheduler);
 
             // hold off on starting to poll until devices that already are defined as things are added.
@@ -91,7 +107,8 @@ public class InsteonNetworkHandler extends BaseBridgeHandler {
                 // check to see if it has been at least SETTLE_TIME_IN_SECONDS since last device was created
                 if (System.currentTimeMillis() - lastInsteonDeviceCreatedTimestamp > SETTLE_TIME_IN_SECONDS * 1000) {
                     // settle time has expired start polling
-                    if (insteonBinding.startPolling()) {
+                    InsteonBinding insteonBinding = this.insteonBinding;
+                    if (insteonBinding != null && insteonBinding.startPolling()) {
                         pollingJob = scheduler.scheduleWithFixedDelay(() -> {
                             insteonBinding.logDeviceStatistics();
                         }, 0, LOG_DEVICE_STATISTICS_DELAY_IN_SECONDS, TimeUnit.SECONDS);
@@ -107,8 +124,11 @@ public class InsteonNetworkHandler extends BaseBridgeHandler {
                         updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, msg);
                     }
 
-                    settleJob.cancel(false);
-                    settleJob = null;
+                    ScheduledFuture<?> settleJob = this.settleJob;
+                    if (settleJob != null) {
+                        settleJob.cancel(false);
+                    }
+                    this.settleJob = null;
                 }
             }, SETTLE_TIME_IN_SECONDS, 1, TimeUnit.SECONDS);
         });
@@ -118,24 +138,28 @@ public class InsteonNetworkHandler extends BaseBridgeHandler {
     public void dispose() {
         logger.debug("Shutting down Insteon bridge");
 
+        ScheduledFuture<?> pollingJob = this.pollingJob;
         if (pollingJob != null) {
             pollingJob.cancel(true);
-            pollingJob = null;
+            this.pollingJob = null;
         }
 
+        ScheduledFuture<?> reconnectJob = this.reconnectJob;
         if (reconnectJob != null) {
             reconnectJob.cancel(true);
-            reconnectJob = null;
+            this.reconnectJob = null;
         }
 
+        ScheduledFuture<?> settleJob = this.settleJob;
         if (settleJob != null) {
             settleJob.cancel(true);
-            settleJob = null;
+            this.settleJob = null;
         }
 
+        InsteonBinding insteonBinding = this.insteonBinding;
         if (insteonBinding != null) {
             insteonBinding.shutdown();
-            insteonBinding = null;
+            this.insteonBinding = null;
         }
 
         deviceInfo.clear();
@@ -151,10 +175,14 @@ public class InsteonNetworkHandler extends BaseBridgeHandler {
 
     public void bindingDisconnected() {
         reconnectJob = scheduler.scheduleWithFixedDelay(() -> {
-            if (insteonBinding.reconnect()) {
+            InsteonBinding insteonBinding = this.insteonBinding;
+            if (insteonBinding != null && insteonBinding.reconnect()) {
                 updateStatus(ThingStatus.ONLINE);
-                reconnectJob.cancel(false);
-                reconnectJob = null;
+                ScheduledFuture<?> reconnectJob = this.reconnectJob;
+                if (reconnectJob != null) {
+                    reconnectJob.cancel(false);
+                }
+                this.reconnectJob = null;
             } else {
                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "Port disconnected.");
             }
@@ -165,8 +193,13 @@ public class InsteonNetworkHandler extends BaseBridgeHandler {
         lastInsteonDeviceCreatedTimestamp = System.currentTimeMillis();
     }
 
-    public @Nullable InsteonBinding getInsteonBinding() {
-        return insteonBinding;
+    public InsteonBinding getInsteonBinding() {
+        InsteonBinding insteonBinding = this.insteonBinding;
+        if (insteonBinding != null) {
+            return insteonBinding;
+        } else {
+            throw new IllegalArgumentException("insteon binding is null");
+        }
     }
 
     public void setInsteonDeviceDiscoveryService(InsteonDeviceDiscoveryService insteonDeviceDiscoveryService) {
@@ -175,7 +208,10 @@ public class InsteonNetworkHandler extends BaseBridgeHandler {
 
     public void addMissingDevices(List<String> missing) {
         scheduler.execute(() -> {
-            insteonDeviceDiscoveryService.addInsteonDevices(missing, getThing().getUID());
+            InsteonDeviceDiscoveryService insteonDeviceDiscoveryService = this.insteonDeviceDiscoveryService;
+            if (insteonDeviceDiscoveryService != null) {
+                insteonDeviceDiscoveryService.addInsteonDevices(missing, getThing().getUID());
+            }
         });
     }
 
@@ -188,9 +224,12 @@ public class InsteonNetworkHandler extends BaseBridgeHandler {
     }
 
     public void displayLocalDatabase(Console console) {
-        Map<String, String> databaseInfo = insteonBinding.getDatabaseInfo();
-        console.println("local database contains " + databaseInfo.size() + " entries");
-        display(console, databaseInfo);
+        InsteonBinding insteonBinding = this.insteonBinding;
+        if (insteonBinding != null) {
+            Map<String, String> databaseInfo = insteonBinding.getDatabaseInfo();
+            console.println("local database contains " + databaseInfo.size() + " entries");
+            display(console, databaseInfo);
+        }
     }
 
     public void initialized(ThingUID uid, String msg) {
index 4b2315c44599c273e6fcef41fd823a0938d4e60e..56ccbed72c0d3832c152a07ca4925a508b4d69bd 100644 (file)
@@ -13,9 +13,9 @@
 package org.openhab.binding.insteon.internal.message;
 
 import java.util.HashMap;
+import java.util.Map;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
 
 /**
  * Defines the data types that can be used in the fields of a message.
@@ -31,10 +31,10 @@ public enum DataType {
     ADDRESS("address", 3),
     INVALID("INVALID", -1);
 
-    private static HashMap<String, DataType> typeMap = new HashMap<>();
+    private static Map<String, DataType> typeMap = new HashMap<>();
 
-    private int size = -1; // number of bytes consumed
-    private String name = "";
+    private int size;
+    private String name;
 
     static {
         typeMap.put(BYTE.getName(), BYTE);
@@ -74,7 +74,12 @@ public enum DataType {
      * @param name the string to translate to a type
      * @return the data type corresponding to the name string, or null if not found
      */
-    public static @Nullable DataType getDataType(String name) {
-        return typeMap.get(name);
+    public static DataType getDataType(String name) {
+        DataType dataType = typeMap.get(name);
+        if (dataType != null) {
+            return dataType;
+        } else {
+            throw new IllegalArgumentException("Unable to find data type for " + name);
+        }
     }
 }
index 3197a2163c962861cad9fae21fd8852edcdb98ed..db68b44f969b18f3016bba18a62656ad25096d07 100644 (file)
@@ -28,11 +28,10 @@ import org.openhab.binding.insteon.internal.utils.Utils;
  * @author Rob Nielsen - Port to openHAB 2 insteon binding
  */
 @NonNullByDefault
-@SuppressWarnings("null")
 public final class Field {
     private final String name;
     private final int offset;
-    private final @Nullable DataType type;
+    private final DataType type;
 
     public String getName() {
         return name;
@@ -42,11 +41,11 @@ public final class Field {
         return offset;
     }
 
-    public @Nullable DataType getType() {
+    public DataType getType() {
         return type;
     }
 
-    public Field(String name, @Nullable DataType type, int off) {
+    public Field(String name, DataType type, int off) {
         this.name = name;
         this.type = type;
         this.offset = off;
@@ -74,7 +73,7 @@ public final class Field {
         return getName() + " Type: " + getType() + " Offset " + getOffset();
     }
 
-    public String toString(byte @Nullable [] array) {
+    public String toString(byte[] array) {
         String s = name + ":";
         try {
             switch (type) {
@@ -96,7 +95,7 @@ public final class Field {
         return s;
     }
 
-    public void set(byte @Nullable [] array, Object o) throws FieldException {
+    public void set(byte[] array, Object o) throws FieldException {
         switch (getType()) {
             case BYTE:
                 setByte(array, (Byte) o);
@@ -121,7 +120,7 @@ public final class Field {
      * @param b the value you want to set the byte to
      * @throws FieldException
      */
-    public void setByte(byte @Nullable [] array, byte b) throws FieldException {
+    public void setByte(byte[] array, byte b) throws FieldException {
         check(array.length, DataType.BYTE);
         array[offset] = b;
     }
@@ -133,7 +132,7 @@ public final class Field {
      * @param array the destination array
      * @param i the integer value to set
      */
-    public void setInt(byte @Nullable [] array, int i) throws FieldException {
+    public void setInt(byte[] array, int i) throws FieldException {
         check(array.length, DataType.INT);
         array[offset] = (byte) ((i >>> 24) & 0xFF);
         array[offset + 1] = (byte) ((i >>> 16) & 0xFF);
@@ -149,7 +148,7 @@ public final class Field {
      * @param adr the insteon address value to set
      */
 
-    public void setAddress(byte @Nullable [] array, InsteonAddress adr) throws FieldException {
+    public void setAddress(byte[] array, InsteonAddress adr) throws FieldException {
         check(array.length, DataType.ADDRESS);
         adr.storeBytes(array, offset);
     }
@@ -160,7 +159,7 @@ public final class Field {
      * @param array the array to fetch from
      * @return the byte value of the field
      */
-    public byte getByte(byte @Nullable [] array) throws FieldException {
+    public byte getByte(byte[] array) throws FieldException {
         check(array.length, DataType.BYTE);
         return array[offset];
     }
@@ -171,7 +170,7 @@ public final class Field {
      * @param array the array to fetch from
      * @return the int value of the field
      */
-    public int getInt(byte @Nullable [] array) throws FieldException {
+    public int getInt(byte[] array) throws FieldException {
         check(array.length, DataType.INT);
         byte b1 = array[offset];
         byte b2 = array[offset + 1];
@@ -188,7 +187,7 @@ public final class Field {
      * @return the address
      */
 
-    public InsteonAddress getAddress(byte @Nullable [] array) throws FieldException {
+    public InsteonAddress getAddress(byte[] array) throws FieldException {
         check(array.length, DataType.ADDRESS);
         InsteonAddress adr = new InsteonAddress();
         adr.loadBytes(array, offset);
index 4e8f834f8499e59c9ade6b193f31fe93a07c8afe..9185af7f86de8ddd522541ce91d46be27abff1d2 100644 (file)
@@ -39,7 +39,6 @@ import org.slf4j.LoggerFactory;
  * @author Rob Nielsen - Port to openHAB 2 insteon binding
  */
 @NonNullByDefault
-@SuppressWarnings("null")
 public class Msg {
     private static final Logger logger = LoggerFactory.getLogger(Msg.class);
 
@@ -51,7 +50,7 @@ public class Msg {
         TO_MODEM("TO_MODEM"),
         FROM_MODEM("FROM_MODEM");
 
-        private static HashMap<String, Direction> map = new HashMap<>();
+        private static Map<String, Direction> map = new HashMap<>();
 
         private String directionString;
 
@@ -69,7 +68,12 @@ public class Msg {
         }
 
         public static Direction getDirectionFromString(String dir) {
-            return map.get(dir);
+            Direction direction = map.get(dir);
+            if (direction != null) {
+                return direction;
+            } else {
+                throw new IllegalArgumentException("Unable to find direction for " + dir);
+            }
         }
     }
 
@@ -81,7 +85,7 @@ public class Msg {
     private static final Map<Integer, Msg> REPLY_MAP = new HashMap<>();
 
     private int headerLength = -1;
-    private byte @Nullable [] data = null;
+    private byte[] data;
     private MsgDefinition definition = new MsgDefinition();
     private Direction direction = Direction.TO_MODEM;
     private long quietTime = 0;
@@ -97,7 +101,8 @@ public class Msg {
     public Msg(int headerLength, byte[] data, int dataLength, Direction dir) {
         this.headerLength = headerLength;
         this.direction = dir;
-        initialize(data, 0, dataLength);
+        this.data = new byte[dataLength];
+        System.arraycopy(data, 0, this.data, 0, dataLength);
     }
 
     /**
@@ -119,7 +124,7 @@ public class Msg {
         try {
             InputStream stream = FrameworkUtil.getBundle(Msg.class).getResource("/msg_definitions.xml").openStream();
             if (stream != null) {
-                HashMap<String, Msg> msgs = XMLMessageReader.readMessageDefinitions(stream);
+                Map<String, Msg> msgs = XMLMessageReader.readMessageDefinitions(stream);
                 MSG_MAP.putAll(msgs);
             } else {
                 logger.warn("could not get message definition resource!");
@@ -171,15 +176,15 @@ public class Msg {
     }
 
     public byte getCommandNumber() {
-        return ((data == null || data.length < 2) ? -1 : data[1]);
+        return data.length < 2 ? -1 : data[1];
     }
 
     public boolean isPureNack() {
-        return (data.length == 2 && data[1] == 0x15);
+        return data.length == 2 && data[1] == 0x15;
     }
 
     public boolean isExtended() {
-        if (data == null || getLength() < 2) {
+        if (getLength() < 2) {
             return false;
         }
         if (!definition.containsField("messageFlags")) {
@@ -272,23 +277,6 @@ public class Msg {
         return hops;
     }
 
-    /**
-     * Will initialize the message with a byte[], an offset, and a length
-     *
-     * @param newData the src byte array
-     * @param offset the offset in the src byte array
-     * @param len the length to copy from the src byte array
-     */
-    private void initialize(byte[] newData, int offset, int len) {
-        byte[] data = new byte[len];
-        if (offset >= 0 && offset < newData.length) {
-            System.arraycopy(newData, offset, data, 0, len);
-        } else {
-            logger.warn("intialize(): Offset out of bounds!");
-        }
-        this.data = data;
-    }
-
     /**
      * Will put a byte at the specified key
      *
@@ -346,9 +334,7 @@ public class Msg {
         }
         byte[] section = new byte[numBytes];
         byte[] data = this.data;
-        if (data != null) {
-            System.arraycopy(data, offset, section, 0, numBytes);
-        }
+        System.arraycopy(data, offset, section, 0, numBytes);
         return section;
     }
 
@@ -377,10 +363,7 @@ public class Msg {
     }
 
     public String toHexString() {
-        if (data != null) {
-            return Utils.getHexString(data);
-        }
-        return super.toString();
+        return Utils.getHexString(data);
     }
 
     /**
@@ -473,19 +456,15 @@ public class Msg {
     @Override
     public String toString() {
         String s = (direction == Direction.TO_MODEM) ? "OUT:" : "IN:";
-        if (data == null) {
-            return toHexString();
-        }
         // need to first sort the fields by offset
-        Comparator<@Nullable Field> cmp = new Comparator<@Nullable Field>() {
+        Comparator<Field> cmp = new Comparator<Field>() {
             @Override
-            public int compare(@Nullable Field f1, @Nullable Field f2) {
+            public int compare(Field f1, Field f2) {
                 return f1.getOffset() - f2.getOffset();
             }
         };
-        TreeSet<@Nullable Field> fields = new TreeSet<>(cmp);
-        for (@Nullable
-        Field f : definition.getFields().values()) {
+        TreeSet<Field> fields = new TreeSet<>(cmp);
+        for (Field f : definition.getFields().values()) {
             fields.add(f);
         }
         for (Field f : fields) {
@@ -517,7 +496,7 @@ public class Msg {
      * @return message, or null if the Msg cannot be created
      */
     public static @Nullable Msg createMessage(byte[] buf, int msgLen, boolean isExtended) {
-        if (buf == null || buf.length < 2) {
+        if (buf.length < 2) {
             return null;
         }
         Msg template = REPLY_MAP.get(cmdToKey(buf[1], isExtended));
index 7fdcd66ae3edc4862a88d86e2607745d1625b6a6..34fd7a1d59c7ff3d096cf359e2b6a8a9a7bb1cbe 100644 (file)
@@ -27,7 +27,6 @@ import org.eclipse.jdt.annotation.Nullable;
  * @author Rob Nielsen - Port to openHAB 2 insteon binding
  */
 @NonNullByDefault
-@SuppressWarnings("null")
 public class MsgDefinition {
     private Map<String, Field> fields = new HashMap<>();
 
@@ -39,7 +38,7 @@ public class MsgDefinition {
      *
      * @param m the definition to copy
      */
-    MsgDefinition(@Nullable MsgDefinition m) {
+    MsgDefinition(MsgDefinition m) {
         fields = new HashMap<>(m.fields);
     }
 
index c23a18cc5c6aa5d31fbe33800a4e17dce27dac7f..6ec2b4ffe6d7f484e2f5fc1ee16c9a6d57005351 100644 (file)
@@ -16,6 +16,7 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
+import java.util.Map;
 import java.util.Map.Entry;
 
 import javax.xml.parsers.DocumentBuilder;
@@ -23,7 +24,6 @@ import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
 import org.openhab.binding.insteon.internal.utils.Pair;
 import org.openhab.binding.insteon.internal.utils.Utils.DataTypeParser;
 import org.openhab.binding.insteon.internal.utils.Utils.ParsingException;
@@ -40,7 +40,6 @@ import org.xml.sax.SAXException;
  * @author Rob Nielsen - Port to openHAB 2 insteon binding
  */
 @NonNullByDefault
-@SuppressWarnings("null")
 public class XMLMessageReader {
     /**
      * Reads the message definitions from an xml file
@@ -51,9 +50,9 @@ public class XMLMessageReader {
      * @throws ParsingException something wrong with the file format
      * @throws FieldException something wrong with the field definition
      */
-    public static HashMap<String, Msg> readMessageDefinitions(InputStream input)
+    public static Map<String, Msg> readMessageDefinitions(InputStream input)
             throws IOException, ParsingException, FieldException {
-        HashMap<String, Msg> messageMap = new HashMap<>();
+        Map<String, Msg> messageMap = new HashMap<>();
         try {
             DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
             DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
@@ -133,12 +132,9 @@ public class XMLMessageReader {
         for (int i = 0; i < nodes.getLength(); i++) {
             Node node = nodes.item(i);
             if (node.getNodeType() == Node.ELEMENT_NODE) {
-                @Nullable
                 Pair<Field, Object> definition = readField((Element) node, offset);
-                if (definition != null) {
-                    offset += definition.getKey().getType().getSize();
-                    fields.put(definition.getKey(), definition.getValue());
-                }
+                offset += definition.getKey().getType().getSize();
+                fields.put(definition.getKey(), definition.getValue());
             }
         }
         if (headerLen != offset) {
@@ -165,8 +161,13 @@ public class XMLMessageReader {
         Msg msg = new Msg(headerLength, new byte[length], length, dir);
         for (Entry<Field, Object> e : values.entrySet()) {
             Field f = e.getKey();
-            f.set(msg.getData(), e.getValue());
-            if (f.getName() != null && !f.getName().equals("")) {
+            byte[] data = msg.getData();
+            if (data != null) {
+                f.set(data, e.getValue());
+            } else {
+                throw new FieldException("data is null");
+            }
+            if (!f.getName().equals("")) {
                 msg.addField(f);
             }
         }
index bcc0e3e7ea69154208e0a8adca1428f382a938d3..ba29cd4ec00a070d330a49c8fe2c289612ffd123 100644 (file)
@@ -24,14 +24,13 @@ import org.openhab.binding.insteon.internal.message.DataType;
  * @author Rob Nielsen - Port to openHAB 2 insteon binding
  */
 @NonNullByDefault
-@SuppressWarnings("null")
 public class Utils {
     public static String getHexString(int b) {
         String result = String.format("%02X", b & 0xFF);
         return result;
     }
 
-    public static String getHexString(byte @Nullable [] b) {
+    public static String getHexString(byte[] b) {
         return getHexString(b, b.length);
     }
 
@@ -70,9 +69,8 @@ public class Utils {
         return String.format("0x%02X", b);
     }
 
-    @NonNullByDefault
     public static class DataTypeParser {
-        public static Object parseDataType(@Nullable DataType type, String val) {
+        public static Object parseDataType(DataType type, String val) {
             switch (type) {
                 case BYTE:
                     return parseByte(val);
@@ -123,7 +121,6 @@ public class Utils {
     /**
      * Exception to indicate various xml parsing errors.
      */
-    @NonNullByDefault
     public static class ParsingException extends Exception {
         private static final long serialVersionUID = 3997461423241843949L;
 
index 26535c0fcb63e721797530a5380ef2e8f08a6016..d6347127f03ed49987391cd438a6561b6c70ddf1 100644 (file)
                <message-dispatcher>DefaultDispatcher</message-dispatcher>
                <!-- handles direct extended message after query -->
                <message-handler cmd="0x2e" ext="1" match_cmd1="0x2e" match_cmd2="0x02" match_d1="0x01"
-                       low_byte="userData10" high_byte="userData9" factor="0.1">NumberMsgHandler</message-handler>
+                       low_byte="userData10" high_byte="userData9" factor="0.1" scale="celsius">NumberMsgHandler</message-handler>
                <!-- handles out-of band status messages -->
                <message-handler cmd="0x6e" ext="0" match_cmd1="0x6e" low_byte="command2" offset="-17.7777778"
                        factor="0.2777778" scale="celsius">NumberMsgHandler</message-handler>
                <message-dispatcher>DefaultDispatcher</message-dispatcher>
                <!-- handles direct extended message after query -->
                <message-handler cmd="0x2e" ext="1" match_cmd1="0x2e" match_cmd2="0x02" match_d1="0x01"
-                       low_byte="userData10" high_byte="userData9" offset="32" factor="0.18">NumberMsgHandler</message-handler>
+                       low_byte="userData10" high_byte="userData9" offset="32" factor="0.18" scale="fahrenheit">NumberMsgHandler</message-handler>
                <!-- handles out-of band status messages -->
                <message-handler cmd="0x6e" ext="0" match_cmd1="0x6e" low_byte="command2" offset="0" factor="0.5"
                        scale="fahrenheit">NumberMsgHandler</message-handler>