因子水準の展開

因子水準を展開するサンプル

```java
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class TEMP {
	public static void main(String[] args){
		new TEMP();
	}
	
	TEMP() {
		TestCase1 testCase1 = new TestCase1();
		
		List<String> testCasesString = testCase1.getTestCasesStringList();
		for(String testCaseString : testCasesString) {
			System.out.println(testCaseString);
		}
		
		List<Map<String, String>> testCases = testCase1.getTestCasesMapList();
		for(Map<String, String> testcase : testCases){
			System.out.print(testcase.get("甲"));
			System.out.print(testcase.get("乙"));
			System.out.println(testcase.get("丙"));
		}
	}
	
	class TestCase1 extends AbsFactorLevelTypeTestCase{
		
		void setFactorAndLevel() {
			factors.add(new Factor("甲").setLevels("1", "2"));
			factors.add(new Factor("乙").setLevels("a", "b", "c"));
			factors.add(new Factor("丙").setLevels("A", "B", "C"));
			exclude("2,b,C");
		}
	}
	
	/**
	 * @author maruta_r
	 * For test-cases using factor and level.
	 */
	abstract class AbsFactorLevelTypeTestCase {
		protected List<Factor> factors = new ArrayList<Factor>();
		private List<String> testCases;
		
		AbsFactorLevelTypeTestCase(){
			setFactorAndLevel();
		}
		
		/**
		 * Specify factors and levels at subclass.
		 * 
		 * [EXAMPLE]
		 * void setFactorAndLevel() {
		 *   factors.add(new Factor("甲").setLevels("1", "2"));
		 *   factors.add(new Factor("乙").setLevels("a", "b", "c"));
		 *   factors.add(new Factor("丙").setLevels("A", "B", "C"));
		 * }
		 * 
		 */
		abstract void setFactorAndLevel();
		
		/**
		 * Combination to be excluded from tests.
		 * Specify the name of each levels separated by comma.
		 * 
		 * [EXAMPLE]
		 * exclude("1,a,B");
		 * exclude("2,c,A");
		 */
		protected void exclude(String combination) {
			if(this.testCases == null) expandAll();
			testCases.remove(combination);
		}
		
		/**
		 * @return All combination of each levels separated by comma. Header included.
		 */
		public List<String> getTestCasesStringList() {
			if(this.testCases == null) expandAll(); 
			return this.testCases;
		}
		
		/**
		 * @return Test-cases converted Map List. Factor name is key.
		 */
		public List<Map<String, String>> getTestCasesMapList() {
			List<Map<String, String>> testCasesMapList = new ArrayList<Map<String, String>>();
			List<String> copy = new ArrayList<String>(getTestCasesStringList());
			
			String[] keys = null;
			for(String testCase : copy) {
				Map<String, String> map = new HashMap<String, String>();
				
				//setting header as a keys
				String[] values = testCase.split(",");
				if(keys == null) {
					keys = values;
					continue;
				}
				
				for(int i = 0; i < values.length; i++) {
					map.put(keys[i], values[i]);
				}
				
				testCasesMapList.add(map);
			}
			return testCasesMapList;
		}
		
		private void expandAll() {
			List<String> result = new ArrayList<String>();
			result.add("");
			String header = "";
			
			for(Factor factor : factors) {
				if(header.length() > 0) header += ",";
				header += factor.getFoctorName();
				
				List<String> newResult = new ArrayList<String>();
				
				for(int i = 0; i < result.size(); i++) {
					List<String> levels = factor.getLevels();
					
					for(String level : levels) {
						String prevStr = result.get(i);
						if(prevStr.length() > 0) prevStr += ",";
						newResult.add(prevStr + level);
					}
				}
				result = newResult;
			}
			result.add(0, header);
			this.testCases =  result;
		}
	}
	
	class Factor {
		private final String factorName;
		private List<String> levels = new ArrayList<String>();

		
		public Factor(String factorName, String... args) {
			this.factorName = factorName;
			setLevels(args);
		}
		
		public Factor setLevels(String... args) {
			for(int i = 0; i < args.length; i++){
				levels.add(args[i]);
			}
			return this;
		}
		
		public List<String> getLevels() {
			 return this.levels;
		}
		
		public String getFoctorName() {
			return this.factorName;
		}
	}
```