Package org.openhab.io.rest.internal.resources

Source Code of org.openhab.io.rest.internal.resources.ItemResource

/**
* Copyright (c) 2010-2014, openHAB.org and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.openhab.io.rest.internal.resources;

import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;

import javax.ws.rs.Consumes;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;

import org.atmosphere.annotation.Suspend.SCOPE;
import org.atmosphere.cpr.AtmosphereResource;
import org.atmosphere.cpr.BroadcasterFactory;
import org.atmosphere.cpr.HeaderConfig;
import org.atmosphere.jersey.SuspendResponse;
import org.openhab.core.items.GroupItem;
import org.openhab.core.items.Item;
import org.openhab.core.items.ItemNotFoundException;
import org.openhab.core.library.items.RollershutterItem;
import org.openhab.core.library.items.SwitchItem;
import org.openhab.core.library.types.OnOffType;
import org.openhab.core.library.types.UpDownType;
import org.openhab.core.types.Command;
import org.openhab.core.types.State;
import org.openhab.core.types.TypeParser;
import org.openhab.io.rest.RESTApplication;
import org.openhab.io.rest.internal.broadcaster.GeneralBroadcaster;
import org.openhab.io.rest.internal.listeners.ItemStateChangeListener;
import org.openhab.io.rest.internal.resources.beans.GroupItemBean;
import org.openhab.io.rest.internal.resources.beans.ItemBean;
import org.openhab.io.rest.internal.resources.beans.ItemListBean;
import org.openhab.ui.items.ItemUIRegistry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.sun.jersey.api.json.JSONWithPadding;

/**
* <p>This class acts as a REST resource for items and provides different methods to interact with them,
* like retrieving lists of items, sending commands to them or checking a single status.</p>
*
* <p>The typical content types are plain text for status values and XML or JSON(P) for more complex data
* structures</p>
*
* <p>This resource is registered with the Jersey servlet.</p>
*
* @author Kai Kreuzer
* @since 0.8.0
*/
@Path(ItemResource.PATH_ITEMS)
public class ItemResource {

  private static final Logger logger = LoggerFactory.getLogger(ItemResource.class);
 
  /** The URI path to this resource */
    public static final String PATH_ITEMS = "items";
   
  @Context UriInfo uriInfo;
  @GET
    @Produces( { MediaType.WILDCARD })
    public Response getItems(
        @Context HttpHeaders headers,
        @QueryParam("type") String type,
        @QueryParam("jsoncallback") @DefaultValue("callback") String callback) {
    logger.debug("Received HTTP GET request at '{}' for media type '{}'.", new String[] { uriInfo.getPath(), type });

    String responseType = MediaTypeHelper.getResponseMediaType(headers.getAcceptableMediaTypes(), type);
    if(responseType!=null) {
        Object responseObject = responseType.equals(MediaTypeHelper.APPLICATION_X_JAVASCRIPT) ?
            new JSONWithPadding(new ItemListBean(getItemBeans()), callback) : new ItemListBean(getItemBeans());
        return Response.ok(responseObject, responseType).build();
    } else {
      return Response.notAcceptable(null).build();
    }
    }

    @GET @Path("/{itemname: [a-zA-Z_0-9]*}/state")
  @Produces( { MediaType.TEXT_PLAIN })
    public SuspendResponse<String> getPlainItemState(
        @PathParam("itemname") String itemname,
        @HeaderParam(HeaderConfig.X_ATMOSPHERE_TRANSPORT) String atmosphereTransport,
        @Context AtmosphereResource resource) {
      if(atmosphereTransport==null || atmosphereTransport.isEmpty()) {
        Item item = getItem(itemname);
        if(item!=null) {
        logger.debug("Received HTTP GET request at '{}'.", uriInfo.getPath());
        throw new WebApplicationException(Response.ok(item.getState().toString()).build());
        } else {
          logger.info("Received HTTP GET request at '{}' for the unknown item '{}'.", uriInfo.getPath(), itemname);
          throw new WebApplicationException(404);
        }
    }
      GeneralBroadcaster itemBroadcaster = (GeneralBroadcaster) BroadcasterFactory.getDefault().lookup(GeneralBroadcaster.class, resource.getRequest().getPathInfo(), true);
    itemBroadcaster.addStateChangeListener(new ItemStateChangeListener());
    return new SuspendResponse.SuspendResponseBuilder<String>()
        .scope(SCOPE.REQUEST)
        .resumeOnBroadcast(!ResponseTypeHelper.isStreamingTransport(resource.getRequest()))
        .broadcaster(itemBroadcaster)
        .outputComments(true).build();
    }

    @GET @Path("/{itemname: [a-zA-Z_0-9]*}")
    @Produces( { MediaType.WILDCARD })
    public SuspendResponse<Response>  getItemData(
        @Context HttpHeaders headers,
        @PathParam("itemname") String itemname,
        @QueryParam("type") String type,
        @QueryParam("jsoncallback") @DefaultValue("callback") String callback,
        @HeaderParam(HeaderConfig.X_ATMOSPHERE_TRANSPORT) String atmosphereTransport,
        @Context AtmosphereResource resource) {
    logger.debug("Received HTTP GET request at '{}' for media type '{}'.", new String[] { uriInfo.getPath(), type });
    if(atmosphereTransport==null || atmosphereTransport.isEmpty()) {
      final String responseType = MediaTypeHelper.getResponseMediaType(headers.getAcceptableMediaTypes(), type);
      if(responseType!=null) {
          final Object responseObject = responseType.equals(MediaTypeHelper.APPLICATION_X_JAVASCRIPT) ?
              new JSONWithPadding(getItemDataBean(itemname), callback) : getItemDataBean(itemname);
          throw new WebApplicationException(Response.ok(responseObject, responseType).build())
   
      } else {
        throw new WebApplicationException(Response.notAcceptable(null).build());
      }
    }
   
    GeneralBroadcaster itemBroadcaster = (GeneralBroadcaster) BroadcasterFactory.getDefault().lookup(GeneralBroadcaster.class, resource.getRequest().getPathInfo(), true);
    itemBroadcaster.addStateChangeListener(new ItemStateChangeListener());
   
    return new SuspendResponse.SuspendResponseBuilder<Response>()
          .scope(SCOPE.REQUEST)
          .resumeOnBroadcast(!ResponseTypeHelper.isStreamingTransport(resource.getRequest()))
          .broadcaster(itemBroadcaster)
          .outputComments(true).build();
    }
   
