package rhogenwizard.buildfile.converter; import java.io.BufferedReader; import java.io.DataInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.InputStreamReader; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.StringTokenizer; import org.yaml.snakeyaml.Yaml; public class CustomConverter extends AbstractStructureConverter { private static final String shiftLevel = " "; private static final String crCode = "\n"; private static final char rubyCommentsCode = '#'; private static final String rubyCommentsCodeStr = "#"; Map<Integer, String> m_commentsStorage = new HashMap<Integer, String>(); @Override public String convertStructure() { StringBuilder sb = new StringBuilder(); Iterator<Map.Entry<Object, Object>> it = m_dataStructure.entrySet().iterator(); while (it.hasNext()) { Map.Entry<Object, Object> pairs = it.next(); Object key = pairs.getKey(); Object val = pairs.getValue(); if (key != null) { saveSelector(sb, "", key.toString(), val); } } return addComments(sb.toString()); } private String addComments(String rawYmlData) { StringTokenizer st = new StringTokenizer(rawYmlData, crCode); StringBuilder sb = new StringBuilder(); int lineNum = 0; while (st.hasMoreTokens()) { String tokenString = st.nextToken(); String comments = m_commentsStorage.get(new Integer(lineNum)); if (comments != null) { sb.append(comments); } sb.append(tokenString); sb.append(crCode); lineNum++; } return sb.toString(); } void saveSelector(StringBuilder sb, String prefix, String name, Object val) { if (name == null || name.isEmpty()) return; if (val instanceof List) { saveList(sb, prefix, name, (List<?>)val); } else if (val instanceof Map) { saveMap(sb, prefix, name, (Map<?, ?>)val); } else { saveValue(sb, prefix, name, val); } } private void saveValue(StringBuilder sb, String prefix, String name, Object l) { sb.append(prefix); sb.append(name); sb.append(": "); if (l != null) { if (l instanceof String) { String itemValue = l.toString(); itemValue = itemValue.replace("\\", "/"); if (itemValue.length() != 0) { sb.append("\""); sb.append(itemValue.toString()); sb.append("\""); } } else { sb.append(l.toString()); } } sb.append(crCode); } private void saveList(StringBuilder sb, String prefix, String name, List<?> l) { sb.append(prefix); sb.append(name); sb.append(":"); sb.append(crCode); for (int i=0; i<l.size(); ++i) { Object val = l.get(i); sb.append(prefix); sb.append(shiftLevel + "- "); String renderVal = val.toString(); if (renderVal.length() != 0) { char firstChar = renderVal.charAt(0); char lstChar = renderVal.charAt(renderVal.length() - 1); if (firstChar == '*' || lstChar == '*') { sb.append("\""); sb.append(val.toString()); sb.append("\""); } else { sb.append(val.toString()); } } sb.append(crCode); } } private void saveMap(StringBuilder sb, String prefix, String name, Map<?, ?> m) { if (name != null) { sb.append(prefix); sb.append(name); sb.append(":"); sb.append(crCode); } Iterator<?> it = m.entrySet().iterator(); while (it.hasNext()) { Map.Entry<?, ?> pairs = (Map.Entry<?, ?>)it.next(); Object key = pairs.getKey(); Object val = pairs.getValue(); saveSelector(sb, prefix + shiftLevel, key.toString(), val); } } private void fillCommentsMap(String filePath) { try { FileInputStream fStream = new FileInputStream(filePath); DataInputStream in = new DataInputStream(fStream); BufferedReader br = new BufferedReader(new InputStreamReader(in)); String strLine = null; StringBuilder commentsBuilder = new StringBuilder(); int lineNum = 0; while((strLine = br.readLine()) != null) { String trimLine = strLine.trim(); if (trimLine.length() != 0) { if (trimLine.charAt(0) == rubyCommentsCode) { commentsBuilder.append(trimLine); commentsBuilder.append(crCode); continue; } else { if (trimLine.contains(rubyCommentsCodeStr)) { int startChar = trimLine.indexOf(rubyCommentsCodeStr); if (startChar > 0) { m_commentsStorage.put(new Integer(lineNum), trimLine.substring(startChar, trimLine.length() - 1) + crCode); continue; } } } } if (commentsBuilder.length() != 0) { m_commentsStorage.put(new Integer(lineNum), commentsBuilder.toString()); commentsBuilder = new StringBuilder(); } ++lineNum; } br.close(); in.close(); fStream.close(); } catch (Exception e) { e.printStackTrace(); } } @Override public Map<Object, Object> getDataStorage(String filePath) throws FileNotFoundException { File ymlFile = new File(filePath); Yaml yaml = new Yaml(); FileReader fr = new FileReader(ymlFile); fillCommentsMap(filePath); return cast(yaml.load(fr)); } @SuppressWarnings("unchecked") private Map<Object, Object> cast(Object mapObject) { return (Map<Object, Object>) mapObject; } }