/**
* Copyright (C) 2010-14 diirt developers. See COPYRIGHT.TXT
* All rights reserved. Use is subject to license terms. See LICENSE.TXT
*/
package org.diirt.service;
import java.util.ArrayList;
import java.util.List;
import static org.diirt.service.Service.namePattern;
import org.diirt.service.ServiceMethod.DataDescription;
/**
* A utility class to gather all the elements that define the service method.
* <p>
* This class is not thread-safe and is meant to be used right before
* the creation of {@link ServiceMethod} objects.
*
* @author carcassi
*/
public abstract class ServiceMethodDescription {
// Access is package private so we don't even bother creating accessors for
// these
String name;
String description;
List<ServiceMethod.DataDescription> arguments = new ArrayList<>();
List<ServiceMethod.DataDescription> results = new ArrayList<>();
/**
* Creates a new service method description with the given name and description,
* both of which are mandatory attributes of the service methods.
*
* @param name the service method name, can't be null or empty
* @param description the service method description, can't be null or empty
*/
public ServiceMethodDescription(String name, String description) {
// Validate the parameters (non-null and non-empty)
if (name == null){
throw new NullPointerException("Name must not be null");
}
if (description == null){
throw new NullPointerException("Description must not be null");
}
if (name.isEmpty()){
throw new IllegalArgumentException("Name must not be empty");
}
if (description.isEmpty()){
throw new IllegalArgumentException("Description must not be empty");
}
this.name = name;
this.description = description;
if (!namePattern.matcher(name).matches()) {
throw new IllegalArgumentException("Name must start by a letter and only consist of letters and numbers");
}
}
/**
* Adds an argument for this method, with the given name, description and type.
* The order in which arguments are added is retained as the preferred order
* of arguments for the service method.
*
* @param name a short argument name; can't be null or empty
* @param description a meaningful description; can't be null or empty
* @param type the type of the argument
* @return this description
*/
public ServiceMethodDescription addArgument(String name, String description, Class<?> type) {
// Validate the parameters (non-null and non-empty)
if (name == null){
throw new NullPointerException("Name must not be null");
}
if (description == null){
throw new NullPointerException("Description must not be null");
}
if (name.isEmpty()){
throw new IllegalArgumentException("Name must not be empty");
}
if (description.isEmpty()){
throw new IllegalArgumentException("Description must not be empty");
}
// Ensures the name makes sense (matches the pattern)
if (!namePattern.matcher(name).matches()) {
throw new IllegalArgumentException("Name must start by a letter and only consist of letters and numbers");
}
// Throws exception if parameter has a duplicate name of an argument
if (arguments.stream().anyMatch((DataDescription t) -> {
return t.getName().equals(name);
})) {
throw new IllegalArgumentException("Argument with name \'" + name + "\' already exists");
}
ServiceMethod.DataDescription dataDescription = new ServiceMethod.DataDescription(name, description, type);
arguments.add(dataDescription);
return this;
}
/**
* Adds a result for this method, with the given name, description and type.
* The order in which results are added is retained as the preferred order
* of arguments for the service method.
*
* @param name a short result name; can't be null
* @param description a meaningful description; can't be null
* @param type the type of the result
* @return this description
*/
public ServiceMethodDescription addResult(String name, String description, Class<?> type) {
// Validate the parameters (non-null and non-empty)
if (name == null){
throw new NullPointerException("Name must not be null");
}
if (description == null){
throw new NullPointerException("Description must not be null");
}
if (name.isEmpty()){
throw new IllegalArgumentException("Name must not be empty");
}
if (description.isEmpty()){
throw new IllegalArgumentException("Description must not be empty");
}
// Ensures the name makes sense (matches the pattern)
if (!namePattern.matcher(name).matches()) {
throw new IllegalArgumentException("Name must start by a letter and only consist of letters and numbers");
}
// Throws exception if parameter has a duplicate name of an argument
if (results.stream().anyMatch((DataDescription t) -> {
return t.getName().equals(name);
})) {
throw new IllegalArgumentException("Result with name \'" + name + "\' already exists");
}
ServiceMethod.DataDescription dataDescription = new ServiceMethod.DataDescription(name, description, type);
results.add(dataDescription);
return this;
}
/**
* Creates a service method with the given description.
* <p>
* A client should implement this to return their service
* method implementation.
*
* @param serviceDescription service description for the new service method
* @return a new service method
*/
public abstract ServiceMethod createServiceMethod(ServiceDescription serviceDescription);
}