View Javadoc

1   /***
2    * Copyright 2009 Martin Vysny.
3    *
4    * This file is part of WebVM.
5    *
6    * WebVM is free software: you can redistribute it and/or modify
7    * it under the terms of the GNU General Public License as published by
8    * the Free Software Foundation, either version 3 of the License, or
9    * (at your option) any later version.
10   *
11   * WebVM is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   * GNU General Public License for more details.
15   *
16   * You should have received a copy of the GNU General Public License
17   * along with WebVM.  If not, see <http://www.gnu.org/licenses/>.
18   */
19  package sk.baka.webvm.analyzer;
20  
21  import java.io.Serializable;
22  import java.util.Collection;
23  import java.util.HashMap;
24  import java.util.Map;
25  import sk.baka.webvm.Problems;
26  
27  /***
28   * Describes a potential problem.
29   * @author Martin Vysny
30   */
31  public final class ProblemReport implements Serializable {
32  
33      private static final long serialVersionUID = 1L;
34      /***
35       * Checks if this really is a problem. true if this might be a serious problem, false if everything is OK or this is only a minor issue.
36       */
37      public final boolean isProblem;
38      /***
39       * description of the problem class, not null
40       */
41      public final String desc;
42      /***
43       * The problem 'class', not null.
44       */
45      public final String pclass;
46      /***
47       * The 'diagnosis' of the problem.
48       */
49      public final String diagnosis;
50  
51      /***
52       * Creates new instance.
53       * @param isProblem true if this might be a serious problem, false if everything is OK or this is only a minor issue.
54       * @param diagnosis diagnosis of the problem, or something like OK if everything is okay. not null
55       * @param pclass the problem class, not null
56       * @param desc description of the problem class, not null
57       */
58      public ProblemReport(final boolean isProblem, final String pclass, final String diagnosis, final String desc) {
59          this.isProblem = isProblem;
60          this.pclass = pclass;
61          this.diagnosis = diagnosis;
62          this.desc = desc;
63      }
64      /***
65       * When this object was created.
66       */
67      public final long created = System.currentTimeMillis();
68  
69      /***
70       * Checks if there is at least one real problem.
71       * @param problems the list of problems
72       * @return true if there is a problem, false otherwise.
73       */
74      public static boolean isProblem(final Collection<? extends ProblemReport> problems) {
75          for (final ProblemReport p : problems) {
76              if (p.isProblem) {
77                  return true;
78              }
79          }
80          return false;
81      }
82  
83      /***
84       * Formats the problem reports in the form of CLASS: DESC\nCLASS: DESC ...
85       * @param problems the problem reports to format.
86       * @return all problem reports.
87       * @param lineSeparator the new-line separator.
88       */
89      public static String toString(final Collection<? extends ProblemReport> problems, final String lineSeparator) {
90          final StringBuilder sb = new StringBuilder();
91          boolean first = true;
92          for (final ProblemReport r : problems) {
93              if (first) {
94                  first = false;
95              } else {
96                  sb.append(lineSeparator);
97              }
98              sb.append(r.toString());
99          }
100         return sb.toString();
101     }
102 
103     /***
104      * Formats the problem reports in the form of a HTML table.
105      * @param problems the problem reports to format.
106      * @return all problem reports.
107      */
108     public static String toHtml(final Collection<? extends ProblemReport> problems) {
109         final StringBuilder sb = new StringBuilder();
110         sb.append("<table border=\"1\"><thead><tr><th>Problem type</th><th>Status</th><th>Diagnosis</th></tr></thead>\n");
111         for (final ProblemReport r : problems) {
112             sb.append("<tr><td>");
113             sb.append(r.pclass);
114             sb.append("</td><td bgcolor=\"#");
115             sb.append(r.isProblem ? Problems.LIGHT_RED : Problems.DARK_GREEN);
116             sb.append("\">");
117             sb.append(r.isProblem ? "WARN" : "OK");
118             sb.append("</td><td><pre>");
119             sb.append(r.diagnosis);
120             sb.append("</pre></td></tr>\n");
121         }
122         return sb.toString();
123     }
124 
125     /***
126      * XML-escapes given text.
127      * @param text the text to escape
128      * @return text with &amp;amp;, &amp;lt; etc.
129      */
130     public static final String escape(final String text) {
131         String result = text.replace("&", "&amp;");
132         result = result.replace("<", "&lt;");
133         result = result.replace(">", "&gt;");
134         return result;
135     }
136 
137     @Override
138     public boolean equals(Object obj) {
139         if (obj == null) {
140             return false;
141         }
142         if (getClass() != obj.getClass()) {
143             return false;
144         }
145         final ProblemReport other = (ProblemReport) obj;
146         if (this.isProblem != other.isProblem) {
147             return false;
148         }
149         if (!this.pclass.equals(other.pclass)) {
150             return false;
151         }
152         if ((this.diagnosis == null) ? (other.diagnosis != null) : !this.diagnosis.equals(other.diagnosis)) {
153             return false;
154         }
155         return true;
156     }
157 
158     @Override
159     public int hashCode() {
160         int hash = 7;
161         hash = 59 * hash + (this.isProblem ? 1 : 0);
162         hash = 59 * hash + this.pclass.hashCode();
163         hash = 59 * hash + (this.diagnosis != null ? this.diagnosis.hashCode() : 0);
164         return hash;
165     }
166 
167     @Override
168     public String toString() {
169         return (isProblem ? "WARN" : "OK  ") + ": " + pclass + ": " + diagnosis;
170     }
171 
172     private static Map<String, ProblemReport> toMap(final Iterable<? extends ProblemReport> reports, final boolean filterProblems) {
173         final Map<String, ProblemReport> result = new HashMap<String, ProblemReport>();
174         for (final ProblemReport r : reports) {
175             if (filterProblems && !r.isProblem) {
176                 continue;
177             }
178             result.put(r.pclass, r);
179         }
180         return result;
181     }
182 
183     /***
184      * Checks if two problem reports are equal. Reports are equal when same classes are problematic and all problematic reports share the same description.
185      * @param reports1 first report set.
186      * @param reports2 second report set.
187      * @return true if report sets are equal, false otherwise.
188      */
189     public static boolean equals(final Collection<? extends ProblemReport> reports1, final Collection<? extends ProblemReport> reports2) {
190         final Map<String, ProblemReport> r1 = toMap(reports1, true);
191         final Map<String, ProblemReport> r2 = toMap(reports2, true);
192         if (!r1.keySet().equals(r2.keySet())) {
193             return false;
194         }
195         for (final String pclass : r1.keySet()) {
196             if (!r1.get(pclass).diagnosis.equals(r2.get(pclass).diagnosis)) {
197                 return false;
198             }
199         }
200         return true;
201     }
202 }