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.marshaller;
014
015import java.io.*;
016import java.lang.reflect.*;
017import java.nio.charset.*;
018
019import org.apache.juneau.*;
020import org.apache.juneau.json.*;
021import org.apache.juneau.parser.*;
022import org.apache.juneau.serializer.*;
023
024/**
025 * A pairing of a {@link JsonSerializer} and {@link JsonParser} into a single class with convenience read/write methods.
026 *
027 * <p>
028 *    The general idea is to combine a single serializer and parser inside a simplified API for reading and writing POJOs.
029 *
030 * <h5 class='figure'>Examples:</h5>
031 * <p class='bjava'>
032 *    <jc>// Using instance.</jc>
033 *    Json <jv>json</jv> = <jk>new</jk> Json();
034 *    MyPojo <jv>myPojo</jv> = <jv>json</jv>.read(<jv>string</jv>, MyPojo.<jk>class</jk>);
035 *    String <jv>string</jv> = <jv>json</jv>.write(<jv>myPojo</jv>);
036 * </p>
037 * <p class='bjava'>
038 * <jc>// Using DEFAULT instance.</jc>
039 *    MyPojo <jv>myPojo</jv> = Json.<jsf>DEFAULT</jsf>.read(<jv>string</jv>, MyPojo.<jk>class</jk>);
040 *    String <jv>string</jv> = Json.<jsf>DEFAULT</jsf>.write(<jv>myPojo</jv>);
041 * </p>
042 *
043 * <h5 class='section'>See Also:</h5><ul>
044 *    <li class='link'><a class="doclink" href="../../../../index.html#jm.Marshallers">Marshallers</a>
045 * </ul>
046 */
047public class Json extends CharMarshaller {
048
049   //-----------------------------------------------------------------------------------------------------------------
050   // Static
051   //-----------------------------------------------------------------------------------------------------------------
052
053   /**
054    * Default reusable instance.
055    */
056   public static final Json DEFAULT = new Json();
057
058   //-----------------------------------------------------------------------------------------------------------------
059   // Instance
060   //-----------------------------------------------------------------------------------------------------------------
061
062   /**
063    * Constructor.
064    *
065    * @param s
066    *    The serializer to use for serializing output.
067    *    <br>Must not be <jk>null</jk>.
068    * @param p
069    *    The parser to use for parsing input.
070    *    <br>Must not be <jk>null</jk>.
071    */
072   public Json(JsonSerializer s, JsonParser p) {
073      super(s, p);
074   }
075
076   /**
077    * Constructor.
078    *
079    * <p>
080    * Uses {@link JsonSerializer#DEFAULT} and {@link JsonParser#DEFAULT}.
081    */
082   public Json() {
083      this(JsonSerializer.DEFAULT, JsonParser.DEFAULT);
084   }
085
086   /**
087    * Parses a JSON input string to the specified type.
088    *
089    * <p>
090    * A shortcut for calling <c><jsf>DEFAULT</jsf>.read(<jv>input</jv>, <jv>type</jv>)</c>.
091    *
092    * @param <T> The class type of the object being created.
093    * @param input The input.
094    * @param type The object type to create.
095    * @return The parsed object.
096    * @throws ParseException Malformed input encountered.
097    */
098   public static <T> T to(String input, Class<T> type) throws ParseException {
099      return DEFAULT.read(input, type);
100   }
101
102   /**
103    * Parses a JSON input object to the specified Java type.
104    *
105    * <p>
106    * A shortcut for calling <c><jsf>DEFAULT</jsf>.read(<jv>input</jv>, <jv>type</jv>)</c>.
107    *
108    * @param <T> The class type of the object being created.
109    * @param input
110    *    The input.
111    *    <br>Can be any of the following types:
112    *    <ul>
113    *       <li><jk>null</jk>
114    *       <li>{@link Reader}
115    *       <li>{@link CharSequence}
116    *       <li>{@link InputStream} containing UTF-8 encoded text (or charset defined by
117    *          {@link org.apache.juneau.parser.ReaderParser.Builder#streamCharset(Charset)} property value).
118    *       <li><code><jk>byte</jk>[]</code> containing UTF-8 encoded text (or charset defined by
119    *          {@link org.apache.juneau.parser.ReaderParser.Builder#streamCharset(Charset)} property value).
120    *       <li>{@link File} containing system encoded text (or charset defined by
121    *          {@link org.apache.juneau.parser.ReaderParser.Builder#fileCharset(Charset)} property value).
122    *    </ul>
123    * @param type The object type to create.
124    * @return The parsed object.
125    * @throws ParseException Malformed input encountered.
126    * @throws IOException Thrown by underlying stream.
127    */
128   public static <T> T to(Object input, Class<T> type) throws ParseException, IOException {
129      return DEFAULT.read(input, type);
130   }
131
132   /**
133    * Parses a JSON input string to the specified Java type.
134    *
135    * <p>
136    * A shortcut for calling <c><jsf>DEFAULT</jsf>.read(<jv>input</jv>, <jv>type</jv>, <jv>args</jv>)</c>.
137    *
138    * @param <T> The class type of the object to create.
139    * @param input The input.
140    * @param type
141    *    The object type to create.
142    *    <br>Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType}
143    * @param args
144    *    The type arguments of the class if it's a collection or map.
145    *    <br>Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType}
146    *    <br>Ignored if the main type is not a map or collection.
147    * @return The parsed object.
148    * @throws ParseException Malformed input encountered.
149    * @see BeanSession#getClassMeta(Type,Type...) for argument syntax for maps and collections.
150    */
151   public static <T> T to(String input, Type type, Type...args) throws ParseException {
152      return DEFAULT.read(input, type, args);
153   }
154
155   /**
156    * Parses a JSON input object to the specified Java type.
157    *
158    * <p>
159    * A shortcut for calling <c><jsf>DEFAULT</jsf>.read(<jv>input</jv>, <jv>type</jv>, <jv>args</jv>)</c>.
160    *
161    * @param <T> The class type of the object to create.
162    * @param input
163    *    The input.
164    *    <br>Can be any of the following types:
165    *    <ul>
166    *       <li><jk>null</jk>
167    *       <li>{@link Reader}
168    *       <li>{@link CharSequence}
169    *       <li>{@link InputStream} containing UTF-8 encoded text (or charset defined by
170    *          {@link org.apache.juneau.parser.ReaderParser.Builder#streamCharset(Charset)} property value).
171    *       <li><code><jk>byte</jk>[]</code> containing UTF-8 encoded text (or charset defined by
172    *          {@link org.apache.juneau.parser.ReaderParser.Builder#streamCharset(Charset)} property value).
173    *       <li>{@link File} containing system encoded text (or charset defined by
174    *          {@link org.apache.juneau.parser.ReaderParser.Builder#fileCharset(Charset)} property value).
175    *    </ul>
176    * @param type
177    *    The object type to create.
178    *    <br>Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType}
179    * @param args
180    *    The type arguments of the class if it's a collection or map.
181    *    <br>Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType}
182    *    <br>Ignored if the main type is not a map or collection.
183    * @return The parsed object.
184    * @throws ParseException Malformed input encountered.
185    * @throws IOException Thrown by underlying stream.
186    * @see BeanSession#getClassMeta(Type,Type...) for argument syntax for maps and collections.
187    */
188   public static <T> T to(Object input, Type type, Type...args) throws ParseException, IOException {
189      return DEFAULT.read(input, type, args);
190   }
191
192   /**
193    * Serializes a Java object to a JSON string.
194    *
195    * <p>
196    * A shortcut for calling <c><jsf>DEFAULT</jsf>.write(<jv>object</jv>)</c>.
197    *
198    * @param object The object to serialize.
199    * @return
200    *    The serialized object.
201    * @throws SerializeException If a problem occurred trying to convert the output.
202    */
203   public static String of(Object object) throws SerializeException {
204      return DEFAULT.write(object);
205   }
206
207   /**
208    * Serializes a Java object to a JSON output.
209    *
210    * <p>
211    * A shortcut for calling <c><jsf>DEFAULT</jsf>.write(<jv>output</jv>)</c>.
212    *
213    * @param object The object to serialize.
214    * @param output
215    *    The output object.
216    *    <br>Can be any of the following types:
217    *    <ul>
218    *       <li>{@link Writer}
219    *       <li>{@link OutputStream} - Output will be written as UTF-8 encoded stream.
220    *       <li>{@link File} - Output will be written as system-default encoded stream.
221    *       <li>{@link StringBuilder} - Output will be written to the specified string builder.
222    *    </ul>
223    * @return The output object.
224    * @throws SerializeException If a problem occurred trying to convert the output.
225    * @throws IOException Thrown by underlying stream.
226    */
227   public static Object of(Object object, Object output) throws SerializeException, IOException {
228      DEFAULT.write(object, output);
229      return output;
230   }
231}