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.json5;
018
019import static org.apache.juneau.commons.utils.Shorts.*;
020
021import org.apache.juneau.commons.collections.*;
022import org.apache.juneau.marshall.json.*;
023
024/**
025 * Parses any valid JSON text into a POJO model.
026 *
027 * <h5 class='topic'>Media types</h5>
028 *
029 * Handles <c>Content-Type</c> types:  <bc>application/json5, text/json5</bc>
030 *
031 * <h5 class='topic'>Description</h5>
032 *
033 * Identical to {@link JsonParser} but accepts JSON5 syntax (single quotes, comments, trailing commas,
034 * unquoted keys) and uses media type <bc>application/json5</bc>. Use this parser when the input may
035 * contain JSON5-style syntax.
036 *
037 * <h5 class='figure'>Example input (Map of name/age):</h5>
038 * <p class='bjson'>
039 *    {name:<js>"Alice"</js>,age:30}
040 * </p>
041 *
042 * <h5 class='figure'>Complex (nested object + array):</h5>
043 * <p class='bjson'>
044 *    {name:<js>"Alice"</js>,age:30,address:{street:<js>"123 Main St"</js>,city:<js>"Boston"</js>,state:<js>"MA"</js>},tags:[<js>"a"</js>,<js>"b"</js>,<js>"c"</js>]}
045 * </p>
046 *
047 * <h5 class='section'>Notes:</h5><ul>
048 *    <li class='note'>This class is thread safe and reusable.
049 * </ul>
050 *
051 * <h5 class='section'>See Also:</h5><ul>
052 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JsonSupport">JSON</a>
053 *    <li class='link'>{@link JsonParser} - For strict RFC 8259 JSON only
054 * </ul>
055 */
056@SuppressWarnings({
057   "java:S110", // Inheritance depth acceptable for Json5Parser hierarchy
058   "java:S1192", // Duplicated literals (argument/property names) read more clearly inline than as constants
059   "java:S9149" // Per-format static factories intentionally shadow the parent's.
060})
061public class Json5Parser extends JsonParser {
062
063   /**
064    * Builder class.
065    */
066   public static class Builder extends JsonParser.Builder<Builder> {
067
068      private static final Cache<HashKey,Json5Parser> CACHE = Cache.of(HashKey.class, Json5Parser.class).build();
069
070      /**
071       * Constructor, default settings.
072       */
073      protected Builder() {
074         consumes("application/json5,text/json5,application/json,text/json");
075      }
076
077      /**
078       * Copy constructor.
079       *
080       * @param copyFrom The builder to copy from.
081       *    <br>Cannot be <jk>null</jk>.
082       */
083      protected Builder(Builder copyFrom) {
084         super(reqnn("copyFrom", copyFrom));
085      }
086
087      /**
088       * Copy constructor.
089       *
090       * @param copyFrom The bean to copy from.
091       *    <br>Cannot be <jk>null</jk>.
092       */
093      protected Builder(Json5Parser copyFrom) {
094         super(reqnn("copyFrom", copyFrom));
095      }
096
097      @Override /* Overridden from Context.Builder<?> */
098      public Json5Parser build() {
099         return cache(CACHE).build(Json5Parser.class);
100      }
101
102      @Override /* Overridden from Context.Builder<?> */
103      public Builder copy() {
104         return new Builder(this);
105      }
106
107
108   }
109
110   /** Default parser, Accept=application/json5. */
111   public static final Json5Parser DEFAULT = new Json5Parser(create());
112
113   /**
114    * Creates a new builder for this object.
115    *
116    * @return A new builder.
117    */
118   public static Builder create() {
119      return new Builder();
120   }
121
122   /**
123    * Constructor.
124    *
125    * @param builder The builder for this object.
126    */
127   public Json5Parser(Builder builder) {
128      super(builder);
129   }
130
131   /**
132    * Constructor.
133    *
134    * @param builder The builder for this object.
135    */
136   public Json5Parser(JsonParser.Builder<?> builder) {
137      super(builder);
138   }
139
140   @Override /* Overridden from Context */
141   public Builder copy() {
142      return new Builder(this);
143   }
144
145   @Override /* Overridden from Context */
146   public Json5ParserSession.Builder createSession() {
147      return Json5ParserSession.create(this);
148   }
149
150   @Override /* Overridden from Context */
151   public Json5ParserSession getSession() { return createSession().build(); }
152
153}