diff --git a/java/src/org/broadinstitute/sting/playground/utils/report/AnalysisModuleScanner.java b/java/src/org/broadinstitute/sting/playground/utils/report/AnalysisModuleScanner.java index 95f4a3746..382086316 100644 --- a/java/src/org/broadinstitute/sting/playground/utils/report/AnalysisModuleScanner.java +++ b/java/src/org/broadinstitute/sting/playground/utils/report/AnalysisModuleScanner.java @@ -1,7 +1,30 @@ +/* + * Copyright (c) 2010. The Broad Institute + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + package org.broadinstitute.sting.playground.utils.report; import org.broadinstitute.sting.playground.utils.report.tags.Analysis; -import org.broadinstitute.sting.playground.utils.report.tags.Datum; +import org.broadinstitute.sting.playground.utils.report.tags.DataPoint; import org.broadinstitute.sting.playground.utils.report.tags.Param; import org.broadinstitute.sting.playground.utils.report.tags.Table; import org.broadinstitute.sting.utils.StingException; @@ -23,9 +46,9 @@ import java.util.Map; public class AnalysisModuleScanner { // what we extracted from the class - private Map parameters = new HashMap(); // the parameter annotations - private Map tables = new HashMap(); // the table annotations - private Map datums = new HashMap(); // the data we've discovered + private Map parameters = new HashMap(); // the parameter annotations + private Map tables = new HashMap(); // the table annotations + private Map datums = new HashMap(); // the data we've discovered private Analysis analysis; // the analysis annotation // private storage of the class type @@ -68,11 +91,11 @@ public class AnalysisModuleScanner { for (Field f : cls.getDeclaredFields()) for (Annotation annotation : f.getAnnotations()) { if (annotation.annotationType().equals(Param.class)) - parameters.put((Param) annotation, f); + parameters.put(f, (Param) annotation); if (annotation.annotationType().equals(Table.class)) - tables.put((Table) annotation, f); - if (annotation.annotationType().equals(Datum.class)) - datums.put((Datum) annotation, f); + tables.put(f,(Table) annotation); + if (annotation.annotationType().equals(DataPoint.class)) + datums.put(f,(DataPoint) annotation); } } @@ -80,7 +103,7 @@ public class AnalysisModuleScanner { * * @return get the list of parameters we found */ - public Map getParameters() { + public Map getParameters() { return parameters; } @@ -88,7 +111,7 @@ public class AnalysisModuleScanner { * * @return a list of table annotations found */ - public Map getTables() { + public Map getTables() { return tables; } @@ -96,7 +119,7 @@ public class AnalysisModuleScanner { * * @return a map of the datum annotations found */ - public Map getData() { + public Map getData() { return datums; } @@ -107,4 +130,8 @@ public class AnalysisModuleScanner { public Analysis getAnalysis() { return analysis; } + + public Class getModuleClass() { + return cls; + } } diff --git a/java/src/org/broadinstitute/sting/playground/utils/report/Marshaller.java b/java/src/org/broadinstitute/sting/playground/utils/report/Marshaller.java deleted file mode 100644 index 4b82388e2..000000000 --- a/java/src/org/broadinstitute/sting/playground/utils/report/Marshaller.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2010. The Broad Institute - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -package org.broadinstitute.sting.playground.utils.report; - -import org.broadinstitute.sting.playground.utils.report.formats.OutputFormater; -import org.broadinstitute.sting.playground.utils.report.tags.*; -import org.broadinstitute.sting.utils.StingException; - -import java.util.Collection; - -/** - * @author aaron - *

- * Class Marshaller - *

- * Given an analysis scan, an object, and a formatter, this class emits - * a report to disk (or other source). - */ -public class Marshaller { - private String report; - private OutputFormater formatter; - - /** - * create a report - * @param reportName the report name - * @param formater the formater to use - */ - public void createReport(String reportName, OutputFormater formater) { - this.formatter = formater; - report = reportName; - formatter.startReport(report); - } - - /** - * add an analysis module to the output source - * @param toMarshall the object to marshall - */ - public void write(Object toMarshall) { - AnalysisModuleScanner moduleScanner = new AnalysisModuleScanner(toMarshall); - formatter.addAnalysis(moduleScanner.getAnalysis()); - for (Param p : moduleScanner.getParameters().keySet()) - try { - formatter.addParam(p, moduleScanner.getParameters().get(p).get(toMarshall).toString()); - } catch (IllegalAccessException e) { - throw new StingException("Unable to access variable " + moduleScanner.getParameters().get(p), e); - } - for (Datum d : moduleScanner.getData().keySet()) - try { - formatter.addDatum(d, moduleScanner.getData().get(d).get(toMarshall).toString()); - } catch (IllegalAccessException e) { - throw new StingException("Unable to access variable " + moduleScanner.getParameters().get(d), e); - } - for (Table t : moduleScanner.getTables().keySet()) - try { - formatter.addTable(t, new TableContainer((Collection) moduleScanner.getTables().get(t).get(toMarshall),t.columns())); - } catch (IllegalAccessException e) { - throw new StingException("Unable to access variable " + moduleScanner.getParameters().get(t), e); - } - - } - - public void endReport() { - formatter.endReport(); - } - - -} diff --git a/java/src/org/broadinstitute/sting/playground/utils/report/ReportMarshaller.java b/java/src/org/broadinstitute/sting/playground/utils/report/ReportMarshaller.java new file mode 100644 index 000000000..47e51bbdc --- /dev/null +++ b/java/src/org/broadinstitute/sting/playground/utils/report/ReportMarshaller.java @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2010. The Broad Institute + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +package org.broadinstitute.sting.playground.utils.report; + +import freemarker.template.Configuration; +import freemarker.template.DefaultObjectWrapper; +import freemarker.template.Template; +import freemarker.template.TemplateException; +import org.broadinstitute.sting.playground.utils.report.chunks.AnalysisChunk; +import org.broadinstitute.sting.playground.utils.report.chunks.DataPointChunk; +import org.broadinstitute.sting.playground.utils.report.chunks.ParameterChunk; +import org.broadinstitute.sting.playground.utils.report.chunks.TableChunk; +import org.broadinstitute.sting.utils.Pair; + +import java.io.*; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +/** + * @author aaron + *

+ * Class ReportMarshaller + *

+ * marshall report data out of the GATK. + */ +public class ReportMarshaller { + private Template temp; + + // the aggregation of all our analyses + private HashMap map; + private List analysisObjects; + private final File writeLocation; + /** + * create a marshaled object + * + * @param reportName the report name + * @param template the template to use + */ + public ReportMarshaller(String reportName, File filename, Template template) { + map = new HashMap(); + analysisObjects = new ArrayList(); + map.put("title",reportName); + temp = template; + this.writeLocation = filename; + } + + /** + * create a marshaled object + * + * @param reportName the report name + */ + public ReportMarshaller(String reportName, File filename) { + map = new HashMap(); + analysisObjects = new ArrayList(); + map.put("title",reportName); + temp = createTemplate(); + this.writeLocation = filename; + } + + + /** + * add an analysis module to the output source + * + * @param toMarshall the object to marshall + */ + public void write(Object toMarshall) { + // Create a context to add data to + HashMap analysisMap = new HashMap(); + AnalysisModuleScanner moduleScanner = new AnalysisModuleScanner(toMarshall); + + Pair pair; + + pair = addAnalysis(moduleScanner); + analysisMap.put(pair.first,pair.second); + + pair = addParameters(toMarshall, moduleScanner); + analysisMap.put(pair.first,pair.second); + + pair = addDataPoints(toMarshall, moduleScanner); + analysisMap.put(pair.first,pair.second); + + pair = addTables(toMarshall, moduleScanner); + analysisMap.put(pair.first,pair.second); + + // add it to the list of analysis maps we have + analysisObjects.add(analysisMap); + + } + + private Pair addAnalysis(AnalysisModuleScanner moduleScanner) { + AnalysisChunk chunk = new AnalysisChunk(moduleScanner); + return new Pair("analysis",chunk); + } + + /** + * output the Params objects we find + * + * @param toMarshall the object to output + * @param moduleScanner our scanner, which stores the annotated field information + * @return a pair of a string and the list of Chunk objects + */ + private Pair addParameters(Object toMarshall, AnalysisModuleScanner moduleScanner) { + List chunks = new ArrayList(); + for (Field f : moduleScanner.getParameters().keySet()) { + ParameterChunk chunk = new ParameterChunk(f, moduleScanner.getParameters(), toMarshall); + if (chunk.isValid()) chunks.add(chunk); + } + return new Pair("parameters",chunks); + } + + /** + * output the Table objects we find + * + * @param toMarshall the object to output + * @param moduleScanner our scanner, which stores the annotated field information + * @return a pair of a string and the list of Chunk objects + */ + private Pair addTables(Object toMarshall, AnalysisModuleScanner moduleScanner) { + List chunks = new ArrayList(); + for (Field f : moduleScanner.getTables().keySet()) { + TableChunk chunk = new TableChunk(f, moduleScanner.getTables(), toMarshall); + if (chunk.isValid()) chunks.add(chunk); + } + return new Pair("tables",chunks); + } + + /** + * output the DataPoint objects we find + * + * @param toMarshall the object to output + * @param moduleScanner our scanner, which stores the annotated field information + * @return a pair of a string and the list of Chunk objects + */ + private Pair addDataPoints(Object toMarshall, AnalysisModuleScanner moduleScanner) { + List chunks = new ArrayList(); + for (Field f : moduleScanner.getData().keySet()) { + DataPointChunk chunk = new DataPointChunk(f, moduleScanner.getData(), toMarshall); + if (chunk.isValid()) chunks.add(chunk); + } + return new Pair("datapoints",chunks); + } + + /** call the method to finalize the report */ + public void close() { + map.put("analyses",this.analysisObjects); + Writer out = null; + try { + out = new OutputStreamWriter(new FileOutputStream(this.writeLocation)); + } catch (FileNotFoundException e) { + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } + try { + temp.process(map, out); + out.flush(); + } catch (TemplateException e) { + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } catch (IOException e) { + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } + } + + private Template createTemplate() { + Configuration cfg = new Configuration(); + try { + cfg.setDirectoryForTemplateLoading(new File("templates")); + } catch (IOException e) { + e.printStackTrace(); + } + cfg.setObjectWrapper(new DefaultObjectWrapper()); + Template temp = null; + try { + temp = cfg.getTemplate("myTestTemp.ftl"); + } catch (IOException e) { + e.printStackTrace(); + } + return temp; + } +} + + diff --git a/java/src/org/broadinstitute/sting/playground/utils/report/TableContainer.java b/java/src/org/broadinstitute/sting/playground/utils/report/TableContainer.java deleted file mode 100644 index 2b2881125..000000000 --- a/java/src/org/broadinstitute/sting/playground/utils/report/TableContainer.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2010. The Broad Institute - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -package org.broadinstitute.sting.playground.utils.report; - -import java.util.*; - - -/** - * - * @author aaron - * - * Class TableContainer - * - * represents a table of data, and formats according to column count. Do not use, - * needs improvement. This is a stand-in for something better. - */ -public class TableContainer { - private List tableEntries; - private int columns = 2; // default to two - - public TableContainer(Collection tbl, int columns) { - tableEntries = new ArrayList(); - if (tbl instanceof List || tbl instanceof Vector || tbl instanceof Set) - tableEntries.addAll(tbl); - if (tbl instanceof Map) - for (Object key : ((Map)tbl).keySet()) { - tableEntries.add(key); - tableEntries.add(((Map) tbl).get(key)); - } - this.columns = columns; - } - - public List> toRows() { - ArrayList> list = new ArrayList>(); - List currentRow = new ArrayList(); - for (Object obj : tableEntries) { - if (currentRow.size() >= columns) { - list.add(currentRow); - currentRow = new ArrayList(); - } - currentRow.add(obj); - } - list.add(currentRow); - return list; - } - -} diff --git a/java/src/org/broadinstitute/sting/playground/utils/report/TableFormatter.java b/java/src/org/broadinstitute/sting/playground/utils/report/TableFormatter.java new file mode 100644 index 000000000..3527af51b --- /dev/null +++ b/java/src/org/broadinstitute/sting/playground/utils/report/TableFormatter.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2010. The Broad Institute + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +package org.broadinstitute.sting.playground.utils.report; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; + + +/** + * + * @author aaron + * + * Class TableFormatter + * + * a helper class for formatting a table of data. Given a collection, it formats it into rows and columns. + * If it's a Map, values are emited as key, value, key, value, so it may make sense to have colums set to 2. + * + * TODO: Needs some cleanup + * + */ +public class TableFormatter { + public Object tableEntries; // data storage + private int columns = 2; // default to two columns of data, overridden in the constructor + + + public TableFormatter(Collection tbl, int columns) { + tableEntries = tbl; + this.columns = columns; + } + + public TableFormatter(Object tbl) { + tableEntries = tbl; + } + + /** + * convert the underlying object to a list of lists, for convenient output + * @return a list of list of objects (a list for each row, then a list of row members) + */ + public List> toRows() { + if (tableEntries instanceof Collection) + return collectionToTable(((Collection)tableEntries)); + else if (tableEntries instanceof Map) + return mapToTable(((Map)tableEntries)); + else + throw new UnsupportedOperationException("underlying collection must be an instance of type Collection or of type Map"); + } + + private List> mapToTable(Map collection) { + ArrayList> list = new ArrayList>(); + for (Object obj : collection.keySet()) { + List currentRow = new ArrayList(); + currentRow.add(obj); + Object data = collection.get(obj); + currentRow.add(data.toString()); + + list.add(currentRow); + } + + return list; + } + + private List> collectionToTable(Collection collection) { + ArrayList> list = new ArrayList>(); + List currentRow = new ArrayList(); + for (Object obj : collection) { + if (currentRow.size() >= columns) { + list.add(currentRow); + currentRow = new ArrayList(); + } + currentRow.add(obj); + } + list.add(currentRow); + return list; + } + +} diff --git a/java/src/org/broadinstitute/sting/playground/utils/report/chunks/AnalysisChunk.java b/java/src/org/broadinstitute/sting/playground/utils/report/chunks/AnalysisChunk.java new file mode 100644 index 000000000..c51011e46 --- /dev/null +++ b/java/src/org/broadinstitute/sting/playground/utils/report/chunks/AnalysisChunk.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2010. The Broad Institute + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +package org.broadinstitute.sting.playground.utils.report.chunks; + +import org.broadinstitute.sting.playground.utils.report.AnalysisModuleScanner; +import org.broadinstitute.sting.playground.utils.report.tags.Analysis; + + +/** + * @author aaron + *

+ * Class AnalysisChunk + *

+ * The basic data we've decorated an analysis with + */ +public class AnalysisChunk implements Chunk { + public String name; + public String description; + public String version; + public String className; + /** + * extract the analysis data from an analysis annotation using the module scanner. + * @param moduleScanner the module scanner + */ + public AnalysisChunk(AnalysisModuleScanner moduleScanner) { + Analysis a = moduleScanner.getAnalysis(); + name = (a.name().equals("") ? moduleScanner.getModuleClass().getSimpleName() : a.name()); + description = a.description(); + version = a.version().equals("") ? "unknown" : a.version(); + className = moduleScanner.getModuleClass().getName(); + + } + + public String getName() { + return name; + } + + public String getDescription() { + return description; + } + + public String getVersion() { + return version; + } + + public String getClassName() { + return className; + } + + /** + * is the chunk we've created valid? Invalid chunk would contain null data, or various other + * factors that eliminate a chunk from being outputted. + * + * @return true if it's valid, false if not. + */ + @Override + public boolean isValid() { + if (name == null || name.equals("")) return false; + if (description == null || description.equals("")) return false; + if (version == null) return false; + if (className == null || className.equals("")) return false; + return true; + } +} diff --git a/java/src/org/broadinstitute/sting/playground/utils/report/chunks/Chunk.java b/java/src/org/broadinstitute/sting/playground/utils/report/chunks/Chunk.java new file mode 100644 index 000000000..1bc73070c --- /dev/null +++ b/java/src/org/broadinstitute/sting/playground/utils/report/chunks/Chunk.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2010. The Broad Institute + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +package org.broadinstitute.sting.playground.utils.report.chunks; + +/** + * @author aaron + *

+ * Interface Chunk + *

+ * the basics of what a report data chunk needs to have + */ +public interface Chunk { + /** + * is the chunk we've created valid? Invalid chunk would contain null data, or various other + * factors that eliminate a chunk from being outputted. + * + * @return true if it's valid, false if not. + */ + public boolean isValid(); +} diff --git a/java/src/org/broadinstitute/sting/playground/utils/report/chunks/DataPointChunk.java b/java/src/org/broadinstitute/sting/playground/utils/report/chunks/DataPointChunk.java new file mode 100644 index 000000000..013493936 --- /dev/null +++ b/java/src/org/broadinstitute/sting/playground/utils/report/chunks/DataPointChunk.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2010. The Broad Institute + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +package org.broadinstitute.sting.playground.utils.report.chunks; + +import org.broadinstitute.sting.playground.utils.report.tags.DataPoint; +import org.broadinstitute.sting.utils.StingException; + +import java.lang.reflect.Field; +import java.util.Map; + + +/** + * @author aaron + *

+ * Class DataPointChunk + *

+ * a data point chunk + */ +public class DataPointChunk implements Chunk { + public String name; + public String description; + public String value; + + /** + * create a DataPointChunk from extracted information + * + * @param dpf the datapoint field + * @param mappings the mapping of datapoints to fields in the analysis object + * @param toMarshall the object we're marshaling from + */ + public DataPointChunk(Field dpf, Map mappings, Object toMarshall) { + try { + // make sure we can access the field + dpf.setAccessible(true); + name = mappings.get(dpf).name().equals("") ? dpf.getName() : mappings.get(dpf).name(); + description = mappings.get(dpf).description(); + value = dpf.get(toMarshall).toString(); + } catch (IllegalAccessException e) { + throw new StingException("Unable to access variable " + mappings.get(mappings.get(dpf)), e); + } + } + + public String getName() { + return name; + } + + public String getDescription() { + return description; + } + + public String getValue() { + return value; + } + + /** + * is the chunk we've created valid? Invalid chunk would contain null data, or various other + * factors that eliminate a chunk from being outputted. + * + * @return true if it's valid, false if not. + */ + @Override + public boolean isValid() { + if (name == null || name.equals("")) return false; + if (description == null || description.equals("")) return false; + return value != null; + } +} diff --git a/java/src/org/broadinstitute/sting/playground/utils/report/chunks/ParameterChunk.java b/java/src/org/broadinstitute/sting/playground/utils/report/chunks/ParameterChunk.java new file mode 100644 index 000000000..679ddb6e1 --- /dev/null +++ b/java/src/org/broadinstitute/sting/playground/utils/report/chunks/ParameterChunk.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2010. The Broad Institute + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +package org.broadinstitute.sting.playground.utils.report.chunks; + +import org.broadinstitute.sting.playground.utils.report.tags.Param; +import org.broadinstitute.sting.utils.StingException; + +import java.lang.reflect.Field; +import java.util.Map; + + +/** + * @author aaron + *

+ * Class ParameterChunk + *

+ * The basics of a parameter + */ +public class ParameterChunk implements Chunk { + public String name; + public String description; + public String value; + + /** + * create a ParameterChunk from extracted information + * + * @param pf the parameter annotated field + * @param mappings the mapping of params to fields in the analysis object + * @param toMarshall the object we're marshaling from + */ + public ParameterChunk(Field pf, Map mappings, Object toMarshall) { + try { + // make sure we can access the field + pf.setAccessible(true); + name = mappings.get(pf).name().equals("") ? pf.getName() : mappings.get(pf).name(); + description = mappings.get(pf).description(); + value = pf.get(toMarshall).toString(); + } catch (IllegalAccessException e) { + throw new StingException("Unable to access variable " + pf, e); + } + } + + public String getName() { + return name; + } + + public String getDescription() { + return description; + } + + public String getValue() { + return value; + } + + /** + * is the chunk we've created valid? Invalid chunk would contain null data, or various other + * factors that eliminate a chunk from being outputted. + * + * @return true if it's valid, false if not. + */ + @Override + public boolean isValid() { + if (name == null || name.equals("")) return false; + if (description == null || description.equals("")) return false; + if (value == null) return false; + return true; + } +} diff --git a/java/src/org/broadinstitute/sting/playground/utils/report/chunks/TableChunk.java b/java/src/org/broadinstitute/sting/playground/utils/report/chunks/TableChunk.java new file mode 100644 index 000000000..381f8e201 --- /dev/null +++ b/java/src/org/broadinstitute/sting/playground/utils/report/chunks/TableChunk.java @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2010. The Broad Institute + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +package org.broadinstitute.sting.playground.utils.report.chunks; + +import org.broadinstitute.sting.playground.utils.report.TableFormatter; +import org.broadinstitute.sting.playground.utils.report.tags.Table; +import org.broadinstitute.sting.utils.StingException; + +import java.lang.reflect.Field; +import java.util.List; +import java.util.Map; + + +/** + * @author aaron + *

+ * Class TableChunk + *

+ * all the information we gleam from a Table annotation, including the table entries + */ +public class TableChunk implements Chunk { + public final String name; + public final String header; + public final String description; + public final int columns; + public final TableFormatter table; + + /** + * create a TableChunk from extracted information + * + * @param tbf the Table annotated field + * @param mappings the mapping of datapoints to fields in the analysis object + * @param toMarshall the object we're marshaling from + */ + public TableChunk(Field tbf, Map mappings, Object toMarshall) { + try { + // make sure we can access the field + tbf.setAccessible(true); + name = mappings.get(tbf).name().equals("") ? tbf.getName() : mappings.get(tbf).name(); + description = mappings.get(tbf).description(); + header = mappings.get(tbf).header(); + columns = mappings.get(tbf).columns(); + table = new TableFormatter(tbf.get(toMarshall)); + } catch (IllegalAccessException e) { + throw new StingException("Unable to access variable " + tbf, e); + } + } + + public String getName() { + return name; + } + + public String getHeader() { + return header; + } + + public String getDescription() { + return description; + } + + public int getColumns() { + return columns; + } + + public TableFormatter getTable() { + return table; + } + + public List> getRows() { + return table.toRows(); + } + + /** + * is the chunk we've created valid? Invalid chunk would contain null data, or various other + * factors that eliminate a chunk from being outputted. + * + * @return true if it's valid, false if not. + */ + @Override + public boolean isValid() { + if (this.name == null || this.name.equals("")) return false; + if (this.header == null || this.header.equals("")) return false; + if (this.description == null) return false; + if (columns < 1) return false; + if (table == null || table.tableEntries == null) return false; + return true; + } +} diff --git a/java/src/org/broadinstitute/sting/playground/utils/report/formats/OutputFormater.java b/java/src/org/broadinstitute/sting/playground/utils/report/formats/OutputFormater.java deleted file mode 100644 index e7117dce6..000000000 --- a/java/src/org/broadinstitute/sting/playground/utils/report/formats/OutputFormater.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2010. The Broad Institute - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -package org.broadinstitute.sting.playground.utils.report.formats; - -import org.broadinstitute.sting.playground.utils.report.TableContainer; -import org.broadinstitute.sting.playground.utils.report.tags.*; - - -/** - * - * @author aaron - * - * Class OutputFormater - * - * The formatter defines a perticular output format style. The formatter methods - * are required to be called in the following order: - * - * 1. startReport() - * 2. for each analysis module: - * addAnalysis() - * with many addParam(), addTable(), and addDatum() in no particular order promised - * 3. endReport() - */ -public interface OutputFormater { - /** - * start the report, given the report tag - * @param reportName the report name. - */ - public void startReport(String reportName); - - /** - * add an analysis to the report - * @param analysisTag the analysis tag - */ - public void addAnalysis(Analysis analysisTag); - - /** - * add a parameter value to the output location - * @param value - */ - public void addParam(Param paramTag, String value); - - /** - * add a parameter value to the output location - * @param value - */ - public void addTable(Table tableTag, TableContainer value); - - /** - * add a datum object to the output location - * @param value - */ - public void addDatum(Datum datumTag, String value); - - /** - * end the report - */ - public void endReport(); -} diff --git a/java/src/org/broadinstitute/sting/playground/utils/report/formats/SimpleTextOutputer.java b/java/src/org/broadinstitute/sting/playground/utils/report/formats/SimpleTextOutputer.java deleted file mode 100644 index 816b19ca8..000000000 --- a/java/src/org/broadinstitute/sting/playground/utils/report/formats/SimpleTextOutputer.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (c) 2010. The Broad Institute - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -package org.broadinstitute.sting.playground.utils.report.formats; - -import org.broadinstitute.sting.playground.utils.report.TableContainer; -import org.broadinstitute.sting.playground.utils.report.tags.*; -import org.broadinstitute.sting.utils.StingException; - -import java.io.*; -import java.util.List; - - -/** - * - * @author aaron - * - * Class SimpleTextOutputer - * - * a very small demo of text output, just to use for testing and development - */ -public class SimpleTextOutputer implements OutputFormater { - protected PrintWriter out; - protected String terminator = "\n"; - protected String spacer = "\t\t\t"; - /** - * create a simple text output format given the output file - * @param outputFile - */ - public SimpleTextOutputer(File outputFile) { - try { - FileOutputStream stream = new FileOutputStream(outputFile); - out = new PrintWriter(stream); - } catch (FileNotFoundException e) { - throw new StingException("Unable to find file ",e); - } - } - - /** - * start the report, given the report tag - * - * @param reportTag the report tag, which describes the basics of the report - */ - @Override - public void startReport(String reportTag) { - out.write("----------------" + reportTag + "----------------" + terminator); - } - - /** - * add an analysis to the report - * - * @param analysisTag the analysis tag - */ - @Override - public void addAnalysis(Analysis analysisTag) { - out.write("----------------" + analysisTag.name() + "----------------" + terminator); - out.write(String.format("Name%s%s%s",spacer,analysisTag.name(),terminator)); - out.write(String.format("Description\t\t%s%s",analysisTag.description(),terminator)); - out.write(String.format("Version%s%s%s",spacer,analysisTag.version(),terminator)); - } - - /** - * add a parameter value to the output location - * - * @param value - */ - @Override - public void addParam(Param paramTag, String value) { - out.write(String.format("Param %s%s%s%s",paramTag.name(),spacer,value,terminator)); - } - - /** - * add a parameter value to the output location - * - * @param value - */ - @Override - public void addTable(Table tableTag, TableContainer value) { - out.write(tableTag.name()); - boolean first = false; - for (List row : value.toRows()) { - if (!first) first = true; - else out.write("\t"); - out.write("\t\t"); - for (Object obj: row) out.write(obj+","); - out.write(terminator); - } - - } - - /** - * add a datum object to the output location - * - * @param value - */ - @Override - public void addDatum(Datum datumTag, String value) { - out.write("Datum "+datumTag.name()+spacer+value+terminator); - } - - /** - * end the report - * - */ - @Override - public void endReport() { - out.write("----------------" + "----------------" + terminator); - out.close(); - } -} diff --git a/java/src/org/broadinstitute/sting/playground/utils/report/tags/Analysis.java b/java/src/org/broadinstitute/sting/playground/utils/report/tags/Analysis.java index 0e2dea55b..584831aa8 100644 --- a/java/src/org/broadinstitute/sting/playground/utils/report/tags/Analysis.java +++ b/java/src/org/broadinstitute/sting/playground/utils/report/tags/Analysis.java @@ -12,7 +12,7 @@ import java.lang.annotation.RetentionPolicy; */ @Retention(RetentionPolicy.RUNTIME) public @interface Analysis { - String name(); // the name of the analysis + String name() default ""; // the name of the analysis String description(); // its description, required - String version() default "unversioned"; // the version, not always used + String version() default ""; // the version, not always used } diff --git a/java/src/org/broadinstitute/sting/playground/utils/report/tags/Datum.java b/java/src/org/broadinstitute/sting/playground/utils/report/tags/DataPoint.java similarity index 85% rename from java/src/org/broadinstitute/sting/playground/utils/report/tags/Datum.java rename to java/src/org/broadinstitute/sting/playground/utils/report/tags/DataPoint.java index 9ffcd1bb3..c19b6d620 100644 --- a/java/src/org/broadinstitute/sting/playground/utils/report/tags/Datum.java +++ b/java/src/org/broadinstitute/sting/playground/utils/report/tags/DataPoint.java @@ -29,13 +29,13 @@ import java.lang.annotation.RetentionPolicy; /** * @author aaron *

- * Annotation Datum + * Annotation DataPoint *

- * The basic Datum annotation, for fields in an analysis that + * The basic DataPoint annotation, for fields in an analysis that * are to be output as data. */ @Retention(RetentionPolicy.RUNTIME) -public @interface Datum { - String name(); // the name, required - String description(); // a description +public @interface DataPoint { + String name() default ""; // the name, required + String description(); // a description } \ No newline at end of file diff --git a/java/test/org/broadinstitute/sting/playground/utils/report/AnalysisModuleScannerTest.java b/java/test/org/broadinstitute/sting/playground/utils/report/AnalysisModuleScannerTest.java index 818c27e23..23a69b826 100644 --- a/java/test/org/broadinstitute/sting/playground/utils/report/AnalysisModuleScannerTest.java +++ b/java/test/org/broadinstitute/sting/playground/utils/report/AnalysisModuleScannerTest.java @@ -2,6 +2,7 @@ package org.broadinstitute.sting.playground.utils.report; import org.broadinstitute.sting.BaseTest; import org.broadinstitute.sting.playground.utils.report.tags.Analysis; +import org.broadinstitute.sting.playground.utils.report.tags.DataPoint; import org.broadinstitute.sting.playground.utils.report.tags.Param; import org.broadinstitute.sting.playground.utils.report.tags.Table; import org.junit.Assert; @@ -25,12 +26,12 @@ public class AnalysisModuleScannerTest extends BaseTest { AnalysisModuleScanner scanner = new AnalysisModuleScanner(FakeAnalysis.class); // check we found one param, and check its description - Assert.assertEquals(1, scanner.getParameters().size()); - Assert.assertTrue("basic description".equals(scanner.getParameters().keySet().iterator().next().description())); + Assert.assertEquals(3, scanner.getParameters().size()); + Assert.assertTrue("basic description".equals(scanner.getParameters().values().iterator().next().description())); // check that we've found a table, and check its description Assert.assertEquals(1, scanner.getTables().size()); - Assert.assertTrue("Generate a table from this data".equals(scanner.getTables().keySet().iterator().next().description())); + Assert.assertTrue("Generate a table from this data".equals(scanner.getTables().values().iterator().next().description())); // check that the analysis name and description were set Assert.assertTrue("testAnalysis".equals(scanner.getAnalysis().name())); @@ -48,6 +49,21 @@ class FakeAnalysis { @Param(description = "basic description") public String text = "GRRR"; + @Param(description = "basic description") + public String text2superlonganme = "GRRR"; + + @Param(description = "basic description") + public String text3 = "GRRR"; + + @DataPoint(description = "basic description") + public String text4 = "GRRR"; + + @DataPoint(description = "basic description") + public String text5 = "GRRR"; + + @DataPoint(description = "basic description") + public String text6 = "GRRR"; + @Table(name="FakeTable", description = "Generate a table from this data",columns=3) public List values = new ArrayList(); diff --git a/java/test/org/broadinstitute/sting/playground/utils/report/MarshallerTest.java b/java/test/org/broadinstitute/sting/playground/utils/report/ReportMarshallerTest.java similarity index 62% rename from java/test/org/broadinstitute/sting/playground/utils/report/MarshallerTest.java rename to java/test/org/broadinstitute/sting/playground/utils/report/ReportMarshallerTest.java index 6475095fb..0e83c65ca 100644 --- a/java/test/org/broadinstitute/sting/playground/utils/report/MarshallerTest.java +++ b/java/test/org/broadinstitute/sting/playground/utils/report/ReportMarshallerTest.java @@ -24,35 +24,39 @@ package org.broadinstitute.sting.playground.utils.report; import org.broadinstitute.sting.BaseTest; -import org.broadinstitute.sting.playground.utils.report.formats.SimpleTextOutputer; import org.junit.Test; -import java.io.File; - /** - * - * @author aaron - * - * Class MarshallerTest - * - * test out the marshaller + * @author aaron + *

+ * Class ReportMarshallerTest + *

+ * test out the marshaller */ -public class MarshallerTest extends BaseTest { +public class ReportMarshallerTest extends BaseTest { @Test public void testMarshalling() { - // output file - /*File fl = new File("testfile.txt"); - fl.deleteOnExit(); - Marshaller m = new Marshaller(); - SimpleTextOutputer format = new SimpleTextOutputer(fl); + /*Configuration cfg = new Configuration(); + try { + cfg.setDirectoryForTemplateLoading(new File("templates")); + } catch (IOException e) { + e.printStackTrace(); + } + cfg.setObjectWrapper(new DefaultObjectWrapper()); + Template temp = null; + try { + temp = cfg.getTemplate("myTestTemp.ftl"); + } catch (IOException e) { + e.printStackTrace(); + } FakeAnalysis fa = new FakeAnalysis(); - - // start the marshall - m.createReport("Fake Report",format); - m.write(fa); - m.write(fa); - m.write(fa); - m.endReport();*/ + File fl = new File("testFile.out"); + fl.deleteOnExit(); + ReportMarshaller marsh = new ReportMarshaller("report",fl,temp); + marsh.write(fa); + marsh.write(fa); + marsh.write(fa); + marsh.close();*/ } }