/* * 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 + '}'; } }