All Downloads are FREE. Search and download functionalities are using the official Maven repository.

fr.opensagres.xdocreport.document.odt.preprocessor.ODTAnnotationParsingHelper Maven / Gradle / Ivy

/**
 * Copyright (C) 2011-2015 The XDocReport Team 
 *
 * All rights reserved.
 *
 * 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 fr.opensagres.xdocreport.document.odt.preprocessor;

import static fr.opensagres.xdocreport.document.odt.ODTConstants.ANNOTATION_DC_NS;
import static fr.opensagres.xdocreport.document.odt.ODTConstants.PARAGRAPH_ELT;
import static java.util.Arrays.asList;
import static java.util.Collections.unmodifiableList;

import java.util.List;

import fr.opensagres.xdocreport.core.utils.StringUtils;

/**
 * ODT annotation handler. Functions:
 * 
    *
  • safe iterate over blok: table:table-row, text:list-item, text:section, * using @before#foreach()$after#end syntax
  • *
  • safe replace range annotations with annotation content
  • *
  • annotation content is treated as simple unformatted text
  • *
* *

Created on 2018-07-06

* * @author Marcin Golebski * @version $Id$ */ public class ODTAnnotationParsingHelper { private static final String BEFORE_LABEL = "@before"; private static final String AFTER_LABEL = "@after"; private static final List PARRENTS = unmodifiableList( asList( "table:table-row", "text:list-item", "text:section") ); private boolean parsing = false; private StringBuilder content; private boolean ignore; private String replacement; private String after; private String before; private String name; private int index; private boolean notReplacedYet; /** * The annotation tag is parsing now. * * @return true if annotation tag is parsing now, * false otherwise */ public boolean isParsing() { return parsing; } /** * Inform this helper which component is parsed now. * * @param uri * @param localName * @param name */ public void setCurrentElement( String uri, String localName, String name ) { if ( ANNOTATION_DC_NS.equals(uri) ) { ignore = true; return; } ignore = false; if( PARAGRAPH_ELT.equals(localName) && content.length()>0 ) { content.append('\n'); } } /** * Set the helper in the state of parsing annotation tag content. * * @param name the name of the annotation. Not null * when annotation has end element somewere in document * @param index index of the annotation element. It is used to close * replacement block in proper place (replacement block is not allowed * to span over the end of enclosed tag) */ public void setParsingBegin( String name, int index ) { this.parsing = true; this.content = new StringBuilder(); this.ignore = false; this.before = null; this.after = null; this.replacement = null; // avoid empty string if( StringUtils.isNotEmpty( name ) ) { this.name = name; } else { this.name = null; } this.index = index; this.notReplacedYet = true; } public void setParsingEnd() { parse(); parsing = false; } /** * Close range annotation. * * @param name the name of the range annotation * @param force if true block will be closed even if name * does not match * @return true if the name is the name of the first oppened * annotation, false otherwise */ public boolean resetRangeAnnotation( String name, boolean force ) { if( force || ( StringUtils.isNotEmpty( name ) && name.equals(this.name) ) ) { this.name = null; this.parsing = false; return true; } return false; } /** * Parse the annotation content. It splits into 3 section: *
    *
  • replacement
  • *
  • before
  • *
  • after
  • *
*/ private void parse() { int indexBefore = content.indexOf(BEFORE_LABEL); int indexAfter = content.indexOf(AFTER_LABEL); if ( indexBefore < 0 && indexAfter < 0 ) { if( content.length() > 0 ) { replacement = content.toString(); } } else if( indexBefore < 0 || indexAfter < 0) { if( indexBefore > 0 || indexAfter > 0 ) { replacement = content.substring(0, Math.max( indexBefore, indexAfter) ); } if( indexBefore < 0 ) { after = content.substring(indexAfter + AFTER_LABEL.length(), content.length()); } else { before = content.substring(indexBefore + BEFORE_LABEL.length(), content.length()); } } else if( indexBefore < indexAfter ) { if( indexBefore > 0 ) { replacement = content.substring(0, indexBefore); } before = content.substring(indexBefore + BEFORE_LABEL.length(), indexAfter); after = content.substring(indexAfter + AFTER_LABEL.length(), content.length()); } else { if( indexAfter > 0) { replacement = content.substring(0, indexAfter); } after = content.substring(indexAfter + AFTER_LABEL.length(), indexBefore); before = content.substring(indexBefore + BEFORE_LABEL.length(), content.length()); } } /** * Append new string into annotation content. * * @param value the value being appended */ public void append( String value ) { if( ignore ) { return; } content.append(value); } /** * Return type of parrents which are itrable using point-annotation. * * @return the list of tag names */ public List getParents() { return PARRENTS; } /** * Check if annotation has "before" part. * * @return true if annotation has "before" part, false * otherwise */ public boolean hasBefore() { return before != null; } /** * Returns "before" part of annotation content. * * @return "before" part */ public String getBefore() { return before; } /** * Check if annotation has "after" part. * * @return true if annotation has "after" part, false * otherwise */ public boolean hasAfter() { return after != null; } /** * Returns "after" part of annotation content. * * @return "after" part */ public String getAfter() { return after; } /** * Check if annotation has "replacement" part. * * @return true if annotation has "replacement" part, * false otherwise */ public boolean hasReplacement() { return replacement != null; } /** * Returns "replacement" part of annotation content. * * @return "replacement" part */ public String getReplacement() { return replacement; } /** * Check if this anotation is "point" or "range" anotation. * * @return true if this is range annotation, false * otherwise */ public boolean isRangeAnnotation() { return name != null; } /** * Check if index of current element shows we are in the same block like * anotation is. It is used to check if we should force to close range * annotation which is setup across many tags. * * @param currentElementIndex the index of current tag * @return true if current tag is the same container like * anotation is, false otherwise */ public boolean isTheSameBlock(int currentElementIndex) { return currentElementIndex >= index; } /** * Check if in case of range annotation replacement has been already done. * * @return true when replacement has been already performed, * false otherwise */ public boolean isNotReplacedYet() { return notReplacedYet; } /** * Should be executed, when range annotation replacemen is done. It prevents * unwanted multiple relacement when several containers is present in * annotation range. */ public void setReplacementDone() { this.notReplacedYet = false; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy