package net.sf.jabref.imports; import java.io.File; import java.io.FileFilter; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.undo.CompoundEdit; import javax.swing.undo.UndoManager; import net.sf.jabref.*; import net.sf.jabref.external.ExternalFileType; import net.sf.jabref.undo.UndoableInsertEntry; /** * The class EntryFromFileCreatorManager manages entry creators. * The manager knows all existing implementations of the interface EntryFromFileCreator. * Given a file, the manager can then provide a creator, which is able to create a Bibtex entry for his file. * Knowing all implementations of the interface, the manager also knows the set of all files, of which Bibtex entries can be created. * The GUI uses this capability for offering the user only such files, of which entries could actually be created. * @author Dan&Nosh * */ public final class EntryFromFileCreatorManager { private List<EntryFromFileCreator> entryCreators; public EntryFromFileCreatorManager() { entryCreators = new ArrayList<EntryFromFileCreator>(10); entryCreators.add(new EntryFromPDFCreator()); // add a creator for each ExternalFileType if there is no specialised // creator existing. ExternalFileType[] fileTypes = JabRefPreferences.getInstance().getExternalFileTypeSelection(); for (ExternalFileType exFileType : fileTypes) { if (!hasSpecialisedCreatorForExternalFileType(exFileType)) { entryCreators.add(new EntryFromExternalFileCreator(exFileType)); } } } private boolean hasSpecialisedCreatorForExternalFileType( ExternalFileType externalFileType) { for (EntryFromFileCreator entryCreator : entryCreators) { if (entryCreator.getExternalFileType() == null || entryCreator.getExternalFileType().getExtension() == null) { continue; } if (entryCreator.getExternalFileType().getExtension().equals( externalFileType.getExtension())) { return true; } } return false; } /** * Returns a EntryFromFileCreator object that is capable of creating a * BibtexEntry for the given File. * * @param pdfFile * @return null if there is no EntryFromFileCreator for this File. */ public EntryFromFileCreator getEntryCreator(File file) { if (file == null || !file.exists()) { return null; } for (EntryFromFileCreator creator : entryCreators) { if (creator.accept(file)) { return creator; } } return null; } /** * Trys to add a entry for each file in the List. * * @param files * @param database * @param entryType * @return List of unexcpected import event messages including failures. */ public List<String> addEntrysFromFiles(List<File> files, BibtexDatabase database, BibtexEntryType entryType, boolean generateKeywordsFromPathToFile) { List<String> importGUIMessages = new LinkedList<String>(); addEntrysFromFiles(files, database, null, entryType, generateKeywordsFromPathToFile, null, importGUIMessages); return importGUIMessages; } /** * Tries to add a entry for each file in the List. * * @param files * @param database * @param panel * @param entryType * @param generateKeywordsFromPathToFile * @param changeListener * @param importGUIMessages list of unexpected import event - Messages including * failures * @return Returns The number of entries added */ public int addEntrysFromFiles(List<File> files, BibtexDatabase database, BasePanel panel, BibtexEntryType entryType, boolean generateKeywordsFromPathToFile, ChangeListener changeListener, List<String> importGUIMessages) { int count = 0; CompoundEdit ce = new CompoundEdit(); for (File f : files) { EntryFromFileCreator creator = getEntryCreator(f); if (creator != null) { BibtexEntry entry = creator.createEntry(f, generateKeywordsFromPathToFile); if (entry == null) { importGUIMessages.add("Problem importing " + f.getPath() + ": Entry could not be created."); continue; } if (entryType != null) { entry.setType(entryType); } if (entry.getId() == null) { entry.setId(Util.createNeutralId()); } /* * TODO: database.insertEntry(BibtexEntry) is not sensible. Why * does 'true' mean "There were duplicates", while 'false' means * "Everything alright"? */ if (database.insertEntry(entry)) { importGUIMessages.add("Problem importing " + f.getPath() + ": Insert into BibtexDatabase failed."); } else { count++; if (panel != null) ce.addEdit(new UndoableInsertEntry(database, entry, panel)); } } else { importGUIMessages.add("Problem importing " + f.getPath() + ": Unknown filetype."); } if (changeListener != null) changeListener.stateChanged(new ChangeEvent(this)); } System.out.println("count = "+count); if ((count > 0) && (panel != null)) { System.out.println("adding edit"); ce.end(); panel.undoManager.addEdit(ce); } return count; } /** * Returns a {@link FileFilter} instance which will accept all files, for * which a {@link EntryFromFileCreator} exists, that accepts the files. <br> * <br> * This {@link FileFilter} will be displayed in the GUI as * "All supported files". * * @return A {@link FileFilter} that accepts all files for which creators * exist. */ public FileFilter getFileFilter() { return new FileFilter() { /** * Accepts all files, which are accepted by any known creator. */ public boolean accept(File file) { for (EntryFromFileCreator creator : entryCreators) { if (creator.accept(file)) { return true; } } return false; } @Override public String toString() { return "All external files"; } }; } /** * Returns a list of all {@link FileFilter} instances (i.e. * {@link EntryFromFileCreator}, plus the file filter that comes with the * {@link #getFileFilter()} method, plus the {@link EntryFromAnyFileCreator} * file filter. * * @return A List of all known possible file filters. */ public List<FileFilter> getFileFilterList() { List<FileFilter> filters = new ArrayList<FileFilter>(); filters.add(getFileFilter()); for (FileFilter creator : entryCreators) { filters.add(creator); } return filters; } }