blob: eb1665c4f54dc6ef4da3343da6138f23f3064631 [file] [log] [blame]
/**
* HTML via Java(tm) Language Bindings
* Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. apidesign.org
* designates this particular file as subject to the
* "Classpath" exception as provided by apidesign.org
* in the License file that accompanied this code.
*
* You should have received a copy of the GNU General Public License
* along with this program. Look for COPYING file in the top folder.
* If not, see http://wiki.apidesign.org/wiki/GPLwithClassPathException
*/
package org.apidesign.html.json.impl;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import net.java.html.json.Context;
import static org.apidesign.html.json.impl.ContextAccessor.findTechnology;
import org.apidesign.html.json.spi.JSONCall;
import org.apidesign.html.json.spi.Technology;
import org.apidesign.html.json.spi.Transfer;
/**
*
* @author Jaroslav Tulach <jtulach@netbeans.org>
*/
public final class JSON {
private JSON() {
}
public static void extract(Context c, Object value, String[] props, Object[] values) {
Transfer t = ContextAccessor.findTransfer(c);
t.extract(value, props, values);
}
private static Object getProperty(Context c, Object obj, String prop) {
if (prop == null) return obj;
String[] arr = { prop };
Object[] val = { null };
extract(c, obj, arr, val);
return val[0];
}
public static Object toJSON(Object value) {
if (value == null) {
return "null";
}
if (value instanceof Enum) {
value = value.toString();
}
if (value instanceof String) {
return '"' +
((String)value).
replace("\"", "\\\"").
replace("\n", "\\n").
replace("\r", "\\r").
replace("\t", "\\t")
+ '"';
}
return value.toString();
}
public static String toString(Context c, Object obj, String prop) {
obj = getProperty(c, obj, prop);
return obj instanceof String ? (String)obj : null;
}
public static Number toNumber(Context c, Object obj, String prop) {
obj = getProperty(c, obj, prop);
if (!(obj instanceof Number)) {
obj = Double.NaN;
}
return (Number)obj;
}
public static <M> M toModel(Context c, Class<M> aClass, Object data, Object object) {
Technology<?> t = findTechnology(c);
Object o = t.toModel(aClass, data);
return aClass.cast(o);
}
public static void loadJSON(
Context c, Runnable whenDone, Object[] result,
String urlBefore, String urlAfter
) {
loadJSON(c, whenDone, result, urlBefore, urlAfter, null, null);
}
public static void loadJSON(
Context c, Runnable whenDone, Object[] result,
String urlBefore, String urlAfter, String method,
Object data
) {
JSONCall call = PropertyBindingAccessor.createCall(whenDone, result, urlBefore, urlAfter, method, data);
Transfer t = ContextAccessor.findTransfer(c);
t.loadJSON(call);
}
private static final Map<Class,FromJSON<?>> froms;
static {
Map<Class,FromJSON<?>> m = new HashMap<Class,FromJSON<?>>();
froms = m;
}
public static void register(FromJSON<?> from) {
froms.put(from.factoryFor(), from);
}
public static boolean isModel(Class<?> clazz) {
for (int i = 0; i < 2; i++) {
FromJSON<?> from = froms.get(clazz);
if (from == null) {
initClass(clazz);
} else {
return true;
}
}
return false;
}
public static <T> T readStream(Context c, Class<T> modelClazz, InputStream data)
throws IOException {
Transfer tr = ContextAccessor.findTransfer(c);
return read(c, modelClazz, tr.toJSON((InputStream)data));
}
public static <T> T read(Context c, Class<T> modelClazz, Object data) {
if (modelClazz == String.class) {
return modelClazz.cast(data.toString());
}
for (int i = 0; i < 2; i++) {
FromJSON<?> from = froms.get(modelClazz);
if (from == null) {
initClass(modelClazz);
} else {
return modelClazz.cast(from.read(c, data));
}
}
throw new NullPointerException();
}
static void initClass(Class<?> modelClazz) {
try {
// try to resolve the class
ClassLoader l;
try {
l = modelClazz.getClassLoader();
} catch (SecurityException ex) {
l = null;
}
if (l != null) {
Class.forName(modelClazz.getName(), true, l);
}
modelClazz.newInstance();
} catch (Exception ex) {
// ignore and try again
}
}
}