001/*
002 * The contents of this file are subject to the terms of the Common Development and
003 * Distribution License (the License). You may not use this file except in compliance with the
004 * License.
005 *
006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
007 * specific language governing permission and limitations under the License.
008 *
009 * When distributing Covered Software, include this CDDL Header Notice in each file and include
010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
011 * Header, with the fields enclosed by brackets [] replaced by your own identifying
012 * information: "Portions copyright [year] [name of copyright owner]".
013 *
014 * Copyright 2016 ForgeRock AS.
015 */
016
017package org.forgerock.api.models;
018
019import static org.forgerock.api.util.ValidationUtil.isEmpty;
020
021import java.util.Arrays;
022import java.util.Objects;
023
024import com.fasterxml.jackson.annotation.JsonProperty;
025import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
026import org.forgerock.api.ApiValidationException;
027import org.forgerock.api.enums.PatchOperation;
028
029/**
030 * Class that represents the Patch operation type in API descriptor.
031 */
032@JsonDeserialize(builder = Patch.Builder.class)
033public final class Patch extends Operation {
034
035    private final PatchOperation[] operations;
036
037    /**
038     * Protected contstructor of the Patch operation.
039     *
040     * @param builder Patch Builder
041     */
042    private Patch(Builder builder) {
043        super(builder);
044        this.operations = builder.operations;
045
046        if (isEmpty(operations)) {
047            throw new ApiValidationException("operations required");
048        }
049    }
050
051    /**
052     * Getter for supported Patch operations.
053     *
054     * @return Supported Patch operations
055     */
056    public PatchOperation[] getOperations() {
057        return operations;
058    }
059
060    @Override
061    public boolean equals(Object o) {
062        if (this == o) {
063            return true;
064        }
065        if (o == null || getClass() != o.getClass()) {
066            return false;
067        }
068        if (!super.equals(o)) {
069            return false;
070        }
071        Patch patch = (Patch) o;
072        return Arrays.equals(operations, patch.operations);
073    }
074
075    @Override
076    public int hashCode() {
077        return Objects.hash(super.hashCode(), operations);
078    }
079
080    /**
081     * Creates a new builder for Patch.
082     *
083     * @return New builder instance
084     */
085    public static final Builder patch() {
086        return new Builder();
087    }
088
089    /**
090     * Allocates the Patch operation type to the given Resource Builder.
091     *
092     * @param resourceBuilder - Resource Builder to add the operation
093     */
094    @Override
095    protected void allocateToResource(Resource.Builder resourceBuilder) {
096        resourceBuilder.patch(this);
097    }
098
099    /**
100     * Builds a Patch object from the data stored in the annotation.
101     * @param patch Patch annotation that holds the data
102     * @param descriptor The root descriptor to add definitions to.
103     * @param relativeType The type relative to which schema resources should be resolved.
104     * @return Patch instance
105     */
106    public static Patch fromAnnotation(org.forgerock.api.annotations.Patch patch, ApiDescription descriptor,
107            Class<?> relativeType) {
108        return patch()
109                .detailsFromAnnotation(patch.operationDescription(), descriptor, relativeType)
110                .operations(patch.operations())
111                .build();
112    }
113
114    /**
115     * Builder to help construct the Patch.
116     */
117    public static final class Builder extends Operation.Builder<Builder> {
118
119        private PatchOperation[] operations;
120
121        private Builder() {
122            super();
123        }
124
125        /**
126         * Setter for supported Patch-operations.
127         *
128         * @param operations Supported Patch-operations
129         * @return Builder
130         */
131        @JsonProperty("operations")
132        public Builder operations(PatchOperation... operations) {
133            this.operations = operations;
134            return this;
135        }
136
137        @Override
138        protected Builder self() {
139            return this;
140        }
141
142        /**
143         * Builds the Patch instance.
144         *
145         * @return Patch instance
146         */
147        public Patch build() {
148            return new Patch(this);
149        }
150    }
151
152}