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.marshall;
018
019import static org.apache.juneau.commons.utils.Shorts.*;
020import static org.apache.juneau.marshall.jsonschema.SchemaUtils.*;
021
022import java.lang.annotation.*;
023import java.util.function.*;
024
025import org.apache.juneau.commons.*;
026import org.apache.juneau.commons.utils.*;
027import org.apache.juneau.marshall.collections.*;
028import org.apache.juneau.marshall.parser.*;
029
030/**
031 * Utility classes and methods for the {@link ExternalDocs @ExternalDocs} annotation.
032 *
033 */
034public class ExternalDocsAnnotation {
035
036   /**
037    * Prevents instantiation.
038    */
039   private ExternalDocsAnnotation() {}
040
041   /**
042    * Builder class.
043    *
044    * <h5 class='section'>See Also:</h5><ul>
045    *    <li class='jm'>{@link MarshallingContext.Builder#annotations(Annotation...)}
046    * </ul>
047    */
048   public static class Builder extends AnnotationObject.Builder {
049
050      private String[] description = {};
051      private String url = "";
052
053      /**
054       * Constructor.
055       */
056      protected Builder() {
057         super(ExternalDocs.class);
058      }
059
060      /**
061       * Instantiates a new {@link ExternalDocs @ExternalDocs} object initialized with this builder.
062       *
063       * @return A new {@link ExternalDocs @ExternalDocs} object.
064       */
065      public ExternalDocs build() {
066         return new Object(this);
067      }
068
069      /**
070       * Sets the description property on this annotation.
071       *
072       * @param value The new value for this property.
073       * @return This object.
074       */
075      public Builder description(String...value) {
076         description = value;
077         return this;
078      }
079
080      /**
081       * Sets the {@link ExternalDocs#url} property on this annotation.
082       *
083       * @param value The new value for this property.
084       * @return This object.
085       */
086      public Builder url(String value) {
087         url = value;
088         return this;
089      }
090
091   }
092
093   @SuppressWarnings({
094      "java:S2160" // equals() inherited from AnnotationObject compares all annotation interface methods; subclass fields are accessed via those methods
095   })
096   private static class Object extends AnnotationObject implements ExternalDocs {
097
098      private final String[] description;
099      private final String url;
100
101      Object(ExternalDocsAnnotation.Builder b) {
102         super(b);
103         description = cp(b.description);
104         url = b.url;
105      }
106
107      @Override
108      public String url() {
109         return url;
110      }
111
112      @Override /* Overridden from annotation */
113      public String[] description() {
114         return description;
115      }
116   }
117
118   /** Default value */
119   public static final ExternalDocs DEFAULT = create().build();
120
121   /**
122    * Instantiates a new builder for this class.
123    *
124    * @return A new builder object.
125    */
126   public static Builder create() {
127      return new Builder();
128   }
129
130   /**
131    * Returns <jk>true</jk> if the specified annotation contains all default values.
132    *
133    * @param a The annotation to check. Can be <jk>null</jk> (returns <jk>true</jk>).
134    * @return <jk>true</jk> if the specified annotation contains all default values.
135    */
136   public static boolean empty(ExternalDocs a) {
137      return a == null || DEFAULT.equals(a);
138   }
139
140   /**
141    * Merges the contents of the specified annotation into the specified generic map.
142    *
143    * @param m The map to copy the contents to. Can be <jk>null</jk> (a new map is created).
144    * @param a The annotation to apply. Can be <jk>null</jk> (returns the map unchanged).
145    * @return The same map (or a new map if <c>m</c> was <jk>null</jk>) with the annotation contents applied.
146    * @throws ParseException Invalid JSON found in value.
147    */
148   public static JsonMap merge(JsonMap m, ExternalDocs a) throws ParseException {
149      if (ExternalDocsAnnotation.empty(a))
150         return m;
151      if (m == null)
152         m = new JsonMap();
153      Predicate<String> ne = Shorts::ine;
154      // @formatter:off
155      return m
156         .appendIf(ne, "description", joinnl(a.description()))
157         .appendIf(ne, "url", a.url())
158      ;
159      // @formatter:on
160   }
161}