/******************************************************************************* * Copyright 2013 Open mHealth * * Licensed 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.openmhealth.reference.domain; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import org.openmhealth.reference.exception.OmhException; /** * <p> * A list of desired columns. * </p> * * <p> * This class is immutable. * </p> * * @author John Jenkins */ public class ColumnList { /** * The separator for columns as defined by Open mHealth. */ public static final String COLUMN_SEPARATOR = "."; /** * The map of children nodes. */ Map<String, ColumnList> children = new HashMap<String, ColumnList>(); /** * Converts a list of {@link ColumnList#COLUMN_SEPARATOR}-separated columns * into a {@link ColumnList} object. * * @param columns * The list of columns. */ public ColumnList(final List<String> columns) { // If the columns are null, then this should just be an empty object. if(columns == null) { return; } // Add each of the columns as children. for(String column : columns) { // Process the node. addChild(column); } } /** * Creates a new {@link ColumnList} object from the column list. * * @param subColumns * The string representing the sub-column and, possibly, its * sub-columns. */ private ColumnList(final String subColumns) { addChild(subColumns); } /** * Returns the number of child elements at this depth. * * @return The number of child elements at this depth. */ public long size() { return children.size(); } /** * Creates a list of {@link #COLUMN_SEPARATOR}-separated strings that * represent this column list. * * @return A list of {@link #COLUMN_SEPARATOR}-separated strings that * represent this list. */ public List<String> toList() { List<String> result = new LinkedList<String>(); for(String childName : children.keySet()) { ColumnList child = children.get(childName); if(child == null) { result.add(childName); } else { for(String childList : child.toList()) { result.add(childName + COLUMN_SEPARATOR + childList); } } } return result; } /** * Creates a comma-separated string of the children. */ public String toString() { // Create the builder. StringBuilder builder = new StringBuilder(); // For each element, add it to the string that is being built. boolean firstPass = true; for(String element : toList()) { if(firstPass) { firstPass = false; } else { builder.append(','); } builder.append(element); } // Return the compiled string. return builder.toString(); } /** * Adds a new child to the current list of children. * * @param column The string representing the child which may be composed of * multiple sub-columns. * * @throws OmhException The column is null or an empty string. */ private void addChild(final String column) throws OmhException { if(column == null) { throw new OmhException("The column is null."); } if(column.trim().length() == 0) { throw new OmhException("The column is empty."); } String[] parts = column.split("\\" + COLUMN_SEPARATOR, 2); String childName = parts[0]; if(parts.length == 1) { children.put(childName, null); } else if(children.containsKey(childName)) { ColumnList child = children.get(childName); if(child != null) { child.addChild(parts[1]); } } else { children.put(childName, new ColumnList(parts[1])); } } }