package gate.compound.gui;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.io.File;
import java.util.*;
import javax.swing.*;
import gate.*;
import gate.compound.CompoundDocument;
import gate.compound.CompoundDocumentEvent;
import gate.compound.CompoundDocumentListener;
import gate.compound.impl.AbstractCompoundDocument;
import gate.corpora.DocumentImpl;
import gate.creole.*;
import gate.event.ProgressListener;
import gate.gui.ActionsPublisher;
import gate.gui.Handle;
import gate.gui.MainFrame;
import gate.gui.NameBearerHandle;
import gate.util.GateException;
import gate.util.GateRuntimeException;
import java.io.*;
/**
* This is an extention of the GATE Document viewer/editor. This class
* provides the implementation for CompoundDocument Editor. Compound
* document is a set of multiple documents. this class simply wrapps all
* document editors for all compound document's member documents under a
* single component.
*/
public class CompoundDocumentEditor extends AbstractVisualResource
implements
ActionsPublisher,
ProgressListener,
CompoundDocumentListener {
private static final long serialVersionUID = -7623216613025540025L;
private JTabbedPane tabbedPane;
private HashMap<String, JComponent> documentsMap;
protected JToolBar toolbar;
protected NewDocumentAction newDocumentAction;
protected RemoveDocumentsAction removeDocumentsAction;
/**
* The document view is just an empty shell. This method publishes the
* actions from the contained views.
*/
public List getActions() {
List actions = new ArrayList();
actions.add(new SaveAllDocuments());
actions.add(new SaveAsASingleXML());
actions.add(new SwitchDocument());
actions.add(new LoadFromXML());
actions.add(new PopulateCorpus());
actions.add(new PopulateCorpusFromXML());
return actions;
}
/*
* (non-Javadoc)
*
* @see gate.Resource#init()
*/
public Resource init() throws ResourceInstantiationException {
tabbedPane = new JTabbedPane();
documentsMap = new HashMap<String, JComponent>();
toolbar = new JToolBar();
toolbar.setFloatable(false);
toolbar.add(newDocumentAction = new NewDocumentAction());
toolbar.add(removeDocumentsAction = new RemoveDocumentsAction());
this.setLayout(new java.awt.BorderLayout());
this.add(tabbedPane, java.awt.BorderLayout.CENTER);
this.add(toolbar, BorderLayout.NORTH);
return this;
}
/*
* (non-Javadoc)
*
* @see gate.VisualResource#setTarget(java.lang.Object)
*/
public void setTarget(Object target) {
this.document = (Document)target;
}
/**
* Used by the main GUI to tell this VR what handle created it. The
* VRs can use this information e.g. to add items to the popup for the
* resource.
*/
public void setHandle(Handle handle) {
super.setHandle(handle);
Map documents = ((CompoundDocument)this.document).getDocuments();
((CompoundDocument)this.document).addCompoundDocumentListener(this);
Iterator iter = documents.values().iterator();
try {
while(iter.hasNext()) {
Document doc = (Document)iter.next();
NameBearerHandle nbHandle = new NameBearerHandle(doc, Main
.getMainFrame());
JComponent largeView = nbHandle.getLargeView();
if(largeView != null) {
tabbedPane.addTab(nbHandle.getTitle(), nbHandle.getIcon(), largeView,
nbHandle.getTooltipText());
documentsMap.put(doc.getName(), largeView);
}
ResourceData rd = (ResourceData)Gate.getCreoleRegister().get(
doc.getClass().getName());
if(rd != null) rd.removeInstantiation(doc);
Gate.setHiddenAttribute(doc.getFeatures(), false);
}
}
catch(Exception e) {
throw new RuntimeException(e);
}
}
class NewDocumentAction extends AbstractAction {
public NewDocumentAction() {
super("Add document", MainFrame.getIcon("add-document"));
putValue(SHORT_DESCRIPTION,
"Add new document(s) to this compound document");
putValue(MNEMONIC_KEY, KeyEvent.VK_ENTER);
}
public void actionPerformed(ActionEvent e) {
try {
// get all the documents loaded in the system
java.util.List loadedDocuments = Gate.getCreoleRegister()
.getAllInstances("gate.Document");
if(loadedDocuments == null || loadedDocuments.isEmpty()) {
JOptionPane.showMessageDialog(CompoundDocumentEditor.this,
"There are no documents available in the system.\n"
+ "Please load some and try again.", "GATE",
JOptionPane.ERROR_MESSAGE);
return;
}
Vector docNames = new Vector();
for(int i = 0; i < loadedDocuments.size(); i++) {
Document doc = (Document)loadedDocuments.get(i);
if(doc instanceof CompoundDocument) {
loadedDocuments.remove(i);
i--;
continue;
}
docNames.add(doc.getName());
}
JList docList = new JList(docNames);
JOptionPane dialog = new JOptionPane(new JScrollPane(docList),
JOptionPane.QUESTION_MESSAGE, JOptionPane.OK_CANCEL_OPTION);
dialog.createDialog(CompoundDocumentEditor.this,
"Add document(s) to compound document").setVisible(true);
if(((Integer)dialog.getValue()).intValue() == JOptionPane.OK_OPTION) {
int[] selection = docList.getSelectedIndices();
for(int i = 0; i < selection.length; i++) {
Document doc = (Document)loadedDocuments.get(selection[i]);
((CompoundDocument)document).addDocument(doc.getName(), doc);
}
}
}
catch(GateException ge) {
// gate.Document is not registered in creole.xml....what is!?
throw new GateRuntimeException(
"gate.Document is not registered in the creole register!\n"
+ "Something must be terribly wrong...take a vacation!");
}
}
}
class RemoveDocumentsAction extends AbstractAction {
public RemoveDocumentsAction() {
super("Remove documents", MainFrame.getIcon("remove-document"));
putValue(SHORT_DESCRIPTION,
"Removes selected document(s) from this corpus");
putValue(MNEMONIC_KEY, KeyEvent.VK_DELETE);
}
public void actionPerformed(ActionEvent e) {
if(tabbedPane.getSelectedIndex() >= 0) {
String docName = tabbedPane.getTitleAt(tabbedPane.getSelectedIndex());
((CompoundDocument)document).removeDocument(docName);
}
}
}
class SaveAllDocuments extends AbstractAction {
private static final long serialVersionUID = -1377052643002026640L;
public SaveAllDocuments() {
super("Save All Documents As XML!");
}
public void actionPerformed(ActionEvent ae) {
CompoundDocument cd = (CompoundDocument)document;
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
try {
fileChooser.showSaveDialog(Main.getMainFrame());
File dir = null;
if((dir = fileChooser.getSelectedFile()) == null) {
return;
}
List<String> docIDs = cd.getDocumentIDs();
for(int i = 0; i < docIDs.size(); i++) {
Document doc = cd.getDocument(docIDs.get(i));
File file = null;
if(doc.getName().equals("Composite")) {
file = new File(dir.getAbsolutePath() + "/Composite.xml");
}
else {
file = new File(doc.getSourceUrl().getFile());
file = new File(dir.getAbsolutePath() + "/" + file.getName());
}
BufferedWriter bw = new BufferedWriter(
new OutputStreamWriter(new FileOutputStream(file),
((DocumentImpl)doc).getEncoding()));
bw.write(doc.toXml());
bw.flush();
bw.close();
}
}
catch(Exception e) {
e.printStackTrace();
}
}
}
class LoadFromXML extends AbstractAction {
private static final long serialVersionUID = -1377052643002026640L;
public LoadFromXML() {
super("Compound Document from XML");
}
public void actionPerformed(ActionEvent ae) {
CompoundDocument cd = (CompoundDocument)document;
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
try {
fileChooser.showOpenDialog(Main.getMainFrame());
File fileToOpen = null;
if((fileToOpen = fileChooser.getSelectedFile()) == null) {
return;
}
StringBuilder xmlString = new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader(
new FileInputStream(fileToOpen), "utf-8"));
String line = br.readLine();
while(line != null) {
xmlString.append("\n").append(line);
line = br.readLine();
}
AbstractCompoundDocument.fromXml(xmlString.toString());
br.close();
}
catch(Exception e) {
e.printStackTrace();
}
}
}
class PopulateCorpusFromXML extends AbstractAction {
private static final long serialVersionUID = -1377052643002026640L;
public PopulateCorpusFromXML() {
super("Populate Corpus From XML");
}
public void actionPerformed(ActionEvent ae) {
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
try {
fileChooser.showOpenDialog(Main.getMainFrame());
File fileToOpen = null;
if((fileToOpen = fileChooser.getSelectedFile()) == null) {
return;
}
File[] files = fileToOpen.listFiles(new FilenameFilter() {
public boolean accept(File dir, String name) {
if(name.endsWith(".xml")) {
return true;
}
return false;
}
});
// file to Open is a directory
String corpusName = JOptionPane.showInputDialog("Enter CorpusName");
Corpus corpusToUse = Factory.newCorpus(corpusName);
for(File aFile : files) {
StringBuilder xmlString = new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader(
new FileInputStream(aFile), "utf-8"));
String line = br.readLine();
while(line != null) {
xmlString.append("\n").append(line);
line = br.readLine();
}
CompoundDocument doc = AbstractCompoundDocument.fromXml(xmlString
.toString());
corpusToUse.add(doc);
br.close();
}
}
catch(Exception e) {
e.printStackTrace();
}
}
}
class PopulateCorpus extends AbstractAction {
private static final long serialVersionUID = -1377052643002026640L;
public PopulateCorpus() {
super("Populate Corpus With Compound Documents");
}
public void actionPerformed(ActionEvent ae) {
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
try {
fileChooser.showOpenDialog(Main.getMainFrame());
File fileToOpen = null;
if((fileToOpen = fileChooser.getSelectedFile()) == null) {
return;
}
// file to Open is a directory
String corpusName = JOptionPane.showInputDialog("Enter CorpusName");
Corpus corpusToUse = Factory.newCorpus(corpusName);
// file to Open is a directory
String langCodes = JOptionPane
.showInputDialog("Enter language codes (comma separated)");
final String[] codes = langCodes.split(",");
File[] files = fileToOpen.listFiles(new FilenameFilter() {
public boolean accept(File dir, String name) {
if(name.indexOf("." + codes[0] + ".") > 0) {
return true;
}
return false;
}
});
List<String> docIds = new ArrayList<String>();
for(String code : codes) {
docIds.add(code);
}
for(File aFile : files) {
FeatureMap fets = Factory.newFeatureMap();
fets.put("sourceUrl", aFile.toURL());
fets.put("documentIDs", docIds);
fets.put("encoding", "UTF-8");
CompoundDocument cd = (CompoundDocument)Factory.createResource(
"gate.compound.impl.CompoundDocumentImpl", fets);
corpusToUse.add(cd);
}
}
catch(Exception e) {
e.printStackTrace();
}
}
}
public class SaveAsASingleXML extends AbstractAction {
private static final long serialVersionUID = -1377052643002026640L;
public SaveAsASingleXML() {
super("Save in a single XML Document");
}
public void actionPerformed(ActionEvent ae) {
CompoundDocument cd = (CompoundDocument)document;
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
try {
fileChooser.showSaveDialog(Main.getMainFrame());
File fileToSaveIn = null;
if((fileToSaveIn = fileChooser.getSelectedFile()) == null) {
return;
}
String xml = AbstractCompoundDocument.toXmlAsASingleDocument(cd);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(fileToSaveIn), cd.getEncoding()));
bw.write(xml);
bw.flush();
bw.close();
}
catch(Exception e) {
e.printStackTrace();
}
}
}
class SwitchDocument extends AbstractAction {
private static final long serialVersionUID = -1377052643002026640L;
public SwitchDocument() {
super("Switch Document");
}
public void actionPerformed(ActionEvent ae) {
CompoundDocument cd = (CompoundDocument)document;
List<String> docIDs = cd.getDocumentIDs();
JComboBox box = new JComboBox(docIDs.toArray());
Object[] options = {"OK", "CANCEL"};
int reply = JOptionPane.showOptionDialog(MainFrame.getInstance(), box,
"Select the document ID to switch to...",
JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null,
options, options[0]);
if(reply == JOptionPane.OK_OPTION) {
String documentID = (String)box.getSelectedItem();
((CompoundDocument)document).setCurrentDocument(documentID);
}
}
}
protected Document document;
public void processFinished() {
((CompoundDocument)this.document).setCurrentDocument("null");
}
public void progressChanged(int prgress) {
}
public void documentAdded(CompoundDocumentEvent event) {
try {
Document doc = event.getSource().getDocument(event.getDocumentID());
final NameBearerHandle nbHandle = new NameBearerHandle(doc, Main
.getMainFrame());
final JComponent largeView = nbHandle.getLargeView();
if(largeView != null) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
tabbedPane.addTab(nbHandle.getTitle(), nbHandle.getIcon(),
largeView, nbHandle.getTooltipText());
}
});
documentsMap.put(doc.getName(), largeView);
}
if(Gate.getHiddenAttribute(doc.getFeatures())) {
ResourceData rd = (ResourceData)Gate.getCreoleRegister().get(
doc.getClass().getName());
if(rd != null) rd.removeInstantiation(doc);
Gate.setHiddenAttribute(doc.getFeatures(), false);
}
tabbedPane.updateUI();
}
catch(Exception e) {
e.printStackTrace();
}
}
public void documentRemoved(CompoundDocumentEvent event) {
Component cmp = (Component)documentsMap.get(event.getDocumentID());
if(cmp != null) {
tabbedPane.remove(cmp);
tabbedPane.updateUI();
Document doc = event.getSource().getDocument(event.getDocumentID());
ResourceData rd = (ResourceData)Gate.getCreoleRegister().get(
doc.getClass().getName());
if(rd != null) {
if(!rd.getInstantiations().contains(doc)) {
Factory.deleteResource(event.getSource().getDocument(
event.getDocumentID()));
}
}
}
}
}