org.araqne.confdb.file.Exporter.java Source code

Java tutorial

Introduction

Here is the source code for org.araqne.confdb.file.Exporter.java

Source

/*
 * Copyright 2011 Future Systems, 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 org.araqne.confdb.file;

import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.json.JSONException;
import org.json.JSONWriter;
import org.araqne.codec.Base64;
import org.araqne.codec.UnsupportedTypeException;
import org.araqne.confdb.ConfigCollection;
import org.araqne.confdb.ConfigIterator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Exporter {
    private final Logger logger = LoggerFactory.getLogger(Exporter.class.getName());
    private FileConfigDatabase db;

    /**
     * CAUTION: thread unsafe for performance reason.
     */
    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssZ");

    public Exporter(FileConfigDatabase db) {
        this.db = db;
    }

    public void exportData(OutputStream os) throws IOException {
        if (os == null)
            throw new IllegalArgumentException("export output stream cannot be null");

        logger.debug("araqne confdb: start export data");
        db.lock();
        try {
            OutputStreamWriter writer = new OutputStreamWriter(os, Charset.forName("utf-8"));
            JSONWriter jw = new JSONWriter(writer);

            jw.object();

            jw.key("metadata");
            jw.object();
            jw.key("version").value(1);
            jw.key("date").value(sdf.format(new Date()));
            jw.endObject();

            jw.key("collections");
            jw.object();

            for (String name : db.getCollectionNames()) {
                ConfigCollection col = db.getCollection(name);

                // collection name
                jw.key(name);

                // typed doc list
                jw.array();

                jw.value("list");

                // doc list begin
                jw.array();

                ConfigIterator it = col.findAll();
                try {
                    while (it.hasNext()) {
                        Object doc = it.next().getDocument();
                        jw.value(insertType(doc));
                    }
                } finally {
                    it.close();
                }

                // end of doc list
                jw.endArray();

                // end of typed list
                jw.endArray();
            }

            // end of collection
            jw.endObject();

            // end of master doc
            jw.endObject();
            writer.flush();
            logger.debug("araqne confdb: export complete");
        } catch (JSONException e) {
            throw new IOException(e);
        } finally {
            db.unlock();
        }
    }

    private Object insertType(Object doc) {
        if (doc instanceof String) {
            return createList("string", doc);
        } else if (doc instanceof Integer) {
            return createList("int", doc);
        } else if (doc instanceof Boolean) {
            return createList("bool", doc);
        } else if (doc instanceof Long) {
            return createList("long", doc);
        } else if (doc instanceof Inet4Address) {
            return createList("ip4", ((Inet4Address) doc).getHostAddress());
        } else if (doc instanceof Inet6Address) {
            return createList("ip6", ((Inet6Address) doc).getHostAddress());
        } else if (doc instanceof Double) {
            return createList("double", doc);
        } else if (doc instanceof Float) {
            return createList("float", doc);
        } else if (doc instanceof Date) {
            Date docDate = (Date) doc;
            return createList("date", sdf.format(docDate));
        } else if (doc instanceof Short) {
            return createList("short", doc);
        } else if (doc == null) {
            return createList("null", doc);
        } else if (doc instanceof Map) {
            @SuppressWarnings("unchecked")
            Map<String, Object> m = (Map<String, Object>) doc;

            for (String name : m.keySet()) {
                m.put(name, insertType(m.get(name)));
            }

            return createList("map", m);
        } else if (doc instanceof List) {
            @SuppressWarnings("unchecked")
            List<Object> l = (List<Object>) doc;
            List<Object> newList = new ArrayList<Object>();

            for (Object o : l) {
                newList.add(insertType(o));
            }

            return createList("list", newList);
        } else if (doc.getClass().isArray()) {
            return insertArrayType(doc);
        } else {
            throw new UnsupportedTypeException(
                    "unsupported value [" + doc + "], type [" + doc.getClass().getName() + "]");
        }
    }

    private List<Object> createList(String type, Object doc) {
        List<Object> l = new ArrayList<Object>(2);
        l.add(type);
        l.add(doc);

        return l;
    }

    private Object insertArrayType(Object doc) {
        Class<?> c = doc.getClass().getComponentType();
        if (c == byte.class) {
            byte[] arr = (byte[]) doc;
            return createList("blob", new String(Base64.encode(arr)));
        } else if (c == int.class || c == double.class || c == float.class || c == long.class || c == short.class
                || c == boolean.class) {
            return createList("list", doc);
        } else if (c == char.class) {
            throw new UnsupportedTypeException("unsupported data type [" + c.getName() + "]");
        } else {
            Object[] os = (Object[]) doc;
            Object[] newOs = new Object[os.length];
            for (int index = 0; index < os.length; index++) {
                newOs[index] = insertType(os[index]);
            }

            return createList("list", newOs);
        }
    }
}