com.epam.wilma.sequence.formatters.SequenceAwareJsonTemplateFormatter.java Source code

Java tutorial

Introduction

Here is the source code for com.epam.wilma.sequence.formatters.SequenceAwareJsonTemplateFormatter.java

Source

package com.epam.wilma.sequence.formatters;

/*==========================================================================
Copyright 2013-2016 EPAM Systems
    
This file is part of Wilma.
    
Wilma 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, either version 3 of the License, or
(at your option) any later version.
    
Wilma 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.
    
You should have received a copy of the GNU General Public License
along with Wilma.  If not, see <http://www.gnu.org/licenses/>.
===========================================================================*/

import java.nio.charset.StandardCharsets;
import java.util.Map;

import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.epam.wilma.domain.http.WilmaHttpRequest;
import com.epam.wilma.domain.stubconfig.dialog.response.template.TemplateFormatter;
import com.epam.wilma.domain.stubconfig.parameter.ParameterList;
import com.epam.wilma.domain.sequence.WilmaSequence;
import com.epam.wilma.sequence.formatters.helper.SequenceJsonTransformer;
import com.epam.wilma.webapp.stub.response.formatter.json.JsonTemplateFormatter;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonPrimitive;
import com.jayway.jsonpath.JsonPath;

import javax.servlet.http.HttpServletResponse;

/**
 * Generates a JSON response from the given template resource by using
 * parameters from the request. Properties in the templates with JsonPath value
 * will be replaces with the evaluated expression value (e.g.
 * {@code"$.persons[0].name"}). This formatter has access previous messages of
 * the session. Those messages can be accessed like
 * {@code"$BalanceCheckRequest.card_details.card_number"}).
 *
 * @author Balazs_Berkes
 */
@Component
public class SequenceAwareJsonTemplateFormatter implements TemplateFormatter {

    @Autowired
    private SequenceJsonTransformer sequenceJsonTransformer;

    @Override
    public byte[] formatTemplate(final WilmaHttpRequest wilmaRequest, final HttpServletResponse resp,
            final byte[] templateResource, final ParameterList params) throws Exception {
        JsonElement response = new JsonParser()
                .parse(IOUtils.toString(templateResource, StandardCharsets.UTF_8.name()));
        new SessionAwareJsonTreeEvaluator(wilmaRequest.getBody(), wilmaRequest.getSequence(), params)
                .replaceAllNonRecursive(response);

        return response.toString().getBytes();
    }

    private final class SessionAwareJsonTreeEvaluator extends JsonTemplateFormatter.NonRecursiveJsonTreeEvaluator {

        private static final String SELF_REQUEST_REFFERENCE = "request";
        private static final String SIMPLE_JSON_PATH_PREFIX = "$.";
        private static final String SESSION_JSON_PATH_PREFIX = "$";

        private final WilmaSequence sequence;
        private final ParameterList params;

        private SessionAwareJsonTreeEvaluator(final String source, final WilmaSequence sequence,
                final ParameterList params) {
            super(source);
            this.sequence = sequence;
            this.params = params;
        }

        @Override
        protected void replaceJsonPath(final JsonObject parent, final String key, final JsonPrimitive value) {
            if (isSimpleExpression(value.getAsString())) {
                evaluateSimpleExpression(parent, key, value);
            } else if (isSessionExpression(value.getAsString())) {
                evaluateSessionExpression(parent, key, value);
            }
        }

        private void evaluateSessionExpression(final JsonObject parent, final String key,
                final JsonPrimitive value) {
            String linkedSource = getReferredSource(value.getAsString());
            String jsonQuery = rebuildQuery(value.getAsString());

            String requestValue = JsonPath.read(linkedSource, jsonQuery).toString();
            parent.add(key, new JsonPrimitive(requestValue));
        }

        private void evaluateSimpleExpression(final JsonObject parent, final String key,
                final JsonPrimitive value) {
            String requestValue = JsonPath.read(getSource(), value.getAsString());
            parent.add(key, new JsonPrimitive(requestValue));
        }

        private String rebuildQuery(final String query) {
            String[] parts = query.split("\\.");
            StringBuilder newQuery = new StringBuilder("$");
            for (int i = 1; i < parts.length; i++) {
                newQuery.append('.').append(parts[i]);
            }
            return newQuery.toString();
        }

        private String getReferredSource(final String expression) {
            String[] parts = expression.substring(1).split("\\.");
            String link = parts[0];
            String linkedContent;
            if (SELF_REQUEST_REFFERENCE.equals(link)) {
                linkedContent = getSource();
            } else {
                Map<String, String> map = sequenceJsonTransformer.transform(params, sequence.getPairs());
                linkedContent = map.get(link);
            }
            return linkedContent;
        }

        private boolean isSessionExpression(final String value) {
            return value.startsWith(SESSION_JSON_PATH_PREFIX);
        }

        private boolean isSimpleExpression(final String value) {
            return value.startsWith(SIMPLE_JSON_PATH_PREFIX);
        }
    }

}