Skip to content

Commit aad6251

Browse files
committed
rework data keys/data holders for nullability of held value
1 parent 0ad5bc1 commit aad6251

File tree

256 files changed

+1225
-775
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

256 files changed

+1225
-775
lines changed

VERSION.md

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -162,11 +162,24 @@ Next
162162
-------
163163

164164
* Fix: add nullable annotations to `DataSet` and `DataKey` classes
165-
* Fix: add 3 argument constructor for `DataKey` which ensures `factory.apply` data holder is
166-
never null.
165+
* Break: `DataKey` now represents not null data values, use `NullableDataKey` if using nullable
166+
values, for processing of either type of data key, use `DataKeyBase` super class which does
167+
not specify nullability for the data value.
168+
* Break: `DataValueFactory` now has non-nullable dataHolder argument and nullable result. Use:
169+
* `DataNotNullValueFactory` for nullable result and non nullable dataHolder
170+
* `DataValueNullableFactory` for nullable result and nullable dataHolder
171+
* `DataNotNullValueNullableFactory` for non-nullable result and non-nullable dataHolder
172+
* Add: `DataKey` 3 argument constructor with pre-computed non null default value to be used for
173+
null dataHolder defaults. This way the factory is `DataNotNullValueFactory` which takes a
174+
non-null data holder and returns a computed value.
175+
* Add: `NullableDataKey` 3 argument constructor with pre-computed nullable default value to be
176+
used for null dataHolder defaults. This way the factory is `DataValueFactory` which
177+
takes a non-null data holder and returns a computed value.
167178
* Fix: add `DataKey.get(DataHolder)` to replace `DataKey.getFrom(DataHolder)`, shorter and
168-
compatible with Kotlin array access syntax.
179+
compatible with Kotlin array access syntax, also handles nullability of data.
169180
* Fix: deprecate `DataKey.getFrom()`
181+
* Fix: replace all `DataHolder.get()` by `DataKey.get()`
182+
* Fix: add nullability annotations to `Node` and a few other classes
170183

171184
0.59.30
172185
-------

flexmark-core-test/src/main/java/com/vladsch/flexmark/core/test/util/TranslationFormatterSpecTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,8 @@ static class TranslationFormatter implements IRender {
105105

106106
public TranslationFormatter(Formatter formatter) {
107107
myFormatter = formatter;
108-
myShowIntermediate = myFormatter.getOptions().get(DETAILS);
109-
myShowIntermediateAst = myFormatter.getOptions().get(AST_DETAILS);
108+
myShowIntermediate = DETAILS.get(myFormatter.getOptions());
109+
myShowIntermediateAst = AST_DETAILS.get(myFormatter.getOptions());
110110
}
111111

112112
public boolean isShowIntermediate() {

flexmark-core-test/src/test/java/com/vladsch/flexmark/core/test/util/formatter/FormatterModifiedAST.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public class FormatterModifiedAST {
2525
final static MutableDataSet FORMAT_OPTIONS = new MutableDataSet();
2626
static {
2727
// copy extensions from Pegdown compatible to Formatting
28-
FORMAT_OPTIONS.set(Parser.EXTENSIONS, OPTIONS.get(Parser.EXTENSIONS));
28+
FORMAT_OPTIONS.set(Parser.EXTENSIONS, Parser.EXTENSIONS.get(OPTIONS));
2929
}
3030

3131
final static Parser PARSER = Parser.builder(OPTIONS).build();

flexmark-docx-converter/src/main/java/com/vladsch/flexmark/docx/converter/DocxRenderer.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ public class DocxRenderer implements IRender {
140140

141141
public static final DataKey<String> DOC_EMOJI_ROOT_IMAGE_PATH = new DataKey<>("DOC_EMOJI_ROOT_IMAGE_PATH", EMOJI_RESOURCE_PREFIX, options -> {
142142
if (options.contains(EmojiExtension.ROOT_IMAGE_PATH)) {
143-
return options.get(EmojiExtension.ROOT_IMAGE_PATH);
143+
return EmojiExtension.ROOT_IMAGE_PATH.get(options);
144144
}
145145

146146
// kludge it to use our resources
@@ -298,7 +298,7 @@ public String render(@NotNull Node document) {
298298
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
299299
try {
300300
mlPackage.save(outputStream, Docx4J.FLAG_SAVE_FLAT_XML);
301-
String s = options.get(RENDER_BODY_ONLY) ? XmlFormatter.formatDocumentBody(outputStream.toString("UTF-8"))
301+
String s = RENDER_BODY_ONLY.get(options) ? XmlFormatter.formatDocumentBody(outputStream.toString("UTF-8"))
302302
: XmlDocxSorter.sortDocumentParts(outputStream.toString("UTF-8"));
303303
return s;
304304
} catch (Docx4JException e) {
@@ -367,7 +367,7 @@ protected boolean loadExtension(Extension extension) {
367367
return true;
368368
} else if (extension instanceof RendererExtension) {
369369
RendererExtension htmlRendererExtension = (RendererExtension) extension;
370-
htmlRendererExtension.extend(this, this.get(HtmlRenderer.TYPE));
370+
htmlRendererExtension.extend(this, HtmlRenderer.TYPE.get(this));
371371
return true;
372372
}
373373
return false;

flexmark-docx-converter/src/main/java/com/vladsch/flexmark/docx/converter/internal/CoreNodeDocxRenderer.java

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import com.vladsch.flexmark.util.data.DataHolder;
4141
import com.vladsch.flexmark.util.data.DataKey;
4242
import com.vladsch.flexmark.util.data.MutableScopedDataSet;
43+
import com.vladsch.flexmark.util.data.NullableDataKey;
4344
import com.vladsch.flexmark.util.format.options.ListSpacing;
4445
import com.vladsch.flexmark.util.html.Attribute;
4546
import com.vladsch.flexmark.util.html.Attributes;
@@ -76,7 +77,7 @@
7677
@SuppressWarnings({ "WeakerAccess", "MethodMayBeStatic", "OverlyCoupledClass" })
7778
public class CoreNodeDocxRenderer implements PhasedNodeDocxRenderer {
7879
public static final DataKey<Integer> LIST_ITEM_NUMBER = new DataKey<>("LIST_ITEM_NUMBER", 0);
79-
public static final DataKey<ListSpacing> LIST_ITEM_SPACING = new DataKey<>("LIST_ITEM_SPACING", (ListSpacing) null);
80+
public static final NullableDataKey<ListSpacing> LIST_ITEM_SPACING = new NullableDataKey<>("LIST_ITEM_SPACING");
8081
public static final HashSet<DocxRendererPhase> RENDERING_PHASES = new HashSet<>(Arrays.asList(
8182
DocxRendererPhase.COLLECT,
8283
DocxRendererPhase.DOCUMENT_TOP,
@@ -97,6 +98,7 @@ public class CoreNodeDocxRenderer implements PhasedNodeDocxRenderer {
9798
protected final int tableLeftIndent;
9899
protected final String tableStyle;
99100
private int imageId;
101+
@SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
100102
private final HashMap<Node, BigInteger> footnoteIDs; // cannot re-use footnote ids, so this is dead code, left in for future if needed
101103
private TocBlockBase lastTocBlock;
102104
private long[] numberedLists = new long[128];
@@ -211,7 +213,7 @@ public Set<Class<?>> getBookmarkWrapsChildrenClasses() {
211213
}
212214

213215
public ReferenceRepository getRepository(DataHolder options) {
214-
return options.get(Parser.REFERENCES);
216+
return Parser.REFERENCES.get(options);
215217
}
216218

217219
@Override
@@ -670,7 +672,6 @@ private void renderListItem(ListItem node, DocxRendererContext docx) {
670672
}
671673
} else if (node.getParent() instanceof BulletList) {
672674
if (node == node.getParent().getFirstChild()) {
673-
idNum = numId;
674675
ensureBulletListLength(listLevel);
675676
bulletLists[listLevel] = idNum;
676677
} else {
@@ -697,20 +698,20 @@ private void render(HtmlBlock node, DocxRendererContext docx) {
697698
// inner blocks handle rendering
698699
docx.renderChildren(node);
699700
} else {
700-
renderHtmlBlock(node, docx, docx.getDocxRendererOptions().suppressHtmlBlocks, true || docx.getDocxRendererOptions().escapeHtmlBlocks);
701+
renderHtmlBlock(node, docx, docx.getDocxRendererOptions().suppressHtmlBlocks, true /*|| docx.getDocxRendererOptions().escapeHtmlBlocks*/);
701702
}
702703
}
703704

704705
private void render(HtmlCommentBlock node, DocxRendererContext docx) {
705-
renderHtmlBlock(node, docx, docx.getDocxRendererOptions().suppressHtmlCommentBlocks, true || docx.getDocxRendererOptions().escapeHtmlCommentBlocks);
706+
renderHtmlBlock(node, docx, docx.getDocxRendererOptions().suppressHtmlCommentBlocks, true /*|| docx.getDocxRendererOptions().escapeHtmlCommentBlocks*/);
706707
}
707708

708709
private void render(HtmlInnerBlock node, DocxRendererContext docx) {
709-
renderHtmlBlock(node, docx, docx.getDocxRendererOptions().suppressHtmlBlocks, true || docx.getDocxRendererOptions().escapeHtmlBlocks);
710+
renderHtmlBlock(node, docx, docx.getDocxRendererOptions().suppressHtmlBlocks, true /*|| docx.getDocxRendererOptions().escapeHtmlBlocks*/);
710711
}
711712

712713
private void render(HtmlInnerBlockComment node, DocxRendererContext docx) {
713-
renderHtmlBlock(node, docx, docx.getDocxRendererOptions().suppressHtmlCommentBlocks, true || docx.getDocxRendererOptions().escapeHtmlCommentBlocks);
714+
renderHtmlBlock(node, docx, docx.getDocxRendererOptions().suppressHtmlCommentBlocks, true /*|| docx.getDocxRendererOptions().escapeHtmlCommentBlocks*/);
714715
}
715716

716717
public void renderHtmlBlock(HtmlBlockBase node, DocxRendererContext docx, boolean suppress, boolean escape) {
@@ -748,14 +749,14 @@ private void render(HtmlInline node, DocxRendererContext docx) {
748749
//if (docx.getDocxRendererOptions().sourceWrapInlineHtml) {
749750
// html.srcPos(node.getChars()).withAttr(AttributablePart.NODE_POSITION).tag("span");
750751
//}
751-
renderInlineHtml(node, docx, docx.getDocxRendererOptions().suppressInlineHtml, true || docx.getDocxRendererOptions().escapeInlineHtml);
752+
renderInlineHtml(node, docx, docx.getDocxRendererOptions().suppressInlineHtml, true /*|| docx.getDocxRendererOptions().escapeInlineHtml*/);
752753
//if (docx.getDocxRendererOptions().sourceWrapInlineHtml) {
753754
// html.tag("/span");
754755
//}
755756
}
756757

757758
private void render(HtmlInlineComment node, DocxRendererContext docx) {
758-
renderInlineHtml(node, docx, docx.getDocxRendererOptions().suppressInlineHtmlComments, true || docx.getDocxRendererOptions().escapeInlineHtmlComments);
759+
renderInlineHtml(node, docx, docx.getDocxRendererOptions().suppressInlineHtmlComments, true /*|| docx.getDocxRendererOptions().escapeInlineHtmlComments*/);
759760
}
760761

761762
public void renderInlineHtml(HtmlInlineBase node, DocxRendererContext docx, boolean suppress, boolean escape) {
@@ -1714,7 +1715,7 @@ public void render(int referenceOrdinal, EnumeratedReferenceBlock referenceForma
17141715
} else {
17151716
if (compoundRunnable != null) {
17161717
docx.text(defaultText + " ");
1717-
if (compoundRunnable != null) compoundRunnable.run();
1718+
compoundRunnable.run();
17181719
docx.text(referenceOrdinal + (needSeparator ? "." : ""));
17191720
} else {
17201721
docx.text(defaultText + " " + referenceOrdinal + (needSeparator ? "." : ""));

flexmark-docx-converter/src/main/java/com/vladsch/flexmark/docx/converter/util/AttributeFormat.java

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,20 @@
22

33
import com.vladsch.flexmark.util.Utils;
44
import org.docx4j.wml.*;
5+
import org.jetbrains.annotations.NotNull;
6+
import org.jetbrains.annotations.Nullable;
57

68
import java.math.BigInteger;
79

810
public class AttributeFormat {
9-
final public String fontFamily;
10-
final public String fontSize;
11-
final public Boolean fontBold;
12-
final public Boolean fontItalic;
13-
final public String textColor;
14-
final public String fillColor;
15-
16-
public AttributeFormat(String fontFamily, String fontSize, String fontWeight, String fontStyle, String textColor, String fillColor) {
11+
final public @Nullable String fontFamily;
12+
final public @Nullable String fontSize;
13+
final public @Nullable Boolean fontBold;
14+
final public @Nullable Boolean fontItalic;
15+
final public @Nullable String textColor;
16+
final public @Nullable String fillColor;
17+
18+
public AttributeFormat(@Nullable String fontFamily, @Nullable String fontSize, @Nullable String fontWeight, @Nullable String fontStyle, @Nullable String textColor, @Nullable String fillColor) {
1719
this.fontFamily = getValidFontFamily(trimEmptyToNull(fontFamily));
1820
this.fontSize = getValidFontSize(trimEmptyToNull(fontSize));
1921
this.fontBold = getValidFontBold(trimEmptyToNull(fontWeight));
@@ -22,7 +24,8 @@ public AttributeFormat(String fontFamily, String fontSize, String fontWeight, St
2224
this.fillColor = getValidNamedOrHexColor(trimEmptyToNull(fillColor));
2325
}
2426

25-
private static String trimEmptyToNull(String textColor) {
27+
@Nullable
28+
private static String trimEmptyToNull(@Nullable String textColor) {
2629
if (textColor == null) return null;
2730

2831
String trimmed = textColor.trim();
@@ -39,27 +42,30 @@ public boolean isEmpty() {
3942
fillColor == null;
4043
}
4144

42-
String getValidHexColor(String s) {
45+
@Nullable String getValidHexColor(@Nullable String s) {
4346
if (s == null) return null;
4447

4548
return ColorNameMapper.getValidHexColor(s);
4649
}
4750

48-
String getValidNamedOrHexColor(String s) {
51+
@Nullable String getValidNamedOrHexColor(@Nullable String s) {
4952
if (s == null) return null;
5053

5154
return ColorNameMapper.getValidNamedOrHexColor(s);
5255
}
5356

54-
private String getValidFontFamily(String fontFamily) {
57+
@Nullable
58+
private String getValidFontFamily(@Nullable String fontFamily) {
5559
return fontFamily == null || fontFamily.isEmpty() ? null : fontFamily;
5660
}
5761

58-
private String getValidFontSize(String fontSize) {
62+
@Nullable
63+
private String getValidFontSize(@Nullable String fontSize) {
5964
return fontSize == null || fontSize.isEmpty() ? null : fontSize;
6065
}
6166

62-
private Boolean getValidFontBold(String s) {
67+
@Nullable
68+
private Boolean getValidFontBold(@Nullable String s) {
6369
if (s == null) return null;
6470

6571
switch (s) {
@@ -80,7 +86,8 @@ private Boolean getValidFontBold(String s) {
8086
return null;
8187
}
8288

83-
private Boolean getValidFontItalic(String s) {
89+
@Nullable
90+
private Boolean getValidFontItalic(@Nullable String s) {
8491
if (s == null) return null;
8592

8693
switch (s) {
@@ -102,19 +109,20 @@ private Boolean getValidFontItalic(String s) {
102109
return null;
103110
}
104111

105-
public <T> CTShd getShd(DocxContext<T> docx) {
112+
@NotNull
113+
public <T> CTShd getShd(@NotNull DocxContext<T> docx) {
106114
CTShd shd = docx.getFactory().createCTShd();
107115
shd.setColor("auto");
108116
shd.setFill(fillColor);
109117
shd.setVal(STShd.CLEAR);
110118
return shd;
111119
}
112120

113-
public <T> void setFormatRPr(RPrAbstract rPr, DocxContext<T> docx) {
121+
public <T> void setFormatRPr(@NotNull RPrAbstract rPr, @NotNull DocxContext<T> docx) {
114122
if (textColor != null) {
115123
Color color = docx.getFactory().createColor();
116124
rPr.setColor(color);
117-
color.setVal(ColorNameMapper.getValidHexColor(textColor).toUpperCase());
125+
color.setVal(ColorNameMapper.getValidHexColorOrDefault(textColor, "000000").toUpperCase());
118126

119127
rPr.setColor(color);
120128
}

flexmark-docx-converter/src/main/java/com/vladsch/flexmark/docx/converter/util/ColorNameMapper.java

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package com.vladsch.flexmark.docx.converter.util;
22

3+
import org.jetbrains.annotations.NotNull;
4+
import org.jetbrains.annotations.Nullable;
5+
36
import java.awt.Color;
47
import java.util.HashMap;
58
import java.util.Map;
@@ -35,7 +38,7 @@ public class ColorNameMapper {
3538
* @param c2 color 2
3639
* @return distance between two colors
3740
*/
38-
public static double colorDistance(Color c1, Color c2) {
41+
public static double colorDistance(@NotNull Color c1, @NotNull Color c2) {
3942
int red1 = c1.getRed();
4043
int red2 = c2.getRed();
4144
int rmean = (red1 + red2) >> 1;
@@ -45,37 +48,46 @@ public static double colorDistance(Color c1, Color c2) {
4548
return Math.sqrt((((512 + rmean) * r * r) >> 8) + 4 * g * g + (((767 - rmean) * b * b) >> 8));
4649
}
4750

48-
public static String colorToString(Color color) {
51+
public static String colorToString(@NotNull Color color) {
4952
int r = color.getRed();
5053
int g = color.getGreen();
5154
int b = color.getBlue();
5255

5356
return String.format("%02x%02x%02x", r, g, b);
5457
}
5558

56-
public static Color colorFromString(String color) {
59+
@NotNull
60+
public static Color colorFromString(@NotNull String color) {
5761
return new Color(
5862
Integer.valueOf(color.substring(0, 2), 16),
5963
Integer.valueOf(color.substring(2, 4), 16),
6064
Integer.valueOf(color.substring(4, 6), 16));
6165
}
6266

63-
public static boolean isHexColor(String color) {
67+
public static boolean isHexColor(@NotNull String color) {
6468
return color.matches(hexPattern);
6569
}
6670

67-
public static boolean isNamedColor(String color) {
71+
public static boolean isNamedColor(@NotNull String color) {
6872
return colors.containsKey(color);
6973
}
7074

71-
public static String getValidNamedOrHexColor(String s) {
75+
@Nullable
76+
public static String getValidNamedOrHexColor(@NotNull String s) {
7277
if (ColorNameMapper.isNamedColor(s) || ColorNameMapper.isHexColor(s)) {
7378
return s;
7479
}
7580
return null;
7681
}
7782

78-
public static String getValidHexColor(String s) {
83+
@NotNull
84+
public static String getValidHexColorOrDefault(@NotNull String s, @NotNull String defaultValue) {
85+
String hexColor = getValidHexColor(s);
86+
return hexColor != null ? hexColor : defaultValue;
87+
}
88+
89+
@Nullable
90+
public static String getValidHexColor(@NotNull String s) {
7991
if (ColorNameMapper.isNamedColor(s)) {
8092
return colorToString(colors.get(s));
8193
} else if (ColorNameMapper.isHexColor(s)) {
@@ -84,7 +96,8 @@ public static String getValidHexColor(String s) {
8496
return null;
8597
}
8698

87-
public static String findClosestNamedColor(Color color) {
99+
@NotNull
100+
public static String findClosestNamedColor(@NotNull Color color) {
88101
String colorName = "black";
89102
double minDistance = Double.MAX_VALUE;
90103

@@ -98,7 +111,8 @@ public static String findClosestNamedColor(Color color) {
98111
return colorName;
99112
}
100113

101-
public static String findClosestNamedColor(String color) {
114+
@NotNull
115+
public static String findClosestNamedColor(@NotNull String color) {
102116
return findClosestNamedColor(colorFromString(color));
103117
}
104118
}

flexmark-ext-abbreviation/src/main/java/com/vladsch/flexmark/ext/abbreviation/Abbreviation.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.vladsch.flexmark.ext.abbreviation.internal.AbbreviationRepository;
44
import com.vladsch.flexmark.util.ast.*;
55
import com.vladsch.flexmark.util.sequence.BasedSequence;
6+
import org.jetbrains.annotations.NotNull;
67

78
/**
89
* A node containing the abbreviated text that will be rendered as an abbr tag or a link with title attribute
@@ -19,6 +20,7 @@ public BasedSequence getAbbreviation() {
1920
return abbreviation;
2021
}
2122

23+
@NotNull
2224
@Override
2325
public BasedSequence[] getSegments() {
2426
return EMPTY_SEGMENTS;

flexmark-ext-abbreviation/src/main/java/com/vladsch/flexmark/ext/abbreviation/AbbreviationBlock.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import com.vladsch.flexmark.util.ast.Node;
66
import com.vladsch.flexmark.util.ast.ReferenceNode;
77
import com.vladsch.flexmark.util.sequence.BasedSequence;
8+
import org.jetbrains.annotations.NotNull;
89

910
/**
1011
* A block node that contains the abbreviation definition
@@ -33,6 +34,7 @@ public void getAstExtra(StringBuilder out) {
3334
segmentSpan(out, abbreviation, "abbreviation");
3435
}
3536

37+
@NotNull
3638
@Override
3739
public BasedSequence[] getSegments() {
3840
return new BasedSequence[] { openingMarker, text, closingMarker, abbreviation };

0 commit comments

Comments
 (0)