1 31 32 package org.opencms.jsp.decorator; 33 34 import org.opencms.file.CmsObject; 35 import org.opencms.main.CmsLog; 36 import org.opencms.util.CmsHtmlParser; 37 import org.opencms.util.CmsStringUtil; 38 39 import java.util.ArrayList ; 40 import java.util.List ; 41 42 import org.apache.commons.logging.Log; 43 44 import org.htmlparser.Text; 45 import org.htmlparser.util.Translate; 46 47 59 public class CmsHtmlDecorator extends CmsHtmlParser { 60 61 62 private static final String [] DELIMITERS = { 63 " ", 64 ",", 65 ".", 66 ";", 67 ":", 68 "!", 69 "(", 70 ")", 71 "'", 72 "?", 73 "\"", 74 " ", 75 """, 76 "\r\n", 77 "\n"}; 78 79 80 private static final String [] DELIMITERS_SECOND_LEVEL = {"-", "@", "/", ".", ","}; 81 82 83 private static final int FORWARD_LOOKUP = 5; 84 85 86 private static final Log LOG = CmsLog.getLog(CmsHtmlDecorator.class); 87 88 89 private static final String [] NON_TRANSLATORS = {" ", """}; 90 91 92 CmsDecoratorConfiguration m_config; 93 94 95 CmsDecorationBundle m_decorations; 96 97 102 public CmsHtmlDecorator(CmsDecoratorConfiguration config) { 103 104 m_config = config; 105 m_decorations = config.getDecorations(); 106 m_result = new StringBuffer (512); 107 m_echo = true; 108 } 109 110 115 public CmsHtmlDecorator(CmsObject cms) { 116 117 m_config = new CmsDecoratorConfiguration(cms); 118 m_decorations = m_config.getDecorations(); 119 m_result = new StringBuffer (512); 120 m_echo = true; 121 122 } 123 124 135 public static List splitAsList(String source, String [] delimiters, boolean trim, boolean includeDelimiters) { 136 137 List result = new ArrayList (); 138 String delimiter = new String (); 139 int i = 0; 140 int l = source.length(); 141 int n = -1; 142 int max = Integer.MAX_VALUE; 143 144 for (int j = 0; j < delimiters.length; j++) { 146 if (source.indexOf(delimiters[j]) > -1) { 147 if (source.indexOf(delimiters[j]) < max) { 148 max = source.indexOf(delimiters[j]); 149 n = source.indexOf(delimiters[j]); 150 delimiter = delimiters[j]; 151 } 152 } 153 } 154 155 while (n != -1) { 156 if ((i < n) || (i > 0) && (i < l)) { 158 result.add(trim ? source.substring(i, n).trim() : source.substring(i, n)); 159 if (includeDelimiters && n + delimiter.length() <= l) { 161 result.add(source.substring(n, n + delimiter.length())); 162 } 163 } else { 164 if (includeDelimiters && source.startsWith(delimiter)) { 166 result.add(delimiter); 167 } 168 } 169 i = n + delimiter.length(); 170 171 max = Integer.MAX_VALUE; 173 n = -1; 174 for (int j = 0; j < delimiters.length; j++) { 175 if (source.indexOf(delimiters[j], i) > -1) { 176 if (source.indexOf(delimiters[j], i) < max) { 177 max = source.indexOf(delimiters[j], i); 178 n = source.indexOf(delimiters[j], i); 179 delimiter = delimiters[j]; 180 } 181 } 182 } 183 184 } 185 if (n < 0) { 187 n = source.length(); 188 } 189 if (i < n) { 190 result.add(trim ? source.substring(i).trim() : source.substring(i)); 191 } 192 return result; 193 } 194 195 206 private void appendText(String text, String [] delimiters, boolean recursive) { 207 208 if (LOG.isDebugEnabled()) { 209 LOG.debug(Messages.get().getBundle().key(Messages.LOG_HTML_DECORATOR_APPEND_TEXT_2, m_config, text)); 210 } 211 212 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(text)) { 213 214 List wordList = splitAsList(text, delimiters, false, true); 216 217 for (int i = 0; i < wordList.size(); i++) { 218 String word = (String )wordList.get(i); 219 220 if (LOG.isDebugEnabled()) { 221 LOG.debug(Messages.get().getBundle().key( 222 Messages.LOG_HTML_DECORATOR_PROCESS_WORD_2, 223 word, 224 new Boolean (mustDecode(word, wordList, i)))); 225 } 226 227 if (mustDecode(word, wordList, i)) { 229 word = Translate.decode(word); 230 if (LOG.isDebugEnabled()) { 231 LOG.debug(Messages.get().getBundle().key(Messages.LOG_HTML_DECORATOR_DECODED_WORD_1, word)); 232 } 233 } 234 235 CmsDecorationObject decObj = null; 238 if (!hasDelimiter(word, delimiters)) { 239 decObj = (CmsDecorationObject)m_decorations.get(word); 240 } 241 242 if (LOG.isDebugEnabled()) { 243 LOG.debug(Messages.get().getBundle().key( 244 Messages.LOG_HTML_DECORATOR_DECORATION_FOUND_2, 245 decObj, 246 word)); 247 } 248 249 if (decObj == null) { 253 if (hasDelimiter(word, DELIMITERS_SECOND_LEVEL) && recursive) { 254 String secondLevel = word; 257 if (i < wordList.size() - 1) { 258 if (!((String )wordList.get(i + 1)).equals(" ")) { 259 secondLevel = word + (String )wordList.get(i + 1); 260 i++; 261 } 262 } 263 appendText(secondLevel, DELIMITERS_SECOND_LEVEL, false); 264 } else { 265 StringBuffer decKey = new StringBuffer (); 269 decKey.append(word); 270 int forwardLookup = wordList.size() - i - 1; 272 if (forwardLookup > FORWARD_LOOKUP) { 273 forwardLookup = FORWARD_LOOKUP; 274 } 275 if (i < wordList.size() - forwardLookup) { 276 for (int j = 1; j <= forwardLookup; j++) { 277 decKey.append(wordList.get(i + j)); 278 decObj = (CmsDecorationObject)m_decorations.get(decKey.toString()); 279 if (LOG.isDebugEnabled()) { 280 LOG.debug(Messages.get().getBundle().key( 281 Messages.LOG_HTML_DECORATOR_DECORATION_FOUND_FWL_3, 282 decObj, 283 word, 284 new Integer (j))); 285 } 286 if (decObj != null) { 287 if (LOG.isDebugEnabled()) { 288 LOG.debug(Messages.get().getBundle().key( 289 Messages.LOG_HTML_DECORATOR_DECORATION_APPEND_DECORATION_1, 290 decObj.getContentDecoration(m_config))); 291 } 292 m_result.append(decObj.getContentDecoration(m_config)); 294 i += j; 296 break; 297 } 298 } 299 } 300 if (decObj == null) { 301 if (LOG.isDebugEnabled()) { 302 LOG.debug(Messages.get().getBundle().key( 303 Messages.LOG_HTML_DECORATOR_DECORATION_APPEND_WORD_1, 304 word)); 305 } 306 m_result.append(word); 308 } 309 } 310 } else { 311 if (LOG.isDebugEnabled()) { 312 LOG.debug(Messages.get().getBundle().key( 313 Messages.LOG_HTML_DECORATOR_DECORATION_APPEND_DECORATION_1, 314 decObj.getContentDecoration(m_config))); 315 } 316 m_result.append(decObj.getContentDecoration(m_config)); 318 } 319 } 320 } else { 321 if (LOG.isDebugEnabled()) { 322 LOG.debug(Messages.get().getBundle().key( 323 Messages.LOG_HTML_DECORATOR_DECORATION_APPEND_ORIGINALTEXT_1, 324 text)); 325 } 326 m_result.append(text); 327 } 328 } 329 330 338 public String doDecoration(String html, String encoding) throws Exception { 339 340 return process(html, encoding); 341 } 342 343 350 private boolean hasDelimiter(String word, String [] delimiters) { 351 352 boolean delim = false; 353 for (int i = 0; i < delimiters.length; i++) { 354 if (word.indexOf(delimiters[i]) > -1) { 355 delim = true; 356 break; 357 } 358 } 359 return delim; 360 } 361 362 369 private boolean mustDecode(String word, List wordList, int count) { 370 371 boolean decode = true; 372 String nextWord = null; 373 374 if (count < wordList.size() - 1) { 375 nextWord = (String )wordList.get(count + 1); 376 } 377 if (nextWord != null && word.indexOf("&") > -1 && nextWord.startsWith(";")) { 380 return false; 381 } else { 382 for (int i = 0; i < NON_TRANSLATORS.length; i++) { 384 if (word.startsWith(NON_TRANSLATORS[i])) { 385 decode = false; 386 break; 387 } 388 } 389 } 390 return decode; 391 } 392 393 398 public void resetDecorationDefinitions() { 399 400 m_config.resetMarkedDecorations(); 401 } 402 403 406 public void visitStringNode(Text text) { 407 408 appendText(text.toPlainTextString(), DELIMITERS, true); 409 } 410 411 } 412 | Popular Tags |