/**
  * Handles the "restoreOnStartup" strategy for the item. If the item state is still undefined when
  * entering this method, all persistence configurations are checked, if they have the
  * "restoreOnStartup" strategy configured for the item. If so, the item state will be set to its
  * last persisted value.
  *
  * @param item the item to restore the state for
  */
 protected void initialize(Item item) {
   // get the last persisted state from the persistence service if no state is yet set
   if (item.getState().equals(UnDefType.NULL) && item instanceof GenericItem) {
     for (Entry<String, List<PersistenceConfiguration>> entry :
         persistenceConfigurations.entrySet()) {
       String serviceName = entry.getKey();
       for (PersistenceConfiguration config : entry.getValue()) {
         if (hasStrategy(serviceName, config, GlobalStrategies.RESTORE)) {
           if (appliesToItem(config, item)) {
             PersistenceService service = persistenceServices.get(serviceName);
             if (service instanceof QueryablePersistenceService) {
               QueryablePersistenceService queryService = (QueryablePersistenceService) service;
               FilterCriteria filter =
                   new FilterCriteria().setItemName(item.getName()).setPageSize(1);
               Iterable<HistoricItem> result = queryService.query(filter);
               Iterator<HistoricItem> it = result.iterator();
               if (it.hasNext()) {
                 HistoricItem historicItem = it.next();
                 GenericItem genericItem = (GenericItem) item;
                 genericItem.removeStateChangeListener(this);
                 genericItem.setState(historicItem.getState());
                 genericItem.addStateChangeListener(this);
                 logger.debug(
                     "Restored item state from '{}' for item '{}' -> '{}'",
                     new Object[] {
                       DateFormat.getDateTimeInstance().format(historicItem.getTimestamp()),
                       item.getName(),
                       historicItem.getState().toString()
                     });
                 return;
               }
             } else if (service != null) {
               logger.warn(
                   "Failed to restore item states as persistence service '{}' can not be queried.",
                   serviceName);
             }
           }
         }
       }
     }
   }
 }
  public Object getPersistenceSeries(
      QueryablePersistenceService persistenceService,
      Item item,
      Date timeBegin,
      Date timeEnd,
      long resolution) {
    Map<Long, ArrayList<String>> data = new HashMap<Long, ArrayList<String>>();

    // Define the data filter
    FilterCriteria filter = new FilterCriteria();
    filter.setBeginDate(timeBegin);
    filter.setEndDate(timeEnd);
    filter.setItemName(item.getName());
    filter.setOrdering(Ordering.ASCENDING);

    // Get the data from the persistence store
    Iterable<HistoricItem> result = persistenceService.query(filter);
    Iterator<HistoricItem> it = result.iterator();

    // Iterate through the data
    int dataCounter = 0;
    while (it.hasNext()) {
      dataCounter++;
      HistoricItem historicItem = it.next();
      org.eclipse.smarthome.core.types.State state = historicItem.getState();
      if (state instanceof DecimalType) {
        ArrayList<String> vals = new ArrayList<String>();
        vals.add(formatDouble(((DecimalType) state).doubleValue(), "null", true));
        data.put(historicItem.getTimestamp().getTime(), vals);
      }
    }
    logger.debug(
        "'{}' querying item '{}' from '{}' to '{}' => '{}' results",
        persistenceService.getId(),
        filter.getItemName(),
        filter.getBeginDate(),
        filter.getEndDate(),
        dataCounter);
    return convertToRrd(data);
  }
  @GET
  @Produces({MediaType.APPLICATION_JSON})
  public Response getChartSeries(
      @Context HttpHeaders headers,
      @QueryParam("rrd") String itemName,
      @QueryParam("ds") String consFunction,
      @QueryParam("start") String start,
      @QueryParam("end") String end,
      @QueryParam("res") long resolution) {
    if (logger.isDebugEnabled()) {
      logger.debug("Received GET request at '{}' for rrd '{}'.", uriInfo.getPath(), itemName);
    }
    String responseType = MediaType.APPLICATION_JSON;

    // RRD specific: no equivalent in PersistenceService known
    ConsolFun consilidationFunction = ConsolFun.valueOf(consFunction);

    // read the start/end time as they are provided in the RRD-way, we use
    // the RRD4j to read them
    long[] times = Util.getTimestamps(start, end);
    Date startTime = new Date();
    startTime.setTime(times[0] * 1000L);
    Date endTime = new Date();
    endTime.setTime(times[1] * 1000L);

    if (itemName.endsWith(".rrd")) {
      itemName = itemName.substring(0, itemName.length() - 4);
    }
    String[] parts = itemName.split(":");
    String service = "rrd4j";

    if (parts.length == 2) {
      itemName = parts[1];
      service = parts[0];
    }

    Item item;
    try {
      item = itemRegistry.getItem(itemName);
      logger.debug("item '{}' found ", item);

      // Prefer RRD-Service
      QueryablePersistenceService persistenceService = getPersistenceServices().get(service);
      // Fallback to first persistenceService from list
      if (persistenceService == null) {
        Iterator<Entry<String, QueryablePersistenceService>> pit =
            getPersistenceServices().entrySet().iterator();
        if (pit.hasNext()) {
          persistenceService = pit.next().getValue();
        } else {
          throw new IllegalArgumentException("No Persistence service found.");
        }
      }
      Object data = null;
      if (persistenceService.getId().equals("rrd4j")) {
        data =
            getRrdSeries(
                persistenceService, item, consilidationFunction, startTime, endTime, resolution);
      } else {
        data = getPersistenceSeries(persistenceService, item, startTime, endTime, resolution);
      }
      return Response.ok(data, responseType).build();
    } catch (ItemNotFoundException e1) {
      logger.error("Item '{}' not found error while requesting series data.", itemName);
    }
    return Response.serverError().build();
  }