下面列出了怎么用com.fasterxml.jackson.core.JsonStreamContext的API类实例代码及写法,或者点击链接到github查看源代码。
static String toJsonPath(JsonStreamContext context) {
StringBuilder builder = new StringBuilder();
for (JsonStreamContext c = context; c != null; c = c.getParent()) {
if (c.inArray()) {
builder.insert(0, "[" + c.getCurrentIndex() + "]");
} else if (c.inObject()) {
@Nullable String name = c.getCurrentName();
if (name == null || name.isEmpty()) {
builder.insert(0, "[]");
} else if (isAsciiIdentifierPath(name)) {
builder.insert(0, "." + name);
} else {
builder.insert(0, "['" + name + "']");
}
} else if (c.inRoot()) {
builder.insert(0, "$");
}
}
return builder.toString();
}
@Override
public void close() throws IOException {
if (generator.isClosed()) {
return;
}
JsonStreamContext context = generator.getOutputContext();
if ((context != null) && (context.inRoot() == false)) {
throw new IOException("Unclosed object or array found");
}
if (writeLineFeedAtEnd) {
flush();
// Bypass generator to always write the line feed
getLowLevelGenerator().writeRaw(LF);
}
generator.close();
}
@Override
public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
JsonStreamContext jsonStreamContext = p.getParsingContext().getParent();
InnerSearchHit hit = (InnerSearchHit) jsonStreamContext.getCurrentValue();
ESClass refs = null;
if(hit != null) {
if (hit.getIndex() == null) {
refs = getESInnerTypeReferences(hit.getType());
} else {
refs = getESInnerTypeReferences(getTypeName(p));
}
}
if(refs == null){
return ctxt.findRootValueDeserializer(ESSerialThreadLocal.getMapObjectType()).deserialize(p,ctxt);
}
else
{
if(refs instanceof ESTypeReferences)
return ctxt.findRootValueDeserializer(ESSerialThreadLocal.getJavaType(((ESTypeReferences)refs).getHitType())).deserialize(p,ctxt);
else
{
ESClassType classType = (ESClassType)refs;
return ctxt.findRootValueDeserializer(ESSerialThreadLocal.getJavaType(classType.getHitClass())).deserialize(p,ctxt);
}
}
}
protected boolean inRoot() {
if (isFiltered()) {
JsonStreamContext context = filter.getFilterContext();
return ((context != null) && (context.inRoot() && context.getCurrentName() == null));
}
return false;
}
@Override
public void serialize(T value, JsonGenerator gen, SerializerProvider provider) throws IOException {
JsonStreamContext context = gen.getOutputContext();
gen.setCurrentValue(value); // must set manually, or else the result of context.getCurrentValue() will be null。this method will call context.setCurrentValue(value);
gen.writeStartObject(); // writeStartObject(value) will call setCurrentValue(value) well
Class<?> entityClass = value.getClass();
Method[] methods = entityClass.getMethods(); // include method inherited from super classes
for(Method method : methods) {
// check whether serialization will be recursive
if (willRecursive(gen, context, method)) {
gen.writeEndObject();
return;
}
// method annotated with @Field
Field fieldAnnotation = method.getAnnotation(Field.class);
if(fieldAnnotation != null) {
serializeField(value, gen, entityClass, method, fieldAnnotation);
}else {
MultiFields multiFields = method.getAnnotation(MultiFields.class);
if(multiFields != null) {
Field mainFieldAnnotation = multiFields.mainField();
serializeField(value, gen, entityClass, method, mainFieldAnnotation);
}
}
}
// gen.writeObjectField("extra_field", "whatever_value");
gen.writeEndObject();
}
private boolean willRecursive(JsonGenerator gen, JsonStreamContext ctxt, Method method) throws IOException {
if (ctxt != null) {
JsonStreamContext ptxt = ctxt.getParent();
while(ptxt != null) {
// if(ctxt.getCurrentValue() != ptxt.getCurrentValue()) {
// ptxt = ptxt.getParent();
// }else {
// gen.writeEndObject();
// return;
// }
// if(ptxt.getCurrentValue() == null || !ctxt.getCurrentValue().getClass().equals(ptxt.getCurrentValue().getClass())) {
// ptxt = ptxt.getParent();
// }else {
// gen.writeEndObject();
// return;
// }
// String typeName = method.getGenericReturnType().getTypeName();
if(ptxt.getCurrentValue() == null || !ReflectionUtils.getInnermostType(method).equals(ptxt.getCurrentValue().getClass().getCanonicalName())) {
ptxt = ptxt.getParent();
}else {
return true;
}
}
}
return false;
}
private boolean willRecursive(JsonStreamContext ctxt, Method method) throws IOException {
if (ctxt != null) {
JsonStreamContext ptxt;
ptxt = ctxt.getParent();
while(ptxt != null) {
if(ptxt.getCurrentValue() == null
|| !ReflectionUtils.getInnermostType(method).equals(ptxt.getCurrentValue().getClass().getCanonicalName())) {
ptxt = ptxt.getParent();
}else {
return true;
}
}
}
return false;
}
@Override
public Object deserialize(JsonParser p, DeserializationContext ctx) throws IOException {
if(jobsManager == null) {
throw new IllegalStateException("This deserializer need a jobsManager instance, see 'JobParametersDeserializer.setJobsManager'");
}
final JsonStreamContext jsc = p.getParsingContext();
String paramName = null;
JsonStreamContext parent = jsc;
while(parent != null) {
paramName = parent.getCurrentName();
if(paramName != null) {
break;
}
parent = parent.getParent();
}
if(parent == null) {
throw new NullPointerException("Something wrong: we can not find our parent object, " +
"may be you use this deserializer on custom object?");
}
JobParameters.Builder r = (JobParameters.Builder) parent.getParent().getCurrentValue();
String jobType = r.getType();
JobDescription desc = jobsManager.getDescription(jobType);
JobParameterDescription param = desc.getParameters().get(paramName);
TypeFactory typeFactory = ctx.getTypeFactory();
JavaType type;
if(param == null) {
type = typeFactory.constructType(Object.class);
} else {
type = typeFactory.constructType(param.getType());
}
JsonDeserializer<Object> deser = ctx.findNonContextualValueDeserializer(type);
try {
return deser.deserialize(p, ctx);
} catch (Exception e) {
throw new RuntimeException("Can not deserialize '" + jobType + "." + paramName + "' job parameter ", e );
}
}
/**
* Default constructor
* @param message The error message
* @param jsonStreamContext The JSON stream context
* @param throwable An optional throwable associated with the error
*/
JsonError(String message, JsonStreamContext jsonStreamContext,
Throwable throwable)
{
this.message = message;
this.jsonPath = Collections.unmodifiableList(
createJsonPath(jsonStreamContext));
this.throwable = throwable;
}
/**
* Create a list of strings describing the JSON path for the given
* stream context
*
* @param streamContext The stream context
* @return The string list
*/
private static List<String> createJsonPath(JsonStreamContext streamContext)
{
Collection<JsonStreamContext> list = expand(streamContext);
return list.stream()
.map(c -> c.getCurrentName() == null ?
"" : c.getCurrentName())
.collect(Collectors.toList());
}
/**
* Create a collection consisting of stream contexts, starting at the root
* node and ending at the given stream context
*
* @param streamContext The stream context
* @return The collection
*/
private static Collection<JsonStreamContext> expand(
JsonStreamContext streamContext)
{
Deque<JsonStreamContext> collection =
new LinkedList<JsonStreamContext>();
JsonStreamContext current = streamContext;
while (current != null)
{
collection.addFirst(current);
current = current.getParent();
}
return collection;
}
@Override
protected Object deserializeFromObjectUsingNonDefault(JsonParser p, DeserializationContext ctxt) throws IOException {
JsonStreamContext parent = p.getParsingContext().getParent();
// handle embedded types
if (parent != null && parent.getCurrentValue() != null) {
Object value = parent.getCurrentValue();
Class<?> parentClass = value.getClass();
Method method = embeddedGetters.get(parentClass);
if (method == null) {
Class<?> target = getValueType().getRawClass();
for (Method m : parentClass.getDeclaredMethods()) {
if (target.isAssignableFrom(m.getReturnType()) && m.getParameterTypes().length == 0) {
embeddedGetters.put(parentClass, m);
method = m;
break;
}
}
}
if (method != null) {
try {
return method.invoke(value);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
return super.deserializeFromObjectUsingNonDefault(p, ctxt);
}
protected static boolean isInICalProperty(JsonStreamContext context) {
if (context == null) {
return false;
}
Object currentValue = context.getCurrentValue();
if (currentValue == PROPERTY_VALUE) {
return true;
}
return isInICalProperty(context.getParent());
}
String getPropertyName(JsonStreamContext context) {
String name;
if (context.inObject()) {
name = context.getCurrentName();
} else if (context.inArray()) {
name = context.getParent().getCurrentName() + String.format("[%d]", context.getEntryCount());
} else {
name = "<root>";
}
return name;
}
@Override
public void serializeValue(JsonGenerator jgen, Object value) throws IOException {
JsonStreamContext ctxt = jgen.getOutputContext();
try {
super.serializeValue(jgen, value);
} catch (Exception e) {
onSerializationException(ctxt, jgen, value, e);
}
}
@Override
public void serializeValue(JsonGenerator jgen, Object value, JavaType rootType) throws IOException {
JsonStreamContext ctxt = jgen.getOutputContext();
try {
super.serializeValue(jgen, value, rootType);
} catch (Exception e) {
onSerializationException(ctxt, jgen, value, e);
}
}
protected void onSerializationException(JsonStreamContext ctxt, JsonGenerator jgen, Object value, Exception e) throws IOException {
Exceptions.propagateIfFatal(e);
JsonSerializer<Object> unknownTypeSerializer = getUnknownTypeSerializer(value.getClass());
if (unknownTypeSerializer instanceof ErrorAndToStringUnknownTypeSerializer) {
((ErrorAndToStringUnknownTypeSerializer)unknownTypeSerializer).serializeFromError(ctxt, e, value, jgen, this);
} else {
unknownTypeSerializer.serialize(value, jgen, this);
}
}
/**
* only first call return FetchPath
* <p>
* and then call is bean sub-path (property)
*
* @return fetch path or null
*/
private FetchPath getPathProperties(JsonGenerator jsonGenerator) {
FetchPath fetchPath = EbeanUtils.getRequestFetchPath();
if (fetchPath != null) {
JsonStreamContext context = jsonGenerator.getOutputContext();
JsonStreamContext parent = context.getParent();
if (parent == null) {
return fetchPath;
}
StringBuilder path = new StringBuilder();
while (parent != null && !parent.inRoot()) {
if (parent != context.getParent()) {
path.insert(0, '.');
}
path.insert(0, parent.getCurrentName());
parent = parent.getParent();
}
String fp = path.toString();
PathProperties fetch = new PathProperties();
EbeanPathProps src = (EbeanPathProps) fetchPath;
String cp = fp + ".";
for (BeanPathProperties.Props prop : src.getPathProps()) {
String pp = prop.getPath();
if (pp != null) {
if (pp.equals(fp)) {
addToFetchPath(fetch, null, prop);
} else if (pp.startsWith(cp)) {
addToFetchPath(fetch, pp.substring(cp.length()), prop);
}
}
}
return fetch;
}
return null;
}
public NumericallyIndexedObjectBackedArray(ConfigValue n, HoconNodeCursor p) {
super(JsonStreamContext.TYPE_ARRAY, p);
TreeMap<Integer, ConfigValue> sortedContents = new TreeMap<Integer, ConfigValue>();
for (Map.Entry<String, ConfigValue> entry: ((ConfigObject) n).entrySet()) {
try {
Integer key = Integer.parseInt(entry.getKey());
sortedContents.put(key, entry.getValue());
} catch (NumberFormatException e) {
throw new IllegalStateException("Key: '" + entry.getKey() +
"' in object could not be parsed to an Integer, therefor we cannot be using a " +
getClass().getSimpleName());
}
}
_contents = sortedContents.values().iterator();
}
@Override
public JsonStreamContext getParsingContext() {
throw new UnsupportedOperationException();
}
@Override
public JsonStreamContext getParsingContext() {
throw new UnsupportedOperationException();
}
@Override
public JsonStreamContext getParsingContext() {
return jsonParser.getParsingContext();
}
@Override
public JsonStreamContext getOutputContext() {
return null;
}
@Override
public JsonStreamContext getParsingContext() {
return null;
}
private void updateIndenter(JsonStreamContext context) {
boolean inICalProperty = isInICalProperty(context);
super.indentArraysWith(inICalProperty ? propertyIndenter : arrayIndenter);
super.indentObjectsWith(inICalProperty ? propertyIndenter : objectIndenter);
}
protected JsonStreamContext getRootContext() {
return rootContext;
}
public void serializeFromError(JsonStreamContext ctxt, @Nullable Exception error, Object value, JsonGenerator jgen, SerializerProvider configurableSerializerProvider) throws IOException {
if (log.isDebugEnabled())
log.debug("Recovering from json serialization error, serializing "+value+": "+error);
if (BidiSerialization.isStrictSerialization())
throw new JsonMappingException("Cannot serialize "
+ (ctxt!=null && !ctxt.inRoot() ? "object containing " : "")
+ value.getClass().getName()+" when strict serialization requested");
if (WARNED_CLASSES.add(value.getClass().getCanonicalName())) {
log.warn("Standard serialization not possible for "+value.getClass()+" ("+value+")", error);
}
JsonStreamContext newCtxt = jgen.getOutputContext();
// very odd, but flush seems necessary when working with large objects; presumably a buffer which is allowed to clear itself?
// without this, when serializing the large (1.5M) Server json object from BrooklynJacksonSerializerTest creates invalid json,
// containing: "foo":false,"{"error":true,...
jgen.flush();
boolean createObject = !newCtxt.inObject() || newCtxt.getCurrentName()!=null;
if (createObject) {
jgen.writeStartObject();
}
if (allowEmpty(value.getClass())) {
// write nothing
} else {
jgen.writeFieldName("error");
jgen.writeBoolean(true);
jgen.writeFieldName("errorType");
jgen.writeString(NotSerializableException.class.getCanonicalName());
jgen.writeFieldName("type");
jgen.writeString(value.getClass().getCanonicalName());
jgen.writeFieldName("toString");
jgen.writeString(value.toString());
if (error!=null) {
jgen.writeFieldName("causedByError");
jgen.writeString(error.toString());
}
}
if (createObject) {
jgen.writeEndObject();
}
while (newCtxt!=null && !newCtxt.equals(ctxt)) {
if (jgen.getOutputContext().inArray()) { jgen.writeEndArray(); continue; }
if (jgen.getOutputContext().inObject()) { jgen.writeEndObject(); continue; }
break;
}
}
@Override
public JsonStreamContext getParsingContext() {
return _nodeCursor;
}
public RootValue(ConfigValue n, HoconNodeCursor p) {
super(JsonStreamContext.TYPE_ROOT, p);
_node = n;
}
public Array(ConfigValue n, HoconNodeCursor p) {
super(JsonStreamContext.TYPE_ARRAY, p);
_contents = ((ConfigList)n).iterator();
}