2
* AccessODF - Accessibility checker for OpenOffice.org and LibreOffice Writer.
4
* Copyright (c) 2011 by DocArch <http://www.docarch.be>.
6
* This program is free software: you can redistribute it and/or modify
7
* it under the terms of the GNU Lesser General Public License as
8
* published by the Free Software Foundation, either version 3 of the
9
* License, or (at your option) any later version.
11
* This program 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 Lesser General Public License for more details.
16
* You should have received a copy of the GNU Lesser General Public License
17
* along with this program. If not, see <http://www.gnu.org/licenses/>.
20
package be.docarch.accessodf.ooo;
23
import java.util.Date;
24
import java.util.ArrayList;
25
import java.util.List;
27
import java.util.HashMap;
28
import java.util.Collection;
29
import java.util.Collections;
30
import java.util.logging.Logger;
31
import java.util.logging.Level;
33
import java.text.ParseException;
34
import java.io.IOException;
36
import com.sun.star.lang.EventObject;
37
import com.sun.star.container.XEnumeration;
38
import com.sun.star.rdf.Statement;
39
import com.sun.star.rdf.XURI;
40
import com.sun.star.rdf.URI;
41
import com.sun.star.rdf.XResource;
42
import com.sun.star.rdf.XRepository;
43
import com.sun.star.rdf.XNamedGraph;
45
import com.sun.star.container.NoSuchElementException;
46
import com.sun.star.rdf.RepositoryException;
47
import com.sun.star.lang.WrappedTargetException;
48
import com.sun.star.lang.IllegalArgumentException;
49
import com.sun.star.beans.UnknownPropertyException;
50
import com.sun.star.beans.PropertyVetoException;
52
import be.docarch.accessodf.Check;
53
import be.docarch.accessodf.DummyCheck;
54
import be.docarch.accessodf.Checker;
55
import be.docarch.accessodf.Provider;
56
import be.docarch.accessodf.RunnableChecker;
57
import be.docarch.accessodf.RemoteRunnableChecker;
58
import be.docarch.accessodf.Constants;
59
import be.docarch.accessodf.Report;
60
import be.docarch.accessodf.Issue;
61
import be.docarch.accessodf.FilterSorter;
62
import be.docarch.accessodf.Repairer;
63
import be.docarch.accessodf.Repairer.RepairMode;
64
import be.docarch.accessodf.ooo.rdf.*;
70
public class IssueManager {
72
private static final Logger logger = Logger.getLogger(Constants.LOGGER_NAME);
73
private static final String TMP_NAME = Constants.TMP_PREFIX;
74
private static final File TMP_DIR = Constants.getTmpDirectory();
76
public static enum Status { ALERT,
81
private final Document document;
82
private final Settings settings;
83
private final Provider<Checker> checkers;
84
private final Provider<Repairer> repairers;
86
private final List<Issue> allIssues;
87
private FilterSorter filterSorter = null;
88
private Issue selectedIssue = null;
89
private Check selectedCheck = null;
90
private Map<Check,List<Issue>> check2IssuesMap = null;
91
//private Map<Check,Repairer> check2repairerMap = null;
93
public IssueManager(Document document,
94
Provider<Checker> checkers,
95
Provider<Repairer> repairers)
96
throws IllegalArgumentException,
97
NoSuchElementException,
99
PropertyVetoException,
100
WrappedTargetException,
102
com.sun.star.uno.Exception {
104
logger.entering("IssueManager", "<init>");
106
this.document = document;
107
this.checkers = checkers;
108
this.repairers = repairers;
109
//Provider<Check> checks = new CheckProvider(checkers);
111
settings = new Settings(document.xContext);
112
//check2repairerMap = new HashMap<Check,Repairer>();
113
check2IssuesMap = new HashMap<Check,List<Issue>>();
115
filterSorter = new FilterSorter();
116
filterSorter.setOrderPriority(FilterSorter.NAME, true);
117
filterSorter.setOrderPriority(FilterSorter.CHECKID, true);
118
allIssues = new ArrayList<Issue>();
120
// Load accessibility issues from metadata
123
logger.exiting("IssueManager", "<init>");
127
public void refresh() throws IllegalArgumentException,
129
UnknownPropertyException,
130
NoSuchElementException,
131
WrappedTargetException,
132
PropertyVetoException,
135
com.sun.star.uno.Exception {
140
for (Checker checker : checkers.list()) {
141
if (checker instanceof RemoteRunnableChecker) {
142
if (!settings.brailleChecks() && checker.getIdentifier().equals("http://docarch.be/odt2braille/checker/BrailleChecker")) {
145
if (odtFile == null) {
146
odtFile = File.createTempFile(TMP_NAME, ".odt", TMP_DIR);
147
odtFile.deleteOnExit();
148
document.ensureMetadataReferences();
149
document.storeToFile(odtFile);
151
RemoteRunnableChecker remoteChecker = (RemoteRunnableChecker)checker;
152
remoteChecker.setOdtFile(odtFile);
153
if (remoteChecker.run()) {
154
document.removeAccessibilityData(remoteChecker.getIdentifier());
155
Report report = remoteChecker.getAccessibilityReport();
156
if (report != null) {
157
document.importAccessibilityData(report.getFile(), remoteChecker.getIdentifier(), report.getName());
160
} else if (checker instanceof RunnableChecker) {
161
((RunnableChecker)checker).run();
165
// Load accessibility issues from metadata
169
public void clear() throws IllegalArgumentException,
171
PropertyVetoException,
172
NoSuchElementException {
174
Collection<XNamedGraph> accessibilityDataGraphs = getAccessibilityDataGraphs();
176
for (XNamedGraph accessibilityDataGraph : accessibilityDataGraphs) {
177
document.xDMA.removeMetadataFile(accessibilityDataGraph.getName());
179
if (allIssues.size() > 0) {
180
document.setModified();
184
check2IssuesMap.clear();
189
private Collection<XNamedGraph> getAccessibilityDataGraphs() throws IllegalArgumentException,
190
RepositoryException {
192
Collection<XNamedGraph> accessibilityDataGraphs = new ArrayList<XNamedGraph>();
194
XRepository xRepository = document.xDMA.getRDFRepository();
196
for (Checker checker : checkers.list()) {
197
XURI type = URI.create(document.xContext, checker.getIdentifier());
198
XURI[] graphNames = document.xDMA.getMetadataGraphsWithType(type);
199
for (int i=0; i<graphNames.length; i++) {
200
accessibilityDataGraphs.add(xRepository.getGraph(graphNames[i]));
204
return accessibilityDataGraphs;
207
private void loadMetadata() throws NoSuchElementException,
209
WrappedTargetException,
210
IllegalArgumentException,
211
PropertyVetoException {
213
logger.entering("IssueManager", "loadMetadata");
215
Collection<XNamedGraph> accessibilityDataGraphs = getAccessibilityDataGraphs();
217
Map<String,Date> checkerDates = new HashMap<String,Date>();
218
Date longAgo = new Date(0);
219
for (Checker checker : checkers.list()) {
220
checkerDates.put(checker.getIdentifier(), longAgo);
225
Issue issue, sameIssue;
226
for (XNamedGraph graph : accessibilityDataGraphs) {
227
Assertions assertions = new Assertions(graph, document);
228
XEnumeration assertionEnum = graph.getStatements(null, URIs.RDF_TYPE, URIs.EARL_ASSERTION);
229
XResource assertion = null;
230
while (assertionEnum.hasMoreElements()) {
231
assertion = ((Statement)assertionEnum.nextElement()).Subject;
233
issue = assertions.read(assertion, checkers).getIssue();
234
} catch (Exception e) {
235
logger.log(Level.SEVERE, null, e);
238
if (issue.getCheck() instanceof DummyCheck) {
239
checkerDates.put(issue.getChecker().getIdentifier(), issue.getCheckDate());
242
if (allIssues.contains(issue)) {
243
sameIssue = allIssues.remove(allIssues.indexOf(issue));
244
if (issue.getCheckDate().before(sameIssue.getCheckDate())) {
245
if (issue.ignored()) {
246
sameIssue.ignored(true);
251
if (sameIssue.ignored()) {
257
allIssues.add(issue);
261
for (Issue i : allIssues) {
262
String checker = i.getChecker().getIdentifier();
263
if (i.getCheckDate().after(checkerDates.get(checker))) {
264
checkerDates.put(checker, i.getCheckDate());
268
for (Issue i : allIssues) {
269
if (i.getCheckDate().before(checkerDates.get(i.getChecker().getIdentifier()))) {
276
logger.exiting("IssueManager", "loadMetadata");
280
public void select(Object o) {
282
selectedCheck = null;
283
selectedIssue = null;
286
if (o instanceof Check) {
287
Check check = (Check)o;
288
for (Check c : getChecks()) {
289
if (c.equals(check)) {
293
} else if (o instanceof Issue) {
294
Issue issue = (Issue)o;
295
for (Issue i : allIssues) {
296
if (issue.equals(i)) {
298
selectedCheck = selectedIssue.getCheck();
305
public boolean repair(Issue issue)
306
throws IllegalArgumentException,
308
PropertyVetoException,
309
NoSuchElementException {
311
if (issue == null) { return false; }
312
for (Repairer repairer : repairers.list()) {
314
if (repairer.repair(issue)) {
315
issue.repaired(true);
318
} catch (Exception e) {
324
public boolean repairable(Issue issue) {
326
for (Repairer repairer : repairers.list()) {
327
if (repairer.supports(issue)) {
334
public RepairMode getRepairMode(Issue issue)
335
throws java.lang.IllegalArgumentException {
337
for (Repairer repairer : repairers.list()) {
338
if (repairer.supports(issue)) {
339
return repairer.getRepairMode(issue);
342
throw new java.lang.IllegalArgumentException();
345
private void arrangeIssues() {
347
Collections.sort(allIssues, filterSorter);
349
check2IssuesMap.clear();
351
Check prevCheck = null;
352
ArrayList<Issue> issueList = null;
353
for (Issue issue : allIssues) {
354
Check check = issue.getCheck();
355
if (!check.equals(prevCheck)) {
356
issueList = new ArrayList<Issue>();
357
check2IssuesMap.put(check, issueList);
359
issueList.add(issue);
364
public Collection<Check> getChecks() {
365
return check2IssuesMap.keySet();
368
public List<Issue> getIssuesByCheck(Check check) {
369
return check2IssuesMap.get(check);
372
public Status getStatus(Object o) {
375
if (o instanceof Check) {
377
Check check = (Check)o;
378
boolean alert = (check.getStatus() == Check.Status.ALERT);
379
boolean allRepaired = true;
380
boolean allIgnored = true;
381
for (Issue issue : check2IssuesMap.get(check)) {
382
if (!issue.ignored()) {
385
if (!issue.repaired()) {
389
return (allRepaired? Status.REPAIRED:
390
allIgnored? Status.IGNORED:
394
} else if (o instanceof Issue) {
396
Issue issue = (Issue)o;
397
boolean alert = (issue.getCheck().getStatus() == Check.Status.ALERT);
399
return (issue.repaired()? Status.REPAIRED:
400
issue.ignored()? Status.IGNORED:
409
public Issue selectedIssue() {
410
return selectedIssue;
413
public Check selectedCheck() {
414
return selectedCheck;
417
public void disposing(EventObject event) {}