changelog.java
来自「Semantic Web Ontology Editor」· Java 代码 · 共 2,028 行 · 第 1/5 页
JAVA
2,028 行
//The MIT License
//
// Copyright (c) 2004 Mindswap Research Group, University of Maryland, College Park
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
package org.mindswap.swoop.change;
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.Vector;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JEditorPane;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTree;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.table.TableColumn;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;
import org.mindswap.swoop.ModelChangeEvent;
import org.mindswap.swoop.SwoopFrame;
import org.mindswap.swoop.SwoopModel;
import org.mindswap.swoop.SwoopModelListener;
import org.mindswap.swoop.renderer.entity.ConciseFormatEntityRenderer;
import org.mindswap.swoop.renderer.entity.RDFXMLEntityRenderer;
import org.mindswap.swoop.treetable.JTreeTable;
import org.mindswap.swoop.utils.change.BooleanElementChange;
import org.mindswap.swoop.utils.change.EnumElementChange;
import org.mindswap.swoop.utils.change.RevertCheckpointChange;
import org.mindswap.swoop.utils.change.SaveCheckpointChange;
import org.mindswap.swoop.utils.owlapi.CorrectedRDFRenderer;
import org.mindswap.swoop.utils.rdfapi.EConnTripleVisitor;
import org.mindswap.swoop.utils.rdfapi.PrettyXMLWriter;
import org.mindswap.swoop.utils.rdfapi.TripleVisitor;
import org.mindswap.swoop.utils.ui.ChangeComparator;
import org.semanticweb.owl.io.RendererException;
import org.semanticweb.owl.model.OWLAnd;
import org.semanticweb.owl.model.OWLAnnotationProperty;
import org.semanticweb.owl.model.OWLClass;
import org.semanticweb.owl.model.OWLClassAxiom;
import org.semanticweb.owl.model.OWLDataProperty;
import org.semanticweb.owl.model.OWLDataRange;
import org.semanticweb.owl.model.OWLDataValue;
import org.semanticweb.owl.model.OWLDescription;
import org.semanticweb.owl.model.OWLDifferentIndividualsAxiom;
import org.semanticweb.owl.model.OWLDisjointClassesAxiom;
import org.semanticweb.owl.model.OWLEntity;
import org.semanticweb.owl.model.OWLException;
import org.semanticweb.owl.model.OWLIndividual;
import org.semanticweb.owl.model.OWLIndividualAxiom;
import org.semanticweb.owl.model.OWLNamedObject;
import org.semanticweb.owl.model.OWLObject;
import org.semanticweb.owl.model.OWLObjectProperty;
import org.semanticweb.owl.model.OWLOntology;
import org.semanticweb.owl.model.OWLOr;
import org.semanticweb.owl.model.OWLProperty;
import org.semanticweb.owl.model.OWLSameIndividualsAxiom;
import org.semanticweb.owl.model.OWLSubClassAxiom;
import org.semanticweb.owl.model.change.AddAnnotationInstance;
import org.semanticweb.owl.model.change.AddClassAxiom;
import org.semanticweb.owl.model.change.AddDataPropertyInstance;
import org.semanticweb.owl.model.change.AddDataPropertyRange;
import org.semanticweb.owl.model.change.AddDomain;
import org.semanticweb.owl.model.change.AddEntity;
import org.semanticweb.owl.model.change.AddEquivalentClass;
import org.semanticweb.owl.model.change.AddImport;
import org.semanticweb.owl.model.change.AddIndividualAxiom;
import org.semanticweb.owl.model.change.AddIndividualClass;
import org.semanticweb.owl.model.change.AddInverse;
import org.semanticweb.owl.model.change.AddObjectPropertyInstance;
import org.semanticweb.owl.model.change.AddObjectPropertyRange;
import org.semanticweb.owl.model.change.AddSuperClass;
import org.semanticweb.owl.model.change.AddSuperProperty;
import org.semanticweb.owl.model.change.ChangeVisitor;
import org.semanticweb.owl.model.change.OntologyChange;
import org.semanticweb.owl.model.change.RemoveAnnotationInstance;
import org.semanticweb.owl.model.change.RemoveClassAxiom;
import org.semanticweb.owl.model.change.RemoveDataPropertyInstance;
import org.semanticweb.owl.model.change.RemoveDataPropertyRange;
import org.semanticweb.owl.model.change.RemoveDomain;
import org.semanticweb.owl.model.change.RemoveEntity;
import org.semanticweb.owl.model.change.RemoveEquivalentClass;
import org.semanticweb.owl.model.change.RemoveImport;
import org.semanticweb.owl.model.change.RemoveIndividualAxiom;
import org.semanticweb.owl.model.change.RemoveIndividualClass;
import org.semanticweb.owl.model.change.RemoveInverse;
import org.semanticweb.owl.model.change.RemoveObjectPropertyInstance;
import org.semanticweb.owl.model.change.RemoveObjectPropertyRange;
import org.semanticweb.owl.model.change.RemoveSuperClass;
import org.semanticweb.owl.model.change.RemoveSuperProperty;
import org.semanticweb.owl.model.change.SetFunctional;
import org.semanticweb.owl.model.change.SetInverseFunctional;
import org.semanticweb.owl.model.change.SetSymmetric;
import org.semanticweb.owl.model.change.SetTransitive;
import org.xngr.browser.editor.XmlEditorPane;
/**
* @author Aditya Kalyanpur
* A file used to display Ontology Change information (i.e. change logs),
* obtain an inverse of an Ontology Change (used for undoing committed changes)
* and help serialize an Ontology Change in RDFXML (for sharing using Annotea)
*/
public class ChangeLog extends JPanel implements ActionListener, HyperlinkListener, SwoopModelListener, TreeSelectionListener {
JEditorPane logPane;
public SwoopModel swoopModel;
public SwoopFrame swoopHandler;
JCheckBoxMenuItem stayTopChk;
JMenu saveOntMenu, saveChSetMenu, exportMenu;
JMenuItem openMItem;
Font tahoma = new Font("Tahoma", Font.PLAIN, 10);
Font tahomaL = new Font("Tahoma", Font.PLAIN, 11);
JRadioButton entityRadio, ontRadio, wkspcRadio;
JPanel topPanel, bottomPanel;
JScrollPane threadTableScroll, htmlPanel;
JCheckBox showChanges, showChkPts;
JTreeTable changeTreeTable;
private Map localDirty;
JButton undoBtn, serBtn, attachBtn, deleteBtn, saveBtn;
final String[] cNames = {"Author", "Description", "Date", "Entity"};
public int scope = 0;
public static int ENTITY_SCOPE = 1;
public static int ONTOLOGY_SCOPE = 2;
public static int WORKSPACE_SCOPE = 3;
public final static int CHANGE_DESCRIPTION = 4;
public final static int CHANGE_RDFXML = 5;
public final static int CHANGE_INVERSE = 6;
public final static int CHANGE_ALIGN = 7;
public ChangeLog(SwoopFrame handler, SwoopModel model) {
this.swoopHandler = handler;
this.swoopModel = model;
this.localDirty = new HashMap();
setupUI();
}
private void setupUI() {
// create radio buttons
entityRadio = new JRadioButton("Entity");
entityRadio.setFont(tahomaL);
ontRadio = new JRadioButton("Ontology");
ontRadio.setFont(tahomaL);
wkspcRadio = new JRadioButton("Workspace");
wkspcRadio.setFont(tahomaL);
// add to button group
ButtonGroup group = new ButtonGroup();
group.add(entityRadio);
group.add(ontRadio);
group.add(wkspcRadio);
JLabel radioLbl = new JLabel("Scope:");
radioLbl.setFont(tahomaL);
JPanel radioPanel = new JPanel();
//radioPanel.setLayout(new GridLayout(1,4));
radioPanel.add(radioLbl);
radioPanel.add(entityRadio);
radioPanel.add(ontRadio);
radioPanel.add(wkspcRadio);
// create checkboxes
showChanges = new JCheckBox("Show Changes");
showChanges.setFont(tahomaL);
showChanges.addActionListener(this);
showChkPts = new JCheckBox("Show Checkpoints");
showChkPts.setFont(tahomaL);
showChkPts.addActionListener(this);
JPanel chkBoxPanel = new JPanel();
chkBoxPanel.add(showChanges);
chkBoxPanel.add(showChkPts);
// load settings from swoopModel
if (swoopModel!=null) {
showChanges.setSelected(swoopModel.getEnableChangeLogDisplay());
showChkPts.setSelected(swoopModel.isShowCheckPts());
}
// create change log pane
logPane = new JEditorPane();
logPane.setContentType("text/html");
logPane.setEditable(false);
logPane.addHyperlinkListener(this);
JPanel optionPanel = new JPanel();
optionPanel.setLayout(new GridLayout(2,1));
optionPanel.add(radioPanel);
optionPanel.add(chkBoxPanel);
setLayout(new BorderLayout());
add(optionPanel, "North");
// create change tree table
this.changeTreeTable = new JTreeTable(new DefaultTreeTableModel(getTreeRoot(), cNames));
this.changeTreeTable.setFont(tahomaL);
threadTableScroll = new JScrollPane(changeTreeTable);
// set some other properties of the change tree table
// set preferred col widths
TableColumn column = null;
for (int i = 0; i < changeTreeTable.getColumnCount(); i++) {
column = changeTreeTable.getColumnModel().getColumn(i);
switch (i) {
case 0: column.setPreferredWidth(40); break;
case 1: column.setPreferredWidth(70); break;
case 2: column.setPreferredWidth(20); break;
case 3: column.setPreferredWidth(60); break;
}
}
// set default change tree params
changeTreeTable.getTree().addTreeSelectionListener(this);
changeTreeTable.getTree().setRootVisible(false);
// create scroll for log pane
htmlPanel = new JScrollPane(logPane);
// create main change display pane with changeTree on top and change log pane below
JSplitPane mainPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
topPanel = new JPanel();
topPanel.setLayout(new BorderLayout());
topPanel.add(threadTableScroll, "Center");
bottomPanel = new JPanel();
bottomPanel.setLayout(new BorderLayout());
bottomPanel.add(htmlPanel, "Center");
mainPane.setTopComponent(topPanel);
mainPane.setBottomComponent(bottomPanel);
// add save checkpoint button to top of topPanel
saveBtn = this.initButton("Save Ontology Checkpoint", "Save Checkpoint");
topPanel.add(saveBtn, "North");
// add toolbar on bottom of topPanel
undoBtn = initButton("Undo", "Undo Selected Change(s)");
serBtn = initButton("Serialize", "Serialize Selected Change(s) in RDF/XML");
attachBtn = initButton("Attach", "Attach Selected Change(s) in an Annotea Annotation");
deleteBtn = initButton("Clear", "Delete Selected Change(s) from the Log Permanently");
//TODO: weirdest bug ever...make the below a JToolBar and hell breaks lose!
JPanel toolBar = new JPanel();
toolBar.setLayout(new GridLayout(1, 4));
toolBar.add(undoBtn);
toolBar.add(serBtn);
toolBar.add(attachBtn);
toolBar.add(deleteBtn);
topPanel.add(toolBar, "South");
add(mainPane, "Center");
mainPane.setDividerLocation(200);
// add actionListeners
entityRadio.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
setScope(ENTITY_SCOPE);
}
});
ontRadio.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
setScope(ONTOLOGY_SCOPE);
}
});
wkspcRadio.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
setScope(WORKSPACE_SCOPE);
}
});
}
public TreeTableNode getTreeRoot() {
SwoopChange root = null;
try {
root = new SwoopChange("", new URI("/"), null, "", "", true, true);
}
catch (Exception ex) {
}
return new TreeTableNode(root);
}
/**
* Set the scope of the change log. Can be one of three values,
* Entity, Ontology or Workspace
* @param scope - new scope value to set
*/
public void setScope(int scope) {
this.scope = scope;
// change save checkpoint button label accordingly
String scopeStr = "Entity";
if (scope==this.ONTOLOGY_SCOPE) scopeStr = "Ontology";
else if (scope==this.WORKSPACE_SCOPE) scopeStr = "Workspace";
saveBtn.setText("Save "+scopeStr+" Checkpoint");
this.refreshChangePane();
}
public int getScope() {
return this.scope;
}
/**
* Re-render the change display pane by displaying
* uncommitted and committed changes. Take into account
* the current scope level
*/
public void refreshChangePane() {
// populate the treetable based on scope and object selected in swoop
try {
List changeList = new ArrayList();
switch (scope) {
case 1: // ENTITY SCOPE
if (swoopModel.getSelectedEntity()!=null) {
URI uri = swoopModel.getSelectedEntity().getURI();
changeList = swoopModel.getChangesCache().getChangeList(uri);
}
break;
case 2: // ONTOLOGY SCOPE
if (swoopModel.getSelectedOntology()!=null) {
URI uri = swoopModel.getSelectedOntology().getURI();
changeList = swoopModel.getChangesCache().getChangeList(uri);
}
break;
case 3: // WORKSPACE SCOPE
List changes = swoopModel.getChangesCache().getAllChanges();
// remove all entity-scope changes
// since entity-scope changes are subsumed by ontology-scope changes
for (Iterator iter = changes.iterator(); iter.hasNext();) {
SwoopChange swc = (SwoopChange) iter.next();
if (swoopModel.getOntologyURIs().contains(swc.getOwlObjectURI())) {
changeList.add(swc);
}
}
break;
}
setChangeNodeTree(changeList);
}
catch (OWLException ex) {
ex.printStackTrace();
}
}
public void setChangeNodeTree(List changeList) {
// get rootnode from changetreetable
JTree changeTree = changeTreeTable.getTree();
TreeTableNode rootNode = (TreeTableNode) changeTree.getModel().getRoot();
rootNode.children = new Vector();
logPane.setText("");
// sort changes based on "timestamp" value
SortedSet changeSet = new TreeSet(ChangeComparator.INSTANCE);
changeSet.addAll(changeList);
// populate node tree
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?