package net.sf.jabref.export;
import java.awt.event.ActionEvent;
import java.io.File;
import java.util.*;
import javax.swing.AbstractAction;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileFilter;
import net.sf.jabref.*;
import net.sf.jabref.plugin.PluginCore;
import net.sf.jabref.plugin.core.JabRefPlugin;
import net.sf.jabref.plugin.core.generated._JabRefPlugin.ExportFormatExtension;
import net.sf.jabref.plugin.core.generated._JabRefPlugin.ExportFormatProviderExtension;
import net.sf.jabref.plugin.core.generated._JabRefPlugin.ExportFormatTemplateExtension;
/**
* User: alver
*
* Date: Oct 18, 2006
*
* Time: 9:35:08 PM
*/
public class ExportFormats {
private static Map<String,IExportFormat> exportFormats = new TreeMap<String,IExportFormat>();
// Global variable that is used for counting output entries when exporting:
public static int entryNumber = 0;
public static void initAllExports() {
exportFormats.clear();
// Initialize Build-In Export Formats
putFormat(new ExportFormat(
Globals.lang("HTML"), "html", "html", null, ".html"));
putFormat(new ExportFormat(
Globals.lang("Simple HTML"), "simplehtml", "simplehtml", null, ".html"));
putFormat(new ExportFormat(Globals.lang("DocBook").concat(" 4.4"), "docbook", "docbook", null, ".xml"));
putFormat(new ExportFormat(Globals.lang("BibTeXML"), "bibtexml", "bibtexml", null, ".xml"));
putFormat(new ExportFormat(Globals.lang("BibO RDF"), "bibordf", "bibordf", null, ".rdf"));
putFormat(new ModsExportFormat());
putFormat(new ExportFormat(Globals.lang("HTML table"),
"tablerefs", "tablerefs", "tablerefs", ".html"));
putFormat(new ExportFormat(Globals.lang("HTML table (with Abstract & BibTeX)"),
"tablerefsabsbib", "tablerefsabsbib", "tablerefsabsbib", ".html"));
putFormat(new ExportFormat(Globals.lang("Harvard RTF"), "harvard", "harvard",
"harvard", ".rtf"));
putFormat(new ExportFormat(Globals.lang("Endnote"), "endnote", "EndNote",
"endnote", ".txt"));
putFormat(new ExportFormat(Globals.lang("OpenOffice CSV"), "oocsv", "openoffice-csv",
"openoffice", ".csv"));
ExportFormat ef = new ExportFormat(Globals.lang("RIS"), "ris", "ris", "ris", ".ris");
ef.encoding = "UTF-8";
putFormat(ef);
putFormat(new OpenOfficeDocumentCreator());
putFormat(new OpenDocumentSpreadsheetCreator());
putFormat(new MSBibExportFormat());
putFormat(new MySQLExport());
// Add Export Formats contributed by Plugins
JabRefPlugin plugin = JabRefPlugin.getInstance(PluginCore.getManager());
if (plugin != null){
// 1. ExportFormats based on Templates
for (ExportFormatTemplateExtension e : plugin.getExportFormatTemplateExtensions()){
ExportFormat format = PluginBasedExportFormat.getFormat(e);
if (format != null){
putFormat(format);
}
}
// 2. ExportFormat classed
for (final ExportFormatExtension e : plugin.getExportFormatExtensions()) {
putFormat(new IExportFormat(){
public String getConsoleName() {
return e.getConsoleName();
}
public String getDisplayName() {
return e.getDisplayName();
}
public FileFilter getFileFilter() {
return new ExportFileFilter(this, e.getExtension());
}
IExportFormat wrapped;
public void performExport(BibtexDatabase database, MetaData metaData,
String file, String encoding, Set<String> entryIds)
throws Exception {
if (wrapped == null)
wrapped = e.getExportFormat();
wrapped.performExport(database, metaData, file, encoding, entryIds);
}
});
}
// 3. Formatters provided by Export Format Providers
for (ExportFormatProviderExtension e : plugin.getExportFormatProviderExtensions()) {
IExportFormatProvider formatProvider = e.getFormatProvider();
for (IExportFormat exportFormat : formatProvider.getExportFormats()) {
putFormat(exportFormat);
}
}
}
// Now add custom export formats
TreeMap<String, ExportFormat> customFormats = Globals.prefs.customExports.getCustomExportFormats();
for (IExportFormat format : customFormats.values()){
putFormat(format);
}
}
/**
* Build a string listing of all available export formats.
*
* @param maxLineLength
* The max line length before a line break must be added.
* @param linePrefix
* If a line break is added, this prefix will be inserted at the
* beginning of the next line.
* @return The string describing available formats.
*/
public static String getConsoleExportList(int maxLineLength, int firstLineSubtr,
String linePrefix) {
StringBuffer sb = new StringBuffer();
int lastBreak = -firstLineSubtr;
for (Iterator<String> i = exportFormats.keySet().iterator(); i.hasNext();) {
String name = i.next();
if (sb.length() + 2 + name.length() - lastBreak > maxLineLength) {
sb.append(",\n");
lastBreak = sb.length();
sb.append(linePrefix);
} else if (sb.length() > 0)
sb.append(", ");
sb.append(name);
}
return sb.toString();
}
/**
* Get a Map of all export formats.
* @return A Map containing all export formats, mapped to their console names.
*/
public static Map<String, IExportFormat> getExportFormats() {
// It is perhaps overly paranoid to make a defensive copy in this case:
return Collections.unmodifiableMap(exportFormats);
}
/**
* Look up the named export format.
*
* @param consoleName
* The export name given in the JabRef console help information.
* @return The ExportFormat, or null if no exportformat with that name is
* registered.
*/
public static IExportFormat getExportFormat(String consoleName) {
return exportFormats.get(consoleName);
}
/**
* Create an AbstractAction for performing an export operation.
*
* @param frame
* The JabRefFrame of this JabRef instance.
* @param selectedOnly
* true indicates that only selected entries should be exported,
* false indicates that all entries should be exported.
* @return The action.
*/
public static AbstractAction getExportAction(JabRefFrame frame, boolean selectedOnly) {
class ExportAction extends MnemonicAwareAction {
private static final long serialVersionUID = 639463604530580554L;
private JabRefFrame frame;
private boolean selectedOnly;
public ExportAction(JabRefFrame frame, boolean selectedOnly) {
this.frame = frame;
this.selectedOnly = selectedOnly;
putValue(NAME, selectedOnly ? "Export selected entries" : "Export");
}
public void actionPerformed(ActionEvent e) {
ExportFormats.initAllExports();
JFileChooser fc = ExportFormats.createExportFileChooser(
Globals.prefs.get("exportWorkingDirectory"));
fc.showSaveDialog(frame);
File file = fc.getSelectedFile();
if (file == null)
return;
FileFilter ff = fc.getFileFilter();
if (ff instanceof ExportFileFilter) {
ExportFileFilter eff = (ExportFileFilter) ff;
String path = file.getPath();
if (!path.endsWith(eff.getExtension()))
path = path + eff.getExtension();
file = new File(path);
if (file.exists()) {
// Warn that the file exists:
if (JOptionPane.showConfirmDialog(frame, "'" + file.getName() + "' "
+ Globals.lang("exists. Overwrite file?"), Globals.lang("Export"),
JOptionPane.OK_CANCEL_OPTION) != JOptionPane.OK_OPTION)
return;
}
final IExportFormat format = eff.getExportFormat();
Set<String> entryIds = null;
if (selectedOnly) {
BibtexEntry[] selected = frame.basePanel().getSelectedEntries();
entryIds = new HashSet<String>();
for (int i = 0; i < selected.length; i++) {
BibtexEntry bibtexEntry = selected[i];
entryIds.add(bibtexEntry.getId());
}
}
// Set the global variable for this database's file directory before exporting,
// so formatters can resolve linked files correctly.
// (This is an ugly hack!)
Globals.prefs.fileDirForDatabase = frame.basePanel().metaData()
.getFileDirectory(GUIGlobals.FILE_FIELD);
// Make sure we remember which filter was used, to set
// the default for next time:
Globals.prefs.put("lastUsedExport", format.getConsoleName());
Globals.prefs.put("exportWorkingDirectory", file.getParent());
final File finFile = file;
final Set<String> finEntryIDs = entryIds;
AbstractWorker exportWorker = new AbstractWorker() {
String errorMessage = null;
public void run() {
try {
format.performExport(frame.basePanel().database(),
frame.basePanel().metaData(),
finFile.getPath(), frame
.basePanel().getEncoding(), finEntryIDs);
} catch (Exception ex) {
ex.printStackTrace();
if (ex.getMessage()==null ) {
errorMessage = ex.toString();
} else {
errorMessage = ex.getMessage();
}
}
}
public void update() {
// No error message. Report success:
if (errorMessage == null) {
frame.output(Globals.lang("%0 export successful", format.getDisplayName()));
}
// ... or show an error dialog:
else {
frame.output(Globals.lang("Could not save file")
+ " - " + errorMessage);
// Need to warn the user that saving failed!
JOptionPane.showMessageDialog(frame, Globals.lang("Could not save file")
+ ".\n" + errorMessage, Globals.lang("Save database"),
JOptionPane.ERROR_MESSAGE);
}
}
};
// Run the export action in a background thread:
(exportWorker.getWorker()).run();
// Run the update method:
exportWorker.update();
}
}
}
return new ExportAction(frame, selectedOnly);
}
public static JFileChooser createExportFileChooser(String currentDir) {
String lastUsedFormat = Globals.prefs.get("lastUsedExport");
FileFilter defaultFilter = null;
JFileChooser fc = new JFileChooser(currentDir);
TreeSet<FileFilter> filters = new TreeSet<FileFilter>();
for (Map.Entry<String, IExportFormat> e : exportFormats.entrySet()) {
String formatName = e.getKey() ;
IExportFormat format = e.getValue();
filters.add(format.getFileFilter());
if (formatName.equals(lastUsedFormat))
defaultFilter = format.getFileFilter();
}
for (FileFilter ff : filters) {
fc.addChoosableFileFilter(ff);
}
fc.setAcceptAllFileFilterUsed(false);
if (defaultFilter != null)
fc.setFileFilter(defaultFilter);
return fc;
}
private static void putFormat(IExportFormat format) {
exportFormats.put(format.getConsoleName(), format);
}
}