001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.juneau.bean.jsonapi;
018
019import static org.apache.juneau.commons.utils.CollectionUtils.*;
020import static org.apache.juneau.commons.utils.Shorts.*;
021
022import java.util.*;
023
024import org.apache.juneau.commons.bean.*;
025import org.apache.juneau.marshall.*;
026import org.apache.juneau.marshall.marshaller.*;
027
028/**
029 * Represents a JSON:API Relationship Object as defined by
030 * <a href="https://jsonapi.org/format/#document-resource-object-relationships">JSON:API v1.1 &#167; Relationships</a>.
031 *
032 * <p>
033 * A relationship carries:
034 * <ul class='spaced-list'>
035 *   <li>{@code data} - resource linkage. Per spec, this can be {@code null}, a single
036 *     {@link JsonApiResourceIdentifier}, or a JSON array of identifiers. Modeled here as {@code Object}.
037 *   <li>{@code links} - related URLs. Each value can be either a JSON string URL or a {@link JsonApiLink} object;
038 *     the field-level {@link JsonApiLinkOrStringSwap} swap handles the union.
039 *   <li>{@code meta} - free-form meta bag.
040 * </ul>
041 *
042 * <h5 class='section'>See Also:</h5><ul>
043 *   <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauBeanJsonApi">juneau-bean-jsonapi</a>
044 * </ul>
045 */
046@Marshalled
047public class JsonApiRelationship {
048
049   private Object data;
050   private Map<String,Object> links;
051   private Map<String,Object> meta;
052
053   /**
054    * Default constructor.
055    */
056   public JsonApiRelationship() { /* intentionally empty */ }
057
058   /**
059    * Bean property getter:  <property>data</property>.
060    *
061    * <p>
062    * Resource linkage. Per spec, this may be {@code null}, a single {@link JsonApiResourceIdentifier}, or a
063    * {@code List&lt;JsonApiResourceIdentifier&gt;}.
064    *
065    * @return The value of the <property>data</property> property, or <jk>null</jk> if it is not set.
066    */
067   public Object getData() { return data; }
068
069   /**
070    * Bean property setter:  <property>data</property>.
071    *
072    * @param value The new value (single identifier, list of identifiers, or {@code null} to unset).
073    * @return This object.
074    */
075   public JsonApiRelationship setData(Object value) {
076      data = value;
077      return this;
078   }
079
080   /**
081    * Typed setter for single-identifier linkage.
082    *
083    * @param value The identifier.  Can be <jk>null</jk> to unset the property.
084    * @return This object.
085    */
086   public JsonApiRelationship setData(JsonApiResourceIdentifier value) {
087      data = value;
088      return this;
089   }
090
091   /**
092    * Typed setter for to-many linkage.
093    *
094    * @param value The list of identifiers.  Can be <jk>null</jk> to unset the property.
095    * @return This object.
096    */
097   public JsonApiRelationship setData(List<JsonApiResourceIdentifier> value) {
098      data = value;
099      return this;
100   }
101
102   /**
103    * Bean property getter:  <property>links</property>.
104    *
105    * <p>
106    * Per spec, each {@code links} value can be either a JSON string URL or a {@link JsonApiLink} object.
107    *
108    * @return The value of the <property>links</property> property, or <jk>null</jk> if it is not set.
109    */
110   @BeanProp(value="links")
111   @Swap(JsonApiLinkOrStringSwap.class)
112   public Map<String,Object> getLinks() { return u(links); }
113
114   /**
115    * Bean property setter:  <property>links</property>.
116    *
117    * @param value The new value for this property.  Can be <jk>null</jk> to unset the property.
118    * @return This object.
119    */
120   @BeanProp(value="links")
121   @Swap(JsonApiLinkOrStringSwap.class)
122   public JsonApiRelationship setLinks(Map<String,Object> value) {
123      links = value;
124      return this;
125   }
126
127   /**
128    * Convenience method to add a single link.
129    *
130    * @param name The link name.  Can be <jk>null</jk> ({@link LinkedHashMap} tolerates a <jk>null</jk> key).
131    * @param value The link value (a {@link String} URL or a {@link JsonApiLink} object).  Can be <jk>null</jk> (stored as <jk>null</jk>).
132    * @return This object.
133    */
134   public JsonApiRelationship putLink(String name, Object value) {
135      if (links == null)
136         links = map();
137      links.put(name, value);
138      return this;
139   }
140
141   /**
142    * Bean property getter:  <property>meta</property>.
143    *
144    * @return The value of the <property>meta</property> property, or <jk>null</jk> if it is not set.
145    */
146   public Map<String,Object> getMeta() { return u(meta); }
147
148   /**
149    * Bean property setter:  <property>meta</property>.
150    *
151    * @param value The new value for this property.  Can be <jk>null</jk> to unset the property.
152    * @return This object.
153    */
154   public JsonApiRelationship setMeta(Map<String,Object> value) {
155      meta = value;
156      return this;
157   }
158
159   /**
160    * Convenience method to add a single meta entry.
161    *
162    * @param name The meta key.  Can be <jk>null</jk> ({@link LinkedHashMap} tolerates a <jk>null</jk> key).
163    * @param value The meta value.  Can be <jk>null</jk> (stored as <jk>null</jk>).
164    * @return This object.
165    */
166   public JsonApiRelationship putMeta(String name, Object value) {
167      if (meta == null)
168         meta = map();
169      meta.put(name, value);
170      return this;
171   }
172
173   @Override /* Overridden from Object */
174   public String toString() {
175      return Json.of(this);
176   }
177}