/*=============================================================================# # Copyright (c) 2014-2016 Stephan Wahlbrink (WalWare.de) and others. # All rights reserved. This program and the accompanying materials # are made available under the terms of the Eclipse Public License v1.0 # which accompanies this distribution, and is available at # http://www.eclipse.org/legal/epl-v10.html # # Contributors: # Stephan Wahlbrink - initial API and implementation #=============================================================================*/ package de.walware.docmlet.wikitext.core.source.extdoc; import java.util.List; import de.walware.jcommons.collections.ImCollections; import de.walware.docmlet.wikitext.core.markup.IMarkupConfig; public abstract class AbstractMarkupConfig<T extends AbstractMarkupConfig<? super T>> implements IMarkupConfig { public static final String YAML_METADATA_ENABLED_PROP= "YamlMetadataEnabled"; //$NON-NLS-1$ private static final String YAML_METADATA_ENABLED_KEY= "yaml_metadata_block"; //$NON-NLS-1$ public static final String TEX_MATH_DOLLARS_ENABLED_PROP= "TexMathDollarsEnabled"; //$NON-NLS-1$ private static final String TEX_MATH_DOLLARS_ENABLED_KEY= "tex_math_dollars"; //$NON-NLS-1$ public static final String TEX_MATH_SBACKSLASH_ENABLED_PROP= "TexMathSBackslashEnabled"; //$NON-NLS-1$ private static final String TEX_MATH_SBACKSLASH_ENABLED_KEY= "tex_math_single_backslash"; //$NON-NLS-1$ private boolean isSealed; private boolean isYamlMetadataEnabled; private boolean isTexMathDollarsEnabled; private boolean isTexMathSBackslashEnabled; private String configString; protected AbstractMarkupConfig() { } @Override public T clone() { try { final AbstractMarkupConfig clone= (AbstractMarkupConfig) super.clone(); clone.isSealed= false; return (T) clone; } catch (final CloneNotSupportedException e) { throw new RuntimeException(e); } } @Override public void seal() { this.isSealed= true; } @Override public final boolean isSealed() { return this.isSealed; } protected final void checkSeal() { if (isSealed()) { throw new IllegalStateException("object is read only"); } } protected void afterChange(final String propertyName) { this.configString= null; } public synchronized void setYamlMetadataEnabled(final boolean enabled) { checkSeal(); if (this.isYamlMetadataEnabled != enabled) { this.isYamlMetadataEnabled= enabled; afterChange(YAML_METADATA_ENABLED_PROP); } } public boolean isYamlMetadataEnabled() { return this.isYamlMetadataEnabled; } public void setTexMathDollarsEnabled(final boolean enabled) { checkSeal(); if (this.isTexMathDollarsEnabled != enabled) { this.isTexMathDollarsEnabled= enabled; afterChange(TEX_MATH_DOLLARS_ENABLED_PROP); } } public boolean isTexMathDollarsEnabled() { return this.isTexMathDollarsEnabled; } public void setTexMathSBackslashEnabled(final boolean enabled) { checkSeal(); if (this.isTexMathSBackslashEnabled != enabled) { this.isTexMathSBackslashEnabled= enabled; afterChange(TEX_MATH_SBACKSLASH_ENABLED_PROP); } } public boolean isTexMathSBackslashEnabled() { return this.isTexMathSBackslashEnabled; } @Override public String getString() { String s= this.configString; if (s == null) { final StringBuilder sb= new StringBuilder(getConfigType()); sb.append(':'); createConfigString(sb); s= (sb.charAt(sb.length() - 1) == ';') ? sb.substring(0, sb.length() - 1) : sb.toString(); this.configString= s; } return s; } protected abstract String getConfigType(); protected boolean supportsConfigType(final String configType) { return getConfigType().equals(configType); } protected void createConfigString(final StringBuilder sb) { if (isYamlMetadataEnabled()) { sb.append(YAML_METADATA_ENABLED_KEY + ';'); } if (isTexMathDollarsEnabled()) { sb.append(TEX_MATH_DOLLARS_ENABLED_KEY + ';'); } if (isTexMathSBackslashEnabled()) { sb.append(TEX_MATH_SBACKSLASH_ENABLED_KEY + ';'); } } protected void load(final String configType, final List<String> s) { setYamlMetadataEnabled(s.contains(YAML_METADATA_ENABLED_KEY)); setTexMathDollarsEnabled(s.contains(TEX_MATH_DOLLARS_ENABLED_KEY)); setTexMathSBackslashEnabled(s.contains(TEX_MATH_SBACKSLASH_ENABLED_KEY)); } @Override public boolean load(final String configString) { final int i= configString.indexOf(':'); final String configType; if (i < 0 || !supportsConfigType((configType= configString.substring(0, i)))) { return false; } load(configType, ImCollections.newList(configString.substring(i + 1).split(";")) ); //$NON-NLS-1$ return true; } public void load(final T config) { setYamlMetadataEnabled(config.isYamlMetadataEnabled()); setTexMathDollarsEnabled(config.isTexMathDollarsEnabled()); setTexMathSBackslashEnabled(config.isTexMathSBackslashEnabled()); } @Override public int hashCode() { return getString().hashCode(); } @Override public boolean equals(final Object obj) { if (this == obj) { return true; } if (obj instanceof AbstractMarkupConfig) { final AbstractMarkupConfig<?> other= (AbstractMarkupConfig<?>) obj; return (getConfigType() == other.getConfigType() && isYamlMetadataEnabled() == other.isYamlMetadataEnabled() && isTexMathDollarsEnabled() == other.isTexMathDollarsEnabled() && isTexMathSBackslashEnabled() == other.isTexMathSBackslashEnabled() ); } return false; } @Override public String toString() { return getClass().getSimpleName() + ": " + getString(); //$NON-NLS-1$ } }