Skip to content

Commit

Permalink
Externalize FileField parsing logic
Browse files Browse the repository at this point in the history
  • Loading branch information
stefan-kolb committed Jan 24, 2016
1 parent 5cf5329 commit 56b2798
Show file tree
Hide file tree
Showing 5 changed files with 231 additions and 158 deletions.
139 changes: 14 additions & 125 deletions src/main/java/net/sf/jabref/gui/FileListTableModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import net.sf.jabref.external.UnknownExternalFileType;
import net.sf.jabref.logic.util.io.FileUtil;
import net.sf.jabref.logic.util.strings.StringUtil;
import net.sf.jabref.model.entry.FileField;

/**
* Data structure to contain a list of file links, parseable from a coded string.
Expand Down Expand Up @@ -127,117 +128,19 @@ public void setContentDontGuessTypes(String value) {
setContent(value, false, false);
}

public List<FileListEntry> parseFileField(String value) {
if (value == null) {
value = "";
}

ArrayList<FileListEntry> files = new ArrayList<>();
ArrayList<String> entry = new ArrayList<>();

StringBuilder sb = new StringBuilder();
boolean inXmlChar = false;
boolean escaped = false;

for (int i = 0; i < value.length(); i++) {
char c = value.charAt(i);
if (!escaped && (c == '\\')) {
escaped = true;
continue;
}
// Check if we are entering an XML special character construct such
// as "&#44;", because we need to know in order to ignore the semicolon.
else if (!escaped && (c == '&') && !inXmlChar) {
sb.append(c);
if ((value.length() > (i + 1)) && (value.charAt(i + 1) == '#')) {
inXmlChar = true;
}
}
// Check if we are exiting an XML special character construct:
else if (!escaped && inXmlChar && (c == ';')) {
sb.append(c);
inXmlChar = false;
}
else if (!escaped && (c == ':')) {
entry.add(sb.toString());
sb = new StringBuilder();
}
else if (!escaped && (c == ';') && !inXmlChar) {
entry.add(sb.toString());
sb = new StringBuilder();

files.add(decodeEntry(entry, true));
entry.clear();
} else {
sb.append(c);
}
escaped = false;
}
if (sb.length() > 0) {
entry.add(sb.toString());
}

if (!entry.isEmpty()) {
files.add(decodeEntry(entry, true));
}

return files;
}

private FileListEntry setContent(String value, boolean firstOnly, boolean deduceUnknownTypes) {
if (value == null) {
value = "";
}

List<FileField.ParsedFileField> fields = FileField.parse(value);
ArrayList<FileListEntry> files = new ArrayList<>();
ArrayList<String> entry = new ArrayList<>();

StringBuilder sb = new StringBuilder();
boolean inXmlChar = false;
boolean escaped = false;

for (int i = 0; i < value.length(); i++) {
char c = value.charAt(i);
if (!escaped && (c == '\\')) {
escaped = true;
for(FileField.ParsedFileField entry : fields) {
if (entry.isEmpty()) {
continue;
}
// Check if we are entering an XML special character construct such
// as "&#44;", because we need to know in order to ignore the semicolon.
else if (!escaped && (c == '&') && !inXmlChar) {
sb.append(c);
if ((value.length() > (i + 1)) && (value.charAt(i + 1) == '#')) {
inXmlChar = true;
}
}
// Check if we are exiting an XML special character construct:
else if (!escaped && inXmlChar && (c == ';')) {
sb.append(c);
inXmlChar = false;
}
else if (!escaped && (c == ':')) {
entry.add(sb.toString());
sb = new StringBuilder();
}
else if (!escaped && (c == ';') && !inXmlChar) {
entry.add(sb.toString());
sb = new StringBuilder();
if (firstOnly) {
return decodeEntry(entry, deduceUnknownTypes);
} else {
files.add(decodeEntry(entry, deduceUnknownTypes));
entry.clear();
}
} else {
sb.append(c);
}
escaped = false;
}
if (sb.length() > 0) {
entry.add(sb.toString());
}

if (!entry.isEmpty()) {
if (firstOnly) {
return decodeEntry(entry, deduceUnknownTypes);
} else {
Expand Down Expand Up @@ -272,41 +175,27 @@ public static JLabel getFirstLabel(String content) {
return entry.getType().getIconLabel();
}

private FileListEntry decodeEntry(ArrayList<String> contents, boolean deduceUnknownType) {
ExternalFileType type = Globals.prefs.getExternalFileTypeByName
(getElementIfAvailable(contents, 2));
private FileListEntry decodeEntry(FileField.ParsedFileField entry, boolean deduceUnknownType) {
ExternalFileType type = Globals.prefs.getExternalFileTypeByName(entry.fileType);

if (deduceUnknownType && (type instanceof UnknownExternalFileType)) {
// No file type was recognized. Try to find a usable file type based
// on mime type:
type = Globals.prefs.getExternalFileTypeByMimeType
(getElementIfAvailable(contents, 2));
type = Globals.prefs.getExternalFileTypeByMimeType(entry.fileType);
if (type == null) {
// No type could be found from mime type on the extension:
//System.out.println("Not found by mime: '"+getElementIfAvailable(contents, 2));
ExternalFileType typeGuess = null;
String link = getElementIfAvailable(contents, 1);
Optional<String> extension = FileUtil.getFileExtension(link);
Optional<String> extension = FileUtil.getFileExtension(entry.link);
if (extension.isPresent()) {
typeGuess = Globals.prefs.getExternalFileTypeByExt(extension.get());
}
if (typeGuess != null) {
type = typeGuess;
ExternalFileType typeGuess = Globals.prefs.getExternalFileTypeByExt(extension.get());

if (typeGuess != null) {
type = typeGuess;
}
}
}
}

return new FileListEntry(getElementIfAvailable(contents, 0),
getElementIfAvailable(contents, 1),
type);
}

private String getElementIfAvailable(ArrayList<String> contents, int index) {
if (index < contents.size()) {
return contents.get(index);
} else {
return "";
}
return new FileListEntry(entry.description, entry.link, type);
}

/**
Expand Down
15 changes: 6 additions & 9 deletions src/main/java/net/sf/jabref/importer/DatabaseFileLookup.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import net.sf.jabref.JabRef;
import net.sf.jabref.gui.FileListEntry;
import net.sf.jabref.gui.FileListTableModel;
import net.sf.jabref.model.entry.FileField;

/**
* Search class for files. <br>
Expand Down Expand Up @@ -71,25 +72,21 @@ public DatabaseFileLookup(BibDatabase database) {
* entry in the database, otherwise <code>false</code>.
*/
public boolean lookupDatabase(File file) {
if (fileCache.contains(file)) {
return true;
} else {
return false;
}
return fileCache.contains(file);
}

