001package Torello.JavaDoc.SyntaxHiLite; 002 003import Torello.CSS.ClassNameCSSException; 004 005import Torello.HTML.HTMLTags; 006import Torello.HTML.TagNode; 007import Torello.HTML.SD; 008import Torello.HTML.TC; 009 010import Torello.Java.Additional.Ret2; 011 012import java.util.Objects; 013import java.util.Arrays; 014 015public class AbstractConfig<T extends AbstractConfig<T>> 016 implements java.io.Serializable 017{ 018 protected static final long serialVersionUID = 1; 019 020 021 // ******************************************************************************************** 022 // ******************************************************************************************** 023 // Class-Config - Fields (These a) 024 // ******************************************************************************************** 025 // ******************************************************************************************** 026 027 028 protected final String[] classNames; 029 030 protected final boolean[] spansOrBolds, utilize; 031 032 protected boolean upperOrLower_TagName = true; 033 protected boolean upperOrLower_ClassAttrName = true; 034 protected SD quotes = null; 035 036 private final int CONFIG_ARR_LEN; 037 038 private final Class<T> captureTheClassDummy; 039 040 protected AbstractConfig( 041 final int CONFIG_ARR_LEN, 042 final boolean[] spansOrBolds, 043 final Class<T> captureTheClassDummy 044 ) 045 { 046 Objects.requireNonNull 047 (spansOrBolds, "The array passed to parameter 'spansOrBolds' is null"); 048 049 Objects.requireNonNull 050 (captureTheClassDummy, "The class passed to parameter 'captureTheClassDummy' is null"); 051 052 if (CONFIG_ARR_LEN < 1) throw new IllegalArgumentException( 053 '[' + CONFIG_ARR_LEN + "] was passed to CONFIG_ARR_LEN, but this value must be a " + 054 "positive integer that is greater than 0." 055 ); 056 057 if (spansOrBolds.length != CONFIG_ARR_LEN) throw new IllegalArgumentException( 058 "The length of the Array-Parameter 'spansOrBolds' is [" + spansOrBolds.length + "], " + 059 "but the value passed to parameter CONFIG_ARR_LENGTH was [" + CONFIG_ARR_LEN + "]. " + 060 "These values must be equals." 061 ); 062 063 this.CONFIG_ARR_LEN = CONFIG_ARR_LEN; 064 this.captureTheClassDummy = captureTheClassDummy; 065 066 this.classNames = new String[CONFIG_ARR_LEN]; 067 this.spansOrBolds = new boolean[CONFIG_ARR_LEN]; 068 this.utilize = new boolean[CONFIG_ARR_LEN]; 069 070 for (int i=1; i < CONFIG_ARR_LEN; i++) this.classNames[i] = "HL-" + i; 071 for (int i=0; i < CONFIG_ARR_LEN; i++) this.spansOrBolds[i] = spansOrBolds[i]; 072 for (int i=0; i < CONFIG_ARR_LEN; i++) this.utilize[i] = true; 073 } 074 075 protected AbstractConfig(AbstractConfig<T> c) 076 { 077 final int L = this.CONFIG_ARR_LEN = c.CONFIG_ARR_LEN; 078 079 this.captureTheClassDummy = c.captureTheClassDummy; 080 081 this.classNames = new String[c.CONFIG_ARR_LEN]; 082 this.spansOrBolds = new boolean[c.CONFIG_ARR_LEN]; 083 this.utilize = new boolean[c.CONFIG_ARR_LEN]; 084 085 System.arraycopy(c.classNames, 0, this.classNames, 0, L); 086 System.arraycopy(c.spansOrBolds, 0, this.spansOrBolds, 0, L); 087 System.arraycopy(c.utilize, 0, this.utilize, 0, L); 088 089 this.upperOrLower_TagName = c.upperOrLower_TagName; 090 this.upperOrLower_ClassAttrName = c.upperOrLower_ClassAttrName; 091 this.quotes = c.quotes; 092 } 093 094 095 // ******************************************************************************************** 096 // ******************************************************************************************** 097 // Class-Config - "Setters" and "Getters" (This is SYNCHRONIZED, That's Why) 098 // ******************************************************************************************** 099 // ******************************************************************************************** 100 101 102 public synchronized AbstractConfig<T> setClassNameCSS(byte whichOne, String className) 103 { 104 checkWhichOne(whichOne); 105 ClassNameCSSException.check(className); 106 this.classNames[whichOne] = className; 107 return this; 108 } 109 110 public synchronized String getClassName(byte whichOne) 111 { checkWhichOne(whichOne); return this.classNames[whichOne]; } 112 113 public synchronized AbstractConfig<T> setSpanOrBold(byte whichOne, boolean spanOrBold) 114 { 115 checkWhichOne(whichOne); 116 this.spansOrBolds[whichOne] = spanOrBold; 117 return this; 118 } 119 120 public synchronized boolean getSpansOrBolds(byte whichOne) 121 { checkWhichOne(whichOne); return this.spansOrBolds[whichOne]; } 122 123 public synchronized AbstractConfig<T> setUtilizeOrForget(byte whichOne, boolean useOrForget) 124 { 125 checkWhichOne(whichOne); 126 this.utilize[whichOne] = useOrForget; 127 return this; 128 } 129 130 public synchronized boolean getUtilized(byte whichOne) 131 { checkWhichOne(whichOne); return this.utilize[whichOne]; } 132 133 private void checkWhichOne(byte whichOne) 134 { 135 if ((whichOne < 1) || (whichOne >= this.CONFIG_ARR_LEN)) 136 137 throw new IllegalArgumentException( 138 "You have passed an invalid value [" + whichOne + "], to parameter 'whichOne'. " + 139 "This must be a valid byte, whose value is between 1 and " + 140 (this.CONFIG_ARR_LEN - 1) 141 ); 142 } 143 144 145 // ******************************************************************************************** 146 // ******************************************************************************************** 147 // This method serves as a "Helper" to the method that creates a HiLiter in sub-classes 148 // ******************************************************************************************** 149 // ******************************************************************************************** 150 151 152 protected Ret2<TagNode[], TagNode[]> generateHiLiterHelper() 153 { 154 final String cAttr = this.upperOrLower_ClassAttrName ? "CLASS" : "class"; 155 final boolean useQuotes = (this.quotes != null); 156 final String q = useQuotes ? ("" + this.quotes.quote) : ""; 157 158 final TagNode CLOSE_SPAN = this.upperOrLower_TagName 159 ? HTMLTags.hasTag("SPAN", TC.ClosingTags) 160 : HTMLTags.hasTag("span", TC.ClosingTags); 161 162 final TagNode CLOSE_BOLD = this.upperOrLower_TagName 163 ? HTMLTags.hasTag("B", TC.ClosingTags) 164 : HTMLTags.hasTag("b", TC.ClosingTags); 165 166 final TagNode[] openers = new TagNode[this.CONFIG_ARR_LEN]; 167 final TagNode[] closers = new TagNode[this.CONFIG_ARR_LEN]; 168 169 for (int i=1; i < this.CONFIG_ARR_LEN; i++) 170 { 171 openers[i] = this.utilize[i] 172 ? TAG(cAttr, q, this.classNames[i], this.spansOrBolds[i]) 173 : null; 174 175 closers[i] = this.utilize[i] 176 ? (spansOrBolds[i] ? CLOSE_SPAN : CLOSE_BOLD) 177 : null; 178 } 179 180 return new Ret2<>(openers, closers); 181 } 182 183 private TagNode TAG(String cAttr, String q, String className, boolean spanOrBold) 184 { 185 final String tag; 186 187 if (upperOrLower_TagName) tag = spanOrBold ? "SPAN" : "B"; 188 else tag = spanOrBold ? "span" : "b"; 189 190 return new TagNode('<' + tag + ' ' + cAttr + '=' + q + className + q + '>'); 191 } 192 193 194 // ******************************************************************************************** 195 // ******************************************************************************************** 196 // Class-Config - java.lang.Object (JLO) & java.lang.Cloneable 197 // ******************************************************************************************** 198 // ******************************************************************************************** 199 200 201 public boolean equals(Object other) 202 { 203 if (! (other instanceof Torello.JavaDoc.SyntaxHiLite.AbstractConfig)) 204 return false; 205 206 @SuppressWarnings("rawtypes") 207 Torello.JavaDoc.SyntaxHiLite.AbstractConfig o = 208 (Torello.JavaDoc.SyntaxHiLite.AbstractConfig) other; 209 210 return 211 (this.CONFIG_ARR_LEN == o.CONFIG_ARR_LEN) 212 && Objects.equals(this.captureTheClassDummy, o.captureTheClassDummy) 213 214 && Arrays.equals(this.classNames, o.classNames) 215 && Arrays.equals(this.spansOrBolds, o.spansOrBolds) 216 && Arrays.equals(this.utilize, o.utilize) 217 218 // Tag-Case / Upper-Case or Lower-Case 219 && (this.upperOrLower_TagName == o.upperOrLower_TagName) 220 && (this.upperOrLower_ClassAttrName == o.upperOrLower_ClassAttrName) 221 && Objects.equals(this.quotes, o.quotes); 222 } 223 224 public int hashCode() 225 { 226 int ret = 0; 227 228 for (int i=0; i < this.CONFIG_ARR_LEN; i += 3) 229 ret += this.classNames[i].hashCode(); 230 231 for (int i=0; i < this.CONFIG_ARR_LEN; i += 3) 232 ret += (this.spansOrBolds[i] ? 1 : 0) * 1; 233 234 return ret; 235 } 236}