001// Copyright 2007 by Basil Vandegriend. All rights reserved. 002 003package com.basilv.envgen; 004 005import com.basilv.core.Assert; 006import com.basilv.core.StringUtilities; 007import 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 */ 022public 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 String propertyName = reader.get(0); 042 if (isComment(propertyName)) { 043 continue; 044 } 045 046 int columnCount = reader.getColumnCount(); 047 Assert.isTrue("Must have at least two columns - one for the property name " + 048 "and one row per environment for the property value.", columnCount > 1); 049 if (rowNumber == FIRST_ROW) { 050 int envCount = columnCount - 1; 051 envProps = new EnvironmentProperties(envCount); 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}