private List<File> parseFileField(BibEntry entry) {
Objects.requireNonNull(entry);

String fileField = entry.getField(DatabaseFileLookup.KEY_FILE_FIELD);
List<FileListEntry> entries = new FileListTableModel().parseFileField(fileField);
List<FileField.ParsedFileField> entries = FileField.parse(fileField);

List<File> fileLinks = new ArrayList<>();
for (FileListEntry e : entries) {
String link = e.getLink();
for (FileField.ParsedFileField field : entries) {
String link = field.link;

// Do not query external file links (huge performance leak)
if(link == null || link.contains("//")) {
if(link.contains("//")) {
continue;
}

Expand Down
49 changes: 25 additions & 24 deletions src/main/java/net/sf/jabref/logic/util/io/FileUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -83,23 +83,23 @@ public static List<String> uniquePathSubstrings(List<String> paths) {
List<String> pathSubstrings = Arrays.asList(arr);

// compute shortest folder substrings
while(!stackList.stream().allMatch(Vector::isEmpty)) {
for(int i = 0; i < stackList.size(); i++) {
while (!stackList.stream().allMatch(Vector::isEmpty)) {
for (int i = 0; i < stackList.size(); i++) {
String tempString = pathSubstrings.get(i);

if(tempString.isEmpty() && !stackList.get(i).isEmpty()) {
if (tempString.isEmpty() && !stackList.get(i).isEmpty()) {
pathSubstrings.set(i, stackList.get(i).pop());
} else {
if(!stackList.get(i).isEmpty()) {
if (!stackList.get(i).isEmpty()) {
pathSubstrings.set(i, stackList.get(i).pop() + File.separator + tempString);
}
}
}

for(int i = 0; i < stackList.size(); i++) {
for (int i = 0; i < stackList.size(); i++) {
String tempString = pathSubstrings.get(i);

if(Collections.frequency(pathSubstrings, tempString) == 1) {
if (Collections.frequency(pathSubstrings, tempString) == 1) {
stackList.get(i).clear();
}
}
Expand Down Expand Up @@ -232,28 +232,29 @@ public static File expandFilename(String name, String dir) {
}

File file = new File(name);
if (file.exists() || dir == null) {
return file;
}

if (!file.exists() && (dir != null)) {
if (dir.endsWith(FILE_SEPARATOR)) {
name = dir + name;
} else {
name = dir + FILE_SEPARATOR + name;
}

// fix / and \ problems:
if (OS.WINDOWS) {
name = SLASH.matcher(name).replaceAll("\\\\");
} else {
name = BACKSLASH.matcher(name).replaceAll("/");
}
if (dir.endsWith(FILE_SEPARATOR)) {
name = dir + name;
} else {
name = dir + FILE_SEPARATOR + name;
}

file = new File(name);
// fix / and \ problems:
if (OS.WINDOWS) {
name = SLASH.matcher(name).replaceAll("\\\\");
} else {
name = BACKSLASH.matcher(name).replaceAll("/");
}

if (!file.exists()) {
file = null;
}
File fileInDir = new File(name);
if (fileInDir.exists()) {
return fileInDir;
} else {
return null;
}
return file;
}

/**
Expand Down
Loading

0 comments on commit 56b2798

Please sign in to comment.