001 // Copyright 2007 by Basil Vandegriend. All rights reserved.
002
003 package com.basilv.envgen;
004
005 import com.basilv.core.Assert;
006 import com.basilv.core.StringUtilities;
007 import com.csvreader.CsvReader;
008
009 /**
010 * Loads environment properties from the specified CSV file and populates an instance of
011 * EnvironmentProperties.
012 *
013 * The file format is as follows:
014 * <ul>
015 * <li>Each row corresponds to a single property or to a comment.</li>
016 * <li>For a property, the first column contains the name of the property.<br>
017 * Each subsequent column contains the value of the property for a single environment.</li>
018 * <li>For a comment, the first column must start with the symbol '#' or '//', or be completely empty.
019 * The remainder of the row is ignored. </li>
020 * </ul>
021 */
022 public class EnvironmentPropertiesLoader
023 {
024
025 /**
026 * Load the CSV file into an EnvironmentProperties instance.
027 * @param filename Cannot be null or empty. Must correspond to a CSV file of the correct format.
028 * @return the EnvironmentProperties instance.
029 */
030 public static EnvironmentProperties load(String filename) {
031 Assert.notNullOrEmpty("filename", filename);
032
033 try {
034 CsvReader reader = new CsvReader(filename);
035 try {
036 EnvironmentProperties envProps = null;
037
038 final int FIRST_ROW = 1;
039 int rowNumber = FIRST_ROW; // Indexed from one.
040 while (reader.readRecord()) {
041 int columnCount = reader.getColumnCount();
042 Assert.isTrue("Must have at least two columns - one for the property name " +
043 "and one row per environment for the property value.", columnCount > 1);
044 if (rowNumber == FIRST_ROW) {
045 int envCount = columnCount - 1;
046 envProps = new EnvironmentProperties(envCount);
047 }
048
049 String propertyName = reader.get(0);
050 if (isComment(propertyName)) {
051 continue;
052 }
053
054 for (int column = 1; column < columnCount; column++) {
055 int environment = column - 1;
056 String propertyValue = reader.get(column);
057 envProps.addProperty(environment, propertyName, propertyValue);
058 }
059
060 rowNumber++;
061 }
062 if (envProps == null) {
063 Assert.shouldNotReach("File [" + filename + "] does not contain any rows.");
064 }
065
066 return envProps;
067
068 } finally {
069 reader.close();
070 }
071 } catch (Exception e) {
072 throw new RuntimeException("Error reading cvs file [" +
073 filename + "] due to " + e.getMessage() + ".", e);
074 }
075
076 }
077
078 // Non-private for testing
079 static boolean isComment(String propertyName) {
080 if (StringUtilities.isNullOrEmpty(propertyName)) {
081 return true;
082 }
083
084 if (propertyName.startsWith("#")) {
085 return true;
086 }
087
088 if (propertyName.startsWith("//")) {
089 return true;
090 }
091
092 return false;
093 }
094
095 }