    @PUT @Path("/{itemname: [a-zA-Z_0-9]*}/state")
  @Consumes(MediaType.TEXT_PLAIN
  public Response putItemState(@PathParam("itemname") String itemname, String value) {
      Item item = getItem(itemname);
      if(item!=null) {
        State state = TypeParser.parseState(item.getAcceptedDataTypes(), value);
        if(state!=null) {
          logger.debug("Received HTTP PUT request at '{}' with value '{}'.", uriInfo.getPath(), value);
          RESTApplication.getEventPublisher().postUpdate(itemname, state);
          return Response.ok().build();
        } else {
          logger.warn("Received HTTP PUT request at '{}' with an invalid status value '{}'.", uriInfo.getPath(), value);
          return Response.status(Status.BAD_REQUEST).build();
        }
      } else {
        logger.info("Received HTTP PUT request at '{}' for the unknown item '{}'.", uriInfo.getPath(), itemname);
        throw new WebApplicationException(404);
      }
  }

  @Context UriInfo localUriInfo;
    @POST @Path("/{itemname: [a-zA-Z_0-9]*}")
  @Consumes(MediaType.TEXT_PLAIN
  public Response postItemCommand(@PathParam("itemname") String itemname, String value) {
      Item item = getItem(itemname);
      Command command = null;
      if(item!=null) {
        // support for TOGGLE, see https://code.google.com/p/openhab/issues/detail?id=336
        if("toggle".equalsIgnoreCase(value) &&
            (item instanceof SwitchItem ||
             item instanceof RollershutterItem)) {
          if(OnOffType.ON.equals(item.getStateAs(OnOffType.class))) command = OnOffType.OFF;
          if(OnOffType.OFF.equals(item.getStateAs(OnOffType.class))) command = OnOffType.ON;
          if(UpDownType.UP.equals(item.getStateAs(UpDownType.class))) command = UpDownType.DOWN;
          if(UpDownType.DOWN.equals(item.getStateAs(UpDownType.class))) command = UpDownType.UP;
        } else {
          command = TypeParser.parseCommand(item.getAcceptedCommandTypes(), value);
        }
        if(command!=null) {
          logger.debug("Received HTTP POST request at '{}' with value '{}'.", uriInfo.getPath(), value);
          RESTApplication.getEventPublisher().postCommand(itemname, command);
          return Response.created(localUriInfo.getAbsolutePathBuilder().path("state").build()).build();
        } else {
          logger.warn("Received HTTP POST request at '{}' with an invalid status value '{}'.", uriInfo.getPath(), value);
          return Response.status(Status.BAD_REQUEST).build();
        }
      } else {
        logger.info("Received HTTP POST request at '{}' for the unknown item '{}'.", uriInfo.getPath(), itemname);
        throw new WebApplicationException(404);
      }
  }

    public static ItemBean createItemBean(Item item, boolean drillDown, String uriPath) {
      ItemBean bean;
      if(item instanceof GroupItem && drillDown) {
        GroupItem groupItem = (GroupItem) item;
        GroupItemBean groupBean = new GroupItemBean();
        Collection<ItemBean> members = new HashSet<ItemBean>();
        for(Item member : groupItem.getMembers()) {
          members.add(createItemBean(member, false, uriPath));
        }
        groupBean.members = members.toArray(new ItemBean[members.size()]);
        bean = groupBean;
      } else {
         bean = new ItemBean();
      }
      bean.name = item.getName();
      bean.state = item.getState().toString();
      bean.type = item.getClass().getSimpleName();
      bean.link = UriBuilder.fromUri(uriPath).path(ItemResource.PATH_ITEMS).path(bean.name).build().toASCIIString();
     
      return bean;
    }
   
    static public Item getItem(String itemname) {
        ItemUIRegistry registry = RESTApplication.getItemUIRegistry();
        if(registry!=null) {
          try {
        Item item = registry.getItem(itemname);
        return item;
      } catch (ItemNotFoundException e) {
        logger.debug(e.getMessage());
      }
        }
        return null;
    }

  private List<ItemBean> getItemBeans() {
    List<ItemBean> beans = new LinkedList<ItemBean>();
    ItemUIRegistry registry = RESTApplication.getItemUIRegistry();
    for(Item item : registry.getItems()) {
      beans.add(createItemBean(item, false, uriInfo.getBaseUri().toASCIIString()));
    }
    return beans;
  }

  private ItemBean getItemDataBean(String itemname) {
    Item item = getItem(itemname);
    if(item!=null) {
      return createItemBean(item, true, uriInfo.getBaseUri().toASCIIString());
    } else {
      logger.info("Received HTTP GET request at '{}' for the unknown item '{}'.", uriInfo.getPath(), itemname);
      throw new WebApplicationException(404);
    }
  }
}
TOP

Related Classes of org.openhab.io.rest.internal.resources.ItemResource

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.