1 package acl2s.plugin.certify;
2
3 import java.io.File;
4 import java.io.IOException;
5 import java.io.PrintWriter;
6
7 import org.eclipse.core.resources.IFile;
8 import org.eclipse.core.resources.ResourcesPlugin;
9 import org.eclipse.core.runtime.CoreException;
10 import org.eclipse.core.runtime.Path;
11 import org.eclipse.jface.resource.ImageDescriptor;
12 import org.eclipse.ui.console.IConsoleManager;
13 import org.eclipse.ui.console.IOConsoleOutputStream;
14
15 import acl2s.lib.certify.CertificationSessionConfig;
16 import acl2s.lib.certify.Certifier;
17 import acl2s.lib.session.BatchSession;
18 import acl2s.plugin.Acl2sPlugin;
19 import acl2s.plugin.console.IIdentifiableConsole;
20 import acl2s.plugin.console.IKillableConsole;
21 import acl2s.plugin.console.MyConsole;
22 import acl2s.plugin.misc.Colors;
23 import acl2s.plugin.misc.DisplayAsyncRunnable;
24 import acl2s.plugin.misc.IOConsoleWriter;
25
26 // TODO: abstract away UI dependence and put most in acl2s.lib.certify
27 public class CertifyConsole extends MyConsole implements IKillableConsole, IIdentifiableConsole {
28 protected final IOConsoleOutputStream stream;
29 protected final IOConsoleWriter writer;
30 protected final Certifier cert;
31 protected final File lispFile;
32 protected BatchSession sess = null;
33 protected long startTime = 0L;
34
35 CertifyConsole(File lispFile) {
36 this.lispFile = lispFile;
37 this.cert = new Certifier(getConfig(lispFile));
38 setName("Certification of " + lispFile.getName());
39 setImageDescriptor(image);
40
41 stream = newOutputStream();
42 stream.setColor(Colors.get(64, 64, 192));
43 writer = new IOConsoleWriter(stream);
44
45 try {
46 getInputStream().close();
47 } catch (IOException ioe) {
48 // already closed; ok
49 }
50 }
51
52 public Object getIdentity() {
53 return lispFile.getAbsolutePath();
54 }
55
56 public synchronized void kill() {
57 if (sess != null) {
58 sess.kill();
59 }
60 }
61
62 public synchronized boolean started() {
63 return sess != null;
64 }
65
66 public synchronized boolean finished() {
67 return sess != null && !sess.isAlive();
68 }
69
70
71 public synchronized void start() {
72 if (sess != null) throw new IllegalStateException("Already started.");
73
74 startTime = System.currentTimeMillis();
75
76 sess = cert.createSession();
77 notifyAll();
78 if (pp != null) pp.update();
79
80 cert.attemptRemoveCertFile();
81
82 PrintWriter commentary = new PrintWriter(writer);
83 commentary.println("Certification of " + lispFile.getAbsolutePath() + "\n");
84
85 if (!cert.buildPreambleCommentary(false, commentary)) {
86 return; // failure in extracting preamble
87 }
88
89 commentary.println("\nStarting ACL2...");
90
91 BatchSession.OutputHandler h = sess.createOutputHandler(writer);
92 h.appendPostEOFhook(new Runnable() {
93 public void run() {
94 try {
95 if (certFileWritten()) {
96 writer.append("\n### CERTIFICATION FILE WRITTEN SUCCESSFULLY ###\n");
97 } else if (cert.certFileExists()){
98 writer.append("\n!!! CERTIFICATION FILE WRITTEN BUT OUT OF DATE !!!\n");
99 } else {
100 writer.append("\n!!! CERTIFICATION FILE NOT WRITTEN !!!\n");
101 }
102 } catch (IOException ioe) {
103 handleException(ioe);
104 }
105 }
106 });
107 h.appendCloseOnEOFhook();
108 h.appendPostEOFhook(new DisplayAsyncRunnable() {
109 protected void asyncRun() {
110 if (pp != null) {
111 pp.update();
112 }
113 IFile f = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(new Path(lispFile.getAbsolutePath()));
114 if (f != null) {
115 try {
116 f.getParent().refreshLocal(1, null);
117 } catch (CoreException e) {
118 Acl2sPlugin.logError("Error refreshing directory following certification", e);
119 }
120 }
121 }
122 });
123 h.setSnipEnabled(true);
124 h.setExceptionHandler(this);
125
126 try {
127 sess.init();
128 } catch (IOException e) {
129 commentary.println("Error: " + e.getMessage());
130 }
131
132 commentary.flush();
133 commentary = null; // no more
134
135 h.start();
136 }
137
138 public synchronized void ensureStarted() {
139 if (sess == null) {
140 start();
141 }
142 }
143
144 public void waitFor() throws InterruptedException {
145 BatchSession s;
146 synchronized (this) {
147 for (;;) {
148 s = sess;
149 if (s != null) break;
150 wait();
151 }
152 }
153 synchronized (s) {
154 while (s.isAlive()) {
155 s.wait();
156 }
157 }
158 }
159
160 public synchronized boolean certFileWritten() {
161 if (!finished()) throw new IllegalStateException();
162 return cert.certFileNewer();
163 }
164
165 @Override
166 protected void dispose() {
167 kill();
168 super.dispose();
169 }
170
171 protected synchronized void doHandleException(IOException e) {
172 super.doHandleException(e);
173 kill();
174 try {
175 stream.write(e.getMessage());
176 } catch (IOException ioe) {
177 // ignore
178 }
179 }
180
181
182
183
184 // STATIC STUFF
185
186 public static CertifyConsole findOrCreate(File lispFile) {
187 IConsoleManager conman = getConsoleManager();
188 synchronized (conman) {
189 CertifyConsole cc = find(CertifyConsole.class, lispFile.getAbsolutePath());
190 cc = removeIfFinished(cc);
191 if (cc != null) {
192 return cc;
193 }
194 // not found or removed finished
195 cc = new CertifyConsole(lispFile);
196 cc.add();
197 cc.show();
198 return cc;
199 }
200 }
201
202 static CertificationSessionConfig getConfig(File lispFile) {
203 return new CertificationSessionConfig(Acl2sPlugin.getBaseConfig(),lispFile);
204 }
205
206 static final ImageDescriptor image =
207 ImageDescriptor.createFromURL(Acl2sPlugin.getDefault().getBundle().getEntry("/icons/acl2.gif"));
208 }