blob: 215a7a184a1e27aff6092d90ac88885eb4d9356b [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
* <p>
* Contributors:
* Roman Grigoriadi
******************************************************************************/
package org.eclipse.persistence.json.bind.internal.unmarshaller;
import org.eclipse.persistence.json.bind.internal.JsonbContext;
import org.eclipse.persistence.json.bind.internal.JsonbParser;
import org.eclipse.persistence.json.bind.internal.JsonbRiParser;
import org.eclipse.persistence.json.bind.internal.ReflectionUtils;
import org.eclipse.persistence.json.bind.internal.Unmarshaller;
import org.eclipse.persistence.json.bind.internal.properties.MessageKeys;
import org.eclipse.persistence.json.bind.internal.properties.Messages;
import org.eclipse.persistence.json.bind.model.JsonBindingModel;
import javax.json.bind.JsonbException;
import javax.json.bind.serializer.DeserializationContext;
import javax.json.bind.serializer.JsonbDeserializer;
import javax.json.stream.JsonParser;
import java.lang.reflect.Type;
/**
* @author Roman Grigoriadi
*/
public abstract class AbstractContainerDeserializer<T> extends AbstractItem<T> implements JsonbDeserializer<T> {
protected JsonbRiParser.LevelContext parserContext;
/**
* Create instance of current item with its builder.
*
* @param builder
*/
protected AbstractContainerDeserializer(DeserializerBuilder builder) {
super(builder);
}
/**
* Drives JSONP {@link JsonParser} to deserialize json document.
*
* @return instance of a type for this item
*/
@Override
public final T deserialize(JsonParser parser, DeserializationContext context, Type rtType) {
Unmarshaller ctx = (Unmarshaller) context;
ctx.setCurrent(this);
deserializeInternal((JsonbParser) parser, ctx);
ctx.setCurrent(getWrapper());
return getInstance((Unmarshaller) context);
}
protected abstract T getInstance(Unmarshaller unmarshaller);
protected void deserializeInternal(JsonbParser parser, Unmarshaller context) {
parserContext = moveToFirst(parser);
while (parser.hasNext()) {
final JsonParser.Event event = parser.next();
switch (event) {
case START_OBJECT:
case START_ARRAY:
case VALUE_STRING:
case VALUE_NUMBER:
case VALUE_FALSE:
case VALUE_TRUE:
deserializeNext(parser, context);
break;
case KEY_NAME:
break;
case VALUE_NULL:
appendResult(null);
break;
case END_OBJECT:
case END_ARRAY:
return;
default:
throw new JsonbException(Messages.getMessage(MessageKeys.NOT_VALUE_TYPE, event));
}
}
}
/**
* Determine class mappings and create an instance of a new deserializer.
* Currently processed deserializer is pushed to stack, for waiting till new object is finished.
*/
protected abstract void deserializeNext(JsonParser parser, Unmarshaller context);
/**
* Move to first event for current deserializer structure.
* @param parser parser
* @return first event
*/
protected abstract JsonbRiParser.LevelContext moveToFirst(JsonbParser parser);
/**
* Binding model for current deserializer.
* @return model
*/
protected abstract JsonBindingModel getModel();
protected DeserializerBuilder newUnmarshallerItemBuilder(JsonbContext ctx) {
return new DeserializerBuilder(ctx).withWrapper(this).withJsonValueType(JsonValueType.of(parserContext.getLastEvent()));
}
protected JsonbDeserializer<?> newCollectionOrMapItem(Type valueType, JsonbContext ctx) {
Type actualValueType = ReflectionUtils.resolveType(this, valueType);
return newUnmarshallerItemBuilder(ctx).withType(actualValueType).withModel(getModel()).build();
}
/**
* After object is transitively deserialized from JSON, "append" it to its wrapper.
* In case of a field set value to field, in case of collections
* or other embedded objects use methods provided.
* @param result instance result of an item
*/
public abstract void appendResult(Object result);
}