Skip to content

Commit c41d8b8

Browse files
committed
Add Pseudonymization to CLI
- A new pseudonymize command has been created. - Test cases has been added. - The display of commands has been sorted for ease of use. - An entry has been added to CHANGELOG.md.
1 parent dee9627 commit c41d8b8

File tree

7 files changed

+352
-4
lines changed

7 files changed

+352
-4
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv
2323
- We added an "Open example library" button to Welcome Tab. [#13014](https://github.com/JabRef/jabref/issues/13014)
2424
- We added automatic detection and selection of the identifier type (e.g., DOI, ISBN, arXiv) based on clipboard content when opening the "New Entry" dialog [#13111](https://github.com/JabRef/jabref/pull/13111)
2525
- We added support for import of a Refer/BibIX file format. [#13069](https://github.com/JabRef/jabref/issues/13069)
26+
- We added a new command (pseudonymize) to the anonymize the library. [#13109](https://github.com/JabRef/jabref/issues/13109)
2627

2728
### Changed
2829

jabkit/src/main/java/org/jabref/cli/ArgumentProcessor.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,16 @@
3939
@Command(name = "jabkit",
4040
mixinStandardHelpOptions = true,
4141
subcommands = {
42-
GenerateCitationKeys.class,
4342
CheckConsistency.class,
4443
// CheckIntegrity.class,
45-
Fetch.class,
46-
Search.class,
4744
Convert.class,
45+
Fetch.class,
4846
GenerateBibFromAux.class,
47+
GenerateCitationKeys.class,
48+
Pdf.class,
4949
Preferences.class,
50-
Pdf.class
50+
Pseudonymize.class,
51+
Search.class
5152
})
5253
public class ArgumentProcessor implements Runnable {
5354
private static final Logger LOGGER = LoggerFactory.getLogger(ArgumentProcessor.class);
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
package org.jabref.cli;
2+
3+
import java.io.IOException;
4+
import java.nio.file.Path;
5+
import java.util.Objects;
6+
import java.util.Optional;
7+
8+
import org.jabref.logic.importer.ParserResult;
9+
import org.jabref.logic.l10n.Localization;
10+
import org.jabref.logic.pseudonymization.Pseudonymization;
11+
import org.jabref.logic.pseudonymization.PseudonymizationResultCsvWriter;
12+
import org.jabref.model.database.BibDatabase;
13+
import org.jabref.model.database.BibDatabaseContext;
14+
15+
import org.slf4j.Logger;
16+
import org.slf4j.LoggerFactory;
17+
import picocli.CommandLine.Command;
18+
import picocli.CommandLine.Mixin;
19+
import picocli.CommandLine.Option;
20+
import picocli.CommandLine.Parameters;
21+
import picocli.CommandLine.ParentCommand;
22+
23+
@Command(name = "pseudonymize", description = "Anonymize the library")
24+
public class Pseudonymize implements Runnable {
25+
private final static Logger LOGGER = LoggerFactory.getLogger(Pseudonymize.class);
26+
27+
@ParentCommand
28+
private ArgumentProcessor argumentProcessor;
29+
30+
@Mixin
31+
private ArgumentProcessor.SharedOptions sharedOptions = new ArgumentProcessor.SharedOptions();
32+
33+
@Parameters(index = "0", description = "File to be anonymized")
34+
private String inputFile;
35+
36+
@Option(names = {"--output"}, description = "Output file")
37+
private String outputFile;
38+
39+
@Option(names = {"--key"}, description = "Output keys file")
40+
private String key;
41+
42+
@Override
43+
public void run() {
44+
String fileName = getFileName(inputFile);
45+
String outputFileName = fileName + ".bib";
46+
String keyFileName = fileName + "_keys.csv";
47+
48+
// todo: case- output file already exist !
49+
50+
Optional<ParserResult> parserResult = ArgumentProcessor.importFile(
51+
inputFile,
52+
"bibtex",
53+
argumentProcessor.cliPreferences,
54+
sharedOptions.porcelain);
55+
56+
if (parserResult.isEmpty()) {
57+
System.out.println(Localization.lang("Unable to open file '%0'.", inputFile));
58+
return;
59+
}
60+
61+
if (parserResult.get().isInvalid()) {
62+
System.out.println(Localization.lang("Input file '%0' is invalid and could not be parsed.", inputFile));
63+
return;
64+
}
65+
66+
System.out.println(Localization.lang("Anonymizing the library '%0' ...", fileName));
67+
Pseudonymization pseudonymization = new Pseudonymization();
68+
BibDatabaseContext databaseContext = parserResult.get().getDatabaseContext();
69+
Pseudonymization.Result result = pseudonymization.pseudonymizeLibrary(databaseContext);
70+
71+
ArgumentProcessor.saveDatabase(
72+
argumentProcessor.cliPreferences,
73+
argumentProcessor.entryTypesManager,
74+
new BibDatabase(result.bibDatabaseContext().getEntries()),
75+
Path.of(Objects.requireNonNullElse(outputFile, outputFileName)));
76+
77+
try {
78+
Path keysPath = Path.of(Objects.requireNonNullElse(key, keyFileName));
79+
System.out.println(Localization.lang("Saving") + ": " + keysPath);
80+
PseudonymizationResultCsvWriter.writeValuesMappingAsCsv(keysPath, result);
81+
} catch (IOException ex) {
82+
System.err.println(Localization.lang("Unable to save keys: %0", ex.getMessage()));
83+
LOGGER.error("Unable to save keys of anonymized library");
84+
}
85+
}
86+
87+
public static String getFileName(String inputFile) {
88+
String fileName = Path.of(inputFile).getFileName().toString();
89+
int dotIndex = fileName.lastIndexOf('.');
90+
String suffix = "_pseudo";
91+
92+
if (dotIndex != -1) {
93+
return fileName.substring(0, dotIndex) + suffix;
94+
} else {
95+
return fileName + suffix;
96+
}
97+
}
98+
}

jabkit/src/test/java/org/jabref/cli/ArgumentProcessorTest.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,4 +169,23 @@ void checkConsistencyPorcelain() throws URISyntaxException {
169169

170170
System.setOut(System.out);
171171
}
172+
173+
@Test
174+
void performPseudonymize(@TempDir Path tempDir) throws URISyntaxException {
175+
Path path = Path.of(Objects.requireNonNull(ArgumentProcessorTest.class.getResource("Chocolate.bib")).toURI());
176+
String inputFile = path.toAbsolutePath().toString();
177+
178+
Path fileOutput = tempDir.resolve("Choco_pseudo.bib").toAbsolutePath();
179+
Path keyOutput = tempDir.resolve("Choco_pseudo_keys.csv").toAbsolutePath();
180+
181+
List<String> args = List.of(
182+
"pseudonymize", inputFile,
183+
"--output", fileOutput.toString(),
184+
"--key", keyOutput.toString());
185+
186+
commandLine.execute(args.toArray(String[]::new));
187+
188+
assertTrue(Files.exists(fileOutput));
189+
assertTrue(Files.exists(keyOutput));
190+
}
172191
}
Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
@Article{Corti_2009,
2+
author = {Corti, Roberto and Flammer, Andreas J. and Hollenberg, Norman K. and Lüscher, Thomas F.},
3+
date = {2009-03},
4+
journaltitle = {Circulation},
5+
title = {Cocoa and Cardiovascular Health},
6+
doi = {10.1161/circulationaha.108.827022},
7+
issn = {1524-4539},
8+
number = {10},
9+
pages = {1433--1441},
10+
volume = {119},
11+
file = {:DownloadedViaJabRef/Corti et al. (2009-03) Cocoa Cardiovascular Health.pdf:PDF},
12+
publisher = {Ovid Technologies (Wolters Kluwer Health)},
13+
}
14+
15+
@Article{Cooper_2007,
16+
author = {Cooper, Karen A. and Donovan, Jennifer L. and Waterhouse, Andrew L. and Williamson, Gary},
17+
date = {2007-08},
18+
journaltitle = {British Journal of Nutrition},
19+
title = {Cocoa and health: a decade of research},
20+
doi = {10.1017/s0007114507795296},
21+
issn = {1475-2662},
22+
number = {1},
23+
pages = {1--11},
24+
volume = {99},
25+
file = {:DownloadedViaJabRef/Cooper et al. (2007-08) Cocoa health_ decade.pdf:PDF},
26+
publisher = {Cambridge University Press (CUP)},
27+
}
28+
29+
@Article{Ding_2006,
30+
author = {Ding, Eric L and Hutfless, Susan M and Ding, Xin and Girotra, Saket},
31+
date = {2006-01},
32+
journaltitle = {Nutrition &amp; Metabolism},
33+
title = {Chocolate and Prevention of Cardiovascular Disease: A Systematic Review},
34+
doi = {10.1186/1743-7075-3-2},
35+
issn = {1743-7075},
36+
number = {1},
37+
volume = {3},
38+
file = {:DownloadedViaJabRef/Ding et al. (2006-01) Chocolate Prevention Cardiovascular.pdf:PDF},
39+
publisher = {Springer Science and Business Media LLC},
40+
}
41+
42+
@Article{Keen_2001,
43+
author = {Keen, Carl L.},
44+
date = {2001-10},
45+
journaltitle = {Journal of the American College of Nutrition},
46+
title = {Chocolate: Food as Medicine/Medicine as Food},
47+
doi = {10.1080/07315724.2001.10719181},
48+
issn = {1541-1087},
49+
number = {sup5},
50+
pages = {436S--439S},
51+
volume = {20},
52+
publisher = {Informa UK Limited},
53+
}
54+
55+
@Article{Katz_2011,
56+
author = {Katz, David L. and Doughty, Kim and Ali, Ather},
57+
date = {2011-11},
58+
journaltitle = {Antioxidants &amp; Redox Signaling},
59+
title = {Cocoa and Chocolate in Human Health and Disease},
60+
doi = {10.1089/ars.2010.3697},
61+
issn = {1557-7716},
62+
number = {10},
63+
pages = {2779--2811},
64+
volume = {15},
65+
file = {:DownloadedViaJabRef/Katz et al. (2011-11) Cocoa Chocolate Human.pdf:PDF},
66+
publisher = {Mary Ann Liebert Inc},
67+
readstatus = {skimmed},
68+
}
69+
70+
@Article{Parker_2006,
71+
author = {Parker, Gordon and Parker, Isabella and Brotchie, Heather},
72+
date = {2006-06},
73+
journaltitle = {Journal of Affective Disorders},
74+
title = {Mood state effects of chocolate},
75+
doi = {10.1016/j.jad.2006.02.007},
76+
issn = {0165-0327},
77+
number = {2–3},
78+
pages = {149--159},
79+
volume = {92},
80+
groups = {Used},
81+
publisher = {Elsevier BV},
82+
readstatus = {read},
83+
}
84+
85+
@Article{Scholey_2013,
86+
author = {Scholey, Andrew and Owen, Lauren},
87+
date = {2013-10},
88+
journaltitle = {Nutrition Reviews},
89+
title = {Effects of chocolate on cognitive function and mood: a systematic review},
90+
doi = {10.1111/nure.12065},
91+
issn = {0029-6643},
92+
number = {10},
93+
pages = {665--681},
94+
volume = {71},
95+
file = {:Used/Scholey & Owen (2013-10) Effects chocolate cognitive.pdf:PDF},
96+
groups = {Used},
97+
publisher = {Oxford University Press (OUP)},
98+
readstatus = {read},
99+
}
100+
101+
@Article{Tan_2021,
102+
author = {Tan, Terence Yew Chin and Lim, Xin Yi and Yeo, Julie Hsiao Hui and Lee, Shaun Wen Huey and Lai, Nai Ming},
103+
date = {2021-08},
104+
journaltitle = {Nutrients},
105+
title = {The Health Effects of Chocolate and Cocoa: A Systematic Review},
106+
doi = {10.3390/nu13092909},
107+
issn = {2072-6643},
108+
number = {9},
109+
pages = {2909},
110+
volume = {13},
111+
file = {:DownloadedViaJabRef/Tan et al. (2021-08) Health Effects Chocolate.pdf:PDF},
112+
publisher = {MDPI AG},
113+
readstatus = {skimmed},
114+
}
115+
116+
@Article{Macht_2007,
117+
author = {Macht, Michael and Mueller, Jochen},
118+
date = {2007-11},
119+
journaltitle = {Appetite},
120+
title = {Immediate effects of chocolate on experimentally induced mood states},
121+
doi = {10.1016/j.appet.2007.05.004},
122+
issn = {0195-6663},
123+
number = {3},
124+
pages = {667--674},
125+
volume = {49},
126+
groups = {Used},
127+
publisher = {Elsevier BV},
128+
readstatus = {read},
129+
}
130+
131+
@Article{Tokede_2011,
132+
author = {Tokede, O A and Gaziano, J M and Djoussé, L},
133+
date = {2011-05},
134+
journaltitle = {European Journal of Clinical Nutrition},
135+
title = {Effects of cocoa products/dark chocolate on serum lipids: a meta-analysis},
136+
doi = {10.1038/ejcn.2011.64},
137+
issn = {1476-5640},
138+
number = {8},
139+
pages = {879--886},
140+
volume = {65},
141+
publisher = {Springer Science and Business Media LLC},
142+
}
143+
144+
@Article{Garcia_2018,
145+
author = {Garcia, Jose P and Santana, Adrian and Baruqui, Diego Lugo and Suraci, Nicholas},
146+
date = {2018-12},
147+
journaltitle = {Reviews in Cardiovascular Medicine},
148+
title = {The Cardiovascular effects of chocolate.},
149+
doi = {10.31083/j.rcm.2018.04.3187},
150+
issn = {2153-8174},
151+
number = {4},
152+
volume = {19},
153+
publisher = {IMR Press},
154+
}
155+
156+
@Article{Hooper_2012,
157+
author = {Hooper, Lee and Kay, Colin and Abdelhamid, Asmaa and Kroon, Paul A and Cohn, Jeffrey S and Rimm, Eric B and Cassidy, Aedín},
158+
date = {2012-03},
159+
journaltitle = {The American Journal of Clinical Nutrition},
160+
title = {Effects of chocolate, cocoa, and flavan-3-ols on cardiovascular health: a systematic review and meta-analysis of randomized trials},
161+
doi = {10.3945/ajcn.111.023457},
162+
issn = {0002-9165},
163+
number = {3},
164+
pages = {740--751},
165+
volume = {95},
166+
publisher = {Elsevier BV},
167+
readstatus = {skimmed},
168+
}
169+
170+
@Article{Di_Renzo_2012,
171+
author = {Di Renzo, Gian Carlo and Brillo, Eleonora and Romanelli, Maila and Porcaro, Giuseppina and Capanna, Federica and Kanninen, Tomi T and Gerli, Sandro and Clerici, Graziano},
172+
date = {2012-06},
173+
journaltitle = {The Journal of Maternal-Fetal &amp; Neonatal Medicine},
174+
title = {Potential effects of chocolate on human pregnancy: a randomized controlled trial},
175+
doi = {10.3109/14767058.2012.683085},
176+
issn = {1476-4954},
177+
number = {10},
178+
pages = {1860--1867},
179+
volume = {25},
180+
groups = {Used},
181+
publisher = {Informa UK Limited},
182+
readstatus = {read},
183+
}
184+
185+
@Article{Richard_2017,
186+
author = {Richard, Anna and Meule, Adrian and Friese, Malte and Blechert, Jens},
187+
date = {2017-09},
188+
journaltitle = {Frontiers in Psychology},
189+
title = {Effects of Chocolate Deprivation on Implicit and Explicit Evaluation of Chocolate in High and Low Trait Chocolate Cravers},
190+
doi = {10.3389/fpsyg.2017.01591},
191+
issn = {1664-1078},
192+
volume = {8},
193+
groups = {Used},
194+
publisher = {Frontiers Media SA},
195+
readstatus = {read},
196+
}
197+
198+
@Article{Fulton_1969,
199+
author = {Fulton, James E., Jr. and Plewig, Gerd and Kligman, Albert M.},
200+
date = {1969-12},
201+
journaltitle = {JAMA: The Journal of the American Medical Association},
202+
title = {{Effect of Chocolate on Acne Vulgaris}},
203+
doi = {10.1001/jama.1969.03160370055011},
204+
eprint = {https://jamanetwork.com/journals/jama/articlepdf/350738/jama\_210\_11\_011.pdf},
205+
issn = {0098-7484},
206+
number = {11},
207+
pages = {2071-2074},
208+
url = {https://doi.org/10.1001/jama.1969.03160370055011},
209+
volume = {210},
210+
publisher = {American Medical Association (AMA)},
211+
}
212+
213+
@Comment{jabref-meta: databaseType:biblatex;}
214+
215+
@Comment{jabref-meta: grouping:
216+
0 AllEntriesGroup:;
217+
1 SearchGroup:Entries without a group\;0\;groups !=~ .+\;0\;1\;1\;\;\;\;;
218+
1 SearchGroup:Entries without a linked file\;0\;file !=~ .+\;0\;1\;1\;\;\;\;;
219+
1 StaticGroup:Paywalled\;0\;1\;\;\;\;;
220+
1 SearchGroup:To read\;0\;groups !=~ .+ and readstatus !=~ .+\;0\;1\;1\;0x008080ff\;\;\;;
221+
1 KeywordGroup:Skimmed\;0\;readstatus\;skimmed\;0\;0\;1\;0xffff00ff\;\;\;;
222+
1 KeywordGroup:Read\;0\;readstatus\;read\;0\;0\;0\;0x00ff00ff\;\;\;;
223+
1 StaticGroup:Used\;0\;1\;0x0000ffff\;\;\;;
224+
}
225+
226+
@Comment{jabref-meta: groups-search-syntax-version:6.0-alpha_1}

jablib/src/main/java/module-info.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@
103103
exports org.jabref.logic.shared.event;
104104
exports org.jabref.logic.crawler;
105105
exports org.jabref.logic.git;
106+
exports org.jabref.logic.pseudonymization;
106107

107108
requires javafx.base;
108109
requires javafx.graphics;

jablib/src/main/resources/l10n/JabRef_en.properties

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2945,3 +2945,5 @@ The\ following\ providers\ are\ available\:=The following providers are availabl
29452945
Unable\ to\ open\ file\ '%0'.=Unable to open file '%0'.
29462946
Unknown\ export\ format\ '%0'.=Unknown export format '%0'.
29472947
Updating\ PDF\ metadata.=Updating PDF metadata.
2948+
Anonymizing\ the\ library\ '%0'\ ...=Anonymizing the library '%0' ...
2949+
Unable\ to\ save\ keys\:\ %0=Unable to save keys: %0

0 commit comments

Comments
 (0)