/** * Copyright 2004-2016 Riccardo Solmi. All rights reserved. * This file is part of the Whole Platform. * * The Whole Platform is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The Whole Platform 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the Whole Platform. If not, see <http://www.gnu.org/licenses/>. */ package org.whole.lang.json.util; import java.io.IOException; import org.whole.lang.builders.IBuilderOperation; import org.whole.lang.factories.RegistryConfigurations; import org.whole.lang.json.builders.IJSONBuilder; import org.whole.lang.json.factories.JSONEntityFactory; import org.whole.lang.json.model.Value; import org.whole.lang.json.reflect.JSONLanguageKit; import org.whole.lang.model.IEntity; import org.whole.lang.templates.ITemplateFactory; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonToken; /** * @author Riccardo Solmi */ public class JSONParserTemplateFactory implements ITemplateFactory<Value> { private Value template; protected JsonParser parser; protected JSONEntityFactory factory; protected IJSONBuilder builder; public JSONParserTemplateFactory(JsonParser parser) { this.parser = parser; this.factory = JSONEntityFactory.instance(RegistryConfigurations.RESOLVER); } public void apply(IBuilderOperation operation) { this.builder = (IJSONBuilder) operation.wGetBuilder(JSONLanguageKit.URI); try { stream(); } catch (Exception e) { throw new IllegalArgumentException(e); } } public Value create() { try { return (Value) build(); } catch (Exception e) { throw new IllegalArgumentException(e); } } public Value share() { if (template == null) template = create(); return template; } public void stream() throws JsonParseException, IOException { switch (parser.nextToken()) { case START_OBJECT: builder.Object_(); do { stream(); } while (parser.getCurrentToken() != JsonToken.END_OBJECT); parser.clearCurrentToken(); break; case FIELD_NAME: builder.Pair_(); builder.Name(parser.getText()); stream(); builder._Pair(); break; case END_OBJECT: builder._Object(); break; case START_ARRAY: builder.Array_(); do { stream(); } while (parser.getCurrentToken() != JsonToken.END_ARRAY); parser.clearCurrentToken(); break; case END_ARRAY: builder._Array(); break; case VALUE_STRING: builder.String(parser.getText()); break; case VALUE_NUMBER_FLOAT: builder.Decimal(parser.getDoubleValue()); break; case VALUE_NUMBER_INT: builder.Int(parser.getLongValue()); break; case VALUE_FALSE: builder.Bool(false); break; case VALUE_TRUE: builder.Bool(true); break; case VALUE_NULL: builder.Null(); break; default: throw new IllegalArgumentException(); } } public IEntity build() throws JsonParseException, IOException { switch (parser.nextToken()) { case START_OBJECT: Value object = factory.createObject(); do { IEntity value = build(); if (parser.getCurrentToken() == JsonToken.END_OBJECT) { parser.clearCurrentToken(); return object; } object.wAdd(value); } while (true); case FIELD_NAME: return factory.createPair(factory.createName(parser.getText()), (Value) build()); case END_OBJECT: return null; case START_ARRAY: Value array = factory.createArray(); do { IEntity value = build(); if (parser.getCurrentToken() == JsonToken.END_ARRAY) { parser.clearCurrentToken(); return array; } array.wAdd(value); } while (true); case END_ARRAY: return null; case VALUE_STRING: return factory.createString(parser.getText()); case VALUE_NUMBER_FLOAT: return factory.createDecimal(parser.getDoubleValue()); case VALUE_NUMBER_INT: return factory.createInt(parser.getLongValue()); case VALUE_FALSE: return factory.createBool(false); case VALUE_TRUE: return factory.createBool(true); case VALUE_NULL: return factory.createNull(); default: throw new IllegalArgumentException(); } } }