CoverityFix-CID:1351079 Inner class could be made static
[scilab.git] / scilab / modules / xcos / src / java / org / scilab / modules / xcos / modelica / listener / SolveAction.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2010-2010 - DIGITEO - Clement DAVID <clement.david@scilab.org>
4  * Copyright (C) 2011-2014 - Scilab Enterprises - Clement DAVID
5  *
6  * Copyright (C) 2012 - 2016 - Scilab Enterprises
7  *
8  * This file is hereby licensed under the terms of the GNU GPL v2.0,
9  * pursuant to article 5.3.4 of the CeCILL v.2.1.
10  * This file was originally licensed under the terms of the CeCILL v2.1,
11  * and continues to be available under such terms.
12  * For more information, see the COPYING file which you should have received
13  * along with this program.
14  *
15  */
16
17 package org.scilab.modules.xcos.modelica.listener;
18
19 import java.awt.event.ActionEvent;
20 import java.io.File;
21 import java.util.List;
22 import java.util.logging.Logger;
23
24 import javax.swing.AbstractAction;
25 import javax.swing.JProgressBar;
26 import javax.swing.SwingWorker;
27
28 import org.scilab.modules.action_binding.highlevel.ScilabInterpreterManagement;
29 import org.scilab.modules.commons.ScilabConstants;
30 import org.scilab.modules.xcos.modelica.ModelStatistics;
31 import org.scilab.modules.xcos.modelica.Modelica;
32 import org.scilab.modules.xcos.modelica.ModelicaController;
33 import org.scilab.modules.xcos.modelica.ModelicaMessages;
34 import org.scilab.modules.xcos.modelica.model.Model;
35
36 /**
37  * Solve the model.
38  */
39 @SuppressWarnings(value = { "serial" })
40 public final class SolveAction extends AbstractAction {
41     private static final String COMPILE_STRING = "fw='%s'; paremb='%s'; jaco='%s'; " + "if(compile_init_modelica(fw, paremb, jaco)) then "
42             + "mopen('%s', 'w'); end ";
43     private static final String COMPUTE_STRING = "method='%s'; Nunknowns='%s'; " + "if(Compute_cic(method,Nunknowns)) then " + "mopen('%s', 'w'); " + "end ";
44
45     private static final String IMF_INIT = "_init";
46     private static final String EXTENSION = ".xml";
47     private static final String INCIDENCE = "i_incidence_matrix";
48
49     private enum ActionToPerform {EXPORT, COMPILE, COMPUTE, FINISH};
50     private static class Worker extends SwingWorker<Void, ActionToPerform> {
51
52         private final ModelicaController controller;
53         private final JProgressBar progress;
54
55         public Worker(ModelicaController controller, JProgressBar progress) {
56             this.controller = controller;
57             this.progress = progress;
58         }
59
60         @Override
61         protected Void doInBackground() throws Exception {
62             String cmd;
63
64             final String modelName = controller.getRoot().getName();
65             // creating a temporary status file
66             final File statusFile = File.createTempFile(modelName, null);
67
68             // defensive programming
69             if (!controller.isSquare()) {
70                 Logger.getLogger(SolveAction.class.getName()).severe(ModelicaMessages.MODEL_INVALID);
71             }
72
73             /*
74              * Export the compilation data to xml
75              */
76             publish(ActionToPerform.EXPORT);
77
78             // store the updated values
79             final File updatedInitFile = new File(ScilabConstants.TMPDIR, modelName + IMF_INIT + EXTENSION);
80             Modelica.getInstance().save(controller.getRoot(), updatedInitFile);
81
82             /*
83              * Compile the data from xml to a modelica file
84              */
85             publish(ActionToPerform.COMPILE);
86             final int paremb;
87             if (controller.isParameterEmbedded()) {
88                 paremb = 1;
89             } else {
90                 paremb = 0;
91             }
92
93             final int jaco;
94             if (controller.isJacobianEnable()) {
95                 jaco = 1;
96             } else {
97                 jaco = 0;
98             }
99
100             if(!statusFile.delete())
101             { 
102                System.err.println("Cannot delete '" + statusFile + "'"); 
103             }
104             cmd = String.format(COMPILE_STRING, modelName, paremb, jaco, statusFile.getAbsolutePath());
105
106             Logger.getLogger(SolveAction.class.getName()).finest("Compiling");
107             ScilabInterpreterManagement.synchronousScilabExec(cmd);
108
109             if (!statusFile.exists()) {
110                 publish(ActionToPerform.FINISH);
111                 return null;
112             } else {
113                 if(!statusFile.delete())
114                 {
115                    System.err.println("Cannot delete '" + statusFile + "'");
116                 }
117             }
118
119             /*
120              * Launch a modelica initialization with the generated file
121              */
122             publish(ActionToPerform.COMPUTE);
123
124             // update the model with the computed identifiers
125             final File incidence = new File(ScilabConstants.TMPDIR, modelName + INCIDENCE + EXTENSION);
126             final Model incidenceModel = Modelica.getInstance().load(incidence);
127             controller.getRoot().setIdentifiers(incidenceModel.getIdentifiers());
128             controller.getRoot().setOutputs(incidenceModel.getOutputs());
129
130             // update the statistics
131             controller.getStatistics().fireChange();
132
133             // update state
134             controller.setCompileNeeded(false);
135
136             if(!statusFile.delete())
137             {
138                System.err.println("Cannot delete '" + statusFile + "'");
139             }
140             final ModelStatistics stats = controller.getStatistics();
141             long nUnknowns = stats.getUnknowns() - stats.getEquations();
142             cmd = String.format(COMPUTE_STRING, controller.getComputeMethod(), nUnknowns, statusFile.getAbsolutePath());
143
144             // compute now
145             Logger.getLogger(SolveAction.class.getName()).finest("Computing");
146             ScilabInterpreterManagement.synchronousScilabExec(cmd);
147
148             if (!statusFile.exists()) {
149                 publish(ActionToPerform.FINISH);
150                 return null;
151             } else {
152                 if(!statusFile.delete())
153                 {
154                    System.err.println("Cannot delete '" + statusFile + "'");
155                 }
156             }
157
158             /*
159              * Finish the action using a state instead of the done() method
160              */
161             publish(ActionToPerform.FINISH);
162
163             return null;
164         }
165
166         @Override
167         protected void process(List<ActionToPerform> chunks) {
168             // only visual notify accordingly to the last performed action
169             final ActionToPerform action = chunks.get(chunks.size() - 1);
170
171             switch (action) {
172                 case EXPORT:
173                 case COMPILE:
174                 case COMPUTE:
175                     if (!progress.isIndeterminate()) {
176                         progress.setIndeterminate(true);
177                     }
178                     break;
179
180                 case FINISH:
181                 default:
182                     progress.setIndeterminate(false);
183                     break;
184             }
185         }
186     }
187
188     private final ModelicaController controller;
189     private final JProgressBar progress;
190
191     /**
192      * Default constructor
193      *
194      * @param controller
195      *            the associated controller
196      */
197     public SolveAction(final ModelicaController controller, final JProgressBar progress) {
198         super();
199
200         putValue(NAME, ModelicaMessages.SOLVE);
201         this.controller = controller;
202         this.progress = progress;
203
204     }
205
206     /**
207      * action !!!
208      *
209      * @param e
210      *            the event
211      * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
212      */
213     @Override
214     public void actionPerformed(ActionEvent e) {
215         new Worker(controller, progress).execute();
216     }
217 }