001// ***************************************************************************************************************************
002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
003// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
005// * with the License.  You may obtain a copy of the License at                                                              *
006// *                                                                                                                         *
007// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
008// *                                                                                                                         *
009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
011// * specific language governing permissions and limitations under the License.                                              *
012// ***************************************************************************************************************************
013package org.apache.juneau.oapi;
014
015import java.util.*;
016import java.util.concurrent.*;
017
018import org.apache.juneau.*;
019import org.apache.juneau.annotation.*;
020import org.apache.juneau.parser.*;
021import org.apache.juneau.uon.*;
022
023/**
024 * OpenAPI part parser.
025 *
026 * <ul class='seealso'>
027 *    <li class='link'>{@doc juneau-marshall.OpenApiDetails.Parsers}
028 * </ul>
029 */
030@ConfigurableContext
031public class OpenApiParser extends UonParser implements OpenApiMetaProvider, OpenApiCommon {
032
033   //-------------------------------------------------------------------------------------------------------------------
034   // Configurable properties
035   //-------------------------------------------------------------------------------------------------------------------
036
037   static final String PREFIX = "OpenApiParser";
038
039   //-------------------------------------------------------------------------------------------------------------------
040   // Predefined instances
041   //-------------------------------------------------------------------------------------------------------------------
042
043   /** Reusable instance of {@link OpenApiParser}. */
044   public static final OpenApiParser DEFAULT = new OpenApiParser(PropertyStore.DEFAULT);
045
046
047   //-------------------------------------------------------------------------------------------------------------------
048   // Instance
049   //-------------------------------------------------------------------------------------------------------------------
050
051   private final Map<ClassMeta<?>,OpenApiClassMeta> openApiClassMetas = new ConcurrentHashMap<>();
052   private final Map<BeanPropertyMeta,OpenApiBeanPropertyMeta> openApiBeanPropertyMetas = new ConcurrentHashMap<>();
053
054   /**
055    * Constructor.
056    *
057    * @param ps The property store containing all the settings for this object.
058    */
059   public OpenApiParser(PropertyStore ps) {
060      this(ps, "text/openapi");
061   }
062
063   /**
064    * Constructor.
065    *
066    * @param ps
067    *    The property store containing all the settings for this object.
068    * @param consumes
069    *    The list of media types that this parser consumes (e.g. <js>"application/json"</js>, <js>"*&#8203;/json"</js>).
070    */
071   public OpenApiParser(PropertyStore ps, String...consumes) {
072      super(ps, consumes);
073   }
074
075   @Override /* Context */
076   public OpenApiParserBuilder builder() {
077      return new OpenApiParserBuilder(getPropertyStore());
078   }
079
080   /**
081    * Instantiates a new clean-slate {@link OpenApiParserBuilder} object.
082    *
083    * <p>
084    * This is equivalent to simply calling <code><jk>new</jk> UonPartParserBuilder()</code>.
085    *
086    * <p>
087    * Note that this method creates a builder initialized to all default settings, whereas {@link #builder()} copies
088    * the settings of the object called on.
089    *
090    * @return A new {@link OpenApiParserBuilder} object.
091    */
092   public static OpenApiParserBuilder create() {
093      return new OpenApiParserBuilder();
094   }
095
096   //-------------------------------------------------------------------------------------------------------------------
097   // Entry point methods
098   //-------------------------------------------------------------------------------------------------------------------
099
100   @Override
101   public OpenApiParserSession createSession() {
102      return new OpenApiParserSession(this, ParserSessionArgs.DEFAULT);
103   }
104
105   @Override
106   public OpenApiParserSession createPartSession(ParserSessionArgs args) {
107      return new OpenApiParserSession(this, args);
108   }
109
110   //-----------------------------------------------------------------------------------------------------------------
111   // Extended metadata
112   //-----------------------------------------------------------------------------------------------------------------
113
114   @Override /* OpenApiMetaProvider */
115   public OpenApiClassMeta getOpenApiClassMeta(ClassMeta<?> cm) {
116      OpenApiClassMeta m = openApiClassMetas.get(cm);
117      if (m == null) {
118         m = new OpenApiClassMeta(cm, this);
119         openApiClassMetas.put(cm, m);
120      }
121      return m;
122   }
123
124   @Override /* OpenApiMetaProvider */
125   public OpenApiBeanPropertyMeta getOpenApiBeanPropertyMeta(BeanPropertyMeta bpm) {
126      if (bpm == null)
127         return OpenApiBeanPropertyMeta.DEFAULT;
128      OpenApiBeanPropertyMeta m = openApiBeanPropertyMetas.get(bpm);
129      if (m == null) {
130         m = new OpenApiBeanPropertyMeta(bpm.getDelegateFor(), this);
131         openApiBeanPropertyMetas.put(bpm, m);
132      }
133      return m;
134   }
135
136   //-----------------------------------------------------------------------------------------------------------------
137   // Other methods
138   //-----------------------------------------------------------------------------------------------------------------
139
140   @Override /* Context */
141   public ObjectMap toMap() {
142      return super.toMap()
143         .append("OpenApiParser", new DefaultFilteringObjectMap()
144         );
145   }
146}