/**
* Copyright (c) 2014-2017 by the respective copyright holders.
* 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.eclipse.smarthome.io.rest.core.link;
import java.util.ArrayList;
import java.util.Collection;
import javax.annotation.security.RolesAllowed;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.core.UriInfo;
import org.eclipse.smarthome.core.auth.Role;
import org.eclipse.smarthome.core.thing.ChannelUID;
import org.eclipse.smarthome.core.thing.link.AbstractLink;
import org.eclipse.smarthome.core.thing.link.ItemChannelLink;
import org.eclipse.smarthome.core.thing.link.ItemChannelLinkRegistry;
import org.eclipse.smarthome.core.thing.link.ThingLinkManager;
import org.eclipse.smarthome.core.thing.link.dto.AbstractLinkDTO;
import org.eclipse.smarthome.core.thing.link.dto.ItemChannelLinkDTO;
import org.eclipse.smarthome.io.rest.JSONResponse;
import org.eclipse.smarthome.io.rest.SatisfiableRESTResource;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
/**
* This class acts as a REST resource for links.
*
* @author Dennis Nobel - Initial contribution
* @author Yordan Zhelev - Added Swagger annotations
* @author Kai Kreuzer - Removed Thing links and added auto link url
* @author Franck Dechavanne - Added DTOs to ApiResponses
*/
@Path(ItemChannelLinkResource.PATH_LINKS)
@RolesAllowed({ Role.ADMIN })
@Api(value = ItemChannelLinkResource.PATH_LINKS)
public class ItemChannelLinkResource implements SatisfiableRESTResource {
/** The URI path to this resource */
public static final String PATH_LINKS = "links";
private ItemChannelLinkRegistry itemChannelLinkRegistry;
private ThingLinkManager thingLinkManager;
@Context
UriInfo uriInfo;
@GET
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation(value = "Gets all available links.", response = ItemChannelLinkDTO.class, responseContainer = "Collection")
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK", response = ItemChannelLinkDTO.class, responseContainer = "Collection") })
public Response getAll() {
Collection<ItemChannelLink> channelLinks = itemChannelLinkRegistry.getAll();
return Response.ok(toBeans(channelLinks)).build();
}
@GET
@Path("/auto")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation(value = "Tells whether automatic link mode is active or not", response = Boolean.class)
@ApiResponses(value = { @ApiResponse(code = 200, message = "OK", response = Boolean.class) })
public Response isAutomatic() {
return Response.ok(thingLinkManager.isAutoLinksEnabled()).build();
}
@PUT
@Path("/{itemName}/{channelUID}")
@ApiOperation(value = "Links item to a channel.")
@ApiResponses(value = { @ApiResponse(code = 200, message = "OK"),
@ApiResponse(code = 400, message = "Item already linked to the channel.") })
public Response link(@PathParam("itemName") @ApiParam(value = "itemName") String itemName,
@PathParam("channelUID") @ApiParam(value = "channelUID") String channelUid) {
itemChannelLinkRegistry.add(new ItemChannelLink(itemName, new ChannelUID(channelUid)));
return Response.ok().build();
}
@DELETE
@Path("/{itemName}/{channelUID}")
@ApiOperation(value = "Unlinks item from a channel.")
@ApiResponses(value = { @ApiResponse(code = 200, message = "OK"),
@ApiResponse(code = 404, message = "Link not found."),
@ApiResponse(code = 405, message = "Link not editable.") })
public Response unlink(@PathParam("itemName") @ApiParam(value = "itemName") String itemName,
@PathParam("channelUID") @ApiParam(value = "channelUID") String channelUid) {
String linkId = AbstractLink.getIDFor(itemName, new ChannelUID(channelUid));
if (itemChannelLinkRegistry.get(linkId) == null) {
String message = "Link " + linkId + " does not exist!";
return JSONResponse.createResponse(Status.NOT_FOUND, null, message);
}
ItemChannelLink result = itemChannelLinkRegistry
.remove(AbstractLink.getIDFor(itemName, new ChannelUID(channelUid)));
if (result != null) {
return Response.ok().build();
} else {
return JSONResponse.createErrorResponse(Status.METHOD_NOT_ALLOWED, "Channel is read-only.");
}
}
protected void setThingLinkManager(ThingLinkManager thingLinkManager) {
this.thingLinkManager = thingLinkManager;
}
protected void unsetThingLinkManager(ThingLinkManager thingLinkManager) {
this.thingLinkManager = null;
}
protected void setItemChannelLinkRegistry(ItemChannelLinkRegistry itemChannelLinkRegistry) {
this.itemChannelLinkRegistry = itemChannelLinkRegistry;
}
protected void unsetItemChannelLinkRegistry(ItemChannelLinkRegistry itemChannelLinkRegistry) {
this.itemChannelLinkRegistry = null;
}
private Collection<AbstractLinkDTO> toBeans(Iterable<ItemChannelLink> links) {
Collection<AbstractLinkDTO> beans = new ArrayList<>();
for (AbstractLink link : links) {
ItemChannelLinkDTO bean = new ItemChannelLinkDTO(link.getItemName(), link.getUID().toString());
beans.add(bean);
}
return beans;
}
@Override
public boolean isSatisfied() {
return itemChannelLinkRegistry != null && thingLinkManager != null;
}
}