text: /**
   *
   * Copyright (c) 2009-2020 Freedomotic Team http://www.freedomotic-iot.com
   *
   * This file is part of Freedomotic
   *
   * This Program is free software; you can redistribute it and/or modify it under
   * the terms of the GNU General Public License as published by the Free Software
   * Foundation; either version 2, or (at your option) any later version.
   *
   * This Program is distributed in the hope that it will be useful, but WITHOUT
   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
   * details.
   *
   * You should have received a copy of the GNU General Public License along with
   * Freedomotic; see the file COPYING. If not, see
   * <http://www.gnu.org/licenses/>.
   */
  package com.freedomotic.plugins.devices.restapiv3;
  
  import com.freedomotic.api.EventTemplate;
  import com.freedomotic.api.Protocol;
  import com.freedomotic.events.MessageEvent;
  import com.freedomotic.events.ObjectHasChangedBehavior;
  import com.freedomotic.events.PluginHasChanged;
  import com.freedomotic.events.ZoneHasChanged;
  import com.freedomotic.plugins.devices.restapiv3.resources.atmosphere.AtmosphereEventResource;
  import com.freedomotic.plugins.devices.restapiv3.resources.atmosphere.AtmosphereMessageCalloutResource;
  import com.freedomotic.plugins.devices.restapiv3.resources.atmosphere.AtmosphereObjectChangeResource;
  import com.freedomotic.plugins.devices.restapiv3.resources.atmosphere.AtmospherePluginChangeResource;
  import com.freedomotic.plugins.devices.restapiv3.resources.atmosphere.AtmosphereZoneChangeResource;
  import com.freedomotic.reactions.Command;
  import java.net.URI;
  import javax.inject.Inject;
  import javax.ws.rs.core.UriBuilder;
  import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  
  public class RestAPIv3 extends Protocol {
  
      private static final Logger LOG = LoggerFactory.getLogger(RestAPIv3.class.getName());
      private static final String RESOURCE_PKG = "com.freedomotic.plugins.devices.restapiv3.resources";
      public static final String JERSEY_RESOURCE_PKG = RESOURCE_PKG + ".jersey";
      public static final String ATMOSPHRE_RESOURCE_PKG = RESOURCE_PKG + ".atmosphere";
  
      public static URI BASE_URI;
      public static final String API_VERSION = "v3";
  
      @Inject
      private RestJettyServer jServer;
      @Inject
      private AtmosphereObjectChangeResource atmosphereObjectChangeResource;
      @Inject
      private AtmosphereZoneChangeResource atmosphereZoneChangeResource;
      @Inject
      private AtmospherePluginChangeResource atmospherePluginChangeResource;
      @Inject
      private AtmosphereMessageCalloutResource atmosphereMessageCalloutResource;
      @Inject
      private AtmosphereEventResource atmosphereEventResource;
  
      // Hold a preconfigurd static web security manager which can be used by Shiro
      public static DefaultWebSecurityManager defaultWebSecurityManager;
  
      public RestAPIv3() {
          super("RestAPI v3", "/restapi-v3/restapiv3-manifest.xml");
          setPollingWait(-1);
          // Create the preconfigured security manager
          createDefaultWebSecurityManager();
      }
  
      @Override
      protected void onRun() {
  
      }
  
      @Override
      protected void onStart() {
          setDescription("Plugin is starting...");
          String protocol = configuration.getBooleanProperty("enable-ssl", false) ? "https" : "http";
          int port = configuration.getBooleanProperty("enable-ssl", false) ? configuration.getIntProperty("https-port", 9113) : configuration.getIntProperty("http-port", 9111);
  
          BASE_URI = UriBuilder.fromUri(protocol + "://" + configuration.getStringProperty("listen-address", "localhost") + "/").path(API_VERSION).port(port).build();
  
          LOG.info("RestAPI v3 plugin is started at {}", BASE_URI);
  
          try {
              jServer.setMaster(this);
              jServer.startServer();
              setDescription("API is available at " + BASE_URI.toString().substring(0, BASE_URI.toString().length() - 2));
          } catch (Exception ex) {
              LOG.error(ex.getMessage());
          }
  
          addEventListener("app.event.sensor.object.behavior.change");
          addEventListener("app.event.sensor.environment.zone.change");
          addEventListener("app.event.sensor.plugin.change");
          addEventListener("app.event.sensor.messages.callout");
          addEventListener("app.event.sensor.command.change");
          addEventListener("app.event.sensor.reaction.change");
          addEventListener("app.event.sensor.trigger.change");
          
      }
  
      @Override
      protected void onStop() {
          LOG.info("RestAPI v3 plugin is stopped ");
          setDescription("Plugin stopped");
          try {
              jServer.stopServer();
          } catch (Exception ex) {
              LOG.error(ex.getMessage());
          }
      }
  
      @Override
      protected void onCommand(Command c) {
          LOG.info("RestAPI v3 plugin receives a command called {} with parameters {}", new Object[]{c.getName(), c.getProperties().toString()});
  
      }
  
      @Override
      protected boolean canExecute(Command c) {
          //don't mind this method for now
          throw new UnsupportedOperationException("Not supported yet.");
      }
  
      @Override
      protected void onEvent(EventTemplate event) {
          if (event instanceof ObjectHasChangedBehavior) {
              atmosphereObjectChangeResource.broadcast(event);
          } else if (event instanceof ZoneHasChanged) {
              atmosphereZoneChangeResource.broadcast(event);
          } else if (event instanceof PluginHasChanged) {
              atmospherePluginChangeResource.broadcast(event);
          } else if (event instanceof MessageEvent) {
              atmosphereMessageCalloutResource.broadcast(event);
          }
          // broadcast all events to AtmosphereEventResource
          atmosphereEventResource.broadcast(event);
      }
  
      public final void createDefaultWebSecurityManager() {
          defaultWebSecurityManager = new DefaultWebSecurityManager(this.getApi().getAuth().getUserRealm());
      }
  
  }
  