Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix package of PreviewLayout #5702

Merged
merged 21 commits into from
Mar 29, 2020
Merged
Show file tree
Hide file tree
Changes from 17 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
22 changes: 22 additions & 0 deletions docs/adr/0008-use-public-final-instead-of-getters.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Use `public final` instead of getters to offer access to immutable variables

## Context and Problem Statement

When making immutable data accessible in a java class, should it be using getters or by non-modifiable fields?

## Considered Options

* Offer public static field
* Offer getters

## Decision Outcome

Chosen option: "Offer public static field", because getters used to be a convention which was even more manifested due to libraries depending on the existence on getters/setters. In the case of immutable variables, adding public getters is just useless since one is not hiding anything.

### Positive Consequences

* Shorter code

### Negative Consequences

* new comers could get confused, because getters/setters are still teached
2 changes: 1 addition & 1 deletion src/main/java/org/jabref/gui/DragAndDropDataFormats.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import javafx.scene.input.DataFormat;

import org.jabref.logic.citationstyle.PreviewLayout;
import org.jabref.logic.preview.PreviewLayout;

/**
* Contains all the different {@link DataFormat}s that may occur in JabRef.
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/jabref/gui/maintable/RightClickMenu.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
import org.jabref.gui.specialfields.SpecialFieldMenuItemFactory;
import org.jabref.logic.citationstyle.CitationStyleOutputFormat;
import org.jabref.logic.citationstyle.CitationStylePreviewLayout;
import org.jabref.logic.citationstyle.PreviewLayout;
import org.jabref.logic.preview.PreviewLayout;
import org.jabref.model.entry.field.SpecialField;
import org.jabref.preferences.JabRefPreferences;
import org.jabref.preferences.PreferencesService;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
import org.jabref.gui.util.BaseDialog;
import org.jabref.gui.util.ValueTableCellFactory;
import org.jabref.gui.util.ViewModelTableRowFactory;
import org.jabref.logic.citationstyle.TextBasedPreviewLayout;
import org.jabref.logic.l10n.Localization;
import org.jabref.logic.layout.TextBasedPreviewLayout;
import org.jabref.logic.openoffice.OOBibStyle;
import org.jabref.logic.openoffice.StyleLoader;
import org.jabref.logic.util.TestEntry;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@
import org.jabref.gui.preview.PreviewViewer;
import org.jabref.gui.util.IconValidationDecorator;
import org.jabref.gui.util.ViewModelListCellFactory;
import org.jabref.logic.citationstyle.PreviewLayout;
import org.jabref.logic.l10n.Localization;
import org.jabref.logic.preview.PreviewLayout;
import org.jabref.logic.util.TestEntry;
import org.jabref.model.database.BibDatabaseContext;
import org.jabref.preferences.JabRefPreferences;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@
import org.jabref.gui.util.TaskExecutor;
import org.jabref.logic.citationstyle.CitationStyle;
import org.jabref.logic.citationstyle.CitationStylePreviewLayout;
import org.jabref.logic.citationstyle.PreviewLayout;
import org.jabref.logic.citationstyle.TextBasedPreviewLayout;
import org.jabref.logic.l10n.Localization;
import org.jabref.logic.layout.TextBasedPreviewLayout;
import org.jabref.logic.preview.PreviewLayout;
import org.jabref.preferences.JabRefPreferences;
import org.jabref.preferences.PreviewPreferences;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@
import org.jabref.logic.citationstyle.CitationStyleGenerator;
import org.jabref.logic.citationstyle.CitationStyleOutputFormat;
import org.jabref.logic.citationstyle.CitationStylePreviewLayout;
import org.jabref.logic.citationstyle.PreviewLayout;
import org.jabref.logic.l10n.Localization;
import org.jabref.logic.layout.Layout;
import org.jabref.logic.layout.LayoutFormatterPreferences;
import org.jabref.logic.layout.LayoutHelper;
import org.jabref.logic.preview.PreviewLayout;
import org.jabref.logic.util.OS;
import org.jabref.model.entry.BibEntry;
import org.jabref.preferences.PreviewPreferences;
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/jabref/gui/preview/PreviewPanel.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
import org.jabref.gui.icon.IconTheme;
import org.jabref.gui.keyboard.KeyBinding;
import org.jabref.gui.keyboard.KeyBindingRepository;
import org.jabref.logic.citationstyle.PreviewLayout;
import org.jabref.logic.l10n.Localization;
import org.jabref.logic.preview.PreviewLayout;
import org.jabref.model.database.BibDatabaseContext;
import org.jabref.model.entry.BibEntry;
import org.jabref.preferences.JabRefPreferences;
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/jabref/gui/preview/PreviewViewer.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@
import org.jabref.gui.util.BackgroundTask;
import org.jabref.gui.util.TaskExecutor;
import org.jabref.gui.util.ThemeLoader;
import org.jabref.logic.citationstyle.PreviewLayout;
import org.jabref.logic.exporter.ExporterFactory;
import org.jabref.logic.l10n.Localization;
import org.jabref.logic.preview.PreviewLayout;
import org.jabref.logic.search.SearchQuery;
import org.jabref.model.database.BibDatabaseContext;
import org.jabref.model.entry.BibEntry;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import org.jabref.gui.DragAndDropDataFormats;
import org.jabref.gui.StateManager;
import org.jabref.logic.citationstyle.PreviewLayout;
import org.jabref.logic.preview.PreviewLayout;
import org.jabref.model.entry.BibEntry;

/**
Expand Down
6 changes: 1 addition & 5 deletions src/main/java/org/jabref/logic/bibtex/BibEntryWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,7 @@ public void writeWithoutPrependedNewlines(BibEntry entry, Writer out, BibDatabas
}

/**
* Write fields in the order of requiredFields, optionalFields and other fields, but does not sort the fields.
*
* @param entry
* @param out
* @throws IOException
* Writes fields in the order of requiredFields, optionalFields and other fields, but does not sort the fields.
*/
private void writeRequiredFieldsFirstRemainingFieldsSecond(BibEntry entry, Writer out,
BibDatabaseMode bibDatabaseMode) throws IOException {
Expand Down
88 changes: 88 additions & 0 deletions src/main/java/org/jabref/logic/bst/BstPreviewLayout.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package org.jabref.logic.bst;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would move this also to the citationstyle package, because it's not really about bst (which is only used as a tool)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see org.jabref.logic.preview as the other possibility to collect the preview generators. -- I would keep the package org.jabref.logic.citationstyle for CSL only and keep out the relation to .bst and to our other Layouts.


import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;

import org.jabref.logic.preview.PreviewLayout;
import org.jabref.logic.cleanup.ConvertToBibtexCleanup;
import org.jabref.logic.formatter.bibtexfields.RemoveNewlinesFormatter;
import org.jabref.logic.l10n.Localization;
import org.jabref.logic.layout.format.LatexToUnicodeFormatter;
import org.jabref.logic.layout.format.RemoveLatexCommandsFormatter;
import org.jabref.logic.layout.format.RemoveTilde;
import org.jabref.model.database.BibDatabase;
import org.jabref.model.entry.BibEntry;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class BstPreviewLayout implements PreviewLayout {

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

private final String name;

private VM vm;
private String error;

public BstPreviewLayout(String filename) {
this(Paths.get(filename));
}

public BstPreviewLayout(Path path) {
name = path.getFileName().toString();
if (!Files.exists(path)) {
LOGGER.error("File {} not found", path.toAbsolutePath());
error = Localization.lang("Error opening file '%0'.", path.toString());
return;
}
try {
vm = new VM(path.toFile());
} catch (Exception e) {
LOGGER.error("Could not read {}.", path.toAbsolutePath(), e);
error = Localization.lang("Error opening file '%0'.", path.toString());
}
}

@Override
public String generatePreview(BibEntry originalEntry, BibDatabase database) {
if (error != null) {
return error;
}
// ensure that the entry is of BibTeX format (and do not modify the original entry)
BibEntry entry = (BibEntry) originalEntry.clone();
new ConvertToBibtexCleanup().cleanup(entry);
String result = vm.run(List.of(entry));
// Remove all comments
result = result.replaceAll("%.*", "");
// Remove all LaTeX comments
// The RemoveLatexCommandsFormatter keeps the words inside latex environments. Therefore, we remove them manually
result = result.replace("\\begin{thebibliography}{1}", "");
result = result.replace("\\end{thebibliography}", "");
// The RemoveLatexCommandsFormatter keeps the word inside the latex command, but we want to remove that completely
result = result.replaceAll("\\\\bibitem[{].*[}]", "");
// We want to replace \newblock by a space instead of completely removing it
result = result.replace("\\newblock", " ");
// remove all latex commands statements - assumption: command in a separate line
result = result.replaceAll("(?m)^\\\\.*$", "");
// remove some IEEEtran.bst output (resulting from a multiline \providecommand)
result = result.replace("#2}}", "");
// Have quotes right - and more
result = new LatexToUnicodeFormatter().format(result);
result = result.replace("``", "\"");
result = result.replace("''", "\"");
// Final cleanup
result = new RemoveNewlinesFormatter().format(result);
result = new RemoveLatexCommandsFormatter().format(result);
result = new RemoveTilde().format(result);
result = result.trim().replaceAll(" +", " ");
return result;
}

@Override
public String getName() {
return name;
}
}
49 changes: 22 additions & 27 deletions src/main/java/org/jabref/logic/bst/VM.java
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ private VM(CommonTree tree) {
if (context == null) {
throw new VMException("Call.type$ can only be called from within a context (ITERATE or REVERSE).");
}
VM.this.execute(context.getBibtexEntry().getType().getName(), context);
VM.this.execute(context.entry.getType().getName(), context);
});

buildInFunctions.put("change.case$", new ChangeCaseFunction(this));
Expand Down Expand Up @@ -303,7 +303,7 @@ private VM(CommonTree tree) {
if (context == null) {
throw new VMException("Must have an entry to cite$");
}
stack.push(context.getBibtexEntry().getCiteKeyOptional().orElse(null));
stack.push(context.entry.getCiteKeyOptional().orElse(null));
});

/*
Expand Down Expand Up @@ -581,7 +581,7 @@ private VM(CommonTree tree) {
throw new VMException("type$ need a context.");
}

stack.push(context.getBibtexEntry().getType().getName());
stack.push(context.entry.getType().getName());
});

/*
Expand Down Expand Up @@ -843,11 +843,14 @@ public String run(Collection<BibEntry> bibtex) {
}

/**
* @param bibtex list of entries to convert
* Transforms the given list of BibEntries to a rendered list of references using the underlying bst file
*
* @param bibEntries list of entries to convert
* @param bibDatabase (may be null) the bibDatabase used for resolving strings / crossref
* @return list of references in plain text form
*/
public String run(Collection<BibEntry> bibtex, BibDatabase bibDatabase) {
Objects.requireNonNull(bibtex);
public String run(Collection<BibEntry> bibEntries, BibDatabase bibDatabase) {
Objects.requireNonNull(bibEntries);

// Reset
bbl = new StringBuilder();
Expand All @@ -864,8 +867,8 @@ public String run(Collection<BibEntry> bibtex, BibDatabase bibDatabase) {
stack = new Stack<>();

// Create entries
entries = new ArrayList<>(bibtex.size());
for (BibEntry entry : bibtex) {
entries = new ArrayList<>(bibEntries.size());
for (BibEntry entry : bibEntries) {
entries.add(new BstEntry(entry));
}

Expand Down Expand Up @@ -922,16 +925,16 @@ public String run(Collection<BibEntry> bibtex, BibDatabase bibDatabase) {
*/
private void read(BibDatabase bibDatabase) {
for (BstEntry e : entries) {
for (Map.Entry<String, String> mEntry : e.getFields().entrySet()) {
for (Map.Entry<String, String> mEntry : e.fields.entrySet()) {
Field field = FieldFactory.parseField(mEntry.getKey());
String fieldValue = e.getBibtexEntry().getResolvedFieldOrAlias(field, bibDatabase).orElse(null);
String fieldValue = e.entry.getResolvedFieldOrAlias(field, bibDatabase).orElse(null);
mEntry.setValue(fieldValue);
}
}

for (BstEntry e : entries) {
if (!e.getFields().containsKey(StandardField.CROSSREF.getName())) {
e.getFields().put(StandardField.CROSSREF.getName(), null);
if (!e.fields.containsKey(StandardField.CROSSREF.getName())) {
e.fields.put(StandardField.CROSSREF.getName(), null);
}
}
}
Expand Down Expand Up @@ -978,7 +981,7 @@ private void entry(Tree child) {
String name = t.getChild(i).getText();

for (BstEntry entry : entries) {
entry.getFields().put(name, null);
entry.fields.put(name, null);
}
}

Expand Down Expand Up @@ -1103,8 +1106,8 @@ private void execute(String name, BstEntry context) {

if (context != null) {

if (context.getFields().containsKey(name)) {
stack.push(context.getFields().get(name));
if (context.fields.containsKey(name)) {
stack.push(context.fields.get(name));
return;
}
if (context.localStrings.containsKey(name)) {
Expand Down Expand Up @@ -1171,25 +1174,17 @@ private void strings(Tree child) {

public static class BstEntry {

private final BibEntry entry;
public final BibEntry entry;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then this triggers a follow-up question (@LinusDietz): is it ok to make variables with mutable types (like Map<>) public via public final ? Because then outside code can modify the content of a class to their liking (which I guess is against some of the principles of object-oriented programming).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is effective Java #39. "Make defensive copies when needed".

You must program defensively, with the assumption that clients of your class will do their best to destroy its invariants.

However, did not see that being done much, so I am curios to the opinion of @LinusDietz


private final Map<String, String> localStrings = new HashMap<>();
public final Map<String, String> localStrings = new HashMap<>();

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

private final Map<String, Integer> localIntegers = new HashMap<>();
public final Map<String, Integer> localIntegers = new HashMap<>();

public BstEntry(BibEntry e) {
this.entry = e;
}

public Map<String, String> getFields() {
return fields;
}

public BibEntry getBibtexEntry() {
return entry;
}
}

private void push(Integer integer) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.util.Objects;

import org.jabref.logic.preview.PreviewLayout;
import org.jabref.model.database.BibDatabaseContext;
import org.jabref.model.database.event.EntriesRemovedEvent;
import org.jabref.model.entry.BibEntry;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.jabref.logic.citationstyle;

import org.jabref.logic.preview.PreviewLayout;
import org.jabref.model.database.BibDatabase;
import org.jabref.model.entry.BibEntry;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
package org.jabref.logic.citationstyle;
package org.jabref.logic.layout;

import java.io.IOException;
import java.io.StringReader;

import org.jabref.logic.l10n.Localization;
import org.jabref.logic.layout.Layout;
import org.jabref.logic.layout.LayoutFormatterPreferences;
import org.jabref.logic.layout.LayoutHelper;
import org.jabref.logic.preview.PreviewLayout;
import org.jabref.model.database.BibDatabase;
import org.jabref.model.entry.BibEntry;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Implements the preview based JabRef's <a href="https://docs.jabref.org/import-export/export/customexports">Custom export fitlters</a>.
*/
public class TextBasedPreviewLayout implements PreviewLayout {
private static final Logger LOGGER = LoggerFactory.getLogger(TextBasedPreviewLayout.class);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,11 @@

/**
* Remove non printable character formatter.
*
* Based on the RemoveBrackets.java class (Revision 1.2) by mortenalver
*/
public class RemoveWhitespace implements LayoutFormatter {

@Override
public String format(String fieldEntry) {

if (fieldEntry == null) {
return null;
}
Expand Down
Loading