Skip to content

Commit

Permalink
Move keyword functions from Util to BibtexEntry and add addKeyword(s)…
Browse files Browse the repository at this point in the history
… methods
  • Loading branch information
oscargus committed Nov 21, 2015
1 parent 5de89b0 commit fc12ce2
Show file tree
Hide file tree
Showing 11 changed files with 185 additions and 93 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

import net.sf.jabref.*;
import net.sf.jabref.exporter.layout.*;
import net.sf.jabref.util.Util;

public class RisKeywords implements LayoutFormatter {

Expand All @@ -29,11 +28,11 @@ public String format(String s) {
return "";
}
StringBuilder sb = new StringBuilder();
List<String> keywords = Util.getSeparatedKeywords(s);
List<String> keywords = net.sf.jabref.model.entry.EntryUtil.getSeparatedKeywords(s);
for (int i = 0; i < keywords.size(); i++) {
sb.append("KW - ");
sb.append(keywords.get(i));
if (i < keywords.size() - 1) {
if (i < (keywords.size() - 1)) {
sb.append(Globals.NEWLINE);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -745,7 +745,7 @@ else if (val.matches("edtr\\d+")) {
} else if (val.matches("keyword\\d+")) {
// according to LabelPattern.php, it returns keyword number n
int num = Integer.parseInt(val.substring(7));
ArrayList<String> separatedKeywords = Util.getSeparatedKeywords(entry);
ArrayList<String> separatedKeywords = entry.getSeparatedKeywords();
if (separatedKeywords.size() < num) {
// not enough keywords
return "";
Expand All @@ -761,7 +761,7 @@ else if (val.matches("edtr\\d+")) {
} else {
num = Integer.MAX_VALUE;
}
ArrayList<String> separatedKeywords = Util.getSeparatedKeywords(entry);
ArrayList<String> separatedKeywords = entry.getSeparatedKeywords();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < Math.min(separatedKeywords.size(), num); i++) {
String keyword = separatedKeywords.get(i);
Expand Down
67 changes: 67 additions & 0 deletions src/main/java/net/sf/jabref/model/entry/BibtexEntry.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
Expand Down Expand Up @@ -484,4 +485,70 @@ public String getPublicationDate() {
}
return year;
}

public void putKeywords(ArrayList<String> keywords) {
// Set Keyword Field
String oldValue = this.getField("keywords");
String newValue;
if (!keywords.isEmpty()) {
StringBuilder sb = new StringBuilder();
for (String keyword : keywords) {
sb.append(keyword);
sb.append(", ");
}
sb.delete(sb.length() - 2, sb.length());
newValue = sb.toString();
} else {
newValue = null;
}
if ((oldValue == null) && (newValue == null)) {
return;
}
if ((oldValue == null) || !oldValue.equals(newValue)) {
this.setField("keywords", newValue);
}
}

/**
* Check if a keyword already exists (case insensitive), if not: add it
*
* @param keyword Keyword to add
*/
public void addKeyword(String keyword) {
ArrayList<String> keywords = this.getSeparatedKeywords();
Boolean duplicate = false;

if ((keyword == null) || (keyword.length() == 0)) {
return;
}

for (String key : keywords) {
if (keyword.equalsIgnoreCase(key)) {
duplicate = true;
break;
}
}

if (!duplicate) {
keywords.add(keyword);
this.putKeywords(keywords);
}
}

/**
* Add multiple keywords to entry
*
* @param keywords Keywords to add
*/
public void addKeywords(ArrayList<String> keywords) {
if (keywords != null) {
for (String keyword : keywords) {
this.addKeyword(keyword);
}
}
}

public ArrayList<String> getSeparatedKeywords() {
return net.sf.jabref.model.entry.EntryUtil.getSeparatedKeywords(this.getField("keywords"));
}
}
43 changes: 43 additions & 0 deletions src/main/java/net/sf/jabref/model/entry/EntryUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@

import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

public class EntryUtil {

public static final String SEPARATING_CHARS_NOSPACE = ";,\n";


/**
* Static equals that can also return the right result when one of the objects is null.
*
Expand Down Expand Up @@ -57,4 +61,43 @@ public static List<String> getRemainder(List<String> all, List<String> subset) {
}
return al;
}

/**
* Concatenate two String arrays
*
* @param array1
* the first string array
* @param array2
* the second string array
* @return The concatenation of array1 and array2
*/
public static String[] arrayConcat(String[] array1, String[] array2) {
int len1 = array1.length;
int len2 = array2.length;
String[] union = new String[len1 + len2];
System.arraycopy(array1, 0, union, 0, len1);
System.arraycopy(array2, 0, union, len1, len2);
return union;
}

/**
* @param keywords a String of keywords
* @return an ArrayList containing the keywords. An emtpy list if keywords are null or empty
*/
public static ArrayList<String> getSeparatedKeywords(String keywords) {
ArrayList<String> res = new ArrayList<>();
if (keywords == null) {
return res;
}
// _NOSPACE is a hack to support keywords such as "choreography transactions"
// a more intelligent algorithm would check for the separator chosen (SEPARATING_CHARS_NOSPACE)
// if nothing is found, " " is likely to be the separating char.
// solution by RisKeywords.java: s.split(",[ ]*")
StringTokenizer tok = new StringTokenizer(keywords, SEPARATING_CHARS_NOSPACE);
while (tok.hasMoreTokens()) {
String word = tok.nextToken().trim();
res.add(word);
}
return res;
}
}
24 changes: 17 additions & 7 deletions src/main/java/net/sf/jabref/specialfields/SpecialFieldsUtils.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (C) 2012 JabRef contributors.
/* Copyright (C) 2012-2015 JabRef contributors.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
Expand All @@ -23,6 +23,7 @@
import net.sf.jabref.model.entry.BibtexEntry;
import net.sf.jabref.Globals;
import net.sf.jabref.gui.undo.NamedCompound;
import net.sf.jabref.gui.undo.UndoableFieldChange;

public class SpecialFieldsUtils {

Expand Down Expand Up @@ -55,7 +56,7 @@ public class SpecialFieldsUtils {
public static final Boolean PREF_SHOWCOLUMN_PRINTED_DEFAULT = Boolean.FALSE;

// The choice between PREF_AUTOSYNCSPECIALFIELDSTOKEYWORDS and PREF_SERIALIZESPECIALFIELDS is mutually exclusive
// At least in the settings, not in the implementation. But having both confused the users, therefore, having activated both options at the same time has been disabled
// At least in the settings, not in the implementation. But having both confused the users, therefore, having activated both options at the same time has been disabled
public static final String PREF_AUTOSYNCSPECIALFIELDSTOKEYWORDS = "autoSyncSpecialFieldsToKeywords";
public static final Boolean PREF_AUTOSYNCSPECIALFIELDSTOKEYWORDS_DEFAULT = Boolean.TRUE;

Expand Down Expand Up @@ -90,7 +91,7 @@ private static void exportFieldToKeywords(SpecialField e, String newValue, Bibte
if (!SpecialFieldsUtils.keywordSyncEnabled()) {
return;
}
ArrayList<String> keywordList = Util.getSeparatedKeywords(be);
ArrayList<String> keywordList = be.getSeparatedKeywords();
List<String> values = e.getKeyWords();

int foundPos = -1;
Expand All @@ -111,12 +112,20 @@ private static void exportFieldToKeywords(SpecialField e, String newValue, Bibte
keywordList.add(foundPos, newValue);
}
}
Util.putKeywords(be, keywordList, ce);
String oldValue = be.getField("keywords");
be.putKeywords(keywordList);
String updatedValue = be.getField("keywords");
if ((oldValue == null) || !oldValue.equals(updatedValue)) {
if (ce != null) {
ce.addEdit(new UndoableFieldChange(be, "keywords", oldValue, updatedValue));
}
}

}

/**
* Update keywords according to values of special fields
*
*
* @param nc indicates the undo named compound. May be null
*/
public static void syncKeywordsFromSpecialFields(BibtexEntry be, NamedCompound nc) {
Expand All @@ -142,14 +151,15 @@ private static void importKeywordsForField(ArrayList<String> keywordList, Specia

/**
* updates field values according to keywords
*
*
* @param ce indicates the undo named compound. May be null
*/
public static void syncSpecialFieldsFromKeywords(BibtexEntry be, NamedCompound ce) {
if (be.getField("keywords") == null) {
return;
}
ArrayList<String> keywordList = Util.getSeparatedKeywords(be.getField("keywords"));
ArrayList<String> keywordList = net.sf.jabref.model.entry.EntryUtil
.getSeparatedKeywords(be.getField("keywords"));
SpecialFieldsUtils.importKeywordsForField(keywordList, Priority.getInstance(), be, ce);
SpecialFieldsUtils.importKeywordsForField(keywordList, Rank.getInstance(), be, ce);
SpecialFieldsUtils.importKeywordsForField(keywordList, Quality.getInstance(), be, ce);
Expand Down
16 changes: 11 additions & 5 deletions src/main/java/net/sf/jabref/util/ManageKeywordsAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
import net.sf.jabref.specialfields.SpecialFieldsUtils;
import net.sf.jabref.gui.undo.NamedCompound;
import net.sf.jabref.gui.util.PositionWindow;
import net.sf.jabref.gui.undo.UndoableFieldChange;

import com.jgoodies.forms.builder.ButtonBarBuilder;
import com.jgoodies.forms.builder.FormBuilder;
Expand Down Expand Up @@ -378,7 +379,7 @@ public void actionPerformed(ActionEvent e) {
BibtexEntry[] entries = bp.getSelectedEntries();
NamedCompound ce = new NamedCompound(Localization.lang("Update keywords"));
for (BibtexEntry entry : entries) {
ArrayList<String> separatedKeywords = Util.getSeparatedKeywords(entry);
ArrayList<String> separatedKeywords = entry.getSeparatedKeywords();

// we "intercept" with a treeset
// pro: no duplicates
Expand All @@ -393,7 +394,12 @@ public void actionPerformed(ActionEvent e) {
// put keywords back
separatedKeywords.clear();
separatedKeywords.addAll(keywords);
Util.putKeywords(entry, separatedKeywords, ce);
String oldValue = entry.getField("keywords");
entry.putKeywords(separatedKeywords);
String updatedValue = entry.getField("keywords");
if ((oldValue == null) || !oldValue.equals(updatedValue)) {
ce.addEdit(new UndoableFieldChange(entry, "keywords", oldValue, updatedValue));
}

if (SpecialFieldsUtils.keywordSyncEnabled()) {
SpecialFieldsUtils.syncSpecialFieldsFromKeywords(entry, ce);
Expand All @@ -419,22 +425,22 @@ private void fillKeyWordList() {

if (mergeKeywords.isSelected()) {
for (BibtexEntry entry : entries) {
ArrayList<String> separatedKeywords = Util.getSeparatedKeywords(entry);
ArrayList<String> separatedKeywords = entry.getSeparatedKeywords();
sortedKeywordsOfAllEntriesBeforeUpdateByUser.addAll(separatedKeywords);
}
} else {
assert intersectKeywords.isSelected();

// all keywords from first entry have to be added
BibtexEntry firstEntry = entries[0];
ArrayList<String> separatedKeywords = Util.getSeparatedKeywords(firstEntry);
ArrayList<String> separatedKeywords = firstEntry.getSeparatedKeywords();
sortedKeywordsOfAllEntriesBeforeUpdateByUser.addAll(separatedKeywords);

// for the remaining entries, intersection has to be used
// this approach ensures that one empty keyword list leads to an empty set of common keywords
for (int i = 1; i < entries.length; i++) {
BibtexEntry entry = entries[i];
separatedKeywords = Util.getSeparatedKeywords(entry);
separatedKeywords = entry.getSeparatedKeywords();
sortedKeywordsOfAllEntriesBeforeUpdateByUser.retainAll(separatedKeywords);
}
}
Expand Down
53 changes: 0 additions & 53 deletions src/main/java/net/sf/jabref/util/Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,6 @@ public class Util {

public static final String ARXIV_LOOKUP_PREFIX = "http://arxiv.org/abs/";

private static final String SEPARATING_CHARS_NOSPACE = ";,\n";

private static final UnicodeCharMap UNICODE_CHAR_MAP = new UnicodeCharMap();


Expand Down Expand Up @@ -688,57 +686,6 @@ public static String getLinkedFileName(BibtexDatabase database, BibtexEntry entr
return targetName;
}

/**
* @param keywords a String of keywords
* @return an ArrayList containing the keywords. An emtpy list if keywords are null or empty
*/
public static ArrayList<String> getSeparatedKeywords(String keywords) {
ArrayList<String> res = new ArrayList<>();
if (keywords == null) {
return res;
}
// _NOSPACE is a hack to support keywords such as "choreography transactions"
// a more intelligent algorithm would check for the separator chosen (SEPARATING_CHARS_NOSPACE)
// if nothing is found, " " is likely to be the separating char.
// solution by RisKeywords.java: s.split(",[ ]*")
StringTokenizer tok = new StringTokenizer(keywords, net.sf.jabref.util.Util.SEPARATING_CHARS_NOSPACE);
while (tok.hasMoreTokens()) {
String word = tok.nextToken().trim();
res.add(word);
}
return res;
}

public static ArrayList<String> getSeparatedKeywords(BibtexEntry be) {
return net.sf.jabref.util.Util.getSeparatedKeywords(be.getField("keywords"));
}

public static void putKeywords(BibtexEntry entry, ArrayList<String> keywords, NamedCompound ce) {
// Set Keyword Field
String oldValue = entry.getField("keywords");
String newValue;
if (!keywords.isEmpty()) {
StringBuilder sb = new StringBuilder();
for (String keyword : keywords) {
sb.append(keyword);
sb.append(", ");
}
sb.delete(sb.length() - 2, sb.length());
newValue = sb.toString();
} else {
newValue = null;
}
if ((oldValue == null) && (newValue == null)) {
return;
}
if ((oldValue == null) || !oldValue.equals(newValue)) {
entry.setField("keywords", newValue);
if (ce != null) {
ce.addEdit(new UndoableFieldChange(entry, "keywords", oldValue, newValue));
}
}
}

/**
* @param ce indicates the undo named compound. May be null
*/
Expand Down
Loading

0 comments on commit fc12ce2

Please sign in to comment.