/**
  * View details about a batch command invocation.
  *
  * @param batchToken
  * @param request
  * @return
  */
 @RequestMapping("/batch/command/{token}")
 public ModelAndView batchCommandInvocationDetail(
     @PathVariable("token") String batchToken, HttpServletRequest request) {
   Tracer.start(TracerCategory.AdminUserInterface, "batchCommandInvocationDetail", LOGGER);
   try {
     Map<String, Object> data = createBaseData(request);
     ITenant tenant = (ITenant) data.get(DATA_TENANT);
     IDeviceManagement management = SiteWhere.getServer().getDeviceManagement(tenant);
     IBatchOperation operation = management.getBatchOperation(batchToken);
     if (operation != null) {
       data.put("operation", operation);
       String commandToken =
           operation.getParameters().get(IBatchCommandInvocationRequest.PARAM_COMMAND_TOKEN);
       if (commandToken == null) {
         return showError("No command token set for batch operation.");
       }
       IDeviceCommand command = management.getDeviceCommandByToken(commandToken);
       data.put("command", new String(MarshalUtils.marshalJsonAsString(command)));
       return new ModelAndView("batch/command", data);
     }
     return showError("Batch operation for token '" + batchToken + "' not found.");
   } catch (NoTenantException e) {
     return showTenantChoices(getUrl(request), request);
   } catch (SiteWhereException e) {
     return showError(e);
   } finally {
     Tracer.stop(LOGGER);
   }
 }
 /**
  * Display the "device detail" page.
  *
  * @param hardwareId
  * @param request
  * @return
  */
 @RequestMapping("/devices/{hardwareId}")
 public ModelAndView deviceDetail(
     @PathVariable("hardwareId") String hardwareId, HttpServletRequest request) {
   Tracer.start(TracerCategory.AdminUserInterface, "deviceDetail", LOGGER);
   try {
     Map<String, Object> data = createBaseData(request);
     ITenant tenant = (ITenant) data.get(DATA_TENANT);
     IDeviceManagement management = SiteWhere.getServer().getDeviceManagement(tenant);
     IDevice device = management.getDeviceByHardwareId(hardwareId);
     if (device != null) {
       IDeviceSpecification specification =
           management.getDeviceSpecificationByToken(device.getSpecificationToken());
       data.put("device", device);
       data.put("specification", specification);
       return new ModelAndView("devices/detail", data);
     }
     return showError("Device for hardware id '" + hardwareId + "' not found.");
   } catch (NoTenantException e) {
     return showTenantChoices(getUrl(request), request);
   } catch (SiteWhereException e) {
     return showError(e);
   } finally {
     Tracer.stop(LOGGER);
   }
 }
 /**
  * Display the "assignment detail" page.
  *
  * @param token
  * @param request
  * @return
  */
 @RequestMapping("/assignments/{token}")
 public ModelAndView assignmentDetail(
     @PathVariable("token") String token, HttpServletRequest request) {
   Tracer.start(TracerCategory.AdminUserInterface, "assignmentDetail", LOGGER);
   try {
     Map<String, Object> data = createBaseData(request);
     ITenant tenant = (ITenant) data.get(DATA_TENANT);
     IDeviceManagement management = SiteWhere.getServer().getDeviceManagement(tenant);
     IDeviceAssignment assignment = management.getDeviceAssignmentByToken(token);
     if (assignment != null) {
       DeviceAssignmentMarshalHelper helper = new DeviceAssignmentMarshalHelper(tenant);
       helper.setIncludeDevice(true);
       assignment =
           helper.convert(assignment, SiteWhere.getServer().getAssetModuleManager(tenant));
       data.put("assignment", assignment);
       return new ModelAndView("assignments/detail", data);
     }
     return showError("Assignment for token '" + token + "' not found.");
   } catch (NoTenantException e) {
     return showTenantChoices(getUrl(request), request);
   } catch (SiteWhereException e) {
     return showError(e);
   } finally {
     Tracer.stop(LOGGER);
   }
 }
  /**
   * Create the server.
   *
   * @throws SiteWhereException
   */
  public void create() throws SiteWhereException {
    LOGGER.info("Initializing SiteWhere server components.");
    File sitewhereConf = getSiteWhereConfigFolder();

    // Load server configuration.
    LOGGER.info("Loading Spring configuration ...");
    File serverConfigFile = new File(sitewhereConf, SERVER_CONFIG_FILE_NAME);
    if (!serverConfigFile.exists()) {
      throw new SiteWhereException(
          "SiteWhere server configuration not found: " + serverConfigFile.getAbsolutePath());
    }
    SERVER_SPRING_CONTEXT = loadServerApplicationContext(serverConfigFile);

    // Load device management and wrap it for metrics.
    IDeviceManagement deviceManagementImpl =
        (IDeviceManagement)
            SERVER_SPRING_CONTEXT.getBean(SiteWhereServerBeans.BEAN_DEVICE_MANAGEMENT);
    if (deviceManagementImpl == null) {
      throw new SiteWhereException("No device management implementation configured.");
    }
    DeviceManagementMetricsFacade facade = new DeviceManagementMetricsFacade();
    facade.setDelegate(deviceManagementImpl);
    deviceManagement = facade;
    deviceManagement.start();

    // Load user management.
    userManagement =
        (IUserManagement) SERVER_SPRING_CONTEXT.getBean(SiteWhereServerBeans.BEAN_USER_MANAGEMENT);
    if (userManagement == null) {
      throw new SiteWhereException("No user management implementation configured.");
    }
    userManagement.start();

    // Load the asset module manager.
    assetModuleManager =
        (IAssetModuleManager)
            SERVER_SPRING_CONTEXT.getBean(SiteWhereServerBeans.BEAN_ASSET_MODULE_MANAGER);
    if (assetModuleManager == null) {
      throw new SiteWhereException("No asset module manager implementation configured.");
    }

    // Print version information.
    IVersion version = VersionHelper.getVersion();
    List<String> messages = new ArrayList<String>();
    messages.add("SiteWhere Server");
    messages.add("");
    messages.add("Version: " + version.getVersionIdentifier() + "." + version.getBuildTimestamp());
    messages.add("");
    messages.add("Copyright (c) 2013 Reveal Technologies, LLC");
    String message = StringMessageUtils.getBoilerPlate(messages, '*', 60);
    LOGGER.info("\n" + message + "\n");

    verifyUserModel();
    verifyDeviceModel();
  }
 /**
  * Display the "device group detail" page.
  *
  * @param groupToken
  * @param request
  * @return
  */
 @RequestMapping("/groups/{groupToken}")
 public ModelAndView deviceGroupDetail(
     @PathVariable("groupToken") String groupToken, HttpServletRequest request) {
   Tracer.start(TracerCategory.AdminUserInterface, "deviceGroupDetail", LOGGER);
   try {
     Map<String, Object> data = createBaseData(request);
     ITenant tenant = (ITenant) data.get(DATA_TENANT);
     IDeviceManagement management = SiteWhere.getServer().getDeviceManagement(tenant);
     IDeviceGroup group = management.getDeviceGroup(groupToken);
     if (group != null) {
       data.put("group", group);
       return new ModelAndView("groups/detail", data);
     }
     return showError("Device group for token '" + groupToken + "' not found.");
   } catch (NoTenantException e) {
     return showTenantChoices(getUrl(request), request);
   } catch (SiteWhereException e) {
     return showError(e);
   } finally {
     Tracer.stop(LOGGER);
   }
 }
 /**
  * Display the "specification detail" page.
  *
  * @param token
  * @param request
  * @return
  */
 @RequestMapping("/specifications/{token}")
 public ModelAndView specificationDetail(
     @PathVariable("token") String token, HttpServletRequest request) {
   Tracer.start(TracerCategory.AdminUserInterface, "specificationDetail", LOGGER);
   try {
     Map<String, Object> data = createBaseData(request);
     ITenant tenant = (ITenant) data.get(DATA_TENANT);
     IDeviceManagement management = SiteWhere.getServer().getDeviceManagement(tenant);
     IDeviceSpecification spec = management.getDeviceSpecificationByToken(token);
     if (spec != null) {
       data.put("specification", spec);
       return new ModelAndView("specifications/detail", data);
     }
     return showError("Specification for token '" + token + "' not found.");
   } catch (NoTenantException e) {
     return showTenantChoices(getUrl(request), request);
   } catch (SiteWhereException e) {
     return showError(e);
   } finally {
     Tracer.stop(LOGGER);
   }
 }