com.alibaba.fastjson.serializer.MiscCodec Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of fastjson-to-easyjson Show documentation
Show all versions of fastjson-to-easyjson Show documentation
Adapter alibaba fastjson to other json libraries. the fastjson version: 1.2.58
/*
* Copyright 2019 the original author or authors.
*
* Licensed under the Apache, 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.gnu.org/licenses/lgpl-3.0.html
*
* 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 com.alibaba.fastjson.serializer;
import com.alibaba.fastjson.*;
import com.alibaba.fastjson.parser.DefaultJSONParser;
import com.alibaba.fastjson.parser.JSONLexer;
import com.alibaba.fastjson.parser.JSONToken;
import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer;
import com.alibaba.fastjson.util.IOUtils;
import com.alibaba.fastjson.util.TypeUtils;
import org.w3c.dom.Node;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.net.*;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;
/**
* @author wenshao[[email protected]]
*/
public class MiscCodec implements ObjectSerializer, ObjectDeserializer {
public final static MiscCodec instance = new MiscCodec();
private static boolean FILE_RELATIVE_PATH_SUPPORT = false;
private static Method method_paths_get;
private static boolean method_paths_get_error = false;
static {
FILE_RELATIVE_PATH_SUPPORT = "true".equals(IOUtils.getStringProperty("fastjson.deserializer.fileRelativePathSupport"));
}
private static String toString(Node node) {
try {
TransformerFactory transFactory = TransformerFactory.newInstance();
Transformer transformer = transFactory.newTransformer();
DOMSource domSource = new DOMSource(node);
StringWriter out = new StringWriter();
transformer.transform(domSource, new StreamResult(out));
return out.toString();
} catch (TransformerException e) {
throw new JSONException("xml node to string error", e);
}
}
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType,
int features) throws IOException {
SerializeWriter out = serializer.out;
if (object == null) {
out.writeNull();
return;
}
Class> objClass = object.getClass();
String strVal;
if (objClass == SimpleDateFormat.class) {
String pattern = ((SimpleDateFormat) object).toPattern();
if (out.isEnabled(SerializerFeature.WriteClassName)) {
if (object.getClass() != fieldType) {
out.write('{');
out.writeFieldName(JSON.DEFAULT_TYPE_KEY);
serializer.write(object.getClass().getName());
out.writeFieldValue(',', "val", pattern);
out.write('}');
return;
}
}
strVal = pattern;
} else if (objClass == Class.class) {
Class> clazz = (Class>) object;
strVal = clazz.getName();
} else if (objClass == InetSocketAddress.class) {
InetSocketAddress address = (InetSocketAddress) object;
InetAddress inetAddress = address.getAddress();
out.write('{');
if (inetAddress != null) {
out.writeFieldName("address");
serializer.write(inetAddress);
out.write(',');
}
out.writeFieldName("port");
out.writeInt(address.getPort());
out.write('}');
return;
} else if (object instanceof File) {
strVal = ((File) object).getPath();
} else if (object instanceof InetAddress) {
strVal = ((InetAddress) object).getHostAddress();
} else if (object instanceof TimeZone) {
TimeZone timeZone = (TimeZone) object;
strVal = timeZone.getID();
} else if (object instanceof Currency) {
Currency currency = (Currency) object;
strVal = currency.getCurrencyCode();
} else if (object instanceof JSONStreamAware) {
JSONStreamAware aware = (JSONStreamAware) object;
aware.writeJSONString(out);
return;
} else if (object instanceof Iterator) {
Iterator> it = ((Iterator>) object);
writeIterator(serializer, out, it);
return;
} else if (object instanceof Iterable) {
Iterator> it = ((Iterable>) object).iterator();
writeIterator(serializer, out, it);
return;
} else if (object instanceof Map.Entry) {
Map.Entry entry = (Map.Entry) object;
Object objKey = entry.getKey();
Object objVal = entry.getValue();
if (objKey instanceof String) {
String key = (String) objKey;
if (objVal instanceof String) {
String value = (String) objVal;
out.writeFieldValueStringWithDoubleQuoteCheck('{', key, value);
} else {
out.write('{');
out.writeFieldName(key);
serializer.write(objVal);
}
} else {
out.write('{');
serializer.write(objKey);
out.write(':');
serializer.write(objVal);
}
out.write('}');
return;
} else if (object.getClass().getName().equals("net.sf.json.JSONNull")) {
out.writeNull();
return;
} else if (object instanceof Node) {
strVal = toString((Node) object);
} else {
throw new JSONException("not support class : " + objClass);
}
out.writeString(strVal);
}
protected void writeIterator(JSONSerializer serializer, SerializeWriter out, Iterator> it) {
int i = 0;
out.write('[');
while (it.hasNext()) {
if (i != 0) {
out.write(',');
}
Object item = it.next();
serializer.write(item);
++i;
}
out.write(']');
}
@SuppressWarnings("unchecked")
public T deserialze(DefaultJSONParser parser, Type clazz, Object fieldName) {
JSONLexer lexer = parser.lexer;
if (clazz == InetSocketAddress.class) {
if (lexer.token() == JSONToken.NULL) {
lexer.nextToken();
return null;
}
parser.accept(JSONToken.LBRACE);
InetAddress address = null;
int port = 0;
for (; ; ) {
String key = lexer.stringVal();
lexer.nextToken(JSONToken.COLON);
if (key.equals("address")) {
parser.accept(JSONToken.COLON);
address = parser.parseObject(InetAddress.class);
} else if (key.equals("port")) {
parser.accept(JSONToken.COLON);
if (lexer.token() != JSONToken.LITERAL_INT) {
throw new JSONException("port is not int");
}
port = lexer.intValue();
lexer.nextToken();
} else {
parser.accept(JSONToken.COLON);
parser.parse();
}
if (lexer.token() == JSONToken.COMMA) {
lexer.nextToken();
continue;
}
break;
}
parser.accept(JSONToken.RBRACE);
return (T) new InetSocketAddress(address, port);
}
Object objVal;
if (parser.resolveStatus == DefaultJSONParser.TypeNameRedirect) {
parser.resolveStatus = DefaultJSONParser.NONE;
parser.accept(JSONToken.COMMA);
if (lexer.token() == JSONToken.LITERAL_STRING) {
if (!"val".equals(lexer.stringVal())) {
throw new JSONException("syntax error");
}
lexer.nextToken();
} else {
throw new JSONException("syntax error");
}
parser.accept(JSONToken.COLON);
objVal = parser.parse();
parser.accept(JSONToken.RBRACE);
} else {
objVal = parser.parse();
}
String strVal;
if (objVal == null) {
strVal = null;
} else if (objVal instanceof String) {
strVal = (String) objVal;
} else {
if (objVal instanceof JSONObject) {
JSONObject jsonObject = (JSONObject) objVal;
if (clazz == Currency.class) {
String currency = jsonObject.getString("currency");
if (currency != null) {
return (T) Currency.getInstance(currency);
}
String symbol = jsonObject.getString("currencyCode");
if (symbol != null) {
return (T) Currency.getInstance(symbol);
}
}
if (clazz == Map.Entry.class) {
return (T) jsonObject.entrySet().iterator().next();
}
return jsonObject.toJavaObject(clazz);
}
throw new JSONException("expect string");
}
if (strVal == null || strVal.length() == 0) {
return null;
}
if (clazz == UUID.class) {
return (T) UUID.fromString(strVal);
}
if (clazz == URI.class) {
return (T) URI.create(strVal);
}
if (clazz == URL.class) {
try {
return (T) new URL(strVal);
} catch (MalformedURLException e) {
throw new JSONException("create url error", e);
}
}
if (clazz == Pattern.class) {
return (T) Pattern.compile(strVal);
}
if (clazz == Locale.class) {
return (T) TypeUtils.toLocale(strVal);
}
if (clazz == SimpleDateFormat.class) {
SimpleDateFormat dateFormat = new SimpleDateFormat(strVal, lexer.getLocale());
dateFormat.setTimeZone(lexer.getTimeZone());
return (T) dateFormat;
}
if (clazz == InetAddress.class || clazz == Inet4Address.class || clazz == Inet6Address.class) {
try {
return (T) InetAddress.getByName(strVal);
} catch (UnknownHostException e) {
throw new JSONException("deserialize inet adress error", e);
}
}
if (clazz == File.class) {
if (strVal.indexOf("..") >= 0 && !FILE_RELATIVE_PATH_SUPPORT) {
throw new JSONException("file relative path not support.");
}
return (T) new File(strVal);
}
if (clazz == TimeZone.class) {
return (T) TimeZone.getTimeZone(strVal);
}
if (clazz instanceof ParameterizedType) {
ParameterizedType parmeterizedType = (ParameterizedType) clazz;
clazz = parmeterizedType.getRawType();
}
if (clazz == Class.class) {
return (T) TypeUtils.loadClass(strVal, parser.getConfig().getDefaultClassLoader(), false);
}
if (clazz == Charset.class) {
return (T) Charset.forName(strVal);
}
if (clazz == Currency.class) {
return (T) Currency.getInstance(strVal);
}
if (clazz == JSONPath.class) {
return (T) new JSONPath(strVal);
}
if (clazz instanceof Class) {
String className = ((Class) clazz).getName();
if (className.equals("java.nio.file.Path")) {
try {
if (method_paths_get == null && !method_paths_get_error) {
Class> paths = TypeUtils.loadClass("java.nio.file.Paths");
method_paths_get = paths.getMethod("get", String.class, String[].class);
}
if (method_paths_get != null) {
return (T) method_paths_get.invoke(null, strVal, new String[0]);
}
throw new JSONException("Path deserialize erorr");
} catch (NoSuchMethodException ex) {
method_paths_get_error = true;
} catch (IllegalAccessException ex) {
throw new JSONException("Path deserialize erorr", ex);
} catch (InvocationTargetException ex) {
throw new JSONException("Path deserialize erorr", ex);
}
}
throw new JSONException("MiscCodec not support " + className);
}
throw new JSONException("MiscCodec not support " + clazz.toString());
}
public int getFastMatchToken() {
return JSONToken.LITERAL_STRING;
}
}