2 * Copyright (C) 2014, United States Government, as represented by the
3 * Administrator of the National Aeronautics and Space Administration.
6 * The Java Pathfinder core (jpf-core) platform is licensed under the
7 * Apache License, Version 2.0 (the "License"); you may not use this file except
8 * in compliance with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0.
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
19 package gov.nasa.jpf.report;
21 import gov.nasa.jpf.Config;
22 import gov.nasa.jpf.Error;
23 import gov.nasa.jpf.JPF;
24 import gov.nasa.jpf.util.RepositoryEntry;
25 import gov.nasa.jpf.vm.ChoiceGenerator;
26 import gov.nasa.jpf.vm.ElementInfo;
27 import gov.nasa.jpf.vm.VM;
28 import gov.nasa.jpf.vm.Path;
29 import gov.nasa.jpf.vm.StackFrame;
30 import gov.nasa.jpf.vm.Step;
31 import gov.nasa.jpf.vm.ThreadInfo;
32 import gov.nasa.jpf.vm.Transition;
34 import java.io.FileNotFoundException;
35 import java.io.PrintWriter;
36 import java.util.List;
39 import java.util.TreeMap;
41 public class XMLPublisher extends Publisher {
43 public XMLPublisher(Config conf, Reporter reporter) {
44 super(conf, reporter);
48 public String getName() {
53 protected void openChannel(){
55 String fname = getReportFileName("report.xml.file") + ".xml";
57 out = new PrintWriter(fname);
58 } catch (FileNotFoundException fnfx) {
65 protected void closeChannel() {
74 protected void publishProlog() {
75 out.println("<?xml version=\"1.0\" ?>");
76 out.println("<jpfreport>");
80 public void publishTopicStart(String topic) {
81 out.println(" <" + topic + ">");
85 public void publishTopicEnd(String topic) {
86 out.println(" </" + topic + ">");
90 protected void publishEpilog() {
91 out.println("</jpfreport>");
95 protected void publishJPF() {
96 out.println(" <jpf-version>" + JPF.VERSION + "</jpf-version>");
100 protected void publishJPFConfig() {
101 TreeMap<Object,Object> map = conf.asOrderedMap();
102 Set<Map.Entry<Object,Object>> eSet = map.entrySet();
104 out.println(" <jpf-properties>");
106 for (Object src : conf.getSources()){
107 out.println(" <source value=\"" + conf.getSourceName(src) + "\"/>");
110 for (Map.Entry<Object,Object> e : eSet) {
111 out.println(" <entry key=\"" + e.getKey() + "\" value=\"" + e.getValue() + "\"/>");
113 out.println(" </jpf-properties>");
118 protected void publishPlatform() {
119 out.println(" <platform>");
120 out.println(" <hostname>" + reporter.getHostName() + "</hostname>");
121 out.println(" <arch>" + reporter.getArch() + "</arch>");
122 out.println(" <os>" + reporter.getOS() + "</os>");
123 out.println(" <java>" + reporter.getJava() + "</java>");
124 out.println(" </platform>");
128 protected void publishUser() {
129 out.println(" <user>" + reporter.getUser() + "</user>");
133 protected void publishDTG() {
134 out.println(" <started>" + reporter.getStartDate() + "</started>");
138 protected void publishSuT() {
139 out.println(" <sut>");
140 String mainCls = reporter.getSuT();
141 if (mainCls != null) {
142 String mainPath = reporter.getSuT();
143 if (mainPath != null) {
144 out.println(" <source>" + mainPath + "</source>");
146 RepositoryEntry rep = RepositoryEntry.getRepositoryEntry(mainPath);
148 out.println(" <repository>" + rep.getRepository() + "</repository>");
149 out.println(" <revision>" + rep.getRevision() + "</revision>");
152 out.println(" <binary>" + mainCls + ".class" + "</binary>");
157 out.println(" </sut>");
161 protected void publishResult() {
162 List<Error> errors = reporter.getErrors();
164 out.print(" <result findings=\"");
165 if (errors.isEmpty()){
166 out.println("none\"/>");
168 out.println("errors\">");
170 for (Error e : errors) {
171 out.print(" <error id=\"");
174 out.print(" <property>");
175 out.print(e.getProperty().getClass().getName());
176 out.println("</property>");
177 out.print(" <details>");
178 out.print(e.getDetails());
179 out.println(" </details>");
180 out.println(" </error>");
182 out.println(" </result>");
186 // not sure how much effort we want to put into readability here
188 protected void publishTrace() {
189 Path path = reporter.getPath();
192 if (path.size() == 0) {
193 return; // nothing to publish
196 out.println(" <trace>");
197 for (Transition t : path) {
198 ChoiceGenerator<?> cg = t.getChoiceGenerator();
199 out.println(" <transition id=\"" + i++ + "\" thread=\"" + t.getThreadIndex() + "\">");
200 out.println(" <cg class=\""+cg.getClass().getName() + "\" choice=\"" +
201 cg.getProcessedNumberOfChoices() + "\"/>");
203 out.print(" <insn src=\"" + s.getLocationString() + "\">");
204 String insn = s.getInstruction().toString();
205 if (insn.indexOf('<') >= 0) { // <init> and <clinit> clash with XML
206 insn = insn.replaceAll("<", "<");
207 insn = insn.replaceAll(">", ">");
210 out.println("</insn>");
212 out.println(" </transition>");
214 out.println(" </trace>");
218 protected void publishOutput() {
219 Path path = reporter.getPath();
221 if (path.size() == 0) {
222 return; // nothing to publish
225 if (path.hasOutput()) {
226 out.println(" <output>");
227 for (Transition t : path) {
228 String s = t.getOutput();
233 out.println(" </output>");
238 protected void publishSnapshot() {
239 VM vm = reporter.getVM();
241 out.println(" <live-threads>");
242 for (ThreadInfo ti : vm.getLiveThreads()) {
243 out.println(" <thread id=\"" + ti.getId() + "\" name=\"" + ti.getName()
244 + "\" status=\"" + ti.getStateName() + "\">");
246 for (ElementInfo e : ti.getLockedObjects()) {
247 out.println(" <lock-owned object=\"" + e + "\"/>");
250 ElementInfo ei = ti.getLockObject();
252 out.println(" <lock-request object=\"" + ei + "\"/>");
255 for (StackFrame frame : ti){
256 if (!frame.isDirectCallFrame()){
257 out.println(" <frame>" + frame.getStackTraceInfo() + "</frame>");
260 out.println(" </thread>");
262 out.println(" </live-threads>");
266 protected void publishStatistics() {
267 Statistics stat = reporter.getStatistics();
268 out.println(" <statistics>");
269 out.println(" <elapsed-time>" + formatHMS(reporter.getElapsedTime()) + "</elapsed-time>");
270 out.println(" <new-states>" + stat.newStates + "</new-states>");
271 out.println(" <visited-states>" + stat.visitedStates + "</visited-states>");
272 out.println(" <backtracked-states>" + stat.backtracked + "</backtracked-states>");
273 out.println(" <end-states>" + stat.endStates + "</end-states>");
274 out.println(" <max-memory unit=\"MB\">" + (stat.maxUsed >>20) + "</max-memory>");
275 out.println(" </statistics>");