Package org.docx4j.model.styles

Source Code of org.docx4j.model.styles.StyleTree$AugmentedStyle

package org.docx4j.model.styles;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.docx4j.XmlUtils;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.wml.Style;
import org.docx4j.wml.Styles;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Represent a style hierarchy as a tree.
*
* TODO - need a way to update/refresh.
*
* This is useful for creating certain representations
* (eg CSS).
*
* @author jharrop
*
*/
public class StyleTree {
 
  private static Logger log = LoggerFactory.getLogger(StyleTree.class);

  /**
   * Tree of table styles
   */
  private Tree<AugmentedStyle> tableTree = new Tree<AugmentedStyle>();
  public Tree<AugmentedStyle> getTableStylesTree() {
    return tableTree;
  }
 
  /**
   * Tree of paragraph styles
   */
  private Tree<AugmentedStyle> pTree = new Tree<AugmentedStyle>();
  public Tree<AugmentedStyle> getParagraphStylesTree() {
    return pTree;
  }

  /**
   * Tree of character styles
   */
  private Tree<AugmentedStyle> cTree = new Tree<AugmentedStyle>();
  public Tree<AugmentedStyle> getCharacterStylesTree() {
    return cTree;
  }

 
  /**
   * Build a StyleTree for stylesInUse.
   *
   * @param stylesInUse styles actually in use in the main document part, headers/footers, footnotes/endnotes
   * @param allStyles styles defined in the style definitions part
   */
  public StyleTree(Set<String> stylesInUse, Map<String, Style> allStyles) {
   
   
    // Set up Table style tree
    tableTree.setRootElement(new Node<AugmentedStyle>(tableTree, "table-root", null)); // a dummy root node
        for (String styleId : stylesInUse ) {
          if (tableTree.get(styleId)==null) {
           
              Style style = allStyles.get(styleId);
                if (style == null ) {
                  log.warn("Couldn't find style: " + styleId);
                  continue;
                } else if (style.getType()==null) {
                  log.warn("missing type: " + XmlUtils.marshaltoString(style));
                } else
            // Is it a table style?
            if (style.getType().equals("table")) {               
                // Need to create a node for this
              this.addNode(styleId, allStyles, tableTree);
            }
          }
        }
   

    // Set up Paragraph style tree
        Style rootStyle = allStyles.get("DocDefaults");
        if (rootStyle==null) {
          pTree.setRootElement(new Node<AugmentedStyle>(pTree, "p-root", null));
        } else {
          AugmentedStyle as = new AugmentedStyle(rootStyle);         
          pTree.setRootElement(new Node<AugmentedStyle>(pTree, "DocDefaults", as));         
        }
         
        for (String styleId : stylesInUse ) {
          if (pTree.get(styleId)==null) {
           
              Style style = allStyles.get(styleId);
                if (style == null ) {
                  log.warn("Couldn't find style: " + styleId);
                  // See BrokenStyleRemediator for some causes of this, and potential fix
                  continue;
                }
                               
            // Is it a paragraph style?
            if (style.getType()!=null
                && style.getType().equals("paragraph")) {               
                // Need to create a node for this
              log.debug("Adding '" +  styleId + "' to paragraph tree" );
              this.addNode(styleId, allStyles, pTree);
            }
          } else {
            log.debug(styleId + " is already in paragraph tree");
          }
        }
       
    // Set up Character style tree
    cTree.setRootElement(new Node<AugmentedStyle>(cTree, "c-root", null));
        for (String styleId : stylesInUse ) {
          if (cTree.get(styleId)==null) {
           
              Style style = allStyles.get(styleId);
                if (style == null ) {
                  log.warn("Couldn't find style: " + styleId);
                  continue;
                }              
            // Is it a character style?
            if (style.getType()!=null
                && style.getType().equals("character")) {               
                // Need to create a node for this
              this.addNode(styleId, allStyles, cTree);
            }
          } else {
            log.debug(styleId + " is already in character tree");
          }
        }       
  }
 
 
  private Node<AugmentedStyle> addNode(String styleId, Map<String, Style> allStyles,
      Tree<AugmentedStyle> tree) {

    log.debug(styleId);
      Style style = allStyles.get(styleId);
        if (style == null ) {
          log.error("Couldn't find style: " + styleId);
          return null;
        }              
   
      AugmentedStyle as = new AugmentedStyle(style);         
      Node<AugmentedStyle> n =
         new Node<AugmentedStyle>(tree, styleId, as);
     
      // Find its parent
      if (style.getBasedOn()==null) {
       
        // You can have more than 1 node which isn't based on anything
      log.debug("Style " + styleId + " is not based on anything.");
      tree.getRootElement().addChild(n);
     
      // TODO: this should be basedOn DocDefaults.    Consider whether to do this
      // at this point, or in SDP.createVirtualStylesForDocDefaults()
           
      } else if (style.getBasedOn().getVal()!=null) {
          String basedOnStyleName = style.getBasedOn().getVal();  
          log.debug("..based on " + basedOnStyleName);         
          if (tree.get(basedOnStyleName)==null) {
//              log.debug("..can disregard that null, but it shouldn't happen again for this style");         
            Node<AugmentedStyle> parent = addNode(basedOnStyleName, allStyles, tree);
            if (parent!=null) {
              parent.addChild(n);
            }
          } else {
            tree.get(basedOnStyleName).addChild(n);
          }
         
      } else {
        log.error("No basedOn set for: " + style.getStyleId() );
      }
     
      return n;
   
  }
 
 
  public static void main(String[] args) throws Exception {

    String inputfilepath = System.getProperty("user.dir") + "/sample-docs/StyleResolution.xml";
    WordprocessingMLPackage wmlPackage = WordprocessingMLPackage.load(new java.io.File(inputfilepath));   

    // Setup
      Set<String> stylesInUse = wmlPackage.getMainDocumentPart().getStylesInUse();

     
    Map<String, Style> allStyles = new HashMap<String, Style>();
    Styles styles = wmlPackage.getMainDocumentPart().getStyleDefinitionsPart(false).getJaxbElement();   
    for ( org.docx4j.wml.Style s : styles.getStyle() ) {       
      allStyles.put(s.getStyleId(), s)
      log.debug("live style: " + s.getStyleId() );
    }
     
    StyleTree st = new StyleTree(stylesInUse, allStyles);
   
    log.debug("\nParagraph styles\n");
    log.debug(st.pTree.toString());
    log.debug("\nCharacter styles\n");
    log.debug(st.cTree.toString());
   
    log.debug("\nParagraph classes\n");
    Iterator it = st.pTree.nodes.entrySet().iterator();
      while (it.hasNext()) {
          Map.Entry pairs = (Map.Entry)it.next();
         
          // Eclipse is fine with this, but not Ant.
          // Underlying problem is http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6665356 (fixed in  7(b44) )  
          // Preview Milestone 4 is b66. 
          // Which fixes this problem (remember, you need jdk1.7.0/jre/lib/endorsed/jaxb-*
         
          Node<AugmentedStyle> n
            = (Node<AugmentedStyle>)pairs.getValue();
          List<Node<AugmentedStyle>> classVals =  st.pTree.climb(n);
         
          log.debug(n.name + ":'" +
              getHtmlClassAttributeValue(st.pTree, n)
              + "'");
      }

      log.debug("\nRun classes\n");
    it = st.cTree.nodes.entrySet().iterator();
      while (it.hasNext()) {
          Map.Entry pairs = (Map.Entry)it.next();
                   
          Node<AugmentedStyle> n
            = (Node<AugmentedStyle>)pairs.getValue();
          List<Node<AugmentedStyle>> classVals =  st.cTree.climb(n);
         
          log.debug(n.name + ":'" +
              getHtmlClassAttributeValue(st.cTree, n)
              + "'");
      }
     
  }
 
  public static String getHtmlClassAttributeValue(Tree<AugmentedStyle> tree,
      Node<AugmentedStyle> n) {
      if (n==null) {
        log.error("Null node passed");
        return null;
      }
        List<Node<AugmentedStyle>> classVals =  tree.climb(n);
      StringBuffer sb = new StringBuffer();
        for (Node<AugmentedStyle> valNode : classVals) {
          // Avoid including root node (eg dummy character root node)
          if (valNode.getData()!=null) {
            sb.append(valNode.name + " ");
          }
        }
        return sb.toString();
  }
 
 
  public class AugmentedStyle {
   
    private Style s;   
   
    public AugmentedStyle(Style s) {
      this.s = s;
    }

    public Style getStyle() {
      return s;
    }
   
  }

}
TOP

Related Classes of org.docx4j.model.styles.StyleTree$AugmentedStyle

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.