1 package net.sf.jabref.export;
4 import java.io.IOException;
6 import java.util.HashMap;
10 import javax.swing.filechooser.FileFilter;
12 import net.sf.jabref.BibtexDatabase;
13 import net.sf.jabref.BibtexEntry;
14 import net.sf.jabref.MetaData;
15 import net.sf.jabref.Globals;
16 import net.sf.jabref.export.layout.Layout;
17 import net.sf.jabref.export.layout.LayoutHelper;
20 * Base class for export formats based on templates.
23 public class ExportFormat implements IExportFormat {
30 FileFilter fileFilter;
31 boolean customExport = false;
34 * Initialize another export format based on templates stored in dir with
35 * layoutFile lfFilename.
38 * Name to display to the user.
40 * Name to call this format in the console.
42 * Name of the main layout file.
44 * Directory in which to find the layout file.
46 * Should contain the . (for instance .txt).
48 public ExportFormat(String displayName, String consoleName,
49 String lfFileName, String directory, String extension) {
50 this.displayName = displayName;
51 this.consoleName = consoleName;
52 this.lfFileName = lfFileName;
53 this.directory = directory;
54 this.extension = extension;
57 /** Empty default constructor for subclasses */
58 protected ExportFormat() {
59 // intentionally empty
63 * Indicate whether this is a custom export. A custom export looks for its
64 * layout files using a normal file path, while a built-in export looks in
68 * true to indicate a custom export format.
70 public void setCustomExport(boolean custom) {
71 this.customExport = custom;
75 * @see IExportFormat#getConsoleName()
77 public String getConsoleName() {
82 * @see IExportFormat#getDisplayName()
84 public String getDisplayName() {
89 * This method should return a reader from which the given layout file can
92 * This standard implementation of this method will use the
93 * {@link FileActions#getReader(String)} method.
95 * Subclasses of ExportFormat are free to override and provide their own
100 * @throws IOException
101 * if the reader could not be created
103 * @return a newly created reader
105 protected Reader getReader(String filename) throws IOException {
106 // If this is a custom export, just use the given file name:
111 dir = Globals.LAYOUT_PREFIX
112 + (directory == null ? "" : directory + "/");
114 return FileActions.getReader(dir + filename);
118 * Perform the export of {@code database}.
121 * The database to export from.
123 * The database's meta data.
125 * the file to write the resulting export to
127 * The encoding of the database
129 * Contains the IDs of all entries that should be exported. If
130 * <code>null</code>, all entries will be exported.
132 * @throws IOException
133 * if a problem occurred while trying to write to {@code writer}
134 * or read from required resources.
136 * if any other error occurred during export.
138 * @see net.sf.jabref.export.IExportFormat#performExport(net.sf.jabref.BibtexDatabase,
139 * net.sf.jabref.MetaData, java.lang.String, java.lang.String, java.util.Set)
141 public void performExport(final BibtexDatabase database,
142 final MetaData metaData, final String file,
143 final String encoding, Set<String> entryIds) throws Exception {
145 File outFile = new File(file);
146 SaveSession ss = getSaveSession(encoding, outFile);
147 VerifyingWriter ps = ss.getWriter();
150 Layout beginLayout = null;
153 reader = getReader(lfFileName + ".begin.layout");
154 LayoutHelper layoutHelper = new LayoutHelper(reader);
155 beginLayout = layoutHelper
156 .getLayoutFromText(Globals.FORMATTER_PACKAGE);
158 } catch (IOException ex) {
159 // If an exception was cast, export filter doesn't have a begin
163 if (beginLayout != null) {
164 ps.write(beginLayout.doLayout(database, encoding));
168 * Write database entries; entries will be sorted as they appear on the
169 * screen, or sorted by author, depending on Preferences. We also supply
170 * the Set entries - if we are to export only certain entries, it will
171 * be non-null, and be used to choose entries. Otherwise, it will be
172 * null, and be ignored.
174 List<BibtexEntry> sorted = FileActions.getSortedEntries(database,
177 // Load default layout
178 reader = getReader(lfFileName + ".layout");
180 LayoutHelper layoutHelper = new LayoutHelper(reader);
181 Layout defLayout = layoutHelper
182 .getLayoutFromText(Globals.FORMATTER_PACKAGE);
184 HashMap<String, Layout> layouts = new HashMap<String, Layout>();
186 for (BibtexEntry entry : sorted) {
188 String type = entry.getType().getName().toLowerCase();
189 if (layouts.containsKey(type))
190 layout = layouts.get(type);
193 // We try to get a type-specific layout for this entry.
194 reader = getReader(lfFileName + "." + type + ".layout");
195 layoutHelper = new LayoutHelper(reader);
196 layout = layoutHelper
197 .getLayoutFromText(Globals.FORMATTER_PACKAGE);
198 layouts.put(type, layout);
200 } catch (IOException ex) {
201 // The exception indicates that no type-specific layout
203 // go with the default one.
209 ps.write(layout.doLayout(entry, database));
214 // changed section - begin (arudert)
215 Layout endLayout = null;
217 reader = getReader(lfFileName + ".end.layout");
218 layoutHelper = new LayoutHelper(reader);
219 endLayout = layoutHelper
220 .getLayoutFromText(Globals.FORMATTER_PACKAGE);
222 } catch (IOException ex) {
223 // If an exception was thrown, export filter doesn't have an end
228 if (endLayout != null) {
229 ps.write(endLayout.doLayout(database, encoding));
232 finalizeSaveSession(ss);
235 protected SaveSession getSaveSession(final String encoding,
236 final File outFile) throws IOException {
237 return new SaveSession(outFile, encoding, false);
241 * @see net.sf.jabref.export.IExportFormat#getFileFilter()
243 public FileFilter getFileFilter() {
244 if (fileFilter == null)
245 fileFilter = new ExportFileFilter(this, extension);
249 public void finalizeSaveSession(final SaveSession ss) throws Exception {
250 ss.getWriter().flush();
251 ss.getWriter().close();
253 if (!ss.getWriter().couldEncodeAll()) {
254 System.err.println("Could not encode...");