package org.xpect.xtext.lib.util; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.eclipse.xtext.generator.InMemoryFileSystemAccess; import com.google.common.base.Function; import com.google.common.base.Joiner; import com.google.common.collect.Lists; import com.google.common.collect.Maps; public class InMemoryFileSystemAccessFormatter implements Function<InMemoryFileSystemAccess, String> { protected static class FileEntryComparator implements Comparator<Map.Entry<String, Object>> { public int compare(Entry<String, Object> o1, Entry<String, Object> o2) { if (o1.getKey() == null) return 1; if (o2.getKey() == null) return -1; return o1.getKey().compareTo(o2.getKey()); } } protected boolean alwaysShowFileName = false; protected String includeOnlyFileNamesEndingWith = null; public InMemoryFileSystemAccessFormatter alwaysShowFileName() { this.alwaysShowFileName = true; return this; } public String apply(InMemoryFileSystemAccess fsa) { return apply(fsa.getAllFiles()); } public String apply(Map<String, Object> files) { Map<String, Object> filtered = filter(files); if (filtered.isEmpty()) return "(no files have been generated)"; else if (filtered.size() == 1 && !alwaysShowFileName) return formatContent(filtered.values().iterator().next()); else { List<Entry<String, Object>> sorted = sort(Lists.newArrayList(filtered.entrySet())); List<String> result = Lists.newArrayList(); for (Map.Entry<String, Object> e : sorted) { StringBuilder buf = new StringBuilder(); buf.append("-- "); buf.append(e.getKey()); buf.append(" --\n "); buf.append(formatContent(e.getValue()).replace("\n", "\n ")); buf.append("\n-- / --"); result.add(buf.toString()); } return Joiner.on("\n").join(result); } } protected Map<String, Object> filter(Map<String, Object> files) { Map<String, Object> filtered = Maps.newHashMap(); for (Map.Entry<String, Object> e : files.entrySet()) if (isFileNameIncluded(e.getKey())) filtered.put(e.getKey(), e.getValue()); return filtered; } protected String formatContent(byte[] content) { return "(binary content)"; } protected String formatContent(CharSequence content) { return content.toString(); } protected String formatContent(Object content) { if (content instanceof CharSequence) return formatContent((CharSequence) content); if (content instanceof byte[]) return formatContent((byte[]) content); if (content != null) return "(unknown content type: " + content.getClass().getName(); return "(null)"; } public String getIncludeOnlyFileNamesEndingWith() { return includeOnlyFileNamesEndingWith; } public InMemoryFileSystemAccessFormatter includeOnlyFileNamesEndingWith(String includeOnlyFileNamesEndingWith) { this.includeOnlyFileNamesEndingWith = includeOnlyFileNamesEndingWith; return this; } public boolean isAlwaysShowFileName() { return alwaysShowFileName; } protected boolean isFileNameIncluded(String fileName) { if (includeOnlyFileNamesEndingWith != null && fileName != null) return fileName.endsWith(includeOnlyFileNamesEndingWith); return true; } protected List<Map.Entry<String, Object>> sort(List<Map.Entry<String, Object>> files) { Collections.sort(files, new FileEntryComparator()); return files; } }