Skip to content

Commit 40e4142

Browse files
authored
Rearrange some CSL methods, add more tests (#12968)
* Rearrange `CSLStyleUtils`, move `isCitationStyleFIle` Signed-off-by: subhramit <[email protected]> * Add tests for `isCitationStyleFile` Signed-off-by: subhramit <[email protected]> * Refine comment Signed-off-by: subhramit <[email protected]> --------- Signed-off-by: subhramit <[email protected]>
1 parent 68923ad commit 40e4142

File tree

5 files changed

+102
-68
lines changed

5 files changed

+102
-68
lines changed

src/main/java/org/jabref/gui/preferences/JabRefGuiPreferences.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@
4949
import org.jabref.logic.bst.BstPreviewLayout;
5050
import org.jabref.logic.citationstyle.CSLStyleLoader;
5151
import org.jabref.logic.citationstyle.CSLStyleUtils;
52-
import org.jabref.logic.citationstyle.CitationStyle;
5352
import org.jabref.logic.citationstyle.CitationStylePreviewLayout;
5453
import org.jabref.logic.exporter.BibDatabaseWriter;
5554
import org.jabref.logic.exporter.SelfContainedSaveConfiguration;
@@ -905,7 +904,7 @@ private List<PreviewLayout> getPreviewLayouts(String style) {
905904

906905
return cycle.stream()
907906
.map(layout -> {
908-
if (CitationStyle.isCitationStyleFile(layout)) {
907+
if (CSLStyleUtils.isCitationStyleFile(layout)) {
909908
BibEntryTypesManager entryTypesManager = Injector.instantiateModelOrService(BibEntryTypesManager.class);
910909
return CSLStyleUtils.createCitationStyleFromFile(layout)
911910
.map(file -> (PreviewLayout) new CitationStylePreviewLayout(file, entryTypesManager))

src/main/java/org/jabref/logic/citationstyle/CSLStyleUtils.java

Lines changed: 65 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
import javax.xml.stream.XMLStreamException;
1313
import javax.xml.stream.XMLStreamReader;
1414

15+
import org.jabref.logic.util.StandardFileType;
16+
1517
import org.slf4j.Logger;
1618
import org.slf4j.LoggerFactory;
1719

@@ -25,6 +27,12 @@ public class CSLStyleUtils {
2527

2628
private static final Logger LOGGER = LoggerFactory.getLogger(CSLStyleUtils.class);
2729

30+
/**
31+
* Style information record (title, isNumericStyle) pair for a citation style.
32+
*/
33+
public record StyleInfo(String title, boolean isNumericStyle) {
34+
}
35+
2836
static {
2937
XML_INPUT_FACTORY.setProperty(XMLInputFactory.IS_COALESCING, true);
3038
}
@@ -34,9 +42,64 @@ private CSLStyleUtils() {
3442
}
3543

3644
/**
37-
* Style information record (title, isNumericStyle) pair for a citation style.
45+
* Checks if the given style file is a CitationStyle based on its extension
3846
*/
39-
public record StyleInfo(String title, boolean isNumericStyle) {
47+
public static boolean isCitationStyleFile(String styleFile) {
48+
return StandardFileType.CITATION_STYLE.getExtensions().stream().anyMatch(styleFile::endsWith);
49+
}
50+
51+
/**
52+
* Creates a CitationStyle from a file path.
53+
*
54+
* @param styleFile Path to the CSL file
55+
* @return Optional containing the CitationStyle if valid, empty otherwise
56+
*/
57+
public static Optional<CitationStyle> createCitationStyleFromFile(String styleFile) {
58+
if (!isCitationStyleFile(styleFile)) {
59+
LOGGER.error("Can only load style files: {}", styleFile);
60+
return Optional.empty();
61+
}
62+
63+
// Check if this is an absolute path (external file)
64+
Path filePath = Path.of(styleFile);
65+
if (filePath.isAbsolute() && Files.exists(filePath)) {
66+
try (InputStream inputStream = Files.newInputStream(filePath)) {
67+
return createCitationStyleFromSource(inputStream, styleFile, false);
68+
} catch (IOException e) {
69+
LOGGER.error("Error reading source file", e);
70+
return Optional.empty();
71+
}
72+
}
73+
74+
// If not an absolute path, treat as internal resource
75+
String internalFile = STYLES_ROOT + (styleFile.startsWith("/") ? "" : "/") + styleFile;
76+
try (InputStream inputStream = CSLStyleUtils.class.getResourceAsStream(internalFile)) {
77+
if (inputStream == null) {
78+
LOGGER.error("Could not find file: {}", styleFile);
79+
return Optional.empty();
80+
}
81+
return createCitationStyleFromSource(inputStream, styleFile, true);
82+
} catch (IOException e) {
83+
LOGGER.error("Error reading source file", e);
84+
}
85+
return Optional.empty();
86+
}
87+
88+
/**
89+
* Creates a CitationStyle from the input stream.
90+
*
91+
* @return Optional containing the CitationStyle if valid, empty otherwise
92+
*/
93+
private static Optional<CitationStyle> createCitationStyleFromSource(InputStream source, String filename, boolean isInternal) {
94+
try {
95+
String content = new String(source.readAllBytes());
96+
97+
Optional<StyleInfo> styleInfo = parseStyleInfo(filename, content);
98+
return styleInfo.map(info -> new CitationStyle(filename, info.title(), info.isNumericStyle(), content, isInternal));
99+
} catch (IOException e) {
100+
LOGGER.error("Error while parsing source", e);
101+
return Optional.empty();
102+
}
40103
}
41104

42105
/**
@@ -94,58 +157,4 @@ public static Optional<StyleInfo> parseStyleInfo(String filename, String content
94157
return Optional.empty();
95158
}
96159
}
97-
98-
/**
99-
* Creates a CitationStyle from a file path.
100-
*
101-
* @param styleFile Path to the CSL file
102-
* @return Optional containing the CitationStyle if valid, empty otherwise
103-
*/
104-
public static Optional<CitationStyle> createCitationStyleFromFile(String styleFile) {
105-
if (!CitationStyle.isCitationStyleFile(styleFile)) {
106-
LOGGER.error("Can only load style files: {}", styleFile);
107-
return Optional.empty();
108-
}
109-
110-
// Check if this is an absolute path (external file)
111-
Path filePath = Path.of(styleFile);
112-
if (filePath.isAbsolute() && Files.exists(filePath)) {
113-
try (InputStream inputStream = Files.newInputStream(filePath)) {
114-
return createCitationStyleFromSource(inputStream, styleFile, false);
115-
} catch (IOException e) {
116-
LOGGER.error("Error reading source file", e);
117-
return Optional.empty();
118-
}
119-
}
120-
121-
// If not an absolute path, treat as internal resource
122-
String internalFile = STYLES_ROOT + (styleFile.startsWith("/") ? "" : "/") + styleFile;
123-
try (InputStream inputStream = CSLStyleUtils.class.getResourceAsStream(internalFile)) {
124-
if (inputStream == null) {
125-
LOGGER.error("Could not find file: {}", styleFile);
126-
return Optional.empty();
127-
}
128-
return createCitationStyleFromSource(inputStream, styleFile, true);
129-
} catch (IOException e) {
130-
LOGGER.error("Error reading source file", e);
131-
}
132-
return Optional.empty();
133-
}
134-
135-
/**
136-
* Creates a CitationStyle from the input stream.
137-
*
138-
* @return Optional containing the CitationStyle if valid, empty otherwise
139-
*/
140-
private static Optional<CitationStyle> createCitationStyleFromSource(InputStream source, String filename, boolean isInternal) {
141-
try {
142-
String content = new String(source.readAllBytes());
143-
144-
Optional<StyleInfo> styleInfo = parseStyleInfo(filename, content);
145-
return styleInfo.map(info -> new CitationStyle(filename, info.title(), info.isNumericStyle(), content, isInternal));
146-
} catch (IOException e) {
147-
LOGGER.error("Error while parsing source", e);
148-
return Optional.empty();
149-
}
150-
}
151160
}

src/main/java/org/jabref/logic/citationstyle/CitationStyle.java

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import java.util.Objects;
55

66
import org.jabref.logic.openoffice.style.OOStyle;
7-
import org.jabref.logic.util.StandardFileType;
87

98
/**
109
* Representation of a CitationStyle. Stores its name, the file path and the style itself.
@@ -36,13 +35,6 @@ public CitationStyle(String filePath, String title, boolean isNumericStyle, Stri
3635
this(filePath, title, isNumericStyle, source, !Path.of(filePath).isAbsolute());
3736
}
3837

39-
/**
40-
* Checks if the given style file is a CitationStyle based on its extension
41-
*/
42-
public static boolean isCitationStyleFile(String styleFile) {
43-
return StandardFileType.CITATION_STYLE.getExtensions().stream().anyMatch(styleFile::endsWith);
44-
}
45-
4638
public String getTitle() {
4739
return title;
4840
}

src/main/java/org/jabref/logic/preferences/JabRefCliPreferences.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@
4545
import org.jabref.logic.citationkeypattern.GlobalCitationKeyPatterns;
4646
import org.jabref.logic.citationstyle.CSLStyleLoader;
4747
import org.jabref.logic.citationstyle.CSLStyleUtils;
48-
import org.jabref.logic.citationstyle.CitationStyle;
4948
import org.jabref.logic.cleanup.CleanupPreferences;
5049
import org.jabref.logic.cleanup.FieldFormatterCleanups;
5150
import org.jabref.logic.exporter.BibDatabaseWriter;
@@ -1124,7 +1123,7 @@ public OpenOfficePreferences getOpenOfficePreferences() {
11241123
OOStyle currentStyle = CSLStyleLoader.getDefaultStyle(); // Defaults to IEEE CSL Style
11251124

11261125
// Reassign currentStyle based on actual last used CSL style or JStyle
1127-
if (CitationStyle.isCitationStyleFile(currentStylePath)) {
1126+
if (CSLStyleUtils.isCitationStyleFile(currentStylePath)) {
11281127
currentStyle = CSLStyleUtils.createCitationStyleFromFile(currentStylePath)
11291128
.orElse(CSLStyleLoader.getDefaultStyle());
11301129
} else {

src/test/java/org/jabref/logic/citationstyle/CSLStyleUtilsTest.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@
66
import java.util.Optional;
77
import java.util.stream.Stream;
88

9+
import org.junit.jupiter.api.Test;
910
import org.junit.jupiter.params.ParameterizedTest;
1011
import org.junit.jupiter.params.provider.Arguments;
1112
import org.junit.jupiter.params.provider.MethodSource;
13+
import org.junit.jupiter.params.provider.ValueSource;
1214

1315
import static org.junit.jupiter.api.Assertions.assertEquals;
1416
import static org.junit.jupiter.api.Assertions.assertFalse;
@@ -21,6 +23,39 @@ class CSLStyleUtilsTest {
2123
private static final String MODIFIED_APA = "modified-apa.csl";
2224
private static final String LITERATURA = "literatura.csl";
2325

26+
@ParameterizedTest
27+
@ValueSource(strings = {
28+
"ieee.csl",
29+
"apa.csl",
30+
"harvard.csl",
31+
"vancouver.csl",
32+
"/path/to/style/nature.csl",
33+
"C:\\Users\\username\\Documents\\styles\\chicago.csl"
34+
})
35+
void acceptsCslExtension(String filename) {
36+
assertTrue(CSLStyleUtils.isCitationStyleFile(filename));
37+
}
38+
39+
@ParameterizedTest
40+
@ValueSource(strings = {
41+
"ieee.txt",
42+
"apa.xml",
43+
"harvard.css",
44+
"vancouver",
45+
"nature.",
46+
"",
47+
"chicago.CSL" // case sensitivity - should reject
48+
})
49+
void rejectsNonCslExtension(String filename) {
50+
assertFalse(CSLStyleUtils.isCitationStyleFile(filename));
51+
}
52+
53+
@Test
54+
void acceptsFilenameWithMultipleDots() {
55+
assertTrue(CSLStyleUtils.isCitationStyleFile("ieee.modified.csl"));
56+
assertTrue(CSLStyleUtils.isCitationStyleFile("apa.v7.csl"));
57+
}
58+
2459
@ParameterizedTest
2560
@MethodSource("styleTestData")
2661
void parseStyleInfo(String styleName, String expectedTitle, boolean expectedIsNumeric) throws IOException {

0 commit comments

Comments
 (0)