12
12
import javax .xml .stream .XMLStreamException ;
13
13
import javax .xml .stream .XMLStreamReader ;
14
14
15
+ import org .jabref .logic .util .StandardFileType ;
16
+
15
17
import org .slf4j .Logger ;
16
18
import org .slf4j .LoggerFactory ;
17
19
@@ -25,6 +27,12 @@ public class CSLStyleUtils {
25
27
26
28
private static final Logger LOGGER = LoggerFactory .getLogger (CSLStyleUtils .class );
27
29
30
+ /**
31
+ * Style information record (title, isNumericStyle) pair for a citation style.
32
+ */
33
+ public record StyleInfo (String title , boolean isNumericStyle ) {
34
+ }
35
+
28
36
static {
29
37
XML_INPUT_FACTORY .setProperty (XMLInputFactory .IS_COALESCING , true );
30
38
}
@@ -34,9 +42,64 @@ private CSLStyleUtils() {
34
42
}
35
43
36
44
/**
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
38
46
*/
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
+ }
40
103
}
41
104
42
105
/**
@@ -94,58 +157,4 @@ public static Optional<StyleInfo> parseStyleInfo(String filename, String content
94
157
return Optional .empty ();
95
158
}
96
159
}
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
- }
151
160
}
0 commit comments