1 /*
2  * This file is part of ELKI:
3  * Environment for Developing KDD-Applications Supported by Index-Structures
4  *
5  * Copyright (C) 2018
6  * ELKI Development Team
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU Affero General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU Affero General Public License for more details.
17  *
18  * You should have received a copy of the GNU Affero General Public License
19  * along with this program. If not, see <http://www.gnu.org/licenses/>.
20  */
21 package de.lmu.ifi.dbs.elki.workflow;
22 
23 import java.util.ArrayList;
24 import java.util.List;
25 
26 import de.lmu.ifi.dbs.elki.database.Database;
27 import de.lmu.ifi.dbs.elki.result.ResultHandler;
28 import de.lmu.ifi.dbs.elki.result.ResultHierarchy;
29 import de.lmu.ifi.dbs.elki.result.ResultWriter;
30 import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
31 import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
32 import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
33 import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectListParameter;
34 
35 /**
36  * The "output" step, where data is analyzed.
37  *
38  * @author Erich Schubert
39  * @since 0.4.0
40  *
41  * @assoc - - - ResultHierarchy
42  * @has - - - ResultHandler
43  */
44 public class OutputStep implements WorkflowStep {
45   /**
46    * Output handler.
47    */
48   private List<? extends ResultHandler> resulthandlers = null;
49 
50   /**
51    * Constructor.
52    *
53    * @param resulthandlers Result handlers to use
54    */
OutputStep(List<? extends ResultHandler> resulthandlers)55   public OutputStep(List<? extends ResultHandler> resulthandlers) {
56     super();
57     this.resulthandlers = resulthandlers;
58   }
59 
60   /**
61    * Run the result handlers.
62    *
63    * @param hier Result to run on
64    * @param db Database
65    */
runResultHandlers(ResultHierarchy hier, Database db)66   public void runResultHandlers(ResultHierarchy hier, Database db) {
67     // Run result handlers
68     for(ResultHandler resulthandler : resulthandlers) {
69       Thread.currentThread().setName(resulthandler.toString());
70       resulthandler.processNewResult(hier, db);
71     }
72   }
73 
74   /**
75    * Set the default handler to the {@link ResultWriter}.
76    */
setDefaultHandlerWriter()77   public static void setDefaultHandlerWriter() {
78     defaultHandlers = new ArrayList<>(1);
79     defaultHandlers.add(ResultWriter.class);
80   }
81 
82   /**
83    * Set the default handler to the Batik addon visualizer, if available.
84    */
85   @SuppressWarnings("unchecked")
setDefaultHandlerVisualizer()86   public static void setDefaultHandlerVisualizer() {
87     defaultHandlers = new ArrayList<>(1);
88     Class<? extends ResultHandler> clz;
89     try {
90       clz = (Class<? extends ResultHandler>) Thread.currentThread().getContextClassLoader().loadClass(//
91           "de.lmu.ifi.dbs.elki.result.AutomaticVisualization");
92     }
93     catch(ClassNotFoundException e) {
94       clz = ResultWriter.class;
95     }
96     defaultHandlers.add(clz);
97   }
98 
99   protected static ArrayList<Class<? extends ResultHandler>> defaultHandlers = null;
100 
101   /**
102    * Parameterization class.
103    *
104    * @author Erich Schubert
105    */
106   public static class Parameterizer extends AbstractParameterizer {
107     /**
108      * Output handlers.
109      */
110     private List<? extends ResultHandler> resulthandlers = null;
111 
112     /**
113      * Parameter to specify the result handler classes.
114      */
115     public static final OptionID RESULT_HANDLER_ID = new OptionID("resulthandler", "Result handler class.");
116 
117     /**
118      * OptionID for the application output file/folder.
119      */
120     public static final OptionID OUTPUT_ID = new OptionID("out", //
121         "Directory name (or name of an existing file) to write the obtained results in. " + //
122             "If this parameter is omitted, per default the output will sequentially be given to STDOUT.");
123 
124     @Override
makeOptions(Parameterization config)125     protected void makeOptions(Parameterization config) {
126       super.makeOptions(config);
127       // result handlers
128       final ObjectListParameter<ResultHandler> resultHandlerParam = new ObjectListParameter<>(RESULT_HANDLER_ID, ResultHandler.class);
129       if(defaultHandlers != null) {
130         resultHandlerParam.setDefaultValue(defaultHandlers);
131       }
132       if(config.grab(resultHandlerParam)) {
133         resulthandlers = resultHandlerParam.instantiateClasses(config);
134       }
135     }
136 
137     @Override
makeInstance()138     protected OutputStep makeInstance() {
139       return new OutputStep(resulthandlers);
140     }
141   }
142 }
143