org.apache.provisionr.amazon.core.ImageTable.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.provisionr.amazon.core.ImageTable.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.apache.provisionr.amazon.core;

import com.google.common.base.Charsets;
import com.google.common.base.Function;
import com.google.common.base.Objects;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableTable;
import com.google.common.collect.Iterables;
import static com.google.common.collect.Iterables.transform;
import static com.google.common.collect.Lists.newArrayList;
import com.google.common.collect.Maps;
import com.google.common.collect.Table;
import com.google.common.collect.Tables;
import com.google.common.io.Resources;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class ImageTable {

    private static final Splitter COMMA = Splitter.on(",").trimResults();

    /**
     * Load the list of AMIs from a resource file (csv format)
     * <p/>
     * Note: the parser is doing only split by comma. There is no
     * support for escaping line components
     *
     * @param resource path to resource
     * @return an instance of {@see ImageTable}
     * @throws IOException
     */
    public static ImageTable fromCsvResource(String resource) throws IOException {
        checkNotNull(resource, "resource is null");

        List<String> lines = Resources.readLines(Resources.getResource(ImageTable.class, resource), Charsets.UTF_8);
        checkArgument(!lines.isEmpty(), "the resource is an empty file");

        final ImmutableTable.Builder<String, String, String> table = ImmutableTable.builder();
        final Iterable<String> headers = extractHeaders(lines);

        int index = 0;
        for (String line : Iterables.skip(lines, 1)) {
            final Iterable<Table.Cell<String, String, String>> cells = combineHeadersWithLinePartsAsTableCells(
                    index, headers, COMMA.split(line));
            for (Table.Cell<String, String, String> cell : cells) {
                table.put(cell);
            }
            index++;
        }

        return new ImageTable(table.build());
    }

    static Iterable<Table.Cell<String, String, String>> combineHeadersWithLinePartsAsTableCells(int index,
            Iterable<String> headers, Iterable<String> lineParts) {
        final String rowKey = "" + index;
        return transform(zip(headers, lineParts),
                new Function<Map.Entry<String, String>, Table.Cell<String, String, String>>() {
                    @Override
                    public Table.Cell<String, String, String> apply(Map.Entry<String, String> entry) {
                        checkNotNull(entry, "entry is null");
                        return Tables.immutableCell(rowKey, entry.getKey(), entry.getValue());
                    }
                });
    }

    static <K, V> Iterable<Map.Entry<K, V>> zip(Iterable<K> first, Iterable<V> second) {
        checkArgument(Iterables.size(first) == Iterables.size(second), "iterables don't have the same size");

        final Iterator<K> iterator = first.iterator();
        return newArrayList(transform(second, new Function<V, Map.Entry<K, V>>() {
            @Override
            public Map.Entry<K, V> apply(V input) {
                return Maps.immutableEntry(iterator.next(), input);
            }
        }));
    }

    static Iterable<String> extractHeaders(List<String> lines) {
        String headerLine = Iterables.getFirst(lines, "");
        checkArgument(!headerLine.isEmpty(), "Found an empty header line");

        return COMMA.split(headerLine);
    }

    private final Table<String, String, String> table;

    public ImageTable(Table<String, String, String> table) {
        this.table = checkNotNull(table, "table is null");
    }

    Table<String, String, String> getTable() {
        return table;
    }

    public ImageTableQuery query() {
        return new ImageTableQuery(this);
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(table);
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final ImageTable other = (ImageTable) obj;
        return Objects.equal(this.table, other.table);
    }

    @Override
    public String toString() {
        return "ImageTable{" + "table=" + table + '}';
    }
}