/******************************************************************************* * Copyright (c) 2013-2015 Sierra Wireless and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * and Eclipse Distribution License v1.0 which accompany this distribution. * * The Eclipse Public License is available at * http://www.eclipse.org/legal/epl-v10.html * and the Eclipse Distribution License is available at * http://www.eclipse.org/org/documents/edl-v10.html. * * Contributors: * Sierra Wireless - initial API and implementation *******************************************************************************/ package org.eclipse.leshan.core.request; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; import org.eclipse.leshan.core.node.LwM2mObjectInstance; import org.eclipse.leshan.core.node.LwM2mPath; import org.eclipse.leshan.core.node.LwM2mResource; import org.eclipse.leshan.core.request.exception.InvalidRequestException; import org.eclipse.leshan.core.response.CreateResponse; /** * A Lightweight M2M request for creating Object Instance(s) within the LWM2M Client. */ public class CreateRequest extends AbstractDownlinkRequest<CreateResponse> { private final Integer instanceId; private final List<LwM2mResource> resources; private final ContentFormat contentFormat; // ***************** constructors without object instance id ******************* / /** * Creates a request for creating an instance of a particular object without specifying the id of this new instance. * The id will be chosen by the client and accessible in the CreateResponse. * * @param contentFormat the payload format * @param objectId the object id * @param resources the resource values for the new instance * @exception InvalidRequestException if bad @{link ContentFormat} format was used. */ public CreateRequest(ContentFormat contentFormat, int objectId, LwM2mResource... resources) throws InvalidRequestException { this(contentFormat, new LwM2mPath(objectId), null, resources); } /** * Creates a request for creating an instance of a particular object without specifying the id of this new instance * and using the TLV content format. The id will be chosen by the client and accessible in the CreateResponse. * * @param objectId the object id * @param resources the resource values for the new instance */ public CreateRequest(int objectId, LwM2mResource... resources) { this(null, new LwM2mPath(objectId), null, resources); } /** * Creates a request for creating an instance of a particular object without specifying the id of this new instance. * The id will be chosen by the client and accessible in the CreateResponse. * * @param contentFormat the payload format * @param objectId the object id * @param resources the resource values for the new instance * @exception InvalidRequestException if bad @{link ContentFormat} format was used. */ public CreateRequest(ContentFormat contentFormat, int objectId, Collection<LwM2mResource> resources) throws InvalidRequestException { this(contentFormat, objectId, resources.toArray(new LwM2mResource[resources.size()])); } /** * Creates a request for creating an instance of a particular object without specifying the id of this new instance * and using the TLV content format. The id will be chosen by the client and accessible in the CreateResponse. * * @param objectId the object id * @param resources the resource values for the new instance */ public CreateRequest(int objectId, Collection<LwM2mResource> resources) { this(objectId, resources.toArray(new LwM2mResource[resources.size()])); } // ***************** constructor with object instance ******************* / /** * Creates a request for creating an instance of a particular object. * * @param contentFormat the payload format * @param objectId the object id * @param instance the object instance * @exception InvalidRequestException if bad @{link ContentFormat} format was used. */ public CreateRequest(ContentFormat contentFormat, int objectId, LwM2mObjectInstance instance) throws InvalidRequestException { this(contentFormat, new LwM2mPath(objectId), instance.getId(), instance.getResources().values().toArray(new LwM2mResource[0])); } /** * Creates a request for creating an instance of a particular object using the TLV content format. * * @param objectId the object id * @param instance the object instance */ public CreateRequest(int objectId, LwM2mObjectInstance instance) { this(null, objectId, instance); } // ***************** string path constructor ******************* / /** * Creates a request for creating an instance of a particular object using the default TLV content format.<br> * If the path is an object path, the instance id will be chosen by the client and accessible in the CreateResponse. * To choose instance id at server side, the path must be an object instance path. * * @param path the target path (object or object instance) * @param resources the resource values for the new instance * @exception InvalidRequestException if the target path is not valid. */ public CreateRequest(String path, Collection<LwM2mResource> resources) throws InvalidRequestException { this(path, resources.toArray(new LwM2mResource[resources.size()])); } /** * Creates a request for creating an instance of a particular object.<br> * If the path is an object path, the instance id will be chosen by the client and accessible in the CreateResponse. * To choose instance id at server side, the path must be an object instance path. * * @param contentFormat the payload format (TLV or JSON) * @param path the target path (object or object instance) * @param resources the resource values for the new instance * @exception InvalidRequestException if parameters are invalid. */ public CreateRequest(ContentFormat contentFormat, String path, Collection<LwM2mResource> resources) throws InvalidRequestException { this(contentFormat, path, resources.toArray(new LwM2mResource[resources.size()])); } /** * Creates a request for creating an instance of a particular object using the default TLV content format.<br> * If the path is an object path, the instance id will be chosen by the client and accessible in the CreateResponse. * To choose instance id at server side, the path must be an object instance path. * * @param path the target path (object or object instance) * @param resources the resource values for the new instance * @exception InvalidRequestException if the target path is not valid. */ public CreateRequest(String path, LwM2mResource... resources) throws InvalidRequestException { this(null, newPath(path), null, resources); } /** * Creates a request for creating an instance of a particular object.<br> * If the path is an object path, the instance id will be chosen by the client and accessible in the CreateResponse. * To choose instance id at server side, the path must be an object instance path. * * @param contentFormat the payload format (TLV or JSON) * @param path the target path (object or object instance) * @param resources the resource values for the new instance * @exception InvalidRequestException if parameters are invalid. */ public CreateRequest(ContentFormat contentFormat, String path, LwM2mResource... resources) throws InvalidRequestException { this(contentFormat, newPath(path), null, resources); } /** * Creates a request for creating an instance of a particular object.<br> * If the path is an object path, the instance id will be chosen by the client and accessible in the CreateResponse. * To choose instance id at server side, the path must be an object instance path. * * @param path the target path (object or object instance) * @param instance the object instance * @exception InvalidRequestException if the target path is not valid. */ public CreateRequest(String path, LwM2mObjectInstance instance) throws InvalidRequestException { this(null, newPath(path), instance.getId(), instance.getResources().values().toArray((new LwM2mResource[instance.getResources().size()]))); } /** * Creates a request for creating an instance of a particular object.<br> * If the path is an object path, the instance id will be chosen by the client and accessible in the CreateResponse. * To choose instance id at server side, the path must be an object instance path. * * @param contentFormat the payload format (TLV or JSON) * @param path the target path (object or object instance) * @param instance the object instance * @exception InvalidRequestException if parameters are invalid. */ public CreateRequest(ContentFormat contentFormat, String path, LwM2mObjectInstance instance) throws InvalidRequestException { this(contentFormat, newPath(path), instance.getId(), instance.getResources().values().toArray((new LwM2mResource[instance.getResources().size()]))); } // ***************** generic constructor ******************* / private CreateRequest(ContentFormat format, LwM2mPath target, Integer instanceId, LwM2mResource[] resources) { super(target); // accept only object and object instance path if (!target.isObject() && !target.isObjectInstance()) throw new InvalidRequestException( "Invalid path %s: Create request must not target an object or object instance", target); // validate instance id if (instanceId != null && instanceId == LwM2mObjectInstance.UNDEFINED) { instanceId = null; } if (target.isObjectInstance()) { if (instanceId == null) { instanceId = target.getObjectInstanceId(); } else { if (!instanceId.equals(target.getObjectInstanceId())) { throw new InvalidRequestException("Conflict between path instance id %s and node instance id %s", target, instanceId); } } } if (instanceId != null && instanceId < 0) throw new InvalidRequestException("Invalid instance id %s for path %s ", instanceId, target); // store attributes this.instanceId = instanceId; this.resources = Collections.unmodifiableList(Arrays.asList(resources)); this.contentFormat = format != null ? format : ContentFormat.TLV; // default to TLV } @Override public void accept(DownlinkRequestVisitor visitor) { visitor.visit(this); } public List<LwM2mResource> getResources() { return resources; } /** * @return the id of the new instance. <code>null</code> if not assigned by the server. */ public Integer getInstanceId() { return instanceId; } public ContentFormat getContentFormat() { return contentFormat; } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("CreateRequest [").append(getPath()).append("]"); return builder.toString(); } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + ((contentFormat == null) ? 0 : contentFormat.hashCode()); result = prime * result + ((instanceId == null) ? 0 : instanceId.hashCode()); result = prime * result + ((resources == null) ? 0 : resources.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (!super.equals(obj)) return false; if (getClass() != obj.getClass()) return false; CreateRequest other = (CreateRequest) obj; if (contentFormat != other.contentFormat) return false; if (instanceId == null) { if (other.instanceId != null) return false; } else if (!instanceId.equals(other.instanceId)) return false; if (resources == null) { if (other.resources != null) return false; } else if (!resources.equals(other.resources)) return false; return true; } }