org.testifyproject.snakeyaml.representer.SafeRepresenter Maven / Gradle / Ivy
The newest version!
/**
* Copyright (c) 2008, http://www.snakeyaml.org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.testifyproject.snakeyaml.representer;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import java.util.UUID;
import java.util.regex.Pattern;
import org.testifyproject.snakeyaml.error.YAMLException;
import org.testifyproject.snakeyaml.external.biz.base64Coder.Base64Coder;
import org.testifyproject.snakeyaml.nodes.Node;
import org.testifyproject.snakeyaml.nodes.Tag;
import org.testifyproject.snakeyaml.reader.StreamReader;
/**
* Represent standard Java classes
*/
class SafeRepresenter extends BaseRepresenter {
protected Map, Tag> classTags;
protected TimeZone timeZone = null;
public SafeRepresenter() {
this.nullRepresenter = new RepresentNull();
this.representers.put(String.class, new RepresentString());
this.representers.put(Boolean.class, new RepresentBoolean());
this.representers.put(Character.class, new RepresentString());
this.representers.put(UUID.class, new RepresentUuid());
this.representers.put(byte[].class, new RepresentByteArray());
Represent primitiveArray = new RepresentPrimitiveArray();
representers.put(short[].class, primitiveArray);
representers.put(int[].class, primitiveArray);
representers.put(long[].class, primitiveArray);
representers.put(float[].class, primitiveArray);
representers.put(double[].class, primitiveArray);
representers.put(char[].class, primitiveArray);
representers.put(boolean[].class, primitiveArray);
this.multiRepresenters.put(Number.class, new RepresentNumber());
this.multiRepresenters.put(List.class, new RepresentList());
this.multiRepresenters.put(Map.class, new RepresentMap());
this.multiRepresenters.put(Set.class, new RepresentSet());
this.multiRepresenters.put(Iterator.class, new RepresentIterator());
this.multiRepresenters.put(new Object[0].getClass(), new RepresentArray());
this.multiRepresenters.put(Date.class, new RepresentDate());
this.multiRepresenters.put(Enum.class, new RepresentEnum());
this.multiRepresenters.put(Calendar.class, new RepresentDate());
classTags = new HashMap, Tag>();
}
protected Tag getTag(Class> clazz, Tag defaultTag) {
if (classTags.containsKey(clazz)) {
return classTags.get(clazz);
} else {
return defaultTag;
}
}
/**
* Define a tag for the Class
to serialize.
*
* @param clazz
* Class
which tag is changed
* @param tag
* new tag to be used for every instance of the specified
* Class
* @return the previous tag associated with the Class
*/
public Tag addClassTag(Class extends Object> clazz, Tag tag) {
if (tag == null) {
throw new NullPointerException("Tag must be provided.");
}
return classTags.put(clazz, tag);
}
protected class RepresentNull implements Represent {
public Node representData(Object data) {
return representScalar(Tag.NULL, "null");
}
}
public static Pattern MULTILINE_PATTERN = Pattern.compile("\n|\u0085|\u2028|\u2029");
protected class RepresentString implements Represent {
public Node representData(Object data) {
Tag tag = Tag.STR;
Character style = null;
String value = data.toString();
if (!StreamReader.isPrintable(value)) {
tag = Tag.BINARY;
char[] binary;
try {
final byte[] bytes = value.getBytes("UTF-8");
// sometimes above will just silently fail - it will return incomplete data
// it happens when String has invalid code points
// (for example half surrogate character without other half)
final String checkValue = new String(bytes, "UTF-8");
if (!checkValue.equals(value)) {
throw new YAMLException("invalid string value has occurred");
}
binary = Base64Coder.encode(bytes);
} catch (UnsupportedEncodingException e) {
throw new YAMLException(e);
}
value = String.valueOf(binary);
style = '|';
}
// if no other scalar style is explicitly set, use literal style for
// multiline scalars
if (defaultScalarStyle == null && MULTILINE_PATTERN.matcher(value).find()) {
style = '|';
}
return representScalar(tag, value, style);
}
}
protected class RepresentBoolean implements Represent {
public Node representData(Object data) {
String value;
if (Boolean.TRUE.equals(data)) {
value = "true";
} else {
value = "false";
}
return representScalar(Tag.BOOL, value);
}
}
protected class RepresentNumber implements Represent {
public Node representData(Object data) {
Tag tag;
String value;
if (data instanceof Byte || data instanceof Short || data instanceof Integer
|| data instanceof Long || data instanceof BigInteger) {
tag = Tag.INT;
value = data.toString();
} else {
Number number = (Number) data;
tag = Tag.FLOAT;
if (number.equals(Double.NaN)) {
value = ".NaN";
} else if (number.equals(Double.POSITIVE_INFINITY)) {
value = ".inf";
} else if (number.equals(Double.NEGATIVE_INFINITY)) {
value = "-.inf";
} else {
value = number.toString();
}
}
return representScalar(getTag(data.getClass(), tag), value);
}
}
protected class RepresentList implements Represent {
@SuppressWarnings("unchecked")
public Node representData(Object data) {
return representSequence(getTag(data.getClass(), Tag.SEQ), (List