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.httppart;
014
015import java.io.*;
016
017import org.apache.juneau.*;
018import org.apache.juneau.internal.*;
019import org.apache.juneau.uon.*;
020
021/**
022 * Serializes POJOs to values suitable for transmission as HTTP headers, query/form-data parameters, and path variables.
023 * 
024 * <p>
025 * This serializer uses UON notation for all parts by default.  This allows for arbitrary POJOs to be losslessly
026 * serialized as any of the specified HTTP types.
027 */
028public class UonPartSerializer extends UonSerializer implements HttpPartSerializer {
029
030   //-------------------------------------------------------------------------------------------------------------------
031   // Predefined instances
032   //-------------------------------------------------------------------------------------------------------------------
033
034   /** Reusable instance of {@link UonPartSerializer}, all default settings. */
035   public static final UonPartSerializer DEFAULT = new UonPartSerializer(PropertyStore.DEFAULT);
036
037
038   //-------------------------------------------------------------------------------------------------------------------
039   // Instance
040   //-------------------------------------------------------------------------------------------------------------------
041
042   /**
043    * Constructor.
044    * 
045    * @param ps
046    *    The property store containing all the settings for this object.
047    */
048   public UonPartSerializer(PropertyStore ps) {
049      super(
050         ps.builder()
051            .set(UON_encoding, false)
052            .build() 
053      );
054   }
055
056   @Override /* Context */
057   public UonPartSerializerBuilder builder() {
058      return new UonPartSerializerBuilder(getPropertyStore());
059   }
060
061   /**
062    * Instantiates a new clean-slate {@link UonPartSerializerBuilder} object.
063    * 
064    * <p>
065    * Note that this method creates a builder initialized to all default settings, whereas {@link #builder()} copies 
066    * the settings of the object called on.
067    * 
068    * @return A new {@link UonPartSerializerBuilder} object.
069    */
070   public static UonPartSerializerBuilder create() {
071      return new UonPartSerializerBuilder();
072   }
073
074   //--------------------------------------------------------------------------------
075   // Entry point methods
076   //--------------------------------------------------------------------------------
077
078   @Override /* PartSerializer */
079   public String serialize(HttpPartType type, Object value) {
080      try {
081         // Shortcut for simple types.
082         ClassMeta<?> cm = getClassMetaForObject(value);
083         if (cm != null) {
084            if (cm.isNumber() || cm.isBoolean())
085               return ClassUtils.toString(value);
086            if (cm.isString()) {
087               String s = ClassUtils.toString(value);
088               if (s.isEmpty() || ! UonUtils.needsQuotes(s))
089                  return s;
090            }
091         }
092         StringWriter w = new StringWriter();
093         UonSerializerSession s = new UonSerializerSession(this, false, createDefaultSessionArgs());
094         s.serialize(value, w);
095         return w.toString();
096      } catch (Exception e) {
097         throw new RuntimeException(e);
098      }
099   }
100}