blob: 943d772155f5e415bec7159e7c9bc435acb7cdb3 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.component.salesforce.api.dto.approval;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamImplicit;
import org.apache.camel.spi.Metadata;
import org.apache.camel.spi.UriParam;
import org.apache.camel.spi.UriParams;
/**
* Represents approval request sent to submit, approve or reject record.
*
* @see <a href=
* "https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_process_approvals.htm">
* https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_process_approvals.htm</a>
*/
@UriParams
@XStreamAlias("requests")
public final class ApprovalRequest implements Serializable {
public enum Action {
Submit, Approve, Reject
}
/**
* Lazy holder of fields defined in {@link ApprovalRequest}.
*/
private static final class FieldHolder {
public static final FieldHolder INSTANCE = new FieldHolder();
public final List<Field> fields;
private FieldHolder() {
fields = Arrays.stream(ApprovalRequest.class.getDeclaredFields()).filter(f -> !Modifier.isFinal(f.getModifiers())).collect(Collectors.toList());
}
}
/**
*
*/
private static final long serialVersionUID = 1L;
@UriParam
@Metadata(required = true)
private Action actionType;
@UriParam
@Metadata(required = true)
private String contextActorId;
@UriParam
@Metadata(required = true)
private String contextId;
@UriParam
private String comments;
@UriParam
@Metadata(required = true)
@XStreamImplicit(itemFieldName = "nextApproverIds")
private List<String> nextApproverIds;
@UriParam
@Metadata(required = true)
private String processDefinitionNameOrId;
@UriParam
private boolean skipEntryCriteria;
public void addNextApproverId(final String nextApproverId) {
nextApproverIds = Optional.ofNullable(nextApproverIds).orElse(new ArrayList<>());
nextApproverIds.add(nextApproverId);
}
/**
* Creates new {@link ApprovalRequest} by combining values from the given
* template with the values currently present. If the value is not present
* and the template has the corresponding value, then the template value is
* set. The net result is that all set values of an {@link ApprovalRequest}
* are preserved, while the values set on template are used for undefined (
* <code>null</code>) values.
*
* @param template template to apply
* @return newly created object with applied template
*/
public ApprovalRequest applyTemplate(final ApprovalRequest template) {
if (template == null) {
return this;
}
final ApprovalRequest withTemplateValues = new ApprovalRequest();
for (final Field field : FieldHolder.INSTANCE.fields) {
try {
final Object currentValue = field.get(this);
// if a field has not been set, and the template has it set use
// the template value
if (currentValue == null) {
final Object templateValue = field.get(template);
if (templateValue != null) {
field.set(withTemplateValues, templateValue);
}
} else {
field.set(withTemplateValues, currentValue);
}
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new IllegalStateException("Unable to apply values from template", e);
}
}
return withTemplateValues;
}
@Override
public boolean equals(final Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof ApprovalRequest)) {
return false;
}
final ApprovalRequest other = (ApprovalRequest)obj;
return Objects.equals(actionType, other.actionType) && Objects.equals(contextActorId, other.contextActorId) && Objects.equals(contextId, other.contextId)
&& Objects.equals(comments, other.comments) && Objects.equals(nextApproverIds, other.nextApproverIds)
&& Objects.equals(processDefinitionNameOrId, other.processDefinitionNameOrId) && Objects.equals(skipEntryCriteria, other.skipEntryCriteria);
}
public Action getActionType() {
return actionType;
}
public String getComments() {
return comments;
}
public String getContextActorId() {
return contextActorId;
}
public String getContextId() {
return contextId;
}
public List<String> getNextApproverIds() {
return listFromNullable(nextApproverIds);
}
public String getProcessDefinitionNameOrId() {
return processDefinitionNameOrId;
}
@Override
public int hashCode() {
return Arrays.hashCode(new Object[] {actionType, contextActorId, contextId, comments, nextApproverIds, processDefinitionNameOrId, skipEntryCriteria});
}
public boolean isSkipEntryCriteria() {
return skipEntryCriteria;
}
public void setActionType(final Action actionType) {
this.actionType = actionType;
}
public void setComments(final String comments) {
this.comments = comments;
}
public void setContextActorId(final String contextActorId) {
this.contextActorId = contextActorId;
}
public void setContextId(final String contextId) {
this.contextId = contextId;
}
public void setNextApproverIds(final List<String> nextApproverIds) {
this.nextApproverIds = new ArrayList<>(listFromNullable(nextApproverIds));
}
public void setNextApproverIds(final String nextApproverId) {
// set single approver id
this.nextApproverIds = Collections.singletonList(nextApproverId);
}
public void setProcessDefinitionNameOrId(final String processDefinitionNameOrId) {
this.processDefinitionNameOrId = processDefinitionNameOrId;
}
public void setSkipEntryCriteria(final boolean skipEntryCriteria) {
this.skipEntryCriteria = skipEntryCriteria;
}
@Override
public String toString() {
final StringBuilder buildy = new StringBuilder("ApprovalRequest: ");
buildy.append("actionType: ").append(actionType);
buildy.append(", contextActorId: ").append(contextActorId);
buildy.append(", contextId: ").append(contextId);
buildy.append(", comments: ").append(comments);
buildy.append(", nextApproverIds: ").append(nextApproverIds);
buildy.append(", processDefinitionNameOrId: ").append(processDefinitionNameOrId);
buildy.append(", skipEntryCriteria: ").append(skipEntryCriteria);
return buildy.toString();
}
private List<String> listFromNullable(final List<String> nullable) {
return Optional.ofNullable(nullable).orElse(Collections.emptyList());
}
}