View Javadoc

1   /*
2   
3       dsh-venn-tools  Command line tools for venn diagrams.
4       Copyright (c) 2010-2013 held jointly by the individual authors.
5   
6       This library is free software; you can redistribute it and/or modify it
7       under the terms of the GNU Lesser General Public License as published
8       by the Free Software Foundation; either version 3 of the License, or (at
9       your option) any later version.
10  
11      This library is distributed in the hope that it will be useful, but WITHOUT
12      ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
13      FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14      License for more details.
15  
16      You should have received a copy of the GNU Lesser General Public License
17      along with this library;  if not, write to the Free Software Foundation,
18      Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA.
19  
20      > http://www.fsf.org/licensing/licenses/lgpl.html
21      > http://www.opensource.org/licenses/lgpl-license.php
22  
23  */
24  package org.dishevelled.venn.tools;
25  
26  import java.io.BufferedWriter;
27  import java.io.File;
28  import java.io.OutputStreamWriter;
29  import java.io.PrintWriter;
30  
31  import java.util.Iterator;
32  
33  import org.dishevelled.commandline.ArgumentList;
34  import org.dishevelled.commandline.CommandLine;
35  import org.dishevelled.commandline.CommandLineParseException;
36  import org.dishevelled.commandline.CommandLineParser;
37  import org.dishevelled.commandline.Switch;
38  import org.dishevelled.commandline.Usage;
39  
40  import org.dishevelled.commandline.argument.FileArgument;
41  
42  import org.dishevelled.venn.TernaryVennModel;
43  
44  import org.dishevelled.venn.swing.TernaryVennLabel;
45  
46  /**
47   * Venn three input files.
48   *
49   * @author  Michael Heuer
50   * @version $Revision$ $Date$
51   */
52  public final class Venn3
53      extends AbstractVennRunnable
54  {
55      /** First input file. */
56      private final File first;
57  
58      /** Second input file. */
59      private final File second;
60  
61      /** Third input file. */
62      private final File third;
63  
64      /** First only output file, if any. */
65      private final File firstOnly;
66  
67      /** Second only output file, if any. */
68      private final File secondOnly;
69  
70      /** Third only output file, if any. */
71      private final File thirdOnly;
72  
73      /** First second output file, if any. */
74      private final File firstSecond;
75  
76      /** Second third output file, if any. */
77      private final File secondThird;
78  
79      /** Intersection output file, if any. */
80      private final File intersection;
81  
82      /** Union output file, if any. */
83      private final File union;
84  
85      /** Usage string. */
86      private static final String USAGE = "java Venn3 [args] first second third";
87  
88  
89      /**
90       * Create a new venn 3 with the specified arguments.
91       *
92       * @param count true to output count(s) only
93       * @param header true to ouput header(s)
94       * @param first first input file
95       * @param second second input file
96       * @param third third input file
97       * @param firstOnly first only output file
98       * @param secondOnly second only output file
99       * @param thirdOnly third only output file
100      * @param firstSecond first second output file
101      * @param secondThird second third output file
102      * @param intersection intersection output file
103      * @param union union output file
104      */
105     private Venn3(final boolean count,
106                   final boolean header,
107                   final File first,
108                   final File second,
109                   final File third,
110                   final File firstOnly,
111                   final File secondOnly,
112                   final File thirdOnly,
113                   final File firstSecond,
114                   final File secondThird,
115                   final File intersection,
116                   final File union)
117     {
118         super(count, header);
119         this.first = first;
120         this.second = second;
121         this.third = third;
122 
123         // default all to stdout if none are specified
124         if ((firstOnly == null)
125             && (secondOnly == null)
126             && (thirdOnly == null)
127             && (firstSecond == null)
128             && (secondThird == null)
129             && (intersection == null)
130             && (union == null))
131         {
132             this.firstOnly = STDOUT;
133             this.secondOnly = STDOUT;
134             this.thirdOnly = STDOUT;
135             this.firstSecond = STDOUT;
136             this.secondThird = STDOUT;
137             this.intersection = STDOUT;
138             this.union = STDOUT;
139         }
140         else
141         {
142             this.firstOnly = firstOnly;
143             this.secondOnly = secondOnly;
144             this.thirdOnly = thirdOnly;
145             this.firstSecond = firstSecond;
146             this.secondThird = secondThird;
147             this.intersection = intersection;
148             this.union = union;
149         }
150     }
151 
152 
153     /** {@inheritDoc} */
154     public void run()
155     {
156         TernaryVennLabel<String> label = new TernaryVennLabel<String>(first.getName(), read(first), second.getName(), read(second), third.getName(), read(third));
157         TernaryVennModel<String> model = label.getModel();
158 
159         // write individually to output files first
160         write(label.getFirstOnlyLabelText(), model.firstOnly(), firstOnly);
161         write(label.getSecondOnlyLabelText(), model.secondOnly(), secondOnly);
162         write(label.getThirdOnlyLabelText(), model.thirdOnly(), thirdOnly);
163         write(label.getFirstSecondLabelText(), model.firstSecond(), firstSecond);
164         write(label.getSecondThirdLabelText(), model.secondThird(), secondThird);
165         write(label.getIntersectionLabelText(), model.intersection(), intersection);
166         write(label.getUnionLabelText(), model.union(), union);
167 
168         // write collectively to stdout next
169         boolean fo = STDOUT.equals(firstOnly);
170         boolean so = STDOUT.equals(secondOnly);
171         boolean to = STDOUT.equals(thirdOnly);
172         boolean fs = STDOUT.equals(firstSecond);
173         boolean st = STDOUT.equals(secondThird);
174         boolean i = STDOUT.equals(intersection);
175         boolean u = STDOUT.equals(union);
176 
177         PrintWriter stdout = null;
178         stdout = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
179         if (header())
180         {
181             write(fo, label.getFirstOnlyLabelText(), stdout);
182             write(so, label.getSecondOnlyLabelText(), stdout);
183             write(to, label.getThirdOnlyLabelText(), stdout);
184             write(fs, label.getFirstSecondLabelText(), stdout);
185             write(st, label.getSecondThirdLabelText(), stdout);
186             write(i, label.getIntersectionLabelText(), stdout);
187             write(u, label.getUnionLabelText(), stdout);
188             // todo trim extra \t
189             stdout.print("\n");
190         }
191 
192         if (count())
193         {
194             write(fo, model.firstOnly().size(), stdout);
195             write(so, model.secondOnly().size(), stdout);
196             write(to, model.thirdOnly().size(), stdout);
197             write(fs, model.firstSecond().size(), stdout);
198             write(st, model.secondThird().size(), stdout);
199             write(i, model.intersection().size(), stdout);
200             write(u, model.union().size(), stdout);
201             // todo trim extra \t
202             stdout.print("\n");
203         }
204         else
205         {
206             boolean remaining = fo || so || to || fs || st || i || u;
207             Iterator<String> foit = model.firstOnly().iterator();
208             Iterator<String> soit = model.secondOnly().iterator();
209             Iterator<String> toit = model.thirdOnly().iterator();
210             Iterator<String> fsit = model.firstSecond().iterator();
211             Iterator<String> stit = model.secondThird().iterator();
212             Iterator<String> iit = model.intersection().iterator();
213             Iterator<String> uit = model.union().iterator();
214             while (remaining)
215             {
216                 write(fo, foit, stdout);
217                 write(so, soit, stdout);
218                 write(to, toit, stdout);
219                 write(fs, fsit, stdout);
220                 write(st, stit, stdout);
221                 write(i, iit, stdout);
222                 write(u, uit, stdout);
223                 remaining = (fo && foit.hasNext())
224                     || (so && soit.hasNext())
225                     || (to && toit.hasNext())
226                     || (fs && fsit.hasNext())
227                     || (st && stit.hasNext())
228                     || (i && iit.hasNext())
229                     || (u && uit.hasNext());
230 
231                 // todo trim extra \t
232                 stdout.print("\n");
233             }
234         }
235         try
236         {
237             stdout.close();
238         }
239         catch (Exception e)
240         {
241             // ignore
242         }
243     }
244 
245 
246     /**
247      * Main.
248      *
249      * @param args command line arguments
250      */
251     public static void main(final String[] args)
252     {
253         CommandLine commandLine = null;
254         ArgumentList arguments = null;
255         try
256         {
257             Switch help = new Switch("h", "help", "display help message");
258             Switch count = new Switch("c", "count", "output count(s) only");
259             Switch header = new Switch("e", "header", "output header(s)");
260             FileArgument firstOnly = new FileArgument("f", "first-only", "first only output file", false);
261             FileArgument secondOnly = new FileArgument("s", "second-only", "second only output file", false);
262             FileArgument thirdOnly = new FileArgument("t", "third-only", "third only output file", false);
263             FileArgument firstSecond = new FileArgument("j", "first-second", "first second output file", false);
264             FileArgument secondThird = new FileArgument("k", "second-third", "second third output file", false);
265             FileArgument intersection = new FileArgument("i", "intersection", "intersection output file", false);
266             FileArgument union = new FileArgument("u", "union", "union output file", false);
267 
268             arguments = new ArgumentList(help, count, header, firstOnly, secondOnly, thirdOnly, firstSecond, secondThird, intersection, union);
269             commandLine = new CommandLine(args);
270             CommandLineParser.parse(commandLine, arguments);
271 
272             if (help.wasFound())
273             {
274                 Usage.usage(USAGE, null, commandLine, arguments, System.out);
275             }
276             else
277             {
278                 if (args.length < 3)
279                 {
280                     throw new IllegalArgumentException("must have at least three file arguments, first, second, and third input files");
281                 }
282                 File first = new File(args[args.length - 3]);
283                 File second = new File(args[args.length - 2]);
284                 File third = new File(args[args.length - 1]);
285                 if (first.getName().startsWith("-") || second.getName().startsWith("-") || third.getName().startsWith("-"))
286                 {
287                     throw new IllegalArgumentException("must have at least three file arguments, first, second, and third input files");
288                 }
289                 File f = defaultIfFound(firstOnly, first, second, third, STDOUT);
290                 File s = defaultIfFound(secondOnly, first, second, third, STDOUT);
291                 File t = defaultIfFound(thirdOnly, first, second, third, STDOUT);
292                 File j = defaultIfFound(firstSecond, first, second, third, STDOUT);
293                 File k = defaultIfFound(secondThird, first, second, third, STDOUT);
294                 File i = defaultIfFound(intersection, first, second, third,  STDOUT);
295                 File u = defaultIfFound(union, first, second, third, STDOUT);
296                 new Venn3(count.wasFound(), header.wasFound(), first, second, third, f, s, t, j, k, i, u).run();
297             }
298         }
299         catch (CommandLineParseException e)
300         {
301             Usage.usage(USAGE, e, commandLine, arguments, System.err);
302         }
303         catch (IllegalArgumentException e)
304         {
305             Usage.usage(USAGE, e, commandLine, arguments, System.err);
306         }
307     }
308 }