com.indeed.imhotep.web.QueryMetadata.java Source code

Java tutorial

Introduction

Here is the source code for com.indeed.imhotep.web.QueryMetadata.java

Source

/*
 * Copyright (C) 2014 Indeed Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the
 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.indeed.imhotep.web;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.base.Charsets;
import com.google.common.base.Throwables;
import com.google.common.collect.Lists;
import com.google.common.io.CharStreams;

import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * @author vladimir
 */

public class QueryMetadata {
    private final List<QueryMetadataItem> items = Lists.newArrayList();

    public void addItem(String name, Object value) {
        addItem(name, value, true);
    }

    public void addItem(String name, Object value, boolean sendPending) {
        items.add(new QueryMetadataItem(name, value, sendPending));
    }

    public String toJSON() {
        final ObjectMapper mapper = new ObjectMapper();
        final ObjectNode headerObject = mapper.createObjectNode();
        for (QueryMetadataItem queryMetadataItem : items) {
            headerObject.put(queryMetadataItem.name, queryMetadataItem.value);
        }
        return headerObject.toString();
    }

    public void setPendingHeaders(HttpServletResponse resp) {
        for (QueryMetadataItem queryMetadataItem : items) {
            if (queryMetadataItem.sendPending) {
                resp.setHeader(queryMetadataItem.name, queryMetadataItem.value);
                queryMetadataItem.markSent();
            }
        }
    }

    /**
     * Serializes this object to the stream as JSON.
     * Closes the stream after.
     */
    public void toStream(OutputStream outputStream) {
        final String stringSerialization = toJSON();
        try {
            final OutputStreamWriter outputStreamWriter = new OutputStreamWriter(
                    new BufferedOutputStream(outputStream), Charsets.UTF_8);
            outputStreamWriter.write(stringSerialization);
            outputStreamWriter.close();
        } catch (IOException e) {
            throw Throwables.propagate(e);
        }
    }

    public static QueryMetadata fromStream(InputStream inputStream) {
        final String stringVal = streamToString(inputStream);
        return fromJSON(stringVal);
    }

    public static QueryMetadata fromJSON(String json) {
        final QueryMetadata metadataObject = new QueryMetadata();
        final ObjectMapper mapper = new ObjectMapper();
        try {
            final JsonNode root = mapper.readTree(json);
            final Iterator<Map.Entry<String, JsonNode>> nodeIterator = root.fields();
            while (nodeIterator.hasNext()) {
                Map.Entry<String, JsonNode> item = nodeIterator.next();
                metadataObject.addItem(item.getKey(), item.getValue().textValue());
            }
        } catch (IOException e) {
            throw Throwables.propagate(e);
        }
        return metadataObject;
    }

    /**
     * Adds metadata items from another QueryMetadata instance to this instance.
     */
    public void mergeIn(QueryMetadata otherInstance) {
        for (QueryMetadataItem otherItem : otherInstance.items) {
            boolean alreadyExists = false;
            for (QueryMetadataItem item : items) {
                if (item.name.equals(otherItem.name)) {
                    alreadyExists = true;
                }
            }
            if (!alreadyExists) {
                addItem(otherItem.name, otherItem.value);
            }
        }
    }

    private static String streamToString(InputStream inputStream) {
        try {
            final InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charsets.UTF_8);
            final String stringValue = CharStreams.toString(inputStreamReader);
            inputStreamReader.close();
            return stringValue;
        } catch (IOException e) {
            throw Throwables.propagate(e);
        }
    }

    private static class QueryMetadataItem {
        public final String name;
        public final String value;
        public boolean sendPending;

        public QueryMetadataItem(String name, Object value, boolean sendPending) {
            this.name = name;
            this.value = value == null ? "" : String.valueOf(value);
            this.sendPending = sendPending;
        }

        public void markSent() {
            sendPending = false;
        }
    }
}