Package org.concordion.ext.excel.conversion.cellcontent

Source Code of org.concordion.ext.excel.conversion.cellcontent.DefaultCommentConverter

package org.concordion.ext.excel.conversion.cellcontent;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Comment;
import org.concordion.ext.excel.ExcelConversionException;
import org.concordion.ext.excel.conversion.AbstractConversionStrategy;
import org.concordion.ext.excel.conversion.HTMLBuilder;

/**
* Knows how to convert Excel cell comments into html attributes, generally for calling concordion commands.
*
* This can add attributes to not only the current HTML element, but parent elements, by prefixing the name in the excel comment.
*
* <ul>
* <li><strong>name</strong>  Adds to the current element</li>
* <li><strong>../name</strong>  Adds to the parent element</li>
* <li><strong>../../name</strong>  Adds to the parent's parent element (and so on)</li>
* <li><strong>(table)name</strong>  Adds to the first parent element which is a table tag.  (replace table with any tag)</li>
* <li><strong>/name</strong> Adds the attribute to the root element of the HTML doc. </li>
* </ul>
*
* @author robmoffat
*
*/
public class DefaultCommentConverter extends AbstractConversionStrategy<Cell> {

  /**
   * We use a regular expression to extract name="value" pairs from the Excel Cell comments.
   * This is because the comments are not always well-formed markup.
   *
   * This is probably going to be a bit unreliable.
   */
  @Override
  public void process(Cell in, final HTMLBuilder out) {
    if (in == null) {
      return;
    }
   
    Comment comment = in.getCellComment();
    if (comment != null) {
      String commentString =comment.getString().toString();
     
      parseCommentString(commentString, new DefaultCommentConverter.Callback() {
     
        public void addAttribute(String name, String value) {
          setHtmlAttribute(name, value, out);
        }
       
      });
    }
  }
 
  static interface Callback {
   
    public void addAttribute(String name, String value);
   
   
  }
 
  enum Mode { READING_NAME, LOOKING_FOR_EQUALS, LOOKING_FOR_VALUE, READING_VALUE_UNQUOTED, READING_VALUE_SINGLE, READING_VALUE_DOUBLE }
 
  protected void parseCommentString(String in, Callback c) {
    Mode m = Mode.READING_NAME; 
    String name = null;
    StringBuilder elem = new StringBuilder();
    int i = 0;
    while (i < in.length()) {
      char ch = in.charAt(i);
      i++;
      switch (m) {
        case READING_NAME:
          if (Character.isWhitespace(ch))  {
            name = extract(elem);
            m = Mode.LOOKING_FOR_EQUALS;
          } else if ('=' == ch) {
            name = elem.toString();
            elem.setLength(0);
            m = Mode.LOOKING_FOR_VALUE;
          } else{
            elem.append(ch);
          }
          break;
        case LOOKING_FOR_EQUALS:
          if (Character.isWhitespace(ch))  {
            // do nothing
          } else if ('=' == ch) {
            m = Mode.LOOKING_FOR_VALUE;
          } else{
            // starting a new name
            elem.append(ch);
            m = Mode.READING_NAME;
          }
          break;
        case LOOKING_FOR_VALUE:
          if (Character.isWhitespace(ch)) {
            // do nothing
          } else if ('\'' == ch) {
            m = Mode.READING_VALUE_SINGLE;
          } else if ('\"' == ch) {
            m = Mode.READING_VALUE_DOUBLE;
          } else {
            m = Mode.READING_VALUE_UNQUOTED;
          }
          break;
        case READING_VALUE_UNQUOTED:
          if (Character.isWhitespace(ch))  {
            c.addAttribute(name, elem.toString());
            extract(elem);
            m = Mode.READING_NAME;
          } else {
            elem.append(ch);
          }
          break;
        case READING_VALUE_DOUBLE:
          if ('"' == ch)  {
            c.addAttribute(name, elem.toString());
            extract(elem);
            m = Mode.READING_NAME;
          } else {
            elem.append(ch);
          }
          break;
        case READING_VALUE_SINGLE:
          if ('\'' == ch)  {
            c.addAttribute(name, elem.toString());
            extract(elem);
            m = Mode.READING_NAME;
          } else {
            elem.append(ch);
          }
          break;
      }
    }
  }
     
 
  private String extract(StringBuilder elem) {
    String out = elem.toString();
    elem.setLength(0);
    return out;
  }


  private void setHtmlAttribute(String name, String value, HTMLBuilder out) {
    if (name.startsWith("../")) {
      setHtmlAttribute(name.substring(3), value, out.withParentTag());
    } else if (name.startsWith("(")) {
      int rightParen = name.indexOf(")");
      String tag = name.substring(1, rightParen);
      name = name.substring(rightParen+1);
      out = findMatchingParentTag(out, tag);
      out.addAttribute(name, value);
    } else if (name.startsWith("/")) {
      name = name.substring(1);
      out = out.withRootTag();
    } else {
      out.addAttribute(name, value);
    }
  }

  private HTMLBuilder findMatchingParentTag(HTMLBuilder out, String tag) {
    try {
      if (tag.equals(out.getCurrentOpenTag())) {
        return out;
      } else {
        return findMatchingParentTag(out.withParentTag(), tag);
      }
    } catch (ExcelAttributeConversionException e) {
      throw e;
    } catch (ExcelConversionException ce) {
      throw new ExcelAttributeConversionException("Couldn't find matching tag: "+tag, ce);
    }
  }

}
TOP

Related Classes of org.concordion.ext.excel.conversion.cellcontent.DefaultCommentConverter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.