1 #ifndef COMMAND_HPP
2 #define COMMAND_HPP
3 //test2
4 /*
5  *  command.h
6  *  nast
7  *
8  *  Created by Pat Schloss on 10/23/08.
9  *  Copyright 2008 Patrick D. Schloss. All rights reserved.
10  *
11  */
12 
13 /*This class is a parent to all the command classes.  */
14 
15 
16 #include "mothur.h"
17 #include "optionparser.h"
18 #include "validparameter.h"
19 #include "mothurout.h"
20 #include "commandparameter.h"
21 #include "currentfile.h"
22 #include "utils.hpp"
23 
24 class Command {
25 
26 	public:
Command()27 		Command() {
28             m = MothurOut::getInstance();  current = CurrentFile::getInstance();
29             inputdir = current->getInputDir();
30             outputdir = current->getOutputDir();
31         }
32 
33 		//needed by gui
34 		virtual string getCommandName() = 0;
35 		virtual string getCommandCategory() = 0;
36 		virtual string getHelpString() = 0;
37 		virtual string getCitation() = 0;
38 		virtual string getDescription() = 0;
getCommonQuestions()39         virtual string getCommonQuestions()     {  return "Common Questions for commands."; }
getCommandParameters()40         virtual string getCommandParameters() {
41             vector<string> parameterNames = setParameters();
42             sort(parameterNames.begin(), parameterNames.end());
43             string results = util.getStringFromVector(parameterNames, ", ");
44             return results;
45         }
46 
getOutputFiles()47 		virtual map<string, vector<string> > getOutputFiles() { return outputTypes; }
getOutputFileName(string type,map<string,string> variableParts)48         string getOutputFileName(string type, map<string, string> variableParts) {  //uses the pattern to create an output filename for a given type and input file name.
49                try {
50                     string filename = "";
51                     map<string, vector<string> >::iterator it;
52 
53                     //is this a type this command creates
54                     it = outputTypes.find(type);
55                     if (it == outputTypes.end()) {  m->mothurOut("[ERROR]: this command doesn't create a " + type + " output file.\n"); }
56                     else {
57 
58                         string patternTemp = getOutputPattern(type);
59                         vector<string> patterns;
60                         util.splitAtDash(patternTemp, patterns);
61 
62                         //find pattern to use based on number of variables passed in
63                         string pattern = "";
64                         bool foundPattern = false;
65                         vector<int> numVariablesPerPattern;
66                         for (int i = 0; i < patterns.size(); i++) {
67                             int numVariables = 0;
68                             for (int j = 0; j < patterns[i].length(); j++) { if (patterns[i][j] == '[') { numVariables++; } }
69                             numVariablesPerPattern.push_back(numVariables);
70 
71                             if (numVariables == variableParts.size()) { pattern = patterns[i]; foundPattern = true; break; }
72                         }
73 
74                         //if you didn't find an exact match do we have something that might work
75                         if (!foundPattern) {
76                             for (int i = 0; i < numVariablesPerPattern.size(); i++) {
77                                 if (numVariablesPerPattern[i] < variableParts.size()) { pattern = patterns[i]; foundPattern = true; break; }
78                             }
79                             if (!foundPattern) {  m->mothurOut("[ERROR]: Not enough variable pieces for " + type + ".\n"); m->setControl_pressed(true); }
80                         }
81 
82                         if (pattern != "") {
83                             int numVariables = 0;
84                             for (int i = 0; i < pattern.length(); i++) { if (pattern[i] == '[') { numVariables++; } }
85 
86                             vector<string> pieces;
87                             util.splitAtComma(pattern, pieces);
88 
89 
90                             for (int i = 0; i < pieces.size(); i++) {
91                                 if (pieces[i][0] == '[') {
92                                     map<string, string>::iterator it = variableParts.find(pieces[i]);
93                                     if (it == variableParts.end()) {
94                                         m->mothurOut("[ERROR]: Did not provide variable for " + pieces[i] + ".\n"); m->setControl_pressed(true);
95                                     }else {
96                                         if (it->second != "") {
97                                             if (it->first == "[filename]") { filename += it->second; }
98                                             else if (it->first == "[extension]") {
99                                                 if (filename.length() > 0) { //rip off last "."
100                                                     filename = filename.substr(0, filename.length()-1);
101                                                 }
102                                                 filename += it->second + ".";
103                                             }else if ((it->first == "[group]") || (it->first == "[tag]")) {
104                                                 string group = it->second;
105                                                 for (int j = 0; j < group.length(); j++) {
106                                                     if (group[j] == '-') { group[j] = '_'; }
107                                                 }
108                                                 filename += group + ".";
109                                             }else { filename += it->second + "."; }
110                                         }
111                                     }
112                                 }else {
113                                     filename += pieces[i] + ".";
114                                 }
115                             }
116                             if (filename.length() > 0) { //rip off last "."
117                                 filename = filename.substr(0, filename.length()-1);
118                             }
119                         }
120                     }
121                     return filename;
122                 }
123                 catch(exception& e) {
124                     m->errorOut(e, "command", "getOutputFileName");
125                     exit(1);
126                 }
127         }
128 
129         virtual string getOutputPattern(string) = 0; //pass in type, returns something like: [filename],align or [filename],[distance],subsample.shared  strings in [] means its a variable.  This is used by the gui to predict output file names.  use variable keywords: [filename], [distance], [group], [extension], [tag]
130 		virtual vector<string> setParameters() = 0; //to fill parameters
getParameters()131 		virtual vector<CommandParameter> getParameters() { return parameters; }
132 
133 		virtual int execute() = 0;
134 		virtual void help() = 0;
citation()135 		void citation()         { m->mothurOut("\n"+getCitation()+"\n");    }
commonQuestions()136         void commonQuestions()  {  m->mothurOut("\n"+getCommonQuestions()+"\n");   }
~Command()137 		virtual ~Command() { }
138 
139 	protected:
140 		MothurOut* m;
141         Utils util;
142         CurrentFile* current;
143 		bool calledHelp;
144         string inputdir, outputdir;
145 
146 		map<string, vector<string> > outputTypes;
147 		vector<CommandParameter> parameters;
148 
149 		map<string, vector<string> >::iterator itTypes;
150 };
151 
152 #endif
153