blob: f961148f45a1e2a542760221d6dcb7cc25ede519 [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.tools.cpm;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;
import java.util.Vector;
import java.util.prefs.Preferences;
import javax.swing.AbstractButton;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.SwingConstants;
import javax.swing.Timer;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;
import org.apache.uima.UIMAException;
import org.apache.uima.UIMAFramework;
import org.apache.uima.UIMARuntimeException;
import org.apache.uima.UIMA_IllegalStateException;
import org.apache.uima.analysis_engine.AnalysisEngineDescription;
import org.apache.uima.cas.CAS;
import org.apache.uima.collection.CasConsumerDescription;
import org.apache.uima.collection.CasInitializerDescription;
import org.apache.uima.collection.CollectionProcessingEngine;
import org.apache.uima.collection.CollectionReaderDescription;
import org.apache.uima.collection.EntityProcessStatus;
import org.apache.uima.collection.StatusCallbackListener;
import org.apache.uima.collection.impl.metadata.cpe.CpeDescriptorFactory;
import org.apache.uima.collection.metadata.CasProcessorConfigurationParameterSettings;
import org.apache.uima.collection.metadata.CpeCasProcessor;
import org.apache.uima.collection.metadata.CpeCasProcessors;
import org.apache.uima.collection.metadata.CpeCollectionReader;
import org.apache.uima.collection.metadata.CpeCollectionReaderCasInitializer;
import org.apache.uima.collection.metadata.CpeCollectionReaderIterator;
import org.apache.uima.collection.metadata.CpeComponentDescriptor;
import org.apache.uima.collection.metadata.CpeDescription;
import org.apache.uima.collection.metadata.CpeDescriptorException;
import org.apache.uima.resource.ResourceConfigurationException;
import org.apache.uima.resource.ResourceManager;
import org.apache.uima.resource.ResourceSpecifier;
import org.apache.uima.resource.URISpecifier;
import org.apache.uima.resource.metadata.Import;
import org.apache.uima.resource.metadata.ResourceMetaData;
import org.apache.uima.tools.util.gui.FileChooserBugWorkarounds;
import org.apache.uima.tools.util.gui.FileSelector;
import org.apache.uima.tools.util.gui.FileSelectorListener;
import org.apache.uima.tools.util.gui.SwingWorker;
import org.apache.uima.tools.util.gui.TransportControlListener;
import org.apache.uima.tools.util.gui.TransportControlPanel;
import org.apache.uima.tools.util.gui.XMLFileFilter;
import org.apache.uima.util.FileUtils;
import org.apache.uima.util.InvalidXMLException;
import org.apache.uima.util.Progress;
import org.apache.uima.util.XMLInputSource;
public class CpmPanel extends JPanel implements ActionListener, FileSelectorListener,
TabClosedListener, TransportControlListener {
private static final long serialVersionUID = -5096300176103368922L;
public static final String HELP_MESSAGE = "Instructions for using UIMA Collection Processing Engine Configurator:\n\n"
+ "Select a Collection Reader descriptor using the Browse button in the topmost panel.\n\n"
+ "On the Analyis Engines panel and the CAS Consumers panel, use the Add button to select Analysis Engine (AE) \n"
+ "and CAS Consumer descriptors.\n\n"
+ "Press the Play button to start collection processing.\n"
+ "A progress bar in the lower left corner of the window will indicate the processing progress.\n"
+ "When running, you may use the Pause or Stop button to pause or stop the processing.\n\n"
+ "The File menu contains options for opening and saving CPE descriptors.\n\n"
+ "The View menu contains an option to display the CAS Initializer panel. CAS Initializers are deprecated \n"
+ "since UIMA version 2.0, but are still supported by this tool.";
private static final String PREFS_CPE_DESCRIPTOR_FILE = "cpeDescriptorFile";
private static final String PREFS_SAVE_USING_IMPORTS ="saveUsingImports";
private JMenuItem openCpeDescMenuItem;
private JMenuItem saveCpeDescMenuItem;
private JMenuItem refreshMenuItem;
private JMenuItem clearAllMenuItem;
private JSplitPane mainSplitPane;
private JSplitPane readerInitializerSplitPane;
private ResetableMetaDataPanel collectionReaderPanel;
private TitledBorder collectionReaderTitledBorder;
private ResetableMetaDataPanel casInitializerPanel;
private TitledBorder casInitializerTitledBorder;
private FileSelector readerFileSelector;
private FileSelector casInitializerFileSelector;
private JPanel aeMainPanel;
private JTabbedPaneWithCloseIcons aeTabbedPane;
private JButton moveAeRightButton;
private JButton moveAeLeftButton;
private JButton addAeButton;
private TitledBorder aeTitledBorder;
private JPanel consumersPanel;
private TitledBorder consumerTitledBorder;
private JButton addConsumerButton;
private JButton moveConsumerRightButton;
private JButton moveConsumerLeftButton;
private JTabbedPaneWithCloseIcons consumerTabbedPane;
private Vector aeSpecifiers = new Vector();
private Vector consumerSpecifiers = new Vector();
// private static LogDialog logDialog;
private JProgressBar progressBar;
private TransportControlPanel transportControlPanel;
private AbstractButton startButton;
private AbstractButton stopButton;
private JLabel statusLabel;
private Timer progressTimer;
private int elapsedTime;
private Timer performanceQueryTimer;
private CollectionReaderDescription collectionReaderDesc;
private CasInitializerDescription casInitializerDesc;
private CollectionProcessingEngine mCPE;
private boolean indeterminateProgressPause;
private JFileChooser aeFileChooser;
private JFileChooser consumerFileChooser;
private JFileChooser openSaveFileChooser;
private File fileChooserRootDir;
private long collectionReaderLastFileSyncTimestamp;
private long casInitializerLastFileSyncTimestamp;
private long lastFileSyncUserPromptTime;
/** Stores user preferences */
private Preferences prefs = Preferences.userRoot().node("org/apache/uima/tools/CPE_GUI");
private boolean mShuttingDown;
private boolean mPaused;
private boolean selectedComponentsChanged = false;
private JMenuItem viewCasInitializerPanelMenuItem;
private CpeDescription currentCpeDesc = createEmptyCpeDescription();
private final ResourceManager defaultResourceManager = UIMAFramework.newDefaultResourceManager();
private boolean saveUsingImports = true;
private JCheckBoxMenuItem saveUsingImportMenuItem;
public CpmPanel() {
super();
// The following is VERY flaky:
// Don't 'try' this at home:
/*
* try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (Exception
* e) { }
*/
String fileChooserRootDirPath = System.getProperty("uima.file_chooser_root");
if (fileChooserRootDirPath == null) {
fileChooserRootDirPath = System.getProperty("user.dir");
}
fileChooserRootDir = new File(fileChooserRootDirPath);
// setResizable(false);
this.setLayout(new BorderLayout());
mainSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
mainSplitPane.setResizeWeight(0.25);
JSplitPane bottomSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
bottomSplitPane.setResizeWeight(0.5);
mainSplitPane.setBottomComponent(bottomSplitPane);
readerInitializerSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
readerInitializerSplitPane.setResizeWeight(0.5);
collectionReaderPanel = new ResetableMetaDataPanel(2);
// Initialized in readPreferences
Border bevelBorder = BorderFactory.createRaisedBevelBorder();
collectionReaderTitledBorder = BorderFactory.createTitledBorder(bevelBorder,
"Collection Reader");
collectionReaderPanel.setBorder(collectionReaderTitledBorder);
JScrollPane collectionReaderScrollPane = new JScrollPane(collectionReaderPanel);
readerInitializerSplitPane.setLeftComponent(collectionReaderScrollPane);
casInitializerPanel = new ResetableMetaDataPanel(2);
bevelBorder = BorderFactory.createRaisedBevelBorder();
casInitializerTitledBorder = BorderFactory.createTitledBorder(bevelBorder, "CAS Initializer");
casInitializerPanel.setBorder(casInitializerTitledBorder);
readerInitializerSplitPane.setRightComponent(casInitializerPanel);
mainSplitPane.setTopComponent(readerInitializerSplitPane);
// AE Panel
aeMainPanel = new JPanel();
aeMainPanel.setLayout(new BorderLayout());
aeTitledBorder = BorderFactory.createTitledBorder(bevelBorder, "Analysis Engines");
aeMainPanel.setBorder(aeTitledBorder);
addAeButton = new JButton("Add...");
addAeButton.addActionListener(this);
moveAeLeftButton = new JButton("<<");
moveAeLeftButton.addActionListener(this);
moveAeRightButton = new JButton(">>");
moveAeRightButton.addActionListener(this);
JPanel addAePanel = new JPanel();
addAePanel.setLayout(new FlowLayout(FlowLayout.LEFT));
addAePanel.add(addAeButton);
addAePanel.add(moveAeLeftButton);
addAePanel.add(moveAeRightButton);
aeMainPanel.add(addAePanel, BorderLayout.NORTH);
aeTabbedPane = new JTabbedPaneWithCloseIcons();
aeTabbedPane.addTabClosedListener(this);
aeMainPanel.add(aeTabbedPane, BorderLayout.CENTER);
JScrollPane aeScrollPane = new JScrollPane(aeMainPanel);
bottomSplitPane.setTopComponent(aeScrollPane);
// Consumers panel
consumersPanel = new JPanel();
consumersPanel.setLayout(new BorderLayout());
consumerTitledBorder = BorderFactory.createTitledBorder(bevelBorder, "CAS Consumers");
consumersPanel.setBorder(consumerTitledBorder);
addConsumerButton = new JButton("Add...");
addConsumerButton.addActionListener(this);
moveConsumerLeftButton = new JButton("<<");
moveConsumerLeftButton.addActionListener(this);
moveConsumerRightButton = new JButton(">>");
moveConsumerRightButton.addActionListener(this);
JPanel addConsumerPanel = new JPanel();
addConsumerPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
addConsumerPanel.add(addConsumerButton);
addConsumerPanel.add(moveConsumerLeftButton);
addConsumerPanel.add(moveConsumerRightButton);
consumersPanel.add(addConsumerPanel, BorderLayout.NORTH);
consumerTabbedPane = new JTabbedPaneWithCloseIcons();
consumerTabbedPane.addTabClosedListener(this);
consumersPanel.add(consumerTabbedPane, BorderLayout.CENTER);
JScrollPane consumerScrollPane = new JScrollPane(consumersPanel);
bottomSplitPane.setBottomComponent(consumerScrollPane);
// logDialog = new LogDialog();
this.add(mainSplitPane, BorderLayout.CENTER);
JPanel southernPanel = new JPanel();
southernPanel.setLayout(new BorderLayout());
JPanel southernCentralPanel = new JPanel();
GridBagLayout gbl = new GridBagLayout();
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = 3;
gbc.gridy = 0;
gbc.insets = new Insets(4, 4, 4, 4);
southernCentralPanel.setLayout(gbl);
progressBar = new JProgressBar();
gbc.gridx = 0;
gbc.weightx = 1.0;
gbc.anchor = GridBagConstraints.WEST;
southernCentralPanel.add(progressBar, gbc);
transportControlPanel = new TransportControlPanel(this);
transportControlPanel.setButtonTooltipText(TransportControlPanel.PLAY_BUTTON,
"Run Collection Processing");
transportControlPanel.setButtonTooltipText(TransportControlPanel.PAUSE_BUTTON,
"Pause Collection Processing");
transportControlPanel.setButtonTooltipText(TransportControlPanel.STOP_BUTTON,
"Stop Collection Processing");
gbc.gridx = 1;
gbc.weightx = 0.0;
gbc.anchor = GridBagConstraints.CENTER;
southernCentralPanel.add(transportControlPanel, gbc);
southernPanel.add(southernCentralPanel, BorderLayout.CENTER);
statusLabel = new JLabel("Initialized", SwingConstants.LEFT);
southernPanel.add(statusLabel, BorderLayout.SOUTH);
startButton = transportControlPanel.getButton(TransportControlPanel.PLAY_BUTTON);
startButton.addActionListener(this);
stopButton = transportControlPanel.getButton(TransportControlPanel.STOP_BUTTON);
stopButton.addActionListener(this);
this.add(southernPanel, BorderLayout.SOUTH);
progressTimer = new Timer(1000, this);
performanceQueryTimer = new Timer(2000, this);
initFileChoosers();
//create file selectors (used to populate CR and CI panels later)
readerFileSelector = new FileSelector(null, "Collection Reader Descriptor",
JFileChooser.FILES_ONLY, fileChooserRootDir, new XMLFileFilter());
readerFileSelector.addFileSelectorListener(this, collectionReaderPanel);
casInitializerFileSelector = new FileSelector(null, "CAS Initializer Descriptor",
JFileChooser.FILES_ONLY, fileChooserRootDir, new XMLFileFilter());
casInitializerFileSelector.addFileSelectorListener(this, casInitializerPanel);
// initialize empty CollectionReader and CAS Initializer panels
try {
populateCollectionReaderPanel(null);
populateCasInitializerPanel(null);
} catch (Exception e) {
e.printStackTrace();
}
// CAS initializer panel is initially hidden since it is deprecated
setCasInitializerPanelVisible(false);
// read preferences (loads last opened CPE descriptor)
if (System.getProperty("uima.noprefs") == null) {
readPreferences();
}
}
/**
* Initialize the file choosers. This is called initially from the constructor but can be called
* again to reset the file choosers to their default state.
*/
private void initFileChoosers() {
// set up AE file chooser to point to directory containing last
// selected AE
aeFileChooser = new JFileChooser(fileChooserRootDir);
aeFileChooser.setDialogTitle("Add Analysis Engine");
aeFileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
aeFileChooser.addChoosableFileFilter(new XMLFileFilter());
File aeDescDir = fileChooserRootDir;
if (aeSpecifiers.size() > 0) {
File lastAeFile = new File((String) aeSpecifiers.get(aeSpecifiers.size() - 1));
aeDescDir = lastAeFile.getParentFile();
}
if (aeDescDir.exists()) {
FileChooserBugWorkarounds.setCurrentDirectory(aeFileChooser, aeDescDir);
}
// set up CAS consumer file chooser to point to directory containing last
// selected consumer
consumerFileChooser = new JFileChooser(fileChooserRootDir);
consumerFileChooser.setDialogTitle("Add CAS Consumer");
consumerFileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
consumerFileChooser.addChoosableFileFilter(new XMLFileFilter());
File consumerDescDir = fileChooserRootDir;
if (consumerSpecifiers.size() > 0) {
File lastConsumerFile = new File((String) consumerSpecifiers
.get(consumerSpecifiers.size() - 1));
consumerDescDir = lastConsumerFile.getParentFile();
}
if (consumerDescDir.exists()) {
FileChooserBugWorkarounds.setCurrentDirectory(consumerFileChooser, consumerDescDir);
}
this.openSaveFileChooser = new JFileChooser(fileChooserRootDir);
openSaveFileChooser.setFileFilter(new XMLFileFilter());
}
private Frame getParentFrame() {
Component parent = this.getParent();
while (parent != null && !(parent instanceof Frame)) {
parent = parent.getParent();
}
return (Frame) parent;
}
/**
* Creates JMenuItems that should be added to the File menu
*
* @return a List of JMenuItems
*/
public List createFileMenuItems() {
List menuItemList = new ArrayList();
openCpeDescMenuItem = new JMenuItem("Open CPE Descriptor");
openCpeDescMenuItem.addActionListener(this);
menuItemList.add(openCpeDescMenuItem);
saveCpeDescMenuItem = new JMenuItem("Save CPE Descriptor");
saveCpeDescMenuItem.addActionListener(this);
menuItemList.add(saveCpeDescMenuItem);
refreshMenuItem = new JMenuItem("Refresh Descriptors from File System");
refreshMenuItem.addActionListener(this);
menuItemList.add(refreshMenuItem);
JMenu saveOptionsSubmenu = new JMenu ("Save Options");
saveUsingImportMenuItem = new JCheckBoxMenuItem("Use <import>");
saveUsingImportMenuItem.addActionListener(this);
saveUsingImportMenuItem.setSelected(saveUsingImports);
saveOptionsSubmenu.add(saveUsingImportMenuItem);
menuItemList.add(saveOptionsSubmenu);
clearAllMenuItem = new JMenuItem("Clear All");
clearAllMenuItem.addActionListener(this);
menuItemList.add(clearAllMenuItem);
return menuItemList;
}
/**
* Creates JMenuItems that should be added to the View menu
*
* @return a List of JMenuItems
*/
public List createViewMenuItems() {
List menuItemList = new ArrayList();
viewCasInitializerPanelMenuItem = new JCheckBoxMenuItem("CAS Initializer Panel");
viewCasInitializerPanelMenuItem.setSelected(casInitializerPanel.isVisible());
viewCasInitializerPanelMenuItem.addActionListener(this);
menuItemList.add(viewCasInitializerPanelMenuItem);
return menuItemList;
}
private void setCasInitializerPanelVisible(boolean visible) {
casInitializerPanel.setVisible(visible);
if (viewCasInitializerPanelMenuItem != null) {
viewCasInitializerPanelMenuItem.setSelected(visible);
}
if (visible) {
readerInitializerSplitPane.setDividerLocation(0.5);
}
}
private void readPreferences() {
String cpeDescFileString = prefs.get(PREFS_CPE_DESCRIPTOR_FILE, null);
if (cpeDescFileString != null) {
File cpeDescFile = new File(cpeDescFileString);
if (cpeDescFile.exists()) {
openSaveFileChooser.setSelectedFile(cpeDescFile);
try {
openCpeDescriptor(cpeDescFile);
} catch (Exception e) {
System.err.println("Error loading last known CPE Descriptor " + cpeDescFileString);
e.printStackTrace();
}
}
}
String saveUsingImportsString = prefs.get(PREFS_SAVE_USING_IMPORTS, "true");
setSaveUsingImports("true".equalsIgnoreCase(saveUsingImportsString));
}
private void setSaveUsingImports(boolean b) {
saveUsingImports = b;
if (saveUsingImportMenuItem != null)
saveUsingImportMenuItem.setSelected(b);
prefs.put(PREFS_SAVE_USING_IMPORTS, Boolean.toString(b));
}
private void startProcessing() {
// Check that Collection Reader is selected
if (collectionReaderDesc == null) {
JOptionPane.showMessageDialog(CpmPanel.this, "No Collection Reader has been selected",
"Error", JOptionPane.ERROR_MESSAGE);
transportControlPanel.reset();
resetScreen();
return;
}
try {
// update the parameter overrides according to GUI settings
updateCpeDescriptionParameterOverrides();
// intantiate CPE
mCPE = UIMAFramework.produceCollectionProcessingEngine(currentCpeDesc);
// attach callback listener
StatusCallbackListenerImpl statCbL = new StatusCallbackListenerImpl();
mCPE.addStatusCallbackListener(statCbL);
// start processing
mCPE.process();
} catch (Exception ex) {
resetScreen();
displayError(ex);
}
}
/**
* Updates the configuration parameter settings in this.currentCpeDesc to match the current state
* of the GUI.
*/
private void updateCpeDescriptionParameterOverrides() throws Exception {
// first check for descriptors out of sync with filesystem
checkForOutOfSyncFiles();
// Collection Reader
if (readerFileSelector.getSelected().length() > 0) {
if (collectionReaderPanel.isModified()) {
CasProcessorConfigurationParameterSettings crSettings = CpeDescriptorFactory
.produceCasProcessorConfigurationParameterSettings();
currentCpeDesc.getAllCollectionCollectionReaders()[0]
.setConfigurationParameterSettings(crSettings);
createParameterOverrides(crSettings, collectionReaderPanel);
} else {
currentCpeDesc.getAllCollectionCollectionReaders()[0]
.setConfigurationParameterSettings(null);
}
}
// CAS Initializer
if (casInitializerFileSelector.getSelected().length() > 0) {
if (casInitializerPanel.isModified()) {
CasProcessorConfigurationParameterSettings casIniSettings = CpeDescriptorFactory
.produceCasProcessorConfigurationParameterSettings();
currentCpeDesc.getAllCollectionCollectionReaders()[0].getCasInitializer()
.setConfigurationParameterSettings(casIniSettings);
createParameterOverrides(casIniSettings, casInitializerPanel);
} else {
currentCpeDesc.getAllCollectionCollectionReaders()[0].getCasInitializer()
.setConfigurationParameterSettings(null);
}
}
// Analysis Engines
for (int i = 0; i < aeSpecifiers.size(); i++) {
CpeCasProcessor casProc = currentCpeDesc.getCpeCasProcessors().getCpeCasProcessor(i);
AnalysisEnginePanel aePanel = (AnalysisEnginePanel) aeTabbedPane.getComponentAt(i);
if (aePanel.isModified()) {
CasProcessorConfigurationParameterSettings settings = CpeDescriptorFactory
.produceCasProcessorConfigurationParameterSettings();
casProc.setConfigurationParameterSettings(settings);
createParameterOverrides(settings, aePanel);
} else {
casProc.setConfigurationParameterSettings(null);
}
}
// CAS Consumers
for (int i = 0; i < consumerSpecifiers.size(); i++) {
CpeCasProcessor casProc = currentCpeDesc.getCpeCasProcessors().getCpeCasProcessor(
aeSpecifiers.size() + i);
ConsumerPanel consumerPanel = (ConsumerPanel) consumerTabbedPane.getComponentAt(i);
if (consumerPanel.isModified()) {
CasProcessorConfigurationParameterSettings settings = CpeDescriptorFactory
.produceCasProcessorConfigurationParameterSettings();
casProc.setConfigurationParameterSettings(settings);
createParameterOverrides(settings, consumerPanel);
} else {
casProc.setConfigurationParameterSettings(null);
}
}
}
/**
* Called by createCpeDescription to add configuration parameter overrides to the CpeDescription
* being constructed, based on the user's changes in the GUI.
*
* @param aSettings
* the CasProcessorConfigurationParameterSettings element that will be modified
* @param aPanel
* the GUI panel representing settings for the CAS Processor
* @param aClearDirty
* whether to clear the dirty bit of each field. This should be set to true when this
* method is called during the act of saving the CPE descriptor.
*/
private void createParameterOverrides(CasProcessorConfigurationParameterSettings aSettings,
MetaDataPanel aPanel) throws CpeDescriptorException {
List values = aPanel.getValues();
Iterator iterator = values.iterator();
while (iterator.hasNext()) {
ConfigField configField = (ConfigField) iterator.next();
if (configField.isModified()) {
String name = configField.getParameterName();
Object value = configField.getFieldValue();
if (value != null) {
aSettings.setParameterValue(name, value);
}
}
}
}
/**
* Marks all fields as not dirty. To be called when CPE descriptor is opened or saved.
*/
private void clearDirty() {
collectionReaderPanel.clearDirty();
casInitializerPanel.clearDirty();
for (int i = 0; i < aeTabbedPane.getTabCount(); i++) {
((MetaDataPanel) aeTabbedPane.getComponentAt(i)).clearDirty();
}
for (int i = 0; i < consumerTabbedPane.getTabCount(); i++) {
((MetaDataPanel) consumerTabbedPane.getComponentAt(i)).clearDirty();
}
selectedComponentsChanged = false;
}
public void actionPerformed(ActionEvent ev) {
Object source = ev.getSource();
if (source == progressTimer) {
elapsedTime++;
// menuBarLabel.setText(ElapsedTimeFormatter.format(elapsedTime));
displayProgress();
} else if (source == performanceQueryTimer && mCPE != null) {
// printStats();
} else if (source == startButton) {
statusLabel.setText("Initializing");
// logDialog.clear();
progressBar.setValue(0);
final SwingWorker worker = new SwingWorker() {
public Object construct() {
startProcessing();
return null;
}
};
worker.start();
} else if (source == addAeButton) {
int rv = aeFileChooser.showOpenDialog(addAeButton);
if (rv == JFileChooser.APPROVE_OPTION) {
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
File file = aeFileChooser.getSelectedFile();
// Create AE panel on the tabbed pane for this AE specifier file
try {
addAE(file.getPath());
} catch (Exception e) {
displayError(e);
}
int lastTabIndex = aeTabbedPane.getTabCount() - 1;
aeTabbedPane.setSelectedIndex(lastTabIndex);
setCursor(Cursor.getDefaultCursor());
}
} else if (source == moveAeLeftButton) {
int index = aeTabbedPane.getSelectedIndex();
if (index > 0) {
// update CPE descriptor
try {
CpeCasProcessor casProcToMove = currentCpeDesc.getCpeCasProcessors().getCpeCasProcessor(
index);
currentCpeDesc.getCpeCasProcessors().removeCpeCasProcessor(index);
currentCpeDesc.getCpeCasProcessors().addCpeCasProcessor(casProcToMove, index - 1);
} catch (CpeDescriptorException e) {
displayError(e);
return;
}
// update GUI
aeTabbedPane.moveTab(index, index - 1);
aeTabbedPane.setSelectedIndex(index - 1);
Object specifierToMove = aeSpecifiers.remove(index);
aeSpecifiers.add(index - 1, specifierToMove);
}
} else if (source == moveAeRightButton) {
int index = aeTabbedPane.getSelectedIndex();
if (index > -1 && index < aeTabbedPane.getTabCount() - 1) {
// update CPE descriptor
try {
CpeCasProcessor casProcToMove = currentCpeDesc.getCpeCasProcessors().getCpeCasProcessor(
index);
currentCpeDesc.getCpeCasProcessors().removeCpeCasProcessor(index);
currentCpeDesc.getCpeCasProcessors().addCpeCasProcessor(casProcToMove, index + 1);
} catch (CpeDescriptorException e) {
displayError(e);
return;
}
// update GUI
aeTabbedPane.moveTab(index, index + 1);
aeTabbedPane.setSelectedIndex(index + 1);
Object specifierToMove = aeSpecifiers.remove(index);
aeSpecifiers.add(index + 1, specifierToMove);
}
} else if (source == addConsumerButton) {
int rv = consumerFileChooser.showOpenDialog(addConsumerButton);
if (rv == JFileChooser.APPROVE_OPTION) {
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
File file = consumerFileChooser.getSelectedFile();
// Create consumer panel on the tabbed pane
// for this consumer specifier file:
try {
addConsumer(file.getPath());
} catch (Exception e) {
displayError(e);
}
int lastTabIndex = consumerTabbedPane.getTabCount() - 1;
consumerTabbedPane.setSelectedIndex(lastTabIndex);
setCursor(Cursor.getDefaultCursor());
}
} else if (source == moveConsumerLeftButton) {
int index = consumerTabbedPane.getSelectedIndex();
if (index > 0) {
// update CPE descriptor
try {
int absIndex = aeSpecifiers.size() + index;
CpeCasProcessor casProcToMove = currentCpeDesc.getCpeCasProcessors().getCpeCasProcessor(
absIndex);
currentCpeDesc.getCpeCasProcessors().removeCpeCasProcessor(absIndex);
currentCpeDesc.getCpeCasProcessors().addCpeCasProcessor(casProcToMove, absIndex - 1);
} catch (CpeDescriptorException e) {
displayError(e);
return;
}
// update GUI
consumerTabbedPane.moveTab(index, index - 1);
consumerTabbedPane.setSelectedIndex(index - 1);
Object specifierToMove = consumerSpecifiers.remove(index);
consumerSpecifiers.add(index - 1, specifierToMove);
}
} else if (source == moveConsumerRightButton) {
int index = consumerTabbedPane.getSelectedIndex();
if (index > -1 && index < consumerTabbedPane.getTabCount() - 1) {
// update CPE descriptor
try {
int absIndex = aeSpecifiers.size() + index;
CpeCasProcessor casProcToMove = currentCpeDesc.getCpeCasProcessors().getCpeCasProcessor(
absIndex);
currentCpeDesc.getCpeCasProcessors().removeCpeCasProcessor(absIndex);
currentCpeDesc.getCpeCasProcessors().addCpeCasProcessor(casProcToMove, absIndex + 1);
} catch (CpeDescriptorException e) {
displayError(e);
return;
}
// update GUI
consumerTabbedPane.moveTab(index, index + 1);
consumerTabbedPane.setSelectedIndex(index + 1);
Object specifierToMove = consumerSpecifiers.remove(index);
consumerSpecifiers.add(index + 1, specifierToMove);
}
} else if (source == saveCpeDescMenuItem) {
saveCpeDescriptor();
} else if (source == openCpeDescMenuItem) {
int returnVal = this.openSaveFileChooser.showOpenDialog(this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
File f = this.openSaveFileChooser.getSelectedFile();
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
try {
openCpeDescriptor(f);
} catch (Exception e) {
displayError(e);
} finally {
setCursor(Cursor.getDefaultCursor());
}
}
} else if (source == refreshMenuItem) {
refreshOutOfSyncFiles();
} else if (source == clearAllMenuItem) {
clearAll();
} else if (source == viewCasInitializerPanelMenuItem) {
setCasInitializerPanelVisible(!casInitializerPanel.isVisible());
} else if (source == saveUsingImportMenuItem) {
setSaveUsingImports(!saveUsingImports);
}
}
/**
* Resets the GUI to an empty state.
*/
private void clearAll() {
currentCpeDesc = createEmptyCpeDescription();
collectionReaderPanel.reset();
readerFileSelector.setSelected("");
casInitializerPanel.reset();
casInitializerFileSelector.setSelected("");
removeAllAEsAndConsumers();
initFileChoosers();
collectionReaderPanel.validate();
casInitializerPanel.validate();
aeMainPanel.validate();
consumersPanel.validate();
}
/**
* @return
*/
private CpeDescription createEmptyCpeDescription() {
CpeDescription cpeDesc = CpeDescriptorFactory.produceDescriptor();
// We use CAS pool size default of 3
try {
CpeCasProcessors cpeCasProcs = CpeDescriptorFactory.produceCasProcessors();
cpeDesc.setCpeCasProcessors(cpeCasProcs);
cpeCasProcs.setPoolSize(3);
} catch (CpeDescriptorException e) {
e.printStackTrace(); // this should never happen
}
return cpeDesc;
}
/**
* Prompt user for file to save CPE Descriptor to, and do the save.
*/
private void saveCpeDescriptor() {
int returnVal = this.openSaveFileChooser.showSaveDialog(this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
File f = this.openSaveFileChooser.getSelectedFile();
// if .xml filter was seleted, add .xml extension if user did not specify an extension
if (this.openSaveFileChooser.getFileFilter() instanceof XMLFileFilter
&& f.getAbsolutePath().indexOf('.') == -1) {
f = new File(f.getAbsolutePath() + ".xml");
}
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
try {
doSaveCpeDescriptor(f);
prefs.put(PREFS_CPE_DESCRIPTOR_FILE, f.getAbsolutePath());
} catch (Exception e) {
displayError(e);
} finally {
setCursor(Cursor.getDefaultCursor());
}
}
}
private void doSaveCpeDescriptor(File aFile) throws Exception {
// update the parameter overrides according to GUI settings
updateCpeDescriptionParameterOverrides();
if (saveUsingImports) {
//replace <include> with <import>, and update relative import paths
updateImports(aFile);
}
// save descriptor
OutputStream out = null;
try {
File parentFile = aFile.getParentFile();
if (parentFile != null) {
parentFile.mkdirs();
}
out = new FileOutputStream(aFile);
currentCpeDesc.toXML(out);
} finally {
if (out != null) {
out.close();
}
}
//mark descriptor with new location, for later import resolution
currentCpeDesc.setSourceUrl(aFile.toURI().toURL());
clearDirty();
}
/**
* @param file
*/
private void updateImports(File cpeDescSaveFile) throws Exception {
CpeCollectionReader[] readers = currentCpeDesc.getAllCollectionCollectionReaders();
if (readers != null) {
for (int i = 0; i < readers.length; i++) {
updateImport(readers[i].getDescriptor(), cpeDescSaveFile);
if (readers[i].getCasInitializer() != null) {
updateImport(readers[i].getCasInitializer().getDescriptor(), cpeDescSaveFile);
}
}
}
CpeCasProcessor[] casProcs = currentCpeDesc.getCpeCasProcessors().getAllCpeCasProcessors();
for (int i = 0; i < casProcs.length; i++) {
updateImport(casProcs[i].getCpeComponentDescriptor(), cpeDescSaveFile);
}
}
/**
* @param descriptor
* @param cpeDescSaveFile
*/
private void updateImport(CpeComponentDescriptor descriptor, File cpeDescSaveFile) throws Exception {
//don't touch import by name
if (descriptor.getImport() != null && descriptor.getImport().getName() != null)
return;
//for include or import by location, get the absolute URL of the descriptor
URL descUrl = descriptor.findAbsoluteUrl(defaultResourceManager);
//don't touch URLs with protocol other than file:
if ("file".equals(descUrl.getProtocol())) {
File descFile = urlToFile(descUrl);
//try to find relative path from cpeDescSaveFile to descFile
String relPath = FileUtils.findRelativePath(descFile, cpeDescSaveFile.getParentFile());
if (relPath != null) {
//update CPE descriptor
descriptor.setInclude(null);
Import newImport = UIMAFramework.getResourceSpecifierFactory().createImport();
newImport.setLocation(relPath);
descriptor.setImport(newImport);
}
}
}
/**
* Utility method for convertion a URL to a File name, taking care of
* proper escaping.
* @param url a URL
* @return File corresponding to that URL
*/
private File urlToFile(URL url) throws URISyntaxException {
String urlString = url.toString().replaceAll(" ", "%20");
return new File(new URI(urlString));
}
private void displayProgress() {
if (mCPE != null) {
try {
Progress progress[] = mCPE.getProgress();
if (progress != null && progress.length > 0) {
int FILE_ENTITY_PROGRESS_INDEX = -1;
if (FILE_ENTITY_PROGRESS_INDEX == -1) {
for (int i = 0; i < progress.length; i++) {
if (progress[i].getUnit().equals(Progress.ENTITIES)) {
FILE_ENTITY_PROGRESS_INDEX = i;
break;
}
}
}
int value = (int) progress[FILE_ENTITY_PROGRESS_INDEX].getCompleted();
progressBar.setValue(value);
if (progressBar.isIndeterminate())
statusLabel.setText("Processed " + value);
else
statusLabel.setText("Processed " + value + " of " + progressBar.getMaximum());
}
} catch (Exception e) {
displayError(e);
}
}
}
/** Ask user to confirm exist. Return true if they confirm, false if not. */
public boolean confirmExit() {
mShuttingDown = true;
// ask for confirm if CPM is processing
if (mCPE != null && mCPE.isProcessing()) {
int rv = JOptionPane.showConfirmDialog(this,
"Collection Processing is currently running. Do you wish to abort?", "Exit",
JOptionPane.YES_NO_OPTION);
if (rv == JOptionPane.NO_OPTION) {
mShuttingDown = false;
return false;
} else {
mCPE.stop();
resetScreen();
}
}
// ask for confirm if configuration settings have been modified
try {
if (isDirty()) {
int rv = JOptionPane.showConfirmDialog(this, "Configuration settings have been modified. "
+ "Would you like to save the CPE descriptor?", "Exit",
JOptionPane.YES_NO_CANCEL_OPTION);
if (rv == JOptionPane.CANCEL_OPTION) {
mShuttingDown = false;
return false;
}
if (rv == JOptionPane.YES_OPTION) {
saveCpeDescriptor();
}
}
// exit
return true;
} catch (Exception e) {
displayError(e);
return true;
}
}
public void checkForOutOfSyncFiles() {
StringBuffer componentNames = new StringBuffer();
if (collectionReaderDesc != null) {
File readerSpecifierFile = new File(readerFileSelector.getSelected());
if (readerSpecifierFile.lastModified() > this.collectionReaderLastFileSyncTimestamp
&& readerSpecifierFile.lastModified() > this.lastFileSyncUserPromptTime) {
componentNames.append(collectionReaderDesc.getMetaData().getName()).append('\n');
}
}
if (casInitializerDesc != null) {
File casInitializerSpecifierFile = new File(casInitializerFileSelector.getSelected());
if (casInitializerSpecifierFile.lastModified() > this.casInitializerLastFileSyncTimestamp
&& casInitializerSpecifierFile.lastModified() > this.lastFileSyncUserPromptTime) {
componentNames.append(casInitializerDesc.getMetaData().getName()).append('\n');
}
}
int nrTabs = aeTabbedPane.getTabCount();
for (int i = 0; i < nrTabs; i++) {
AnalysisEnginePanel aePanel = (AnalysisEnginePanel) aeTabbedPane.getComponentAt(i);
if (aePanel.hasFileChanged(this.lastFileSyncUserPromptTime)) {
componentNames.append(aeTabbedPane.getTitleAt(i)).append('\n');
}
}
nrTabs = consumerTabbedPane.getTabCount();
for (int i = 0; i < nrTabs; i++) {
ConsumerPanel consumerPanel = (ConsumerPanel) consumerTabbedPane.getComponentAt(i);
if (consumerPanel.hasFileChanged(this.lastFileSyncUserPromptTime)) {
componentNames.append(consumerTabbedPane.getTitleAt(i)).append('\n');
}
}
if (componentNames.length() > 0) {
int rv = JOptionPane.showConfirmDialog(this,
"The following descriptor(s) have changed on the file system:\n"
+ componentNames.toString() + "\n\nDo you want to refresh them?",
"Descriptors Changed On File System", JOptionPane.YES_NO_OPTION);
if (rv == JOptionPane.YES_OPTION) {
refreshOutOfSyncFiles();
}
// record this time so that we don't re-prompt user continuously
this.lastFileSyncUserPromptTime = System.currentTimeMillis();
}
}
public void refreshOutOfSyncFiles() {
if (collectionReaderDesc != null) {
File readerSpecifierFile = new File(readerFileSelector.getSelected());
if (readerSpecifierFile.lastModified() > this.collectionReaderLastFileSyncTimestamp) {
try {
populateCollectionReaderPanel(currentCpeDesc.getAllCollectionCollectionReaders()[0]
.getCollectionIterator());
} catch (Exception e) {
displayError(e);
}
}
}
if (casInitializerDesc != null) {
File casInitializerSpecifierFile = new File(casInitializerFileSelector.getSelected());
if (casInitializerSpecifierFile.lastModified() > this.casInitializerLastFileSyncTimestamp) {
try {
populateCasInitializerPanel(currentCpeDesc.getAllCollectionCollectionReaders()[0]
.getCasInitializer());
} catch (Exception e) {
displayError(e);
}
}
}
int nrTabs = aeTabbedPane.getTabCount();
for (int i = 0; i < nrTabs; i++) {
AnalysisEnginePanel aePanel = (AnalysisEnginePanel) aeTabbedPane.getComponentAt(i);
if (aePanel.hasFileChanged(0)) {
try {
aePanel.refreshFromFile();
} catch (Exception e) {
displayError(e);
}
}
}
nrTabs = consumerTabbedPane.getTabCount();
for (int i = 0; i < nrTabs; i++) {
ConsumerPanel consumerPanel = (ConsumerPanel) consumerTabbedPane.getComponentAt(i);
if (consumerPanel.hasFileChanged(0)) {
try {
consumerPanel.refreshFromFile();
} catch (Exception e) {
displayError(e);
}
}
}
}
/**
* Displays an error message to the user.
*
* @param aErrorString
* error message to display
*/
public void displayError(String aErrorString) {
// word-wrap long mesages
StringBuffer buf = new StringBuffer(aErrorString.length());
final int CHARS_PER_LINE = 80;
int charCount = 0;
StringTokenizer tokenizer = new StringTokenizer(aErrorString, " \n", true);
while (tokenizer.hasMoreTokens()) {
String tok = tokenizer.nextToken();
if (tok.equals("\n")) {
buf.append("\n");
charCount = 0;
} else if ((charCount > 0) && ((charCount + tok.length()) > CHARS_PER_LINE)) {
buf.append("\n").append(tok);
charCount = tok.length();
} else {
buf.append(tok);
charCount += tok.length();
}
}
JOptionPane.showMessageDialog(this, buf.toString(), "Error", JOptionPane.ERROR_MESSAGE);
}
/**
* Displays an error message to the user.
*
* @param aThrowable
* Throwable whose message is to be displayed.
*/
public void displayError(Throwable aThrowable) {
aThrowable.printStackTrace();
String message = aThrowable.toString();
// For UIMAExceptions or UIMARuntimeExceptions, add cause info.
// We have to go through this nonsense to support Java 1.3.
// In 1.4 all exceptions can have a cause, so this wouldn't involve
// all of this typecasting.
while ((aThrowable instanceof UIMAException) || (aThrowable instanceof UIMARuntimeException)) {
if (aThrowable instanceof UIMAException) {
aThrowable = ((UIMAException) aThrowable).getCause();
} else if (aThrowable instanceof UIMARuntimeException) {
aThrowable = ((UIMARuntimeException) aThrowable).getCause();
}
if (aThrowable != null) {
message += ("\nCausedBy: " + aThrowable.toString());
}
}
displayError(message);
}
private boolean populateCollectionReaderPanel(CpeCollectionReaderIterator cpeColRdr)
throws InvalidXMLException, IOException, ResourceConfigurationException {
try {
URL specifierUrl = null;
String specifierFile = null;
if (cpeColRdr != null) {
specifierUrl = cpeColRdr.getDescriptor().findAbsoluteUrl(defaultResourceManager);
//CPE GUI only supports file URLs
if (!"file".equals(specifierUrl.getProtocol())) {
displayError("Could not load descriptor from URL " + specifierUrl.toString() +
". CPE Configurator only supports file: URLs");
return false;
}
try {
specifierFile = urlToFile(specifierUrl).toString();
} catch (URISyntaxException e) {
displayError(e);
return false;
}
}
if (collectionReaderPanel.getNrComponents() == 0) {
collectionReaderPanel.add(new JLabel("Descriptor:"));
collectionReaderPanel.add(readerFileSelector);
readerFileSelector.setSelected(specifierFile);
} else {
collectionReaderPanel.reset();
}
if (specifierFile == null || specifierFile.length() == 0) {
// no CollectionReader selected (allowed, as interemediate state)
collectionReaderDesc = null;
return true;
}
if (specifierFile != null && specifierFile.length() > 0) {
File f = new File(specifierFile);
if (!f.exists()) {
String errorMsg = "Descriptor file " + f.getAbsolutePath() + " does not exist";
JOptionPane.showMessageDialog(this, errorMsg, null, JOptionPane.ERROR_MESSAGE);
transportControlPanel.reset();
resetScreen();
return false;
} else {
collectionReaderLastFileSyncTimestamp = f.lastModified();
XMLInputSource readerInputSource = new XMLInputSource(f);
collectionReaderDesc = UIMAFramework.getXMLParser().parseCollectionReaderDescription(
readerInputSource);
collectionReaderPanel.populate(collectionReaderDesc.getMetaData(), cpeColRdr
.getConfigurationParameterSettings());
}
}
return true;
} finally {
collectionReaderPanel.validate();
collectionReaderPanel.validate();
mainSplitPane.validate();
}
}
private boolean populateCasInitializerPanel(CpeCollectionReaderCasInitializer cpeCasIni)
throws InvalidXMLException, IOException, ResourceConfigurationException {
try {
URL specifierUrl = null;
String specifierFile = null;
if (cpeCasIni != null) {
specifierUrl = cpeCasIni.getDescriptor().findAbsoluteUrl(defaultResourceManager);
//CPE GUI only supports file URLs
if (!"file".equals(specifierUrl.getProtocol())) {
displayError("Could not load descriptor from URL " + specifierUrl.toString() +
". CPE Configurator only supports file: URLs");
return false;
}
try {
specifierFile = urlToFile(specifierUrl).toString();
} catch (URISyntaxException e) {
displayError(e);
return false;
}
}
if (casInitializerPanel.getNrComponents() == 0) {
casInitializerPanel.add(new JLabel("Descriptor:"));
casInitializerPanel.add(casInitializerFileSelector);
casInitializerFileSelector.setSelected(specifierFile);
} else {
casInitializerPanel.reset();
}
if (specifierFile == null || specifierFile.length() == 0) {
// no CAS initializer selected - this is OK
casInitializerDesc = null;
return true;
}
// a CAS initializer is selected, so make sure the panel is made visible
setCasInitializerPanelVisible(true);
File f = new File(specifierFile);
if (!f.exists()) {
String errorMsg = "Descriptor file " + f.getAbsolutePath() + " does not exist";
JOptionPane.showMessageDialog(this, errorMsg, null, JOptionPane.ERROR_MESSAGE);
transportControlPanel.reset();
resetScreen();
return false;
} else {
casInitializerLastFileSyncTimestamp = f.lastModified();
XMLInputSource casIniInputSource = new XMLInputSource(f);
casInitializerDesc = UIMAFramework.getXMLParser().parseCasInitializerDescription(
casIniInputSource);
casInitializerPanel.populate(casInitializerDesc.getMetaData(), cpeCasIni
.getConfigurationParameterSettings());
return true;
}
} finally {
casInitializerPanel.validate();
mainSplitPane.validate();
}
}
private void addAE(String aeSpecifierFile) throws CpeDescriptorException, InvalidXMLException,
IOException, ResourceConfigurationException {
String tempAeName = new File(aeSpecifierFile).getName(); // overriden later
CpeCasProcessor casProc = CpeDescriptorFactory.produceCasProcessor(tempAeName);
casProc.setDescriptor(aeSpecifierFile);
casProc.setBatchSize(10000);
casProc.getErrorHandling().getErrorRateThreshold().setMaxErrorCount(0);
// add to pipeline as last AE but before CAS Consumers
currentCpeDesc.addCasProcessor(aeTabbedPane.getTabCount(), casProc);
// update GUI
addAE(casProc);
}
private boolean addAE(CpeCasProcessor cpeCasProc) throws CpeDescriptorException,
InvalidXMLException, IOException, ResourceConfigurationException {
URL aeSpecifierUrl = cpeCasProc.getCpeComponentDescriptor().findAbsoluteUrl(defaultResourceManager);
//CPE GUI only supports file URLs
if (!"file".equals(aeSpecifierUrl.getProtocol())) {
displayError("Could not load descriptor from URL " + aeSpecifierUrl.toString() +
". CPE Configurator only supports file: URLs");
return false;
}
File f;
try {
f = urlToFile(aeSpecifierUrl);
} catch (URISyntaxException e) {
displayError(e);
return false;
}
long fileModStamp = f.lastModified(); // get mod stamp before parsing, to prevent race condition
XMLInputSource aeInputSource = new XMLInputSource(aeSpecifierUrl);
ResourceSpecifier aeSpecifier = UIMAFramework.getXMLParser().parseResourceSpecifier(
aeInputSource);
AnalysisEnginePanel aePanel = new AnalysisEnginePanel(aeSpecifier, f, fileModStamp);
String tabName;
if (aeSpecifier instanceof AnalysisEngineDescription) {
AnalysisEngineDescription aeDescription = (AnalysisEngineDescription) aeSpecifier;
ResourceMetaData md = aeDescription.getMetaData();
aePanel.populate(md, cpeCasProc.getConfigurationParameterSettings());
tabName = md.getName();
} else {
tabName = f.getName();
}
tabName = makeUniqueCasProcessorName(tabName);
cpeCasProc.setName(tabName);
aeTabbedPane.addTab(tabName, aePanel);
aeSpecifiers.add(f.getAbsolutePath());
selectedComponentsChanged = true;
return true;
}
private void addConsumer(String consumerSpecifierFile) throws CpeDescriptorException,
InvalidXMLException, IOException, ResourceConfigurationException {
String tempName = new File(consumerSpecifierFile).getName(); // overriden later
CpeCasProcessor casProc = CpeDescriptorFactory.produceCasProcessor(tempName);
casProc.setDescriptor(consumerSpecifierFile);
casProc.setBatchSize(10000);
casProc.getErrorHandling().getErrorRateThreshold().setMaxErrorCount(0);
// add to pipeline as last CAS Processor
currentCpeDesc.addCasProcessor(casProc);
// update GUI
addConsumer(casProc);
}
private boolean addConsumer(CpeCasProcessor cpeCasProc) throws CpeDescriptorException,
InvalidXMLException, IOException, ResourceConfigurationException {
URL consumerSpecifierUrl = cpeCasProc.getCpeComponentDescriptor().findAbsoluteUrl(
defaultResourceManager);
//CPE GUI only supports file URLs
if (!"file".equals(consumerSpecifierUrl.getProtocol())) {
displayError("Could not load descriptor from URL " + consumerSpecifierUrl.toString() +
". CPE Configurator only supports file: URLs");
return false;
}
File f;
try {
f = urlToFile(consumerSpecifierUrl);
} catch (URISyntaxException e) {
displayError(e);
return false;
}
long fileModStamp = f.lastModified(); // get mod stamp before parsing, to prevent race condition
XMLInputSource consumerInputSource = new XMLInputSource(consumerSpecifierUrl);
ResourceSpecifier casConsumerSpecifier = UIMAFramework.getXMLParser().parseResourceSpecifier(
consumerInputSource);
ConsumerPanel consumerPanel = new ConsumerPanel(casConsumerSpecifier, f, fileModStamp);
String tabName;
if (casConsumerSpecifier instanceof CasConsumerDescription) {
ResourceMetaData md = ((CasConsumerDescription) casConsumerSpecifier)
.getCasConsumerMetaData();
consumerPanel.populate(md, cpeCasProc.getConfigurationParameterSettings());
tabName = md.getName();
} else {
tabName = f.getName();
}
tabName = makeUniqueCasProcessorName(tabName);
cpeCasProc.setName(tabName);
consumerTabbedPane.addTab(tabName, consumerPanel);
consumerSpecifiers.add(f.getAbsolutePath());
selectedComponentsChanged = true;
return true;
}
private String makeUniqueCasProcessorName(String baseName) {
if (aeTabbedPane.indexOfTab(baseName) == -1 && consumerTabbedPane.indexOfTab(baseName) == -1)
return baseName;
int num = 2;
while (true) {
String name = baseName + " " + num;
if (aeTabbedPane.indexOfTab(name) == -1 && consumerTabbedPane.indexOfTab(name) == -1)
return name;
num++;
}
}
private void removeAllAEsAndConsumers() {
aeTabbedPane.removeAll();
aeSpecifiers.clear();
consumerTabbedPane.removeAll();
consumerSpecifiers.clear();
}
// FileSelectorListener:
public boolean fileSelected(JComponent source, String fileString) {
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
boolean rv = false;
try {
if (source == collectionReaderPanel) {
if (fileString != null && fileString.length() > 0) {
CpeCollectionReader[] readers = currentCpeDesc.getAllCollectionCollectionReaders();
if (readers.length == 0) {
currentCpeDesc.addCollectionReader(fileString);
readers = currentCpeDesc.getAllCollectionCollectionReaders();
} else {
readers[0].getCollectionIterator().getDescriptor().getInclude().set(fileString);
// clear config settings
readers[0].getCollectionIterator().setConfigurationParameterSettings(null);
}
rv = populateCollectionReaderPanel(readers[0].getCollectionIterator());
} else {
// no Collection Reader selected - allowed as intermeidate state
currentCpeDesc.setAllCollectionCollectionReaders(new CpeCollectionReader[0]);
}
selectedComponentsChanged = true;
} else if (source == casInitializerPanel) {
if (fileString != null && fileString.length() > 0) {
CpeCollectionReader[] readers = currentCpeDesc.getAllCollectionCollectionReaders();
if (readers.length == 0 || readers[0].getCasInitializer() == null) {
currentCpeDesc.addCasInitializer(fileString);
readers = currentCpeDesc.getAllCollectionCollectionReaders();
} else {
readers[0].getCasInitializer().getDescriptor().getInclude().set(fileString);
// clear config settings
readers[0].getCasInitializer().setConfigurationParameterSettings(null);
}
rv = populateCasInitializerPanel(readers[0].getCasInitializer());
} else {
// no CAS initializer selected - OK
CpeCollectionReader[] readers = currentCpeDesc.getAllCollectionCollectionReaders();
if (readers.length > 0) {
readers[0].removeCasInitializer();
}
rv = populateCasInitializerPanel(null);
}
selectedComponentsChanged = true;
}
} catch (Exception e) {
displayError(e);
rv = false;
}
setCursor(Cursor.getDefaultCursor());
return rv;
}
// TabClosedListener:
public void tabClosed(JTabbedPaneWithCloseIcons source, int tabPos) {
try {
if (source == consumerTabbedPane) {
currentCpeDesc.getCpeCasProcessors().removeCpeCasProcessor(aeSpecifiers.size() + tabPos);
consumerSpecifiers.remove(tabPos);
} else if (source == aeTabbedPane) {
currentCpeDesc.getCpeCasProcessors().removeCpeCasProcessor(tabPos);
aeSpecifiers.remove(tabPos);
}
selectedComponentsChanged = true;
} catch (CpeDescriptorException e) {
displayError(e);
}
}
public void controlStarted() {
statusLabel.setText("Initializing");
progressBar.setIndeterminate(true);
setFrameEnabled(false);
}
public void controlPaused() {
mPaused = true;
statusLabel.setText("Paused");
indeterminateProgressPause = progressBar.isIndeterminate();
if (indeterminateProgressPause)
progressBar.setIndeterminate(false);
if (!mCPE.isPaused())
mCPE.pause();
progressTimer.stop();
performanceQueryTimer.stop();
PerformanceReportDialog perfReportDlg = new PerformanceReportDialog(CpmPanel.this
.getParentFrame());
perfReportDlg.displayStats(mCPE.getPerformanceReport(), progressBar.getValue(),
"Processing is paused.");
}
public void controlResumed() {
mPaused = false;
statusLabel.setText("Resumed");
if (indeterminateProgressPause)
progressBar.setIndeterminate(true);
mCPE.resume();
progressTimer.restart();
performanceQueryTimer.restart();
}
public void controlStopped() {
try {
mCPE.stop();
} catch (UIMA_IllegalStateException e) {
// already stopped - OK
}
}
private void resetScreen() {
progressTimer.stop();
performanceQueryTimer.stop();
transportControlPanel.reset();
setFrameEnabled(true);
progressBar.setIndeterminate(false);
progressBar.setValue(0);
elapsedTime = 0;
statusLabel.setText("");
}
/**
* Called to lock the GUI while processing is occurring. We don't actually disable the JFrame,
* because we don't want to disable the stop/pause buttons. Instead we disable all of the controls
* that the user shouldn't mess with while processing is occurring.
*
* @param onOff
* true to enable, false to disable
*/
private void setFrameEnabled(boolean onOff) {
Color titleColor = (onOff ? Color.black : Color.gray);
// int nrMenuItems = menuBar.getMenuCount();
// for (int i = 0; i < (nrMenuItems - 2); i++)
// menuBar.getMenu(i).setEnabled(onOff);
readerInitializerSplitPane.setEnabled(onOff);
collectionReaderPanel.setEnabled(onOff);
collectionReaderTitledBorder.setTitleColor(titleColor);
casInitializerPanel.setEnabled(onOff);
casInitializerTitledBorder.setTitleColor(titleColor);
aeMainPanel.setEnabled(onOff);
addAeButton.setEnabled(onOff);
moveAeRightButton.setEnabled(onOff);
moveAeLeftButton.setEnabled(onOff);
aeTitledBorder.setTitleColor(titleColor);
aeTabbedPane.setEnabled(onOff);
// Cycle through each of the AE panels:
int nrTabs = aeTabbedPane.getTabCount();
for (int i = 0; i < nrTabs; i++) {
AnalysisEnginePanel aePanel = (AnalysisEnginePanel) aeTabbedPane.getComponentAt(i);
aePanel.setEnabled(onOff);
}
consumersPanel.setEnabled(onOff);
consumerTitledBorder.setTitleColor(titleColor);
addConsumerButton.setEnabled(onOff);
moveConsumerRightButton.setEnabled(onOff);
moveConsumerLeftButton.setEnabled(onOff);
consumerTabbedPane.setEnabled(onOff);
// Cycle through each of the consumer panels:
nrTabs = consumerTabbedPane.getTabCount();
for (int i = 0; i < nrTabs; i++) {
ConsumerPanel consumerPanel = (ConsumerPanel) consumerTabbedPane.getComponentAt(i);
consumerPanel.setEnabled(onOff);
}
// Cursor cursor = (onOff ? Cursor.getDefaultCursor() : Cursor
// .getPredefinedCursor(Cursor.WAIT_CURSOR));
// setCursor(cursor);
if (openCpeDescMenuItem != null)
openCpeDescMenuItem.setEnabled(onOff);
if (saveCpeDescMenuItem != null)
saveCpeDescMenuItem.setEnabled(onOff);
if (refreshMenuItem != null)
refreshMenuItem.setEnabled(onOff);
if (clearAllMenuItem != null)
clearAllMenuItem.setEnabled(onOff);
}
public void onCompletion() {
try {
// statusLabel.setText("Completed (" + statusLabel.getText() + ")");
setFrameEnabled(true);
transportControlPanel.reset();
displayProgress();
progressBar.setIndeterminate(false);
elapsedTime = 0;
progressTimer.stop();
performanceQueryTimer.stop();
PerformanceReportDialog perfReportDlg = new PerformanceReportDialog(this.getParentFrame());
perfReportDlg.displayStats(mCPE.getPerformanceReport(), progressBar.getValue(),
"Processing completed successfully.");
} catch (Exception e) {
e.printStackTrace();
}
}
public void printStats() {
// logDialog.write( mCPM.getPerformanceReport().toString());
}
/**
* Returns whether the GUI is dirty; that is, whether configuration settings have been modified
* since the last save.
*
* @return
*/
private boolean isDirty() {
// have components been added or removed?
if (selectedComponentsChanged)
return true;
// has configuration of any component changed?
if (collectionReaderPanel.isDirty() || casInitializerPanel.isDirty()) {
return true;
}
for (int i = 0; i < aeTabbedPane.getTabCount(); i++) {
MetaDataPanel panel = (MetaDataPanel) aeTabbedPane.getComponentAt(i);
if (panel.isDirty())
return true;
}
for (int i = 0; i < consumerTabbedPane.getTabCount(); i++) {
MetaDataPanel panel = (MetaDataPanel) consumerTabbedPane.getComponentAt(i);
if (panel.isDirty())
return true;
}
return false;
}
private void openCpeDescriptor(File aFile) throws InvalidXMLException, IOException,
CpeDescriptorException, ResourceConfigurationException {
// parse
currentCpeDesc = UIMAFramework.getXMLParser().parseCpeDescription(new XMLInputSource(aFile));
// update GUI
// Collection Reader
CpeCollectionReader[] collRdrs = currentCpeDesc.getAllCollectionCollectionReaders(); // more
// than
// one??
CpeCollectionReader collRdr = null;
if (collRdrs != null && collRdrs.length > 0) {
collRdr = collRdrs[0];
collectionReaderPanel.clearAll();
populateCollectionReaderPanel(collRdr.getCollectionIterator());
} else {
collectionReaderPanel.reset();
}
// CAS Initializer
CpeCollectionReaderCasInitializer casIni = null;
if (collRdr != null) {
casIni = collRdr.getCasInitializer();
}
if (casIni != null) {
casInitializerPanel.clearAll();
populateCasInitializerPanel(casIni);
} else {
casInitializerPanel.reset();
}
// CAS Processors
int numFailed = 0;
removeAllAEsAndConsumers();
CpeCasProcessor[] casProcs = currentCpeDesc.getCpeCasProcessors().getAllCpeCasProcessors();
for (int i = 0; i < casProcs.length; i++) {
boolean success = true;
try {
URL specifierUrl = casProcs[i].getCpeComponentDescriptor().findAbsoluteUrl(defaultResourceManager);
ResourceSpecifier specifier = UIMAFramework.getXMLParser().parseResourceSpecifier(
new XMLInputSource(specifierUrl));
if (isCasConsumerSpecifier(specifier)) {
success = addConsumer(casProcs[i]);
} else {
success = addAE(casProcs[i]);
}
}
catch(Exception e) {
System.err.println("Error loading CPE Descriptor " + aFile.getPath());
e.printStackTrace();
success= false;
}
if (!success) {
currentCpeDesc.getCpeCasProcessors().removeCpeCasProcessor(i - numFailed);
numFailed++;
}
}
prefs.put(PREFS_CPE_DESCRIPTOR_FILE, aFile.getAbsolutePath());
// nothing should be dirty when we first open
clearDirty();
}
/**
* @param specifier
* @return
*/
private boolean isCasConsumerSpecifier(ResourceSpecifier specifier) {
if (specifier instanceof CasConsumerDescription) {
return true;
} else if (specifier instanceof URISpecifier) {
URISpecifier uriSpec = (URISpecifier) specifier;
return URISpecifier.RESOURCE_TYPE_CAS_CONSUMER.equals(uriSpec.getResourceType());
} else
return false;
}
class StatusCallbackListenerImpl implements StatusCallbackListener {
public void initializationComplete() {
// init progress bar
int nrFiles = -1;
Progress progress[] = mCPE.getProgress();
if (progress != null) {
for (int i = 0; i < progress.length; i++) {
if (progress[i].getUnit().equals(Progress.ENTITIES)) {
nrFiles = (int) progress[i].getTotal();
break;
}
}
}
if (nrFiles != -1) {
progressBar.setMaximum(nrFiles);
progressBar.setIndeterminate(false);
} else
progressBar.setIndeterminate(true);
progressBar.setValue(0);
// start progress timer which will update the progress bar
progressTimer.start();
}
public void entityProcessComplete(CAS aCas, EntityProcessStatus aStatus) {
// report an error if it occurred
if (aStatus.isException()) {
List ex = aStatus.getExceptions();
displayError((Throwable) ex.get(0));
}
}
public void batchProcessComplete() {
}
public void collectionProcessComplete() {
onCompletion();
}
public void paused() {
System.out.println("StatusCallbackListenerImpl::paused()");
}
public void resumed() {
System.out.println("StatusCallbackListenerImpl::resumed");
}
public void aborted() {
if (!mShuttingDown && !mPaused) {
PerformanceReportDialog perfReportDlg = new PerformanceReportDialog(CpmPanel.this
.getParentFrame());
perfReportDlg.displayStats(mCPE.getPerformanceReport(), progressBar.getValue(),
"Processing aborted.");
}
resetScreen();
mPaused = false;
}
}
/**
* MetaDataPanel used for Collection Reader & AE selection and configuration. Adds a reset method
* to clear out related components when specifier file selection changes.
*/
static class ResetableMetaDataPanel extends MetaDataPanel {
private static final long serialVersionUID = -4573780175511175666L;
public ResetableMetaDataPanel() {
super();
}
public ResetableMetaDataPanel(int nrColumns) {
super(nrColumns);
}
/**
* Clears all but the first 2 components from the panel.
*/
public void reset() {
Component components[] = gridBagPanel.getComponents();
if (components.length > 2) {
for (int i = (components.length - 1); i >= 2; i--)
gridBagPanel.remove(i);
componentIndex = 2;
}
fieldsList.clear();
}
}
}