package org.jabref.gui.importer; import java.io.File; import java.io.FileFilter; import java.nio.file.Path; import java.util.List; import java.util.Optional; import java.util.StringTokenizer; import org.jabref.Globals; import org.jabref.JabRefGUI; import org.jabref.gui.externalfiletype.ExternalFileType; import org.jabref.gui.externalfiletype.ExternalFileTypes; import org.jabref.gui.filelist.FileListEntry; import org.jabref.gui.filelist.FileListTableModel; import org.jabref.logic.util.io.FileUtil; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.FieldName; /** * The interface EntryFromFileCreator does twice: <br> * On the one hand, it defines a set of files, which it can deal with, on the * other hand it provides the functionality to create a Bibtex entry out of a * file. The interface extends the java.io.FileFilter to inherit a common way of * defining file sets. * * @author Dan&Nosh * @version 25.11.2008 | 23:39:03 * */ public abstract class EntryFromFileCreator implements FileFilter { private static final int MIN_PATH_TOKEN_LENGTH = 4; protected final ExternalFileType externalFileType; /** * Constructor. <br> * Forces subclasses to provide an {@link ExternalFileType} instance, which * they build on. * * @param externalFileType */ EntryFromFileCreator(ExternalFileType externalFileType) { this.externalFileType = externalFileType; } /** * Splits the path to the file and builds a keywords String in the format * that is used by Jabref. */ private static String extractPathesToKeyWordsfield(String absolutePath) { StringBuilder sb = new StringBuilder(); StringTokenizer st = new StringTokenizer(absolutePath, String.valueOf(File.separatorChar)); while (st.hasMoreTokens()) { String token = st.nextToken(); if (!st.hasMoreTokens()) { // ignore last token. The filename ist not wanted as keyword. break; } if (token.length() >= MIN_PATH_TOKEN_LENGTH) { if (sb.length() > 0) { // TODO: find Jabref constant for delimter sb.append(','); } sb.append(token); } } return sb.toString(); } protected abstract Optional<BibEntry> createBibtexEntry(File f); /** * <p> * To support platform independence, a creator must define what types of * files it accepts on it's own. * </p> * <p> * Basically, accepting files which end with the file extension that is * described in the nested {@link #externalFileType} would work on windows * systems. This is also the recommended criterion, on which files should be * accepted. * </p> * <p> * However, defining what types of files this creator accepts, is a property * of <i>entry creators</i>, that is left to the user. * </p> */ @Override public abstract boolean accept(File f); /** * Name of this import format. * * <p> * The name must be unique. * </p> * * @return format name, must be unique and not <code>null</code> */ public abstract String getFormatName(); /** * Create one BibEntry containing information regarding the given File. * * @param f * @param addPathTokensAsKeywords * @return */ public Optional<BibEntry> createEntry(File f, boolean addPathTokensAsKeywords) { if ((f == null) || !f.exists()) { return Optional.empty(); } Optional<BibEntry> newEntry = createBibtexEntry(f); if (!(newEntry.isPresent())) { return newEntry; } if (addPathTokensAsKeywords) { appendToField(newEntry.get(), FieldName.KEYWORDS, extractPathesToKeyWordsfield(f.getAbsolutePath())); } if (!newEntry.get().hasField(FieldName.TITLE)) { newEntry.get().setField(FieldName.TITLE, f.getName()); } addFileInfo(newEntry.get(), f); return newEntry; } /** Returns the ExternalFileType that is imported here */ public ExternalFileType getExternalFileType() { return externalFileType; } private void addFileInfo(BibEntry entry, File file) { Optional<ExternalFileType> fileType = ExternalFileTypes.getInstance() .getExternalFileTypeByExt(externalFileType.getFieldName()); List<Path> possibleFilePaths = JabRefGUI.getMainFrame().getCurrentBasePanel().getBibDatabaseContext() .getFileDirectoriesAsPaths(Globals.prefs.getFileDirectoryPreferences()); Path shortenedFileName = FileUtil.shortenFileName(file.toPath(), possibleFilePaths); FileListEntry fileListEntry = new FileListEntry("", shortenedFileName.toString(), fileType); FileListTableModel model = new FileListTableModel(); model.addEntry(0, fileListEntry); entry.setField(FieldName.FILE, model.getStringRepresentation()); } protected void appendToField(BibEntry entry, String field, String value) { if ((value == null) || value.isEmpty()) { return; } Optional<String> oVal = entry.getField(field); if (oVal.isPresent()) { // TODO: find Jabref constant for delimter if (!oVal.get().contains(value)) { entry.setField(field, oVal.get() + "," + value); } } else { entry.setField(field, value); } } protected void addEntrysToEntry(BibEntry entry, List<BibEntry> entrys) { if (entrys != null) { for (BibEntry e : entrys) { addEntryDataToEntry(entry, e); } } } protected void addEntryDataToEntry(BibEntry entry, BibEntry e) { for (String field : e.getFieldNames()) { e.getField(field).ifPresent(fieldContent -> appendToField(entry, field, fieldContent)); } } @Override public String toString() { if (externalFileType == null) { return "(undefined)"; } return externalFileType.getName() + " (." + externalFileType.getExtension() + ")"; } }