001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.maven.doxia.sink.impl; 020 021import org.apache.maven.doxia.markup.Markup; 022import org.apache.maven.doxia.sink.EmptyLocator; 023import org.apache.maven.doxia.sink.Locator; 024import org.apache.maven.doxia.sink.Sink; 025import org.apache.maven.doxia.sink.SinkEventAttributes; 026 027/** 028 * An abstract base class that defines some convenience methods for sinks. 029 * Also acts as compatibility bridge for Doxia 1.0 methods which have overloaded variants in Doxia > 1.0 (taking an additional argument {@link SinkEventAttributes}). 030 * This implementation just delegates the former to the latter with argument {@link SinkEventAttributes} being {@code null}. 031 * 032 * @author ltheussl 033 * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a> 034 * @since 1.1 035 */ 036public abstract class AbstractSink implements Sink, Markup { 037 038 private Locator locator; 039 040 // -- start default implementation for legacy doxia 1.0 methods which have overridden variants in Doxia 1.1 or 2.0, 041 // all sink implementation derived from this must only override the Doxia > 1.0 variants 042 @Override 043 public final void head() { 044 head(null); 045 } 046 047 @Override 048 public final void title() { 049 title(null); 050 } 051 052 @Override 053 public final void author() { 054 author(null); 055 } 056 057 @Override 058 public final void date() { 059 date(null); 060 } 061 062 @Override 063 public final void body() { 064 body(null); 065 } 066 067 @Override 068 public final void article() { 069 article(null); 070 } 071 072 @Override 073 public final void navigation() { 074 navigation(null); 075 } 076 077 @Override 078 public final void sidebar() { 079 sidebar(null); 080 } 081 082 @Override 083 public final void sectionTitle() { 084 sectionTitle(0, null); 085 } 086 087 @Override 088 public final void section1() { 089 section(1, null); 090 } 091 092 @Override 093 public final void sectionTitle_() { 094 sectionTitle_(0); 095 } 096 097 @Override 098 public final void section1_() { 099 section_(1); 100 } 101 102 @Override 103 public final void sectionTitle1() { 104 sectionTitle(1, null); 105 } 106 107 @Override 108 public final void sectionTitle1_() { 109 sectionTitle_(1); 110 } 111 112 @Override 113 public final void section2() { 114 section(2, null); 115 } 116 117 @Override 118 public final void section2_() { 119 section_(2); 120 } 121 122 @Override 123 public final void sectionTitle2() { 124 sectionTitle(2, null); 125 } 126 127 @Override 128 public final void sectionTitle2_() { 129 sectionTitle_(2); 130 } 131 132 @Override 133 public final void section3() { 134 section(3, null); 135 } 136 137 @Override 138 public final void section3_() { 139 section_(3); 140 } 141 142 @Override 143 public final void sectionTitle3() { 144 sectionTitle(3, null); 145 } 146 147 @Override 148 public final void sectionTitle3_() { 149 sectionTitle_(3); 150 } 151 152 @Override 153 public final void section4() { 154 section(4, null); 155 } 156 157 @Override 158 public final void section4_() { 159 section_(4); 160 } 161 162 @Override 163 public final void sectionTitle4() { 164 sectionTitle(4, null); 165 } 166 167 @Override 168 public final void sectionTitle4_() { 169 sectionTitle_(4); 170 } 171 172 @Override 173 public final void section5() { 174 section(5, null); 175 } 176 177 @Override 178 public final void section5_() { 179 section_(5); 180 } 181 182 @Override 183 public final void sectionTitle5() { 184 sectionTitle(5, null); 185 } 186 187 @Override 188 public final void sectionTitle5_() { 189 sectionTitle_(5); 190 } 191 192 @Override 193 public final void section6() { 194 section(6, null); 195 } 196 197 @Override 198 public final void section6_() { 199 section_(6); 200 } 201 202 @Override 203 public final void sectionTitle6() { 204 sectionTitle(6, null); 205 } 206 207 @Override 208 public final void sectionTitle6_() { 209 sectionTitle_(6); 210 } 211 212 @Override 213 public final void header() { 214 header(null); 215 } 216 217 @Override 218 public final void content() { 219 content(null); 220 } 221 222 @Override 223 public final void footer() { 224 footer(null); 225 } 226 227 @Override 228 public final void list() { 229 list(null); 230 } 231 232 @Override 233 public final void listItem() { 234 listItem(null); 235 } 236 237 @Override 238 public final void numberedList(int numbering) { 239 numberedList(numbering, null); 240 } 241 242 @Override 243 public final void numberedListItem() { 244 numberedListItem(null); 245 } 246 247 @Override 248 public final void definitionList() { 249 definitionList(null); 250 } 251 252 @Override 253 public final void definitionListItem() { 254 definitionListItem(null); 255 } 256 257 @Override 258 public final void definition() { 259 definition(null); 260 } 261 262 @Override 263 public final void definedTerm() { 264 definedTerm(null); 265 } 266 267 @Override 268 public final void figure() { 269 figure(null); 270 } 271 272 @Override 273 public final void figureCaption() { 274 figureCaption(null); 275 } 276 277 @Override 278 public final void figureGraphics(String name) { 279 figureGraphics(name, null); 280 } 281 282 @Override 283 public final void table() { 284 table(null); 285 } 286 287 @Override 288 public final void tableRows() { 289 tableRows(null, false); 290 } 291 292 @Override 293 public final void tableRow() { 294 tableRow(null); 295 } 296 297 @Override 298 public final void tableCell() { 299 tableCell(null); 300 } 301 302 @Override 303 public final void tableHeaderCell() { 304 tableHeaderCell(null); 305 } 306 307 @Override 308 public final void tableCaption() { 309 tableCaption(null); 310 } 311 312 @Override 313 public final void paragraph() { 314 paragraph(null); 315 } 316 317 @Override 318 public final void data(String value) { 319 data(value, null); 320 } 321 322 @Override 323 public final void time(String datetime) { 324 time(datetime, null); 325 } 326 327 @Override 328 public final void address() { 329 address(null); 330 } 331 332 @Override 333 public final void blockquote() { 334 blockquote(null); 335 } 336 337 @Override 338 public final void division() { 339 division(null); 340 } 341 342 @Override 343 public final void verbatim() { 344 verbatim(null); 345 } 346 347 @Override 348 public final void horizontalRule() { 349 horizontalRule(null); 350 } 351 352 @Override 353 public final void anchor(String name) { 354 anchor(name, null); 355 } 356 357 @Override 358 public final void link(String name) { 359 link(name, null); 360 } 361 362 @Override 363 public final void inline() { 364 inline(null); 365 } 366 367 @Override 368 public final void lineBreak() { 369 lineBreak(null); 370 } 371 372 @Override 373 public final void lineBreakOpportunity() { 374 lineBreakOpportunity(null); 375 } 376 377 @Override 378 public final void text(String text) { 379 text(text, null); 380 } 381 // -- end default implementation for legacy doxia 1.0 methods which have overridden variants in Doxia 1.1 or 2.0 382 383 /** 384 * Parses the given String and replaces all occurrences of 385 * '\n', '\r' and '\r\n' with the system EOL. All Sinks should 386 * make sure that text output is filtered through this method. 387 * 388 * @param text the text to scan. 389 * May be null in which case null is returned. 390 * @return a String that contains only System EOLs. 391 */ 392 protected static String unifyEOLs(String text) { 393 if (text == null) { 394 return null; 395 } 396 397 int length = text.length(); 398 399 StringBuilder buffer = new StringBuilder(length); 400 401 for (int i = 0; i < length; i++) { 402 if (text.charAt(i) == '\r') { 403 if ((i + 1) < length && text.charAt(i + 1) == '\n') { 404 i++; 405 } 406 407 buffer.append(EOL); 408 } else if (text.charAt(i) == '\n') { 409 buffer.append(EOL); 410 } else { 411 buffer.append(text.charAt(i)); 412 } 413 } 414 415 return buffer.toString(); 416 } 417 418 /** 419 * This is called in {@link #head()} or in {@link #close()}, and can be used 420 * to set the sink into a clear state so it can be re-used. 421 * 422 * @since 1.1.2 423 */ 424 protected void init() { 425 // nop 426 } 427 428 @Override 429 public void setDocumentLocator(Locator locator) { 430 this.locator = locator; 431 } 432 433 @Override 434 public Locator getDocumentLocator() { 435 if (locator == null) { 436 return EmptyLocator.INSTANCE; 437 } 438 return locator; 439 } 440 441 protected String getLocationLogPrefix() { 442 return formatLocation(getDocumentLocator()); 443 } 444 445 /** 446 * Creates a string with line/column information. Inspired by 447 * {@code o.a.m.model.building.ModelProblemUtils.formatLocation(...)}. 448 * 449 * @param locator The locator must not be {@code null}. 450 * @return The formatted location or an empty string if unknown, never {@code null}. 451 */ 452 public static String formatLocation(Locator locator) { 453 StringBuilder buffer = new StringBuilder(); 454 455 if (locator.getReference() != null) { 456 buffer.append(locator.getReference()); 457 } else { 458 buffer.append("Unknown source"); 459 } 460 if (locator.getLineNumber() > 0) { 461 buffer.append(", line ").append(locator.getLineNumber()); 462 } 463 if (locator.getColumnNumber() > 0) { 464 buffer.append(", column ").append(locator.getColumnNumber()); 465 } 466 if (buffer.length() > 0) { 467 buffer.append(": "); 468 } 469 return buffer.toString(); 470 } 471}