mirror of https://github.com/weisJ/darklaf.git
weisj
4 years ago
22 changed files with 1442 additions and 3 deletions
@ -0,0 +1,38 @@
|
||||
/* |
||||
* MIT License |
||||
* |
||||
* Copyright (c) 2020 Jannis Weis |
||||
* |
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and |
||||
* associated documentation files (the "Software"), to deal in the Software without restriction, |
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute, |
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is |
||||
* furnished to do so, subject to the following conditions: |
||||
* |
||||
* The above copyright notice and this permission notice shall be included in all copies or |
||||
* substantial portions of the Software. |
||||
* |
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT |
||||
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||||
* |
||||
*/ |
||||
package com.github.weisj.darklaf.parser; |
||||
|
||||
import javax.swing.UIDefaults; |
||||
|
||||
public class ActiveObjectParser extends KeyFilteredParser { |
||||
|
||||
public ActiveObjectParser() { |
||||
super("Component", ".component"); |
||||
} |
||||
|
||||
@Override |
||||
public ParseResult doParse(final ParseResult parseResult, final ParserContext context) { |
||||
return ParserUtil.setNonNull(parseResult, |
||||
(UIDefaults.ActiveValue) (def) -> ParserUtil.createObject(parseResult.value)); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,38 @@
|
||||
/* |
||||
* MIT License |
||||
* |
||||
* Copyright (c) 2020 Jannis Weis |
||||
* |
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and |
||||
* associated documentation files (the "Software"), to deal in the Software without restriction, |
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute, |
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is |
||||
* furnished to do so, subject to the following conditions: |
||||
* |
||||
* The above copyright notice and this permission notice shall be included in all copies or |
||||
* substantial portions of the Software. |
||||
* |
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT |
||||
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||||
* |
||||
*/ |
||||
package com.github.weisj.darklaf.parser; |
||||
|
||||
public interface Delimiters { |
||||
char LIST_START = '['; |
||||
char LIST_END = ']'; |
||||
char LIST_SEPARATOR = ','; |
||||
|
||||
char MAP_START = '{'; |
||||
char MAP_END = '}'; |
||||
char MAP_SEPARATOR = ','; |
||||
|
||||
char ARG_START = '('; |
||||
char ARG_END = ')'; |
||||
char ARG_SEPARATOR = ','; |
||||
|
||||
char PAIR_SEPARATOR = ':'; |
||||
} |
@ -0,0 +1,41 @@
|
||||
/* |
||||
* MIT License |
||||
* |
||||
* Copyright (c) 2020 Jannis Weis |
||||
* |
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and |
||||
* associated documentation files (the "Software"), to deal in the Software without restriction, |
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute, |
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is |
||||
* furnished to do so, subject to the following conditions: |
||||
* |
||||
* The above copyright notice and this permission notice shall be included in all copies or |
||||
* substantial portions of the Software. |
||||
* |
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT |
||||
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||||
* |
||||
*/ |
||||
package com.github.weisj.darklaf.parser; |
||||
|
||||
import java.util.List; |
||||
|
||||
import javax.swing.plaf.DimensionUIResource; |
||||
|
||||
public class DimensionParser extends KeyFilteredParser implements Delimiters { |
||||
|
||||
public DimensionParser() { |
||||
super("Size", ".size"); |
||||
} |
||||
|
||||
@Override |
||||
public ParseResult doParse(final ParseResult parseResult, final ParserContext context) { |
||||
List<Integer> dimensions = ParserUtil.parseDelimited(ARG_SEPARATOR, Integer.class, parseResult, context); |
||||
if (dimensions.size() != 2) return ParserUtil.error(parseResult, "Invalid dimension."); |
||||
return ParserUtil.setNonNull(parseResult, |
||||
new DimensionUIResource(dimensions.get(0), dimensions.get(1))); |
||||
} |
||||
} |
@ -0,0 +1,41 @@
|
||||
/* |
||||
* MIT License |
||||
* |
||||
* Copyright (c) 2020 Jannis Weis |
||||
* |
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and |
||||
* associated documentation files (the "Software"), to deal in the Software without restriction, |
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute, |
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is |
||||
* furnished to do so, subject to the following conditions: |
||||
* |
||||
* The above copyright notice and this permission notice shall be included in all copies or |
||||
* substantial portions of the Software. |
||||
* |
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT |
||||
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||||
* |
||||
*/ |
||||
package com.github.weisj.darklaf.parser; |
||||
|
||||
public class FallbackParser implements PropertyParser { |
||||
|
||||
private static final String FALLBACK_PREFIX = "?:"; |
||||
|
||||
@Override |
||||
public ParseResult doParse(final ParseResult parseResult, final ParserContext context) { |
||||
boolean isFallback = ParserUtil.stripPrefixFromValue(parseResult, FALLBACK_PREFIX); |
||||
if (isFallback) { |
||||
ParserUtil.replaceIfNull(parseResult, parseResult.key, context.accumulator); |
||||
ParserUtil.replaceIfNull(parseResult, parseResult.key, context.defaults); |
||||
if (!parseResult.finished) { |
||||
// Not found. Calculate fallback value.
|
||||
return Parser.parse(parseResult, context); |
||||
} |
||||
} |
||||
return parseResult; |
||||
} |
||||
} |
@ -0,0 +1,101 @@
|
||||
/* |
||||
* MIT License |
||||
* |
||||
* Copyright (c) 2020 Jannis Weis |
||||
* |
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and |
||||
* associated documentation files (the "Software"), to deal in the Software without restriction, |
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute, |
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is |
||||
* furnished to do so, subject to the following conditions: |
||||
* |
||||
* The above copyright notice and this permission notice shall be included in all copies or |
||||
* substantial portions of the Software. |
||||
* |
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT |
||||
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||||
* |
||||
*/ |
||||
package com.github.weisj.darklaf.parser; |
||||
|
||||
import java.awt.Font; |
||||
import java.text.AttributedCharacterIterator; |
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
import com.github.weisj.darklaf.uiresource.DarkFontUIResource; |
||||
import com.github.weisj.darklaf.util.FontUtil; |
||||
|
||||
public class FontParser extends KeyFilteredParser implements Delimiters { |
||||
|
||||
private static final Map<AttributedCharacterIterator.Attribute, Integer> attributes = Collections.emptyMap(); |
||||
|
||||
private static final String BASE_FONT = "font"; |
||||
private static final String FONT_FROM = "from"; |
||||
private static final String FONT_SIZE = "withSize"; |
||||
private static final String FONT_STYLE = "withStyle"; |
||||
private static final char FONT_DELIMITER = '-'; |
||||
|
||||
public FontParser() { |
||||
super("font"); |
||||
} |
||||
|
||||
@Override |
||||
public ParseResult doParse(final ParseResult parseResult, final ParserContext context) { |
||||
Font base = null; |
||||
int size = -1; |
||||
int style = -1; |
||||
while (!parseResult.value.isEmpty()) { |
||||
int length = parseResult.value.length(); |
||||
if (ParserUtil.stripPrefixFromValue(parseResult, BASE_FONT)) { |
||||
if (base != null) ParserUtil.warning("Duplicate Base font declared: '" + parseResult.value + "'"); |
||||
base = ParserUtil |
||||
.parseBetween(ARG_START, ARG_END, this::parseBaseFont, Font.class, parseResult, context) |
||||
.orElse(base); |
||||
} else if (ParserUtil.stripPrefixFromValue(parseResult, FONT_FROM)) { |
||||
if (base != null) ParserUtil.warning("Duplicate Base font declared: '" + parseResult.value + "'"); |
||||
base = ParserUtil.parseBetween(ARG_START, ARG_END, Font.class, parseResult, context) |
||||
.orElse(base); |
||||
} else if (ParserUtil.stripPrefixFromValue(parseResult, FONT_STYLE)) { |
||||
if (style >= 0) ParserUtil.warning("Duplicate font style declared: '" + parseResult.value + "'"); |
||||
style = ParserUtil.parseBetween(ARG_START, ARG_END, Integer.class, parseResult, context) |
||||
.orElse(style); |
||||
} else if (ParserUtil.stripPrefixFromValue(parseResult, FONT_SIZE)) { |
||||
if (size >= 0) ParserUtil.warning("Duplicate font size declared: '" + parseResult.value + "'"); |
||||
size = ParserUtil.parseDelimited(ARG_START, ARG_END, ARG_SEPARATOR, Integer.class, parseResult, context) |
||||
.stream().reduce(Integer::sum).orElse(size); |
||||
} |
||||
if (parseResult.value.length() == length) { |
||||
// Did not make any progress. Bail
|
||||
return ParserUtil.error(parseResult, "Unexpected token while parsing font"); |
||||
} |
||||
} |
||||
if (base == null) base = FontUtil.createFont(null, Font.PLAIN, 12); |
||||
if (size <= 0) size = base.getSize(); |
||||
if (style < 0) style = base.getStyle(); |
||||
|
||||
// noinspection MagicConstant
|
||||
Font font = base.deriveFont(style, size); |
||||
return ParserUtil.setNonNull(parseResult, new DarkFontUIResource(font.deriveFont(attributes))); |
||||
} |
||||
|
||||
private ParseResult parseBaseFont(final ParseResult parseResult, final ParserContext context) { |
||||
List<Object> parts = ParserUtil.parseDelimited(FONT_DELIMITER, Object.class, |
||||
Parser.createParseResult("", parseResult.value), context); |
||||
if (parts.size() != 3) return fontStructureError(parseResult); |
||||
if (!(parts.get(0) instanceof String)) return fontStructureError(parseResult); |
||||
if (!(parts.get(1) instanceof Integer)) return fontStructureError(parseResult); |
||||
if (!(parts.get(2) instanceof Integer)) return fontStructureError(parseResult); |
||||
return ParserUtil.setNonNull(parseResult, |
||||
FontUtil.createFont((String) parts.get(0), (Integer) parts.get(1), (Integer) parts.get((2)))); |
||||
} |
||||
|
||||
private ParseResult fontStructureError(final ParseResult parseResult) { |
||||
return ParserUtil.error(parseResult, |
||||
"Expected structure FontName-FontStyle-FontStyle but got '" + parseResult.value + "'"); |
||||
} |
||||
} |
@ -0,0 +1,102 @@
|
||||
/* |
||||
* MIT License |
||||
* |
||||
* Copyright (c) 2020 Jannis Weis |
||||
* |
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and |
||||
* associated documentation files (the "Software"), to deal in the Software without restriction, |
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute, |
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is |
||||
* furnished to do so, subject to the following conditions: |
||||
* |
||||
* The above copyright notice and this permission notice shall be included in all copies or |
||||
* substantial portions of the Software. |
||||
* |
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT |
||||
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||||
* |
||||
*/ |
||||
package com.github.weisj.darklaf.parser; |
||||
|
||||
import java.awt.Dimension; |
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
|
||||
import javax.swing.Icon; |
||||
|
||||
import com.github.weisj.darklaf.icons.DarkUIAwareIcon; |
||||
import com.github.weisj.darklaf.icons.EmptyIcon; |
||||
import com.github.weisj.darklaf.icons.StateIcon; |
||||
|
||||
public class IconParser extends KeyFilteredParser implements Delimiters { |
||||
|
||||
private static final char MODIFIER_START = '['; |
||||
private static final char MODIFIER_END = ']'; |
||||
private static final char MODIFIER_DELIMITER = ','; |
||||
|
||||
private static final String DUAL_KEY = "dual"; |
||||
private static final String AWARE_KEY = "aware"; |
||||
private static final String THEMED_KEY = "themed"; |
||||
private static final String ICON_EMPTY = "empty"; |
||||
|
||||
public IconParser() { |
||||
super(".icon", "Icon", "Image"); |
||||
} |
||||
|
||||
@Override |
||||
public ParseResult doParse(final ParseResult parseResult, final ParserContext context) { |
||||
if (parseResult.value.startsWith(String.valueOf(LIST_START)) |
||||
&& parseResult.value.endsWith(String.valueOf(LIST_END))) { |
||||
return parseStateIcon(parseResult, context); |
||||
} |
||||
Dimension dim = new Dimension(16, 16); |
||||
if (parseResult.value.endsWith(String.valueOf(ARG_END))) { |
||||
List<Integer> dimensions = ParserUtil.parseDelimited(ARG_START, ARG_END, ARG_SEPARATOR, false, |
||||
PropertyParser.of(Integer::parseInt), Integer.class, parseResult, context); |
||||
if (dimensions.size() != 2) return ParserUtil.error(parseResult, "Invalid dimension."); |
||||
dim.width = dimensions.get(0); |
||||
dim.height = dimensions.get(1); |
||||
} |
||||
|
||||
List<String> modifiers; |
||||
if (parseResult.value.endsWith(String.valueOf(MODIFIER_END))) { |
||||
modifiers = ParserUtil.parseDelimited(MODIFIER_START, MODIFIER_END, MODIFIER_DELIMITER, false, |
||||
PropertyParser.of(s -> s), String.class, parseResult, context); |
||||
|
||||
} else { |
||||
modifiers = Collections.emptyList(); |
||||
} |
||||
boolean dual = modifiers.contains(DUAL_KEY); |
||||
boolean aware = modifiers.contains(AWARE_KEY); |
||||
boolean themed = modifiers.contains(THEMED_KEY); |
||||
if (aware && themed) { |
||||
return ParserUtil.error(parseResult, |
||||
"Modifiers " + AWARE_KEY + " and " + THEMED_KEY + " are mutually exclusive."); |
||||
} |
||||
Icon icon; |
||||
if (ICON_EMPTY.equals(parseResult.value)) { |
||||
icon = EmptyIcon.create(dim.width, dim.height); |
||||
} else if (themed) { |
||||
icon = context.iconLoader.getIcon(parseResult.value, dim.width, dim.height, true); |
||||
} else if (dual || aware) { |
||||
DarkUIAwareIcon awareIcon = context.iconLoader.getUIAwareIcon(parseResult.value, dim.width, dim.height); |
||||
if (dual) { |
||||
icon = awareIcon.getDual(); |
||||
} else { |
||||
icon = awareIcon; |
||||
} |
||||
} else { |
||||
icon = context.iconLoader.getIcon(parseResult.value, dim.width, dim.height); |
||||
} |
||||
return ParserUtil.setNonNull(parseResult, icon); |
||||
} |
||||
|
||||
private static ParseResult parseStateIcon(final ParseResult parseResult, final ParserContext context) { |
||||
return ParserUtil.setNonNull(parseResult, |
||||
new StateIcon(ParserUtil.parseDelimited(LIST_START, LIST_END, LIST_SEPARATOR, |
||||
Icon.class, parseResult, context))); |
||||
} |
||||
} |
@ -0,0 +1,43 @@
|
||||
/* |
||||
* MIT License |
||||
* |
||||
* Copyright (c) 2020 Jannis Weis |
||||
* |
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and |
||||
* associated documentation files (the "Software"), to deal in the Software without restriction, |
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute, |
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is |
||||
* furnished to do so, subject to the following conditions: |
||||
* |
||||
* The above copyright notice and this permission notice shall be included in all copies or |
||||
* substantial portions of the Software. |
||||
* |
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT |
||||
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||||
* |
||||
*/ |
||||
package com.github.weisj.darklaf.parser; |
||||
|
||||
import java.util.List; |
||||
|
||||
import javax.swing.plaf.InsetsUIResource; |
||||
|
||||
public class InsetParser extends KeyFilteredParser implements Delimiters { |
||||
|
||||
public InsetParser() { |
||||
super("Insets", ".insets", ".margins"); |
||||
} |
||||
|
||||
@Override |
||||
public ParseResult doParse(final ParseResult parseResult, final ParserContext context) { |
||||
List<Integer> insetsValues = ParserUtil.parseDelimited(ARG_SEPARATOR, Integer.class, parseResult, context); |
||||
if (insetsValues.size() != 4) { |
||||
return ParserUtil.error(parseResult, "Expected 4 arguments but got " + insetsValues.size()); |
||||
} |
||||
return ParserUtil.setNonNull(parseResult, new InsetsUIResource( |
||||
insetsValues.get(0), insetsValues.get(1), insetsValues.get(2), insetsValues.get(3))); |
||||
} |
||||
} |
@ -0,0 +1,37 @@
|
||||
/* |
||||
* MIT License |
||||
* |
||||
* Copyright (c) 2020 Jannis Weis |
||||
* |
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and |
||||
* associated documentation files (the "Software"), to deal in the Software without restriction, |
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute, |
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is |
||||
* furnished to do so, subject to the following conditions: |
||||
* |
||||
* The above copyright notice and this permission notice shall be included in all copies or |
||||
* substantial portions of the Software. |
||||
* |
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT |
||||
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||||
* |
||||
*/ |
||||
package com.github.weisj.darklaf.parser; |
||||
|
||||
class JoinedParser implements PropertyParser { |
||||
private final PropertyParser first; |
||||
private final PropertyParser second; |
||||
|
||||
JoinedParser(final PropertyParser first, final PropertyParser second) { |
||||
this.first = first; |
||||
this.second = second; |
||||
} |
||||
|
||||
@Override |
||||
public ParseResult doParse(final ParseResult parseResult, final ParserContext context) { |
||||
return ParserUtil.apply(second, ParserUtil.apply(first, parseResult, context), context); |
||||
} |
||||
} |
@ -0,0 +1,38 @@
|
||||
/* |
||||
* MIT License |
||||
* |
||||
* Copyright (c) 2020 Jannis Weis |
||||
* |
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and |
||||
* associated documentation files (the "Software"), to deal in the Software without restriction, |
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute, |
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is |
||||
* furnished to do so, subject to the following conditions: |
||||
* |
||||
* The above copyright notice and this permission notice shall be included in all copies or |
||||
* substantial portions of the Software. |
||||
* |
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT |
||||
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||||
* |
||||
*/ |
||||
package com.github.weisj.darklaf.parser; |
||||
|
||||
import java.util.Arrays; |
||||
|
||||
public abstract class KeyFilteredParser implements PropertyParser { |
||||
|
||||
private final String[] suffixes; |
||||
|
||||
public KeyFilteredParser(final String... suffixes) { |
||||
this.suffixes = suffixes; |
||||
} |
||||
|
||||
@Override |
||||
public boolean filter(final ParseResult parseResult, final ParserContext context) { |
||||
return Arrays.stream(suffixes).anyMatch(it -> parseResult.key.endsWith(it)); |
||||
} |
||||
} |
@ -0,0 +1,37 @@
|
||||
/* |
||||
* MIT License |
||||
* |
||||
* Copyright (c) 2020 Jannis Weis |
||||
* |
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and |
||||
* associated documentation files (the "Software"), to deal in the Software without restriction, |
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute, |
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is |
||||
* furnished to do so, subject to the following conditions: |
||||
* |
||||
* The above copyright notice and this permission notice shall be included in all copies or |
||||
* substantial portions of the Software. |
||||
* |
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT |
||||
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||||
* |
||||
*/ |
||||
package com.github.weisj.darklaf.parser; |
||||
|
||||
import javax.swing.UIDefaults; |
||||
|
||||
public class LazyObjectParser extends KeyFilteredParser { |
||||
|
||||
public LazyObjectParser() { |
||||
super("Border", ".border", "Renderer"); |
||||
} |
||||
|
||||
@Override |
||||
public ParseResult doParse(final ParseResult parseResult, final ParserContext context) { |
||||
return ParserUtil.setNonNull(parseResult, |
||||
(UIDefaults.LazyValue) def -> ParserUtil.createObject(parseResult.value)); |
||||
} |
||||
} |
@ -0,0 +1,34 @@
|
||||
/* |
||||
* MIT License |
||||
* |
||||
* Copyright (c) 2020 Jannis Weis |
||||
* |
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and |
||||
* associated documentation files (the "Software"), to deal in the Software without restriction, |
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute, |
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is |
||||
* furnished to do so, subject to the following conditions: |
||||
* |
||||
* The above copyright notice and this permission notice shall be included in all copies or |
||||
* substantial portions of the Software. |
||||
* |
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT |
||||
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||||
* |
||||
*/ |
||||
package com.github.weisj.darklaf.parser; |
||||
|
||||
public class ListParser implements PropertyParser, Delimiters { |
||||
@Override |
||||
public ParseResult doParse(final ParseResult parseResult, final ParserContext context) { |
||||
if (parseResult.value.startsWith(String.valueOf(LIST_START))) { |
||||
return ParserUtil.setNonNull(parseResult, |
||||
ParserUtil.parseDelimited(LIST_START, LIST_END, LIST_SEPARATOR, Object.class, parseResult, |
||||
context)); |
||||
} |
||||
return parseResult; |
||||
} |
||||
} |
@ -0,0 +1,54 @@
|
||||
/* |
||||
* MIT License |
||||
* |
||||
* Copyright (c) 2020 Jannis Weis |
||||
* |
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and |
||||
* associated documentation files (the "Software"), to deal in the Software without restriction, |
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute, |
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is |
||||
* furnished to do so, subject to the following conditions: |
||||
* |
||||
* The above copyright notice and this permission notice shall be included in all copies or |
||||
* substantial portions of the Software. |
||||
* |
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT |
||||
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||||
* |
||||
*/ |
||||
package com.github.weisj.darklaf.parser; |
||||
|
||||
import java.util.List; |
||||
import java.util.stream.Collectors; |
||||
|
||||
import com.github.weisj.darklaf.util.Pair; |
||||
|
||||
public class MapParser implements PropertyParser, Delimiters { |
||||
|
||||
private final PropertyParser pairParser = (parsable, context) -> { |
||||
if (parsable.value.contains(String.valueOf(PAIR_SEPARATOR))) { |
||||
List<Object> components = ParserUtil.parseDelimited(PAIR_SEPARATOR, Object.class, parsable, context); |
||||
if (components.size() != 2) return ParserUtil.error(parsable, "Expected 2 components"); |
||||
return ParserUtil.setNonNull(parsable, new Pair<>(components.get(0), components.get(1))); |
||||
} else { |
||||
return ParserUtil.setNonNull(parsable, |
||||
new Pair<>(Parser.parse(parsable, context).result, Parser.EMPTY_VALUE)); |
||||
} |
||||
}; |
||||
|
||||
@Override |
||||
public ParseResult doParse(final ParseResult parseResult, final ParserContext context) { |
||||
if (parseResult.value.startsWith(String.valueOf(MAP_START)) |
||||
&& parseResult.value.endsWith(String.valueOf(MAP_END))) { |
||||
return ParserUtil.setNonNull(parseResult, |
||||
ParserUtil.parseDelimited(MAP_START, MAP_END, MAP_SEPARATOR, pairParser, |
||||
Pair.class, parseResult, context).stream() |
||||
.collect(Collectors.toMap(Pair::getFirst, Pair::getSecond))); |
||||
} |
||||
return parseResult; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,35 @@
|
||||
/* |
||||
* MIT License |
||||
* |
||||
* Copyright (c) 2020 Jannis Weis |
||||
* |
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and |
||||
* associated documentation files (the "Software"), to deal in the Software without restriction, |
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute, |
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is |
||||
* furnished to do so, subject to the following conditions: |
||||
* |
||||
* The above copyright notice and this permission notice shall be included in all copies or |
||||
* substantial portions of the Software. |
||||
* |
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT |
||||
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||||
* |
||||
*/ |
||||
package com.github.weisj.darklaf.parser; |
||||
|
||||
import com.github.weisj.darklaf.util.PropertyValue; |
||||
|
||||
public class NullParser implements PropertyParser { |
||||
@Override |
||||
public ParseResult doParse(final ParseResult parseResult, final ParserContext context) { |
||||
if (parseResult.value == null || PropertyValue.NULL.equals(parseResult.value)) { |
||||
parseResult.result = null; |
||||
parseResult.finished = true; |
||||
} |
||||
return parseResult; |
||||
} |
||||
} |
@ -0,0 +1,64 @@
|
||||
/* |
||||
* MIT License |
||||
* |
||||
* Copyright (c) 2020 Jannis Weis |
||||
* |
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and |
||||
* associated documentation files (the "Software"), to deal in the Software without restriction, |
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute, |
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is |
||||
* furnished to do so, subject to the following conditions: |
||||
* |
||||
* The above copyright notice and this permission notice shall be included in all copies or |
||||
* substantial portions of the Software. |
||||
* |
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT |
||||
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||||
* |
||||
*/ |
||||
package com.github.weisj.darklaf.parser; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
public class ParseResult { |
||||
public String key; |
||||
public String value; |
||||
public Object result; |
||||
public boolean finished; |
||||
public List<String> warnings = new ArrayList<>(); |
||||
|
||||
private String savedKey; |
||||
private String savedValue; |
||||
|
||||
public ParseResult(final String key, final String value) { |
||||
this.key = key != null ? key : ""; |
||||
this.value = value != null ? value : ""; |
||||
} |
||||
|
||||
@Override |
||||
public String toString() { |
||||
return "ParseResult{" + |
||||
"key='" + key + '\'' + |
||||
", value='" + value + '\'' + |
||||
", result=" + result + |
||||
", finished=" + finished + |
||||
", warnings=" + warnings + |
||||
", savedKey='" + savedKey + '\'' + |
||||
", savedValue='" + savedValue + '\'' + |
||||
'}'; |
||||
} |
||||
|
||||
public void save() { |
||||
savedKey = key; |
||||
savedValue = value; |
||||
} |
||||
|
||||
public void restore() { |
||||
key = savedKey; |
||||
value = savedValue; |
||||
} |
||||
} |
@ -0,0 +1,88 @@
|
||||
/* |
||||
* MIT License |
||||
* |
||||
* Copyright (c) 2020 Jannis Weis |
||||
* |
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and |
||||
* associated documentation files (the "Software"), to deal in the Software without restriction, |
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute, |
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is |
||||
* furnished to do so, subject to the following conditions: |
||||
* |
||||
* The above copyright notice and this permission notice shall be included in all copies or |
||||
* substantial portions of the Software. |
||||
* |
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT |
||||
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||||
* |
||||
*/ |
||||
package com.github.weisj.darklaf.parser; |
||||
|
||||
import java.util.Arrays; |
||||
import java.util.List; |
||||
|
||||
|
||||
public final class Parser { |
||||
|
||||
public static final Object EMPTY_VALUE = new Object(); |
||||
|
||||
private static final List<PropertyParser> steps = Arrays.asList( |
||||
new NullParser(), |
||||
new FallbackParser(), |
||||
new ReferenceParser(), |
||||
new PrimitiveParser(), |
||||
new InsetParser(), |
||||
new LazyObjectParser(), |
||||
new ActiveObjectParser(), |
||||
new FontParser(), |
||||
new IconParser(), |
||||
new DimensionParser(), |
||||
new ListParser(), |
||||
new MapParser()); |
||||
|
||||
private static boolean debugMode; |
||||
|
||||
public static void setDebugMode(final boolean debugMode) { |
||||
Parser.debugMode = debugMode; |
||||
} |
||||
|
||||
public static boolean isDebugMode() { |
||||
return debugMode; |
||||
} |
||||
|
||||
public static ParseResult parse(final ParseResult parseResult, final ParserContext context) { |
||||
ParseResult p = parseResult; |
||||
String savedValue = parseResult.value; |
||||
for (PropertyParser step : steps) { |
||||
if (p.finished) return p; |
||||
p = step.parse(p, context); |
||||
} |
||||
if (!p.finished) { |
||||
for (String warning : p.warnings) { |
||||
ParserUtil.warning(warning); |
||||
} |
||||
ParserUtil.setNonNull(p, savedValue); |
||||
} |
||||
return p; |
||||
} |
||||
|
||||
public static ParseResult createParseResult(final String key, final String value) { |
||||
if (isDebugMode()) { |
||||
return new DebugParseResult(key, value); |
||||
} else { |
||||
return new ParseResult(key, value); |
||||
} |
||||
} |
||||
|
||||
public static class DebugParseResult extends ParseResult { |
||||
|
||||
public String referenceKey; |
||||
|
||||
public DebugParseResult(final String key, final String value) { |
||||
super(key, value); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,39 @@
|
||||
/* |
||||
* MIT License |
||||
* |
||||
* Copyright (c) 2020 Jannis Weis |
||||
* |
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and |
||||
* associated documentation files (the "Software"), to deal in the Software without restriction, |
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute, |
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is |
||||
* furnished to do so, subject to the following conditions: |
||||
* |
||||
* The above copyright notice and this permission notice shall be included in all copies or |
||||
* substantial portions of the Software. |
||||
* |
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT |
||||
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||||
* |
||||
*/ |
||||
package com.github.weisj.darklaf.parser; |
||||
|
||||
import java.util.Map; |
||||
|
||||
import com.github.weisj.darklaf.icons.IconLoader; |
||||
|
||||
public class ParserContext { |
||||
public final Map<Object, Object> accumulator; |
||||
public final Map<Object, Object> defaults; |
||||
public final IconLoader iconLoader; |
||||
|
||||
public ParserContext(final Map<Object, Object> accumulator, final Map<Object, Object> defaults, |
||||
final IconLoader iconLoader) { |
||||
this.accumulator = accumulator; |
||||
this.defaults = defaults; |
||||
this.iconLoader = iconLoader; |
||||
} |
||||
} |
@ -0,0 +1,230 @@
|
||||
/* |
||||
* MIT License |
||||
* |
||||
* Copyright (c) 2020 Jannis Weis |
||||
* |
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and |
||||
* associated documentation files (the "Software"), to deal in the Software without restriction, |
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute, |
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is |
||||
* furnished to do so, subject to the following conditions: |
||||
* |
||||
* The above copyright notice and this permission notice shall be included in all copies or |
||||
* substantial portions of the Software. |
||||
* |
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT |
||||
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||||
* |
||||
*/ |
||||
package com.github.weisj.darklaf.parser; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
import java.util.Objects; |
||||
import java.util.Optional; |
||||
import java.util.logging.Logger; |
||||
import java.util.stream.Collectors; |
||||
|
||||
import com.github.weisj.darklaf.util.LogUtil; |
||||
import com.github.weisj.darklaf.util.Types; |
||||
|
||||
final class ParserUtil implements Delimiters { |
||||
|
||||
private static final char EMPTY_CHAR = Character.MIN_VALUE; |
||||
private static final Logger LOGGER = LogUtil.getLogger(PropertyParser.class); |
||||
|
||||
static ParseResult error(final ParseResult parseResult, final String message) { |
||||
LOGGER.severe("Error while parsing " + parseResult + ". " + message); |
||||
parseResult.finished = true; |
||||
parseResult.result = null; |
||||
return parseResult; |
||||
} |
||||
|
||||
static void warning(final String message) { |
||||
LOGGER.warning(message); |
||||
} |
||||
|
||||
static ParseResult apply(final PropertyParser parser, final ParseResult p, final ParserContext c) { |
||||
return parser != null ? parser.parse(p, c) : p; |
||||
} |
||||
|
||||
static boolean stripPrefixFromKey(final ParseResult parseResult, final String prefix) { |
||||
if (parseResult.key.startsWith(prefix)) { |
||||
parseResult.key = parseResult.key.substring(prefix.length()); |
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
static boolean stripPrefixFromValue(final ParseResult parseResult, final String prefix) { |
||||
if (parseResult.value.startsWith(prefix)) { |
||||
parseResult.value = parseResult.value.substring(prefix.length()); |
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
static void replaceIfNull(final ParseResult parseResult, final String key, final Map<Object, Object> map) { |
||||
if (parseResult.finished) return; |
||||
Object obj = map.get(key); |
||||
while (obj instanceof ParseResult) { |
||||
obj = ((ParseResult) obj).result; |
||||
} |
||||
setNonNull(parseResult, obj); |
||||
} |
||||
|
||||
static ParseResult setNonNull(final ParseResult parseResult, final Object result) { |
||||
if (result != null) { |
||||
parseResult.result = result; |
||||
parseResult.finished = true; |
||||
} |
||||
return parseResult; |
||||
} |
||||
|
||||
static <T> Optional<T> parseBetween(final char start, final char end, final Class<T> type, |
||||
final ParseResult parseResult, |
||||
final ParserContext context) { |
||||
return parseBetween(start, end, Parser::parse, type, parseResult, context); |
||||
} |
||||
|
||||
static <T> Optional<T> parseBetween(final char start, final char end, final PropertyParser parser, |
||||
final Class<T> type, final ParseResult parseResult, |
||||
final ParserContext context) { |
||||
List<T> parsed = parseDelimited(start, end, EMPTY_CHAR, parser, type, parseResult, context); |
||||
return parsed.stream().findFirst(); |
||||
} |
||||
|
||||
|
||||
static <T> List<T> parseDelimited(final char delimiter, final PropertyParser parser, final Class<T> type, |
||||
final ParseResult parseResult, final ParserContext context) { |
||||
return parseDelimited(EMPTY_CHAR, EMPTY_CHAR, delimiter, parser, type, parseResult, context); |
||||
} |
||||
|
||||
static <T> List<T> parseDelimited(final char delimiter, final Class<T> type, |
||||
final ParseResult parseResult, final ParserContext context) { |
||||
return parseDelimited(delimiter, Parser::parse, type, parseResult, context); |
||||
} |
||||
|
||||
static <T> List<T> parseDelimited(final char start, final char end, final char delimiter, final Class<T> type, |
||||
final ParseResult parseResult, final ParserContext context) { |
||||
return parseDelimited(start, end, delimiter, Parser::parse, type, parseResult, context); |
||||
} |
||||
|
||||
static <T> List<T> parseDelimited(final char start, final char end, final char delimiter, |
||||
final PropertyParser parser, final Class<T> type, final ParseResult parseResult, |
||||
final ParserContext context) { |
||||
return parseDelimited(start, end, delimiter, true, parser, type, parseResult, context); |
||||
} |
||||
|
||||
/* |
||||
* Parses the value in a delimited fashion. The consumed part of the value will be replaced in-place |
||||
* in the Parsable object |
||||
*/ |
||||
static <T> List<T> parseDelimited(final char start, final char end, final char delimiter, final boolean forward, |
||||
final PropertyParser parser, final Class<T> type, final ParseResult parseResult, |
||||
final ParserContext context) { |
||||
if (forward) { |
||||
if (start != EMPTY_CHAR) { |
||||
if (parseResult.value.charAt(0) == start) { |
||||
parseResult.value = parseResult.value.substring(1); |
||||
} else { |
||||
LOGGER.warning("Expected '" + start + "' while parsing " + parseResult.value); |
||||
} |
||||
} |
||||
} else { |
||||
if (end != EMPTY_CHAR) { |
||||
if (parseResult.value.charAt(parseResult.value.length() - 1) == end) { |
||||
parseResult.value = parseResult.value.substring(0, parseResult.value.length() - 1); |
||||
} else { |
||||
LOGGER.warning("Expected '" + start + "' while parsing " + parseResult.value); |
||||
} |
||||
} |
||||
} |
||||
List<String> values = delimitedSplit(delimiter, forward ? end : start, parseResult, forward); |
||||
if (values.size() == 0) return Collections.emptyList(); |
||||
List<T> parsed = values.stream() |
||||
.map(v -> Parser.createParseResult(parseResult.key, v)) |
||||
.map(p -> parser.parse(p, context)) |
||||
.map(p -> { |
||||
T casted = Types.safeCast(p.result, type); |
||||
if (casted == null) LOGGER.warning("Value " + p.result + " is not of type " + type |
||||
+ ". Encountered while parsing '" + p + "' for '" + parseResult + "'"); |
||||
return casted; |
||||
}) |
||||
.filter(Objects::nonNull) |
||||
.collect(Collectors.toList()); |
||||
if (!forward) Collections.reverse(parsed); |
||||
return parsed; |
||||
} |
||||
|
||||
static List<String> delimitedSplit(final char delimiter, final char closingDelimiter, |
||||
final ParseResult parseResult, final boolean forward) { |
||||
String value = parseResult.value; |
||||
int openDelimiters = 0; |
||||
List<String> values = new ArrayList<>(); |
||||
boolean done = false; |
||||
|
||||
int i = forward ? 0 : value.length() - 1; |
||||
int step = forward ? 1 : -1; |
||||
int end = forward ? value.length() : -1; |
||||
int lastPos = forward ? 0 : value.length(); |
||||
for (; i != end; i += step) { |
||||
char c = value.charAt(i); |
||||
if (openDelimiters == 0) { |
||||
if (closingDelimiter != EMPTY_CHAR && closingDelimiter == c) { |
||||
done = true; |
||||
break; |
||||
} else if (delimiter == c) { |
||||
if (forward) { |
||||
values.add(value.substring(lastPos, i)); |
||||
lastPos = i + 1; |
||||
} else { |
||||
values.add(value.substring(i + 1, lastPos)); |
||||
lastPos = i; |
||||
} |
||||
} |
||||
} |
||||
if (isOpenDelimiter(c)) openDelimiters++; |
||||
if (isClosingDelimiter(c)) openDelimiters--; |
||||
} |
||||
if (!done && lastPos != end) { |
||||
if (forward) { |
||||
values.add(value.substring(lastPos)); |
||||
} else { |
||||
values.add(value.substring(0, lastPos)); |
||||
} |
||||
parseResult.value = ""; |
||||
} else { |
||||
if (forward) { |
||||
values.add(value.substring(lastPos, i)); |
||||
int endIndex = closingDelimiter != EMPTY_CHAR ? i + 1 : i; |
||||
parseResult.value = parseResult.value.substring(endIndex); |
||||
} else { |
||||
values.add(value.substring(i + 1, lastPos)); |
||||
parseResult.value = parseResult.value.substring(0, i); |
||||
} |
||||
} |
||||
return values; |
||||
} |
||||
|
||||
static Object createObject(final String value) { |
||||
try { |
||||
return Class.forName(value).getDeclaredConstructor().newInstance(); |
||||
} catch (final Exception ignored) { |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
private static boolean isOpenDelimiter(final char c) { |
||||
return c == LIST_START || c == MAP_START || c == ARG_START; |
||||
} |
||||
|
||||
private static boolean isClosingDelimiter(final char c) { |
||||
return c == LIST_END || c == MAP_END || c == ARG_END; |
||||
} |
||||
} |
@ -0,0 +1,58 @@
|
||||
/* |
||||
* MIT License |
||||
* |
||||
* Copyright (c) 2020 Jannis Weis |
||||
* |
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and |
||||
* associated documentation files (the "Software"), to deal in the Software without restriction, |
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute, |
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is |
||||
* furnished to do so, subject to the following conditions: |
||||
* |
||||
* The above copyright notice and this permission notice shall be included in all copies or |
||||
* substantial portions of the Software. |
||||
* |
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT |
||||
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||||
* |
||||
*/ |
||||
package com.github.weisj.darklaf.parser; |
||||
|
||||
import java.awt.Color; |
||||
|
||||
import com.github.weisj.darklaf.color.ColorUtil; |
||||
import com.github.weisj.darklaf.uiresource.DarkColorUIResource; |
||||
import com.github.weisj.darklaf.util.PropertyValue; |
||||
|
||||
public class PrimitiveParser implements PropertyParser { |
||||
|
||||
@Override |
||||
public ParseResult doParse(final ParseResult parseResult, final ParserContext context) { |
||||
Color c = ColorUtil.fromHex(parseResult.value, null, true); |
||||
ParserUtil.setNonNull(parseResult, c != null ? new DarkColorUIResource(c) : null); |
||||
if (parseResult.finished) return parseResult; |
||||
ParserUtil.setNonNull(parseResult, getInteger(parseResult.value)); |
||||
if (parseResult.finished) return parseResult; |
||||
ParserUtil.setNonNull(parseResult, getBoolean(parseResult.value)); |
||||
return parseResult; |
||||
} |
||||
|
||||
private Boolean getBoolean(final String value) { |
||||
return PropertyValue.TRUE.equalsIgnoreCase(value) |
||||
? Boolean.TRUE |
||||
: PropertyValue.FALSE.equalsIgnoreCase(value) |
||||
? Boolean.FALSE |
||||
: null; |
||||
} |
||||
|
||||
private static Integer getInteger(final String value) { |
||||
try { |
||||
return Integer.parseInt(value); |
||||
} catch (final NumberFormatException ignored) { |
||||
return null; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,58 @@
|
||||
/* |
||||
* MIT License |
||||
* |
||||
* Copyright (c) 2020 Jannis Weis |
||||
* |
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and |
||||
* associated documentation files (the "Software"), to deal in the Software without restriction, |
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute, |
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is |
||||
* furnished to do so, subject to the following conditions: |
||||
* |
||||
* The above copyright notice and this permission notice shall be included in all copies or |
||||
* substantial portions of the Software. |
||||
* |
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT |
||||
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||||
* |
||||
*/ |
||||
package com.github.weisj.darklaf.parser; |
||||
|
||||
import com.github.weisj.darklaf.util.Lambdas; |
||||
|
||||
@FunctionalInterface |
||||
public interface PropertyParser { |
||||
ParseResult doParse(final ParseResult parseResult, final ParserContext context); |
||||
|
||||
default ParseResult parse(final ParseResult parseResult, final ParserContext context) { |
||||
if (parseResult.finished) return parseResult; |
||||
if (!filter(parseResult, context)) return parseResult; |
||||
parseResult.save(); |
||||
ParseResult p = doParse(parseResult, context); |
||||
parseResult.save(); |
||||
return p; |
||||
} |
||||
|
||||
default boolean filter(final ParseResult parseResult, final ParserContext context) { |
||||
return true; |
||||
} |
||||
|
||||
default PropertyParser andThen(final PropertyParser parser) { |
||||
return new JoinedParser(this, parser); |
||||
} |
||||
|
||||
static <E extends Exception> PropertyParser of(final Lambdas.CheckedFunction<String, Object, E> function) { |
||||
return (p, c) -> { |
||||
try { |
||||
return ParserUtil.setNonNull(p, function.apply(p.value)); |
||||
} catch (final Exception e) { |
||||
p.result = null; |
||||
p.finished = true; |
||||
} |
||||
return p; |
||||
}; |
||||
} |
||||
} |
@ -0,0 +1,46 @@
|
||||
/* |
||||
* MIT License |
||||
* |
||||
* Copyright (c) 2020 Jannis Weis |
||||
* |
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and |
||||
* associated documentation files (the "Software"), to deal in the Software without restriction, |
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute, |
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is |
||||
* furnished to do so, subject to the following conditions: |
||||
* |
||||
* The above copyright notice and this permission notice shall be included in all copies or |
||||
* substantial portions of the Software. |
||||
* |
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT |
||||
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||||
* |
||||
*/ |
||||
package com.github.weisj.darklaf.parser; |
||||
|
||||
public class ReferenceParser implements PropertyParser { |
||||
|
||||
private static final String REFERENCE_PREFIX = "%"; |
||||
|
||||
@Override |
||||
public ParseResult doParse(final ParseResult parseResult, final ParserContext context) { |
||||
ParserUtil.stripPrefixFromKey(parseResult, REFERENCE_PREFIX); |
||||
parseResult.save(); |
||||
if (ParserUtil.stripPrefixFromValue(parseResult, REFERENCE_PREFIX)) { |
||||
ParserUtil.replaceIfNull(parseResult, parseResult.value, context.accumulator); |
||||
ParserUtil.replaceIfNull(parseResult, parseResult.value, context.defaults); |
||||
if (!parseResult.finished) { |
||||
parseResult.warnings.add("Could not reference value '" |
||||
+ parseResult.value + "' while loading '" + parseResult.key + "'. " |
||||
+ "Maybe it's a forward reference."); |
||||
parseResult.restore(); |
||||
} else if (parseResult instanceof Parser.DebugParseResult) { |
||||
((Parser.DebugParseResult) parseResult).referenceKey = REFERENCE_PREFIX + parseResult.value; |
||||
} |
||||
} |
||||
return parseResult; |
||||
} |
||||
} |
@ -0,0 +1,213 @@
|
||||
/* |
||||
* MIT License |
||||
* |
||||
* Copyright (c) 2020 Jannis Weis |
||||
* |
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and |
||||
* associated documentation files (the "Software"), to deal in the Software without restriction, |
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute, |
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is |
||||
* furnished to do so, subject to the following conditions: |
||||
* |
||||
* The above copyright notice and this permission notice shall be included in all copies or |
||||
* substantial portions of the Software. |
||||
* |
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT |
||||
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||||
* |
||||
*/ |
||||
package com.github.weisj.darklaf.parser; |
||||
|
||||
import java.awt.Color; |
||||
import java.awt.Dimension; |
||||
import java.awt.Insets; |
||||
import java.util.Arrays; |
||||
import java.util.Collections; |
||||
import java.util.HashMap; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
import java.util.Random; |
||||
|
||||
import javax.swing.UIDefaults; |
||||
|
||||
import org.junit.jupiter.api.Assertions; |
||||
import org.junit.jupiter.api.BeforeEach; |
||||
import org.junit.jupiter.api.Test; |
||||
|
||||
import com.github.weisj.darklaf.color.ColorUtil; |
||||
import com.github.weisj.darklaf.icons.IconLoader; |
||||
|
||||
class ParserTest { |
||||
|
||||
final ParserContext context = new ParserContext( |
||||
new UIDefaults(), new UIDefaults(), |
||||
IconLoader.get(ParserTest.class)); |
||||
|
||||
@BeforeEach |
||||
void setup() { |
||||
context.defaults.clear(); |
||||
context.accumulator.clear(); |
||||
} |
||||
|
||||
Object parse(final String key, final String value) { |
||||
return parse(key, value, true); |
||||
} |
||||
|
||||
Object parse(final String key, final String value, final boolean shouldSucceed) { |
||||
ParseResult p = Parser.parse(new ParseResult(key, value), context); |
||||
Assertions.assertEquals(shouldSucceed, p.finished); |
||||
return p.result; |
||||
} |
||||
|
||||
@Test |
||||
void testPrimitives() { |
||||
Assertions.assertEquals("Hello World", parse("key", "Hello World")); |
||||
|
||||
Assertions.assertEquals(false, parse("key", "false")); |
||||
Assertions.assertEquals(false, parse("key", "FALSE")); |
||||
Assertions.assertEquals(false, parse("key", "FaLsE")); |
||||
|
||||
Assertions.assertEquals(true, parse("key", "true")); |
||||
Assertions.assertEquals(true, parse("key", "TRUE")); |
||||
Assertions.assertEquals(true, parse("key", "tRuE")); |
||||
|
||||
for (int i = -100; i < 100; i++) { |
||||
Assertions.assertEquals(i, parse("key", String.valueOf(i))); |
||||
} |
||||
|
||||
Random r = new Random(); |
||||
for (int i = 0; i < 100; i++) { |
||||
Color c = new Color(r.nextInt(256), r.nextInt(256), r.nextInt(256)); |
||||
Assertions.assertEquals(c, parse("key", ColorUtil.toHex(c))); |
||||
} |
||||
} |
||||
|
||||
@Test |
||||
void testReferences() { |
||||
Assertions.assertEquals("key", Parser.parse(new ParseResult("%key", "value"), context).key); |
||||
|
||||
Object obj = new Object(); |
||||
|
||||
context.accumulator.put("key", obj); |
||||
Assertions.assertEquals(obj, parse("key2", "%key")); |
||||
|
||||
context.accumulator.clear(); |
||||
context.defaults.put("key", obj); |
||||
Assertions.assertEquals(obj, parse("key2", "%key")); |
||||
} |
||||
|
||||
@Test |
||||
void testFallbacks() { |
||||
Object obj = new Object(); |
||||
context.accumulator.put("key1", obj); |
||||
Assertions.assertEquals(obj, parse("key1", "?:false")); |
||||
Assertions.assertEquals(false, parse("key2", "?:false")); |
||||
|
||||
Object obj2 = new Object(); |
||||
context.accumulator.put("key2", obj2); |
||||
Assertions.assertEquals(obj, parse("key3", "?:%key1")); |
||||
} |
||||
|
||||
@Test |
||||
void testDimension() { |
||||
Random r = new Random(); |
||||
for (int i = 0; i < 100; i++) { |
||||
int w = r.nextInt(); |
||||
int h = r.nextInt(); |
||||
Assertions.assertEquals(new Dimension(w, h), parse("test.size", w + "," + h)); |
||||
Assertions.assertEquals(new Dimension(w, h), parse("testSize", w + "," + h)); |
||||
} |
||||
|
||||
Dimension dim = new Dimension(12, 34); |
||||
context.accumulator.put("key.width", dim.width); |
||||
Assertions.assertEquals(dim, parse("key.size", "%key.width," + dim.height)); |
||||
} |
||||
|
||||
@Test |
||||
void testInsets() { |
||||
Random r = new Random(); |
||||
for (int i = 0; i < 100; i++) { |
||||
Insets insets = new Insets(r.nextInt(), r.nextInt(), r.nextInt(), r.nextInt()); |
||||
Assertions.assertEquals(insets, parse("test.insets", |
||||
insets.top + "," + insets.left + "," + insets.bottom + "," + insets.right)); |
||||
Assertions.assertEquals(insets, parse("testInsets", |
||||
insets.top + "," + insets.left + "," + insets.bottom + "," + insets.right)); |
||||
Assertions.assertEquals(insets, parse("test.margins", |
||||
insets.top + "," + insets.left + "," + insets.bottom + "," + insets.right)); |
||||
} |
||||
|
||||
Insets ins = new Insets(1, 2, 3, 4); |
||||
context.accumulator.put("key.left", ins.left); |
||||
context.accumulator.put("key.bottom", ins.bottom); |
||||
Assertions.assertEquals(ins, parse("key.insets", ins.top + ",%key.left,%key.bottom," + ins.right)); |
||||
} |
||||
|
||||
@Test |
||||
void testActiveObject() { |
||||
context.accumulator.put("key", parse("key.component", "java.lang.Object")); |
||||
Assertions.assertEquals(Object.class, context.accumulator.get("key").getClass()); |
||||
Assertions.assertNotEquals(context.accumulator.get("key"), context.accumulator.get("key")); |
||||
|
||||
context.accumulator.put("key2", parse("key2.component", "%key")); |
||||
Assertions.assertEquals(Object.class, context.accumulator.get("key2").getClass()); |
||||
Assertions.assertNotEquals(context.accumulator.get("key"), context.accumulator.get("key2")); |
||||
if (context.accumulator instanceof UIDefaults) { |
||||
// UIDefaults evaluates the active object when resolving the reference.
|
||||
// Hence active values get lost.
|
||||
Assertions.assertEquals(context.accumulator.get("key2"), context.accumulator.get("key2")); |
||||
} else { |
||||
Assertions.assertNotEquals(context.accumulator.get("key2"), context.accumulator.get("key2")); |
||||
} |
||||
} |
||||
|
||||
@Test |
||||
void testLazyObject() { |
||||
context.accumulator.put("key", parse("key.border", "java.lang.Object")); |
||||
Assertions.assertEquals(Object.class, context.accumulator.get("key").getClass()); |
||||
Assertions.assertEquals(context.accumulator.get("key"), context.accumulator.get("key")); |
||||
|
||||
context.accumulator.put("key2", parse("key2.component", "%key")); |
||||
Assertions.assertEquals(Object.class, context.accumulator.get("key2").getClass()); |
||||
Assertions.assertEquals(context.accumulator.get("key"), context.accumulator.get("key2")); |
||||
Assertions.assertEquals(context.accumulator.get("key2"), context.accumulator.get("key2")); |
||||
} |
||||
|
||||
@Test |
||||
void testList() { |
||||
Object obj = new Object(); |
||||
context.accumulator.put("key", obj); |
||||
List<Object> list = Arrays.asList("Test", false, 15, obj); |
||||
Assertions.assertEquals(list, parse("listKey", "[Test;false;15;%key]")); |
||||
|
||||
List<Object> nestedList = |
||||
Arrays.asList(1, 2, Arrays.asList(3, Arrays.asList(4, 5), 6, 7), 8, Collections.singletonList(9), 10); |
||||
Assertions.assertEquals(nestedList, parse("listKey", "[1;2;[3;[4;5];6;7];8;[9];10]")); |
||||
} |
||||
|
||||
@Test |
||||
void testMap() { |
||||
Map<Object, Object> map = new HashMap<>(); |
||||
map.put("key1", 1); |
||||
map.put("key2", false); |
||||
map.put(3, "value3"); |
||||
map.put("key4", Arrays.asList(1, 2, 3)); |
||||
Assertions.assertEquals(map, parse("mapKey", "{key1:1;key2:false;3:value3;key4:[1;2;3]}")); |
||||
} |
||||
|
||||
@Test |
||||
void testDelimitedSplit() { |
||||
String value1 = "a,b,[c,d,{e,f},g],(h),i,j)Suffix"; |
||||
String value2 = "Prefix(a,b,[c,d,{e,f},g],(h),i,j"; |
||||
List<String> expected = Arrays.asList("a", "b", "[c,d,{e,f},g]", "(h)", "i", "j"); |
||||
|
||||
List<String> values1 = ParserUtil.delimitedSplit(',', ')', new ParseResult("key", value1), true); |
||||
Assertions.assertEquals(expected, values1); |
||||
|
||||
Collections.reverse(expected); |
||||
List<String> values2 = ParserUtil.delimitedSplit(',', '(', new ParseResult("key", value2), false); |
||||
Assertions.assertEquals(expected, values2); |
||||
} |
||||
} |
Loading…
Reference in new issue