blob: b4065b89cce1f6daeec057f7e9068e0b31a9cfd6 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.uima.ruta.check;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.apache.uima.UIMAFramework;
import org.apache.uima.cas.CAS;
import org.apache.uima.cas.impl.XmiCasDeserializer;
import org.apache.uima.cas.text.AnnotationFS;
import org.apache.uima.cas.text.AnnotationIndex;
import org.apache.uima.caseditor.ide.TypeSystemLocationPropertyPage;
import org.apache.uima.resource.ResourceInitializationException;
import org.apache.uima.resource.metadata.FsIndexDescription;
import org.apache.uima.resource.metadata.TypeSystemDescription;
import org.apache.uima.ruta.addons.RutaAddonsPlugin;
import org.apache.uima.util.CasCreationUtils;
import org.apache.uima.util.InvalidXMLException;
import org.apache.uima.util.XMLInputSource;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.IHandler;
import org.eclipse.core.commands.IHandlerListener;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.ui.handlers.HandlerUtil;
import org.xml.sax.SAXException;
public class UpdateTaskHandler implements IHandler {
private class CheckAnnotationUpdateTaskJob extends Job {
private String documentSource;
private String typeSystem;
private AnnotationCheckComposite composite;
private String documentSink;
private AnnotationCheckTreeNode previousSelection;
CheckAnnotationUpdateTaskJob(String documentSource, String documentSink, String typeSystem,
AnnotationCheckComposite composite, AnnotationCheckTreeNode previousSelection) {
super("Update annotation check task...");
this.documentSource = documentSource;
this.documentSink = documentSink;
this.typeSystem = typeSystem;
this.composite = composite;
this.previousSelection = previousSelection;
}
CheckAnnotationUpdateTaskJob(AnnotationCheckComposite composite, AnnotationCheckTreeNode previousSelection ) {
this(composite.getDocumentSource(), composite.getDocumentSink(), composite.getTypeSystem(),
composite, previousSelection);
}
public IStatus run(IProgressMonitor monitor) {
List<String> selectedTypes = composite.getSelectedTypes();
File dir = new File(documentSource);
File[] listFiles = dir.listFiles(new FilenameFilter() {
public boolean accept(File file, String string) {
return string.endsWith(".xmi");
}
});
if (listFiles == null) {
return Status.CANCEL_STATUS;
}
File dataFile = new File(documentSink, "data.xml");
List<CheckDocument> docs = new ArrayList<CheckDocument>();
try {
docs = XMLUtils.read(dataFile);
} catch (SAXException e) {
RutaAddonsPlugin.error(e);
} catch (IOException e) {
RutaAddonsPlugin.error(e);
}
setDefaultTypeSystem(documentSource, typeSystem);
TypeSystemDescription tsd = null;
try {
tsd = UIMAFramework.getXMLParser().parseTypeSystemDescription(
new XMLInputSource(typeSystem));
tsd.resolveImports();
} catch (InvalidXMLException e) {
RutaAddonsPlugin.error(e);
} catch (IOException e) {
RutaAddonsPlugin.error(e);
}
CAS cas = null;
try {
cas = CasCreationUtils.createCas(tsd, null, new FsIndexDescription[0]);
} catch (ResourceInitializationException e) {
RutaAddonsPlugin.error(e);
}
if (tsd == null || cas == null) {
return Status.CANCEL_STATUS;
}
TreePath treePath = null;
final IAnnotationCheckTreeNode root = new AnnotationCheckRootNode();
for (File file : listFiles) {
cas.reset();
try {
XmiCasDeserializer.deserialize(new FileInputStream(file), cas, true);
} catch (FileNotFoundException e) {
RutaAddonsPlugin.error(e);
} catch (SAXException e) {
RutaAddonsPlugin.error(e);
} catch (IOException e) {
RutaAddonsPlugin.error(e);
}
CheckDocument element = getCheckDocument(docs, file.getAbsolutePath());
boolean documentAlreadyDone = documentAlreadyDoneforTypes(element, selectedTypes);
if (!documentAlreadyDone) {
AnnotationCheckTreeNode node = new AnnotationCheckTreeNode(root, element);
root.addChild(node);
AnnotationIndex<AnnotationFS> annotationIndex = cas.getAnnotationIndex();
for (AnnotationFS each : annotationIndex) {
boolean annotationAlreadyDoneforTypes = annotationAlreadyDoneforTypes(each,
selectedTypes, element.checkedTypes);
if (!annotationAlreadyDoneforTypes) {
CheckElement ac = new CheckAnnotation(each);
AnnotationCheckTreeNode anode = new AnnotationCheckTreeNode(node, ac);
if (treePath == null) {
treePath = new TreePath(new Object[] { root, node, anode });
}
node.addChild(anode);
}
}
if (treePath == null) {
treePath = new TreePath(new Object[] { root, node });
}
}
}
if(previousSelection != null) {
CheckElement element = previousSelection.getElement();
TreePath oldPath = getPathTo(element, root);
if(oldPath != null) {
treePath = oldPath;
}
}
final TreeSelection firstSelection = new TreeSelection(treePath);
cas.release();
composite.setOldDocs(docs);
composite.getDisplay().asyncExec(new Runnable() {
public void run() {
TreeViewer treeView = composite.getTreeViewer();
treeView.setInput(root);
treeView.setSelection(firstSelection, true);
}
});
return Status.OK_STATUS;
}
private TreePath getPathTo(CheckElement element, IAnnotationCheckTreeNode root) {
AnnotationCheckTreeNode[] children = root.getChildren();
for (AnnotationCheckTreeNode eachDocNode : children) {
if(element instanceof CheckAnnotation) {
AnnotationCheckTreeNode[] children2 = eachDocNode.getChildren();
for (AnnotationCheckTreeNode eachANode : children2) {
if(isSameElement(eachANode.getElement(), element)) {
return new TreePath(new Object[] { root, eachDocNode, eachANode});
}
}
} else {
if(isSameElement(eachDocNode.getElement(), element)) {
return new TreePath(new Object[] { root, eachDocNode});
}
}
}
return null;
}
private boolean isSameElement(CheckElement e1, CheckElement e2) {
if(e1 == null || e2 == null) {
return false;
}
if(e1 instanceof CheckAnnotation && e2 instanceof CheckAnnotation) {
CheckAnnotation ca1 = (CheckAnnotation) e1;
CheckAnnotation ca2 = (CheckAnnotation) e2;
return ca1.begin == ca2.begin && ca1.end == ca2.end && ca1.type.equals(ca2.type);
}
if(e1 instanceof CheckDocument && e2 instanceof CheckDocument) {
CheckDocument cd1 = (CheckDocument) e1;
CheckDocument cd2 = (CheckDocument) e2;
return cd1.source.equals(cd2.source);
}
return false;
}
private boolean documentAlreadyDoneforTypes(CheckDocument element, List<String> selectedTypes) {
if(element.checkedTypes.isEmpty() && !selectedTypes.isEmpty()) {
return false;
}
boolean allCovered = true;
for (String each : selectedTypes) {
allCovered &= element.checkedTypes.contains(each);
}
return allCovered;
}
private boolean annotationAlreadyDoneforTypes(AnnotationFS each,
Collection<String> selectedTypes, Collection<String> alreadyDone) {
String name = each.getType().getName();
if(alreadyDone.contains(name)) {
return true;
}
return !selectedTypes.contains(name);
}
private CheckDocument getCheckDocument(List<CheckDocument> docs, String absolutePath) {
for (CheckDocument checkDocument : docs) {
if (checkDocument.source.equals(absolutePath)) {
return checkDocument;
}
}
return new CheckDocument(absolutePath);
}
public void setDefaultTypeSystem(String documentSource, String typeSystemLocation) {
IFile dsFile = CheckAnnotationUtils.getIFile(documentSource);
IFile tsFile = CheckAnnotationUtils.getIFile(typeSystemLocation);
IProject project = dsFile.getProject();
String portableString = tsFile.getFullPath().toPortableString();
TypeSystemLocationPropertyPage.setTypeSystemLocation(project, portableString);
}
}
public void addHandlerListener(IHandlerListener arg0) {
}
public void dispose() {
}
public Object execute(ExecutionEvent event) throws ExecutionException {
AnnotationCheckView acView;
try {
acView = (AnnotationCheckView) HandlerUtil.getActiveWorkbenchWindow(event).getWorkbench()
.getActiveWorkbenchWindow().getActivePage().showView(AnnotationCheckView.ID);
AnnotationCheckComposite composite = (AnnotationCheckComposite) acView.getComposite();
TreeSelection selection = (TreeSelection) composite.getTreeViewer().getSelection();
AnnotationCheckTreeNode previousSelection = (AnnotationCheckTreeNode) selection.getFirstElement();
CheckAnnotationUpdateTaskJob job = new CheckAnnotationUpdateTaskJob(composite, previousSelection);
job.schedule();
} catch (Exception e) {
RutaAddonsPlugin.error(e);
return Status.CANCEL_STATUS;
}
return Status.OK_STATUS;
}
public boolean isEnabled() {
return true;
}
public boolean isHandled() {
return true;
}
public void removeHandlerListener(IHandlerListener arg0) {
}
}