Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions config/checkstyle/checkstyle.xml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,17 @@
<property name="fileExtensions" value="groovy,java" />
</module>

<!-- Detect Pattern.compile() with a string literal argument outside a static final field declaration.
Use a private static final Pattern field instead to avoid recompiling on every invocation.
Dynamic patterns (where the argument is a variable or concatenation) are intentionally excluded.
Limitation: patterns where the word "static" appears inside the string literal itself would not be flagged. -->
<module name="RegexpSingleline">
<property name="id" value="PatternCompileToStaticField"/>
<property name="message" value="Pattern.compile() with a string literal argument should be a private static final Pattern field to avoid recompiling on every call." />
<property name="format" value="^(?!\s*[/*])(?!.*\bstatic\b).*Pattern\.compile\s*\(\s*&quot;(?:[^&quot;\\]|\\.)*&quot;\s*[,)]" />
<property name="fileExtensions" value="java" />
</module>

<!-- Checks for size violations: https://checkstyle.sourceforge.io/config_sizes.html -->

<!-- LineLength not in place as PreviewerViewer and RelatedArticlesTab have line length with more than 500 charachters -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
///
/// The mode is selected by the preferences whether to use Grobid or not.
public class ExtractReferencesAction extends SimpleCommand {
private static final Pattern COMMENT_NUMBER_PATTERN = Pattern.compile("^\\[(\\d+)\\]");

private final int FILES_LIMIT = 10;

private final DialogService dialogService;
Expand Down Expand Up @@ -182,8 +184,7 @@ private static String getCites(List<BibEntry> entries, BibEntry currentEntry) {
String newCitationKey;
// Could happen if no author and no year is present
// We use the number of the comment field (because there is no other way to get the number reliable)
Pattern pattern = Pattern.compile("^\\[(\\d+)\\]");
Matcher matcher = pattern.matcher(importedEntry.getField(StandardField.COMMENT).orElse(""));
Matcher matcher = COMMENT_NUMBER_PATTERN.matcher(importedEntry.getField(StandardField.COMMENT).orElse(""));
if (matcher.hasMatch()) {
newCitationKey = sourceCitationKey + "-" + matcher.group(1);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@
public class PreviewTabViewModel implements PreferenceTabViewModel {

private static final Logger LOGGER = LoggerFactory.getLogger(PreviewTabViewModel.class);
private static final Pattern XML_TAG_PATTERN = Pattern.compile("(?<ELEMENT>(</?\\h*)(\\w+)([^<>]*)(\\h*/?>))"
+ "|(?<COMMENT><!--[^<>]+-->)");
private static final Pattern XML_ATTRIBUTES_PATTERN = Pattern.compile("(\\w+\\h*)(=)(\\h*\"[^\"]+\")");

private final BooleanProperty showAsExtraTabProperty = new SimpleBooleanProperty(false);
private final BooleanProperty showPreviewInEntryTableTooltip = new SimpleBooleanProperty(false);
Expand Down Expand Up @@ -330,10 +333,6 @@ public void resetDefaultLayout() {
/// @param text to parse and highlight
/// @return highlighted span for codeArea
public StyleSpans<Collection<String>> computeHighlighting(String text) {
final Pattern XML_TAG = Pattern.compile("(?<ELEMENT>(</?\\h*)(\\w+)([^<>]*)(\\h*/?>))"
+ "|(?<COMMENT><!--[^<>]+-->)");
final Pattern ATTRIBUTES = Pattern.compile("(\\w+\\h*)(=)(\\h*\"[^\"]+\")");

final int GROUP_OPEN_BRACKET = 2;
final int GROUP_ELEMENT_NAME = 3;
final int GROUP_ATTRIBUTES_SECTION = 4;
Expand All @@ -342,7 +341,7 @@ public StyleSpans<Collection<String>> computeHighlighting(String text) {
final int GROUP_EQUAL_SYMBOL = 2;
final int GROUP_ATTRIBUTE_VALUE = 3;

Matcher matcher = XML_TAG.matcher(text);
Matcher matcher = XML_TAG_PATTERN.matcher(text);
int lastKeywordEnd = 0;
StyleSpansBuilder<Collection<String>> spansBuilder = new StyleSpansBuilder<>();
while (matcher.find()) {
Expand All @@ -359,7 +358,7 @@ public StyleSpans<Collection<String>> computeHighlighting(String text) {
if (!attributesText.isEmpty()) {
lastKeywordEnd = 0;

Matcher attributesMatcher = ATTRIBUTES.matcher(attributesText);
Matcher attributesMatcher = XML_ATTRIBUTES_PATTERN.matcher(attributesText);
while (attributesMatcher.find()) {
spansBuilder.add(List.of(), attributesMatcher.start() - lastKeywordEnd);
spansBuilder.add(Set.of("attribute"), attributesMatcher.end(GROUP_ATTRIBUTE_NAME) - attributesMatcher.start(GROUP_ATTRIBUTE_NAME));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public class FollowUpQuestionGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(FollowUpQuestionGenerator.class);
private static final int MIN_QUESTION_LENGTH = 5;
private static final int MAX_QUESTION_LENGTH = 100;
private static final Pattern NUMBERED_PATTERN = Pattern.compile("^\\s*\\d+\\.\\s*(.+)$", Pattern.MULTILINE);

private final ChatModel chatLanguageModel;
private final AiTemplatesService aiTemplatesService;
Expand Down Expand Up @@ -58,8 +59,7 @@ private String buildPrompt(String userMessage, String aiResponse) {
private List<String> parseQuestions(String response) {
List<String> questions = new ArrayList<>();

Pattern numberedPattern = Pattern.compile("^\\s*\\d+\\.\\s*(.+)$", Pattern.MULTILINE);
Matcher matcher = numberedPattern.matcher(response);
Matcher matcher = NUMBERED_PATTERN.matcher(response);

while (matcher.find() && questions.size() < aiPreferences.getFollowUpQuestionsCount()) {
String question = matcher.group(1).trim();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@
/// implemented by reverse-engineering <a href="https://github.com/SeerLabs/CiteSeerX/blob/4df28a98083be2829ec4c56ebbac09eb7772d379/src/java/edu/psu/citeseerx/domain/BiblioTransformer.java#L155-L249">the implementation by CiteSeerX</a>
public class CoinsParser implements Parser {

private final Pattern DOI = Pattern.compile("%3Fdoi%3D([^&]+)");
private final Pattern TITLE = Pattern.compile("&amp;rft.atitle=([^&]+)");
private final Pattern JOURNAL = Pattern.compile("&amp;rft.jtitle=([^&]+)");
private final Pattern YEAR = Pattern.compile("&amp;rft.date=([^&]+)");
private final Pattern VOLUME = Pattern.compile("&amp;rft.volume=([^&]+)");
private final Pattern PAGES = Pattern.compile("&amp;rft.pages=([^&]+)");
private final Pattern ISSUE = Pattern.compile("&amp;rft.issue=([^&]+)");
private final Pattern TYPE = Pattern.compile("&amp;rft.genre=([^&]+)");
private final Pattern AUTHOR = Pattern.compile("&amp;rft.au=([^&]+)");
private static final Pattern DOI = Pattern.compile("%3Fdoi%3D([^&]+)");
private static final Pattern TITLE = Pattern.compile("&amp;rft.atitle=([^&]+)");
private static final Pattern JOURNAL = Pattern.compile("&amp;rft.jtitle=([^&]+)");
private static final Pattern YEAR = Pattern.compile("&amp;rft.date=([^&]+)");
private static final Pattern VOLUME = Pattern.compile("&amp;rft.volume=([^&]+)");
private static final Pattern PAGES = Pattern.compile("&amp;rft.pages=([^&]+)");
private static final Pattern ISSUE = Pattern.compile("&amp;rft.issue=([^&]+)");
private static final Pattern TYPE = Pattern.compile("&amp;rft.genre=([^&]+)");
private static final Pattern AUTHOR = Pattern.compile("&amp;rft.au=([^&]+)");

@Override
public List<BibEntry> parseEntries(InputStream inputStream) throws ParseException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,16 @@ public class PagesChecker implements ValueChecker {
+ ")?"
+ "\\z"; // end String

private static final Predicate<String> IS_VALID_PAGE_NUMBER_BIBTEX = Pattern.compile(PAGES_EXP_BIBTEX).asPredicate();
private static final Predicate<String> IS_VALID_PAGE_NUMBER_BIBLATEX = Pattern.compile(PAGES_EXP_BIBLATEX).asPredicate();

private final Predicate<String> isValidPageNumber;

public PagesChecker(BibDatabaseContext databaseContext) {
if (databaseContext.isBiblatexMode()) {
isValidPageNumber = Pattern.compile(PAGES_EXP_BIBLATEX).asPredicate();
isValidPageNumber = IS_VALID_PAGE_NUMBER_BIBLATEX;
} else {
isValidPageNumber = Pattern.compile(PAGES_EXP_BIBTEX).asPredicate();
isValidPageNumber = IS_VALID_PAGE_NUMBER_BIBTEX;
}
}

Expand Down
14 changes: 7 additions & 7 deletions jablib/src/main/java/org/jabref/logic/msbib/MSBibEntry.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@
/// @see <a href="http://www.ecma-international.org/publications/standards/Ecma-376.htm">ECMA Standard</a>
class MSBibEntry {

/// reduced subset, supports only "CITY , STATE, COUNTRY" <br>
/// **\b(\w+)\s?[,]?\s?(\w+)\s?[,]?\s?(\w*)\b** <br>
/// WORD SPACE , SPACE WORD SPACE (Can be zero or more) , SPACE WORD (Can be zero or more) <br>
/// Matches both single locations (only city) like Berlin and full locations like Stroudsburg, PA, USA <br>
/// tested using http://www.regexpal.com/
private static final Pattern ADDRESS_PATTERN = Pattern.compile("\\b(\\w+)\\s?[,]?\\s?(\\w*)\\s?[,]?\\s?(\\w*)\\b");

public Map<String, String> fields = new HashMap<>();

public List<MsBibAuthor> authors;
Expand Down Expand Up @@ -65,13 +72,6 @@ class MSBibEntry {

private String bibtexEntryType;

/// reduced subset, supports only "CITY , STATE, COUNTRY" <br>
/// **\b(\w+)\s?[,]?\s?(\w+)\s?[,]?\s?(\w*)\b** <br>
/// WORD SPACE , SPACE WORD SPACE (Can be zero or more) , SPACE WORD (Can be zero or more) <br>
/// Matches both single locations (only city) like Berlin and full locations like Stroudsburg, PA, USA <br>
/// tested using http://www.regexpal.com/
private final Pattern ADDRESS_PATTERN = Pattern.compile("\\b(\\w+)\\s?[,]?\\s?(\\w*)\\s?[,]?\\s?(\\w*)\\b");

public MSBibEntry() {
// empty
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
public class CSLCitationOOAdapter {

private static final CitationStyleOutputFormat HTML_OUTPUT_FORMAT = CitationStyleOutputFormat.HTML;
private static final Pattern CITATION_NUMBER_PATTERN = Pattern.compile("(\\D*)(\\d+)(\\D*)");

private final XTextDocument document;
private final CSLReferenceMarkManager markManager;
Expand Down Expand Up @@ -259,8 +260,7 @@ private void insertReferences(XTextCursor cursor, List<BibEntry> entries, OOText

/// Transforms the numbers in the citation to globally-unique (and thus, reusable) numbers.
private String updateSingleOrMultipleCitationNumbers(String citation, List<BibEntry> entries) {
Pattern pattern = Pattern.compile("(\\D*)(\\d+)(\\D*)");
Matcher matcher = pattern.matcher(citation);
Matcher matcher = CITATION_NUMBER_PATTERN.matcher(citation);
StringBuilder sb = new StringBuilder();
Iterator<BibEntry> iterator = entries.iterator();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public final class CSLFormatUtils {
private static final String DEFAULT_HANGING_INDENT_BIBLIOGRAPHY_BODY_FORMAT = "Hanging indent";

private static final Pattern YEAR_IN_CITATION_PATTERN = Pattern.compile("(.)(.*), (\\d{4}.*)");
private static final Pattern BIBLIOGRAPHY_NUMBER_PATTERN = Pattern.compile("([\\[(])?(\\d+)([])])?(\\.)?\\s*");

private CSLFormatUtils() {
// prevent instantiation
Expand Down Expand Up @@ -168,8 +169,7 @@ public static String generateAlphanumericInTextCitation(BibEntry entry, BibDatab
/// @param currentNumber the correct number to update the citation with.
/// @return the bibliographic citation with resolved number.
public static String updateSingleBibliographyNumber(String citation, int currentNumber) {
Pattern pattern = Pattern.compile("([\\[(])?(\\d+)([])])?(\\.)?\\s*");
Matcher matcher = pattern.matcher(citation);
Matcher matcher = BIBLIOGRAPHY_NUMBER_PATTERN.matcher(citation);
StringBuilder sb = new StringBuilder();
boolean numberReplaced = false;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
/// Class for generation, insertion and management of all reference marks in the document.
public class CSLReferenceMarkManager {
private static final Logger LOGGER = LoggerFactory.getLogger(CSLReferenceMarkManager.class);
private static final Pattern CITATION_NUMBER_PATTERN = Pattern.compile("(\\D*)(\\d+)(\\D*)");

private final XTextDocument document;
private final XMultiServiceFactory factory;
Expand Down Expand Up @@ -227,8 +228,7 @@ private void updateAllCitationNumbers() throws Exception, CreationException {
}

private String getUpdatedCitationTextWithNewNumbers(String currentText, List<Integer> newNumbers) {
Pattern pattern = Pattern.compile("(\\D*)(\\d+)(\\D*)");
Matcher matcher = pattern.matcher(currentText);
Matcher matcher = CITATION_NUMBER_PATTERN.matcher(currentText);
StringBuilder result = new StringBuilder();
int lastEnd = 0;
int numberIndex = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ public class StringUtil {
private static final UnicodeToReadableCharMap UNICODE_CHAR_MAP = new UnicodeToReadableCharMap();
private static final String WRAPPED_LINE_PREFIX = ""; // If a line break is added, this prefix will be inserted at the beginning of the next line
private static final String STRING_TABLE_DELIMITER = " : ";
// A sentence ends with a .?!;, but not in the case of "Mr.", "Ms.", "Mrs.", "Dr.", "st.", "jr.", "co.", "inc.", and "ltd."
private static final Pattern SPLIT_TEXT_PATTERN = Pattern.compile("(?<=[\\.!;\\?])(?<![Mm](([Rr]|[Rr][Ss])|[Ss])\\.|[Dd][Rr]\\.|[Ss][Tt]\\.|[Jj][Rr]\\.|[Cc][Oo]\\.|[Ii][Nn][Cc]\\.|[Ll][Tt][Dd]\\.)\\s+");

public static String booleanToBinaryString(boolean expression) {
return expression ? "1" : "0";
Expand Down Expand Up @@ -676,9 +678,7 @@ public static List<String> getStringAsWords(String text) {

/// Returns a list of sentences contained in the given text.
public static List<String> getStringAsSentences(String text) {
// A sentence ends with a .?!;, but not in the case of "Mr.", "Ms.", "Mrs.", "Dr.", "st.", "jr.", "co.", "inc.", and "ltd."
Pattern splitTextPattern = Pattern.compile("(?<=[\\.!;\\?])(?<![Mm](([Rr]|[Rr][Ss])|[Ss])\\.|[Dd][Rr]\\.|[Ss][Tt]\\.|[Jj][Rr]\\.|[Cc][Oo]\\.|[Ii][Nn][Cc]\\.|[Ll][Tt][Dd]\\.)\\s+");
return Arrays.asList(splitTextPattern.split(text));
return Arrays.asList(SPLIT_TEXT_PATTERN.split(text));
}

@AllowedToUseApacheCommonsLang3("No direct Guava equivalent existing - see https://stackoverflow.com/q/16560635/873282")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ public class ArXivIdentifier extends EprintIdentifier {

private static final String ARXIV_PREFIX = "http(s)?://arxiv.org/(abs|html|pdf)/|arxiv|arXiv";
private static final Pattern IDENTIFIER_PATTERN = Pattern.compile("(" + ARXIV_PREFIX + ")?\\s?:?\\s?(?<id>\\d{4}\\.\\d{4,5})(v(?<version>\\d+))?\\s?(\\[(?<classification>\\S+)\\])?");
private static final Pattern OLD_IDENTIFIER_PATTERN = Pattern.compile("(" + ARXIV_PREFIX + ")?\\s?:?\\s?(?<id>(?<classification>[a-z\\-]+(\\.[A-Z]{2})?)/\\d{7})(v(?<version>\\d+))?");

private final String identifier;
private final String classification;
private final String version;
Expand All @@ -45,8 +47,7 @@ public static Optional<ArXivIdentifier> parse(String value) {
return getArXivIdentifier(identifierMatcher);
}

Pattern oldIdentifierPattern = Pattern.compile("(" + ARXIV_PREFIX + ")?\\s?:?\\s?(?<id>(?<classification>[a-z\\-]+(\\.[A-Z]{2})?)/\\d{7})(v(?<version>\\d+))?");
Matcher oldIdentifierMatcher = oldIdentifierPattern.matcher(identifier);
Matcher oldIdentifierMatcher = OLD_IDENTIFIER_PATTERN.matcher(identifier);
if (oldIdentifierMatcher.matches()) {
return getArXivIdentifier(oldIdentifierMatcher);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,19 @@
@AllowedToUseLogic("Because URL utility is needed")
public class IacrEprint implements Identifier {
public static final URI RESOLVER = URLUtil.createUri("https://ia.cr");

private static final Logger LOGGER = LoggerFactory.getLogger(IacrEprint.class);

private static final String IACR_EPRINT_EXP = "\\d{4}\\/\\d{3,5}";
private static final Pattern IACR_EPRINT_PATTERN = Pattern.compile(IACR_EPRINT_EXP);

private final String iacrEprint;

IacrEprint(@NonNull String iacrEprint) {
String trimmedId = iacrEprint.trim();

if (matchesExcepted(trimmedId)) {
Matcher matcher = Pattern.compile(IACR_EPRINT_EXP).matcher(trimmedId);
Matcher matcher = IACR_EPRINT_PATTERN.matcher(trimmedId);
matcher.find();
this.iacrEprint = matcher.group(0);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
@ResourceLock("Localization.lang")
public class ImporterTest {

private static final Pattern WHITESPACE_PATTERN = Pattern.compile("\\s");

@ParameterizedTest
@MethodSource("instancesToTest")
void getFormatterNameDoesNotReturnNull(Importer format) {
Expand All @@ -54,8 +56,7 @@ void getIdDoesNotReturnNull(Importer format) {
@ParameterizedTest
@MethodSource("instancesToTest")
void getIdDoesNotContainWhitespace(Importer format) {
Pattern whitespacePattern = Pattern.compile("\\s");
assertFalse(whitespacePattern.matcher(format.getId()).find());
assertFalse(WHITESPACE_PATTERN.matcher(format.getId()).find());
}

@ParameterizedTest
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@

public class MarkdownDefinitionProvider extends DefinitionProvider {

private static final Pattern CITATION_COMMAND_PATTERN = Pattern.compile("(?<keys>\\[[^\\]]*@[^\\]]*\\]|@[a-z0-9_.+:-]+(?:\\s*;\\s*@[a-z0-9_.+:-]+)*)", Pattern.CASE_INSENSITIVE);
private static final Pattern CITATION_KEY_INSIDE_PATTERN = Pattern.compile("@(?<citationkey>[a-z0-9_.+:-]+)", Pattern.CASE_INSENSITIVE);

public MarkdownDefinitionProvider(LspParserHandler parserHandler) {
super(parserHandler);
this.citationCommandPattern = Pattern.compile("(?<keys>\\[[^\\]]*@[^\\]]*\\]|@[a-z0-9_.+:-]+(?:\\s*;\\s*@[a-z0-9_.+:-]+)*)", Pattern.CASE_INSENSITIVE);
this.citationKeyInsidePattern = Pattern.compile("@(?<citationkey>[a-z0-9_.+:-]+)", Pattern.CASE_INSENSITIVE);
this.citationCommandPattern = CITATION_COMMAND_PATTERN;
this.citationKeyInsidePattern = CITATION_KEY_INSIDE_PATTERN;
}
}