Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   package org.docx4j.model;
   
   
   import java.util.HashMap;
   import java.util.Iterator;
   import java.util.List;
   import java.util.Map;
   import java.util.Stack;
   
  
  import org.slf4j.Logger;
This class works out the actual set of properties (paragraph or run) which apply, following the order specified in ECMA-376. From ECMA-376 > Part3 > 2 Introduction to WordprocessingML > 2.8 Styles > 2.8.10 Style Application at http://www.documentinteropinitiative.org/implnotes/ecma-376/P3-2.8.10.aspx (See also Part 4, 2.7.2 which is the normative bit...) With the various flavors of styles available, multiple style types can be applied to the same content within a file, which means that properties must be applied in a specific deterministic order. As with inheritance, the resulting formatting properties set by one type can be unchanged, removed, or altered by following types. The following table illustrates the order of application of these defaults, and which properties are impacted by each: This process can be described as follows: First, the document defaults are applied to all runs and paragraphs in the document. Next, the table style properties are applied to each table in the document, following the conditional formatting inclusions and exclusions specified per table. Next, numbered item and paragraph properties are applied to each paragraph formatted with a numbering style. Next, paragraph and run properties are applied to each paragraph as defined by the paragraph style. Next, run properties are applied to each run with a specific character style applied. Finally, we apply direct formatting (paragraph or run properties not from styles). ----------- Things which are unclear: - the role of w:link on a paragraph style (eg Heading1 links to "Heading1char"), experimentation in Word 2007 suggests the w:link is not used at all - indeed, "Heading1char" is not used at all? ----------- docx4all does not use this; its org.docx4all.swing.text.StyleSheet uses MutableAttributeSet's resolve function to climb the style hierarchy. This is most relevant to XSLFO, which unlike CSS, doesn't have a concept of style. HTML NG2 uses CSS inheritance, and so doesn't need it.

Author(s):
jharrop
  
  public class PropertyResolver {
  	
  	private static Logger log = LoggerFactory.getLogger(PropertyResolver.class);
 	
 //	private DocDefaults docDefaults;	
 	
 	public RPr getDocumentDefaultRPr() {
 	}
 
 	
All styles in the Style Definitions Part.
 
 	private org.docx4j.wml.Styles styles;

Map of all styles in the Style Definitions Part. Note, you need to manually keep this up to date
 
 	private java.util.Map<Stringorg.docx4j.wml.Style>  liveStyles = null;
 	
 	
 	private ThemePart themePart;
 
 
This map also contains the rPr component of a pPr
 
 	
 	public PropertyResolver(WordprocessingMLPackage wordMLPackagethrows Docx4JException {
 		
 		this. = wordMLPackage;
 		
 		MainDocumentPart mdp = wordMLPackage.getMainDocumentPart();
 		
 		if (wordMLPackage.getMainDocumentPart().getDocumentSettingsPart()!=null) {
 		}
 		init();		
 	}
 	
 	
 //	public PropertyResolver(StyleDefinitionsPart styleDefinitionsPart,
 //							ThemePart themePart,
 //							NumberingDefinitionsPart numberingDefinitionsPart) throws Docx4JException {
 //		
 //		this.styleDefinitionsPart= styleDefinitionsPart;
 //		this.themePart = themePart;
 //		this.numberingDefinitionsPart = numberingDefinitionsPart;
 //		init();
 //	}
 	
 	String defaultParagraphStyleId;  // "Normal" in English, but ...
 	
 	private void init() throws Docx4JException {
 
 		
 
 		// Initialise styles
 		
 		Style docDefaults = .getStyleById("DocDefaults");
 		 = docDefaults.getPPr();
 		 = docDefaults.getRPr();
 
 	}
 
 
 		
 		Stack<PPrpPrStack = new Stack<PPr>();
 //		String styleId = "Normal";
 		
 		fillPPrStack(styleIdpPrStack);
 			
 		PPr effectivePPr = .createPPr();			
 		// Now, apply the properties starting at the top of the stack
 		while (!pPrStack.empty() ) {
 			PPr pPr = pPrStack.pop();
 			applyPPr(pPreffectivePPr);
 		}
 		.put(styleIdeffectivePPr);		
 	}
 
 	Stack<RPrrPrStack = new Stack<RPr>();
 
 			// Since default font size might be in there.
 		
 			
 		RPr effectiveRPr = .createRPr();
 		
 		// Now, apply the properties starting at the top of the stack
 		while (!rPrStack.empty() ) {
 			RPr rPr = rPrStack.pop();
 			applyRPr(rPreffectiveRPr);
 		}
 	}
 	
 	public Style getEffectiveTableStyle(TblPr tblPr) {
 		// OK to pass this a null tblPr.
 		
 		Stack<StyletableStyleStack = new Stack<Style>();
 		
 		if (tblPr !=null && tblPr.getTblStyle()!=null) {
 			String styleId = tblPr.getTblStyle().getVal();
 			.debug("Table style: " + styleId);
 			fillTableStyleStack(styleIdtableStyleStack);
 		} else {
 			.debug("No table style specified");
 		}
 		
 		Style result;
 		if (tableStyleStack.size()>0 ) {
 			result = XmlUtils.deepCopy(tableStyleStack.pop());
 		} else {
 			result = Context.getWmlObjectFactory().createStyle();
 			if (tblPr==null) {
 				// Return empty style object
 				return result;
 			}			
 		}
 		while (!tableStyleStack.empty() ) {
 			StyleUtil.apply(tableStyleStack.pop(), result);
 		}
 		
 		// Finally apply the tblPr we were passed
 		result.setTblPr(StyleUtil.apply(tblPrresult.getTblPr()));
 		
 		return result;
 	}

Ascend the style hierarchy, capturing the table styles

Parameters:
stylename
effectivePPr
 
 	private void fillTableStyleStack(String styleIdStack<StyletableStyleStack) {
 		// get the style
 		Style style = .get(styleId);
 		
 		// add it to the stack
 		if (style==null) {
 			// No such style!
 			// For now, just log it..
 			.error("Style definition not found: " + styleId);
 			return;
 		}
 		
 		tableStyleStack.push(style);
 		.debug("Added " + styleId + " to table style stack");
 		
 		// if it is based on, recurse
     	if (style.getBasedOn()==null) {
 			.debug("Style " + styleId + " is a root style.");
     	} else if (style.getBasedOn().getVal()!=null) {
         	String basedOnStyleName = style.getBasedOn().getVal();           	
         	fillTableStyleStackbasedOnStyleNametableStyleStack);
     	} else {
     		.debug("No basedOn set for: " + style.getStyleId() );
     	}
 		
 	}


Follow the resolution rules to return the paragraph properties which actually apply, given this pPr element (on a w:p). Note 1: the properties are not the definition of any style name returned. Note 2: run properties are not resolved or returned by this method. What is returned is a live object. If you want to change it, you should clone it first!

Parameters:
expressPPr
Returns:
 
 	public PPr getEffectivePPr(PPr expressPPr) {
 		
 		PPr effectivePPr = null;
 		//	First, the document defaults are applied
 		
 			// Done elsewhere
 			// PPr effectivePPr = (PPr)XmlUtils.deepCopy(documentDefaultPPr);
 		
 		//	Next, the table style properties are applied to each table in the document, 
 		//	following the conditional formatting inclusions and exclusions specified 
 		//	per table. 
 		
 			// TODO - if the paragraph is in a table?
 				
 		//	Next, numbered item and paragraph properties are applied to each paragraph 
 		//	formatted with a *numbering *style**.
 		
 			// TODO - who uses numbering styles (as opposed to numbering
 			// via a paragraph style or direct formatting)?
 		
 		//  Next, paragraph and run properties are 
 		//	applied to each paragraph as defined by the paragraph style.
 		PPr resolvedPPr = null;
 		String styleId;
 		if (expressPPr == null || expressPPr.getPStyle() == null ) {
 //			styleId = "Normal";
 			
 		} else {
 			styleId = expressPPr.getPStyle().getVal();
 		}
 		resolvedPPr = getEffectivePPr(styleId);
 		
 				
 		//	Next, run properties are applied to each run with a specific character style 
 		//	applied. 
 		
 			// Not for pPr
 				
 		//	Finally, we apply direct formatting (paragraph or run properties not from 
 		//	styles).		
 		if (hasDirectPPrFormatting(expressPPr) ) {
 			if (resolvedPPr==null) {
 				.warn("resolvedPPr was null. Look into this?");
 				effectivePPr = Context.getWmlObjectFactory().createPPr();
 			} else {
 				effectivePPr = (PPr)XmlUtils.deepCopy(resolvedPPr);
 			}
 			applyPPr(expressPPreffectivePPr);
 			return effectivePPr;
 		} else {
 			return resolvedPPr;
 		}
 		
 	}

Follow the resolution rules to return the paragraph properties which actually apply, given this paragraph style Note 1: the properties are not the definition of any style name returned. Note 2: run properties are not resolved or returned by this method. What is returned is a live object. If you want to change it, you should clone it first!

Parameters:
expressPPr
Returns:
 
 	public PPr getEffectivePPr(String styleId) {
 
 		PPr resolvedPPr = .get(styleId);
 		
 		if (resolvedPPr!=null) {
 			return resolvedPPr;
 		}
 		
 		// Hmm, have to do the work
 		Style s = .get(styleId);
 		
 		if (s==null) {
 			.error("Couldn't find style: " + styleId);
 			return null;
 		}
 		
 		PPr expressPPr = s.getPPr();
 		if (expressPPr==null) {
 			// A paragraph style may have no w:pPr component
 			.debug("style: " + styleId + " has no PPr");
 			resolvedPPr = .get(normalId);
 			return resolvedPPr;
 		}
 		
 		//  Next, paragraph and run properties are 
 		//	applied to each paragraph as defined by the paragraph style.
 		Stack<PPrpPrStack = new Stack<PPr>();
 		// Haven't done this one yet				
 		fillPPrStack(styleIdpPrStack);
 		// Finally, on top
 						
 		resolvedPPr = .createPPr();			
 		// Now, apply the properties starting at the top of the stack
 		while (!pPrStack.empty() ) {
 			PPr pPr = pPrStack.pop();
 			applyPPr(pPrresolvedPPr);
 		}
 		.put(styleIdresolvedPPr);
 		return resolvedPPr;
 	}

Parameters:
expressRPr
pPr -
Returns:
 
 	public RPr getEffectiveRPr(RPr expressRPrPPr pPr) {
 		
 		// NB Currently used in PDF viaXSLFO only
 		
 		if (pPr==null) {
 			.debug("pPr was null");
 		} else {
 			// At the pPr level, what rPr do we have?
 			// .. ascend the paragraph style tree
 			if (pPr.getPStyle()==null) {
 //					log.warn("No pstyle:");
 //					log.debug(XmlUtils.marshaltoString(pPr, true, true));
 			} else {
 				.debug("pstyle:" + pPr.getPStyle().getVal());
 				RPr pPrLevelRunStyle = getEffectiveRPr(pPr.getPStyle().getVal());
 				// .. and apply those
 				
 				return getEffectiveRPrUsingPStyleRPr(expressRPrpPrLevelRunStyle);
 			}
 			// Check Paragraph rPr (our special hack of using ParaRPr to format a fo:block)
 			// 2013 10 02: doubts whether this is right?
 			if ((expressRPr == null) && (pPr.getRPr() != null) && (hasDirectRPrFormatting(pPr.getRPr())) ) {			
 				return getEffectiveRPrUsingPStyleRPr(expressRPr
 						StyleUtil.apply(pPr.getRPr(), Context.getWmlObjectFactory().createRPr()));
 			} 
 		}
 
 		return getEffectiveRPrUsingPStyleRPrexpressRPrnull);
 		
 	}
 
 	public RPr getEffectiveRPrUsingPStyleRPr(RPr expressRPrRPr pPrLevelRunStyle) {
 		
 		.debug("in getEffectiveRPrUsingPStyle");
 //		Throwable t = new Throwable();
 //		t.printStackTrace();
 		
 		
 //		Idea is that you pass pPr if you are using this for XSL FO,
 //		since we need to take account of rPr in paragraph styles
 //		(but not the rPr in a pPr direct formatting, since
 //       that only applies to the paragraph mark). 
 //		 * For HTML/CSS, this would be null (since the pPr level rPr 
 //		 * is made into a separate style applied via a second value in
 //		 * the class attribute).  But, in the CSS case, this
 		// function is not used - since the rPr is made into a style as well.
 		
 
 // Not necessary, since docdefaults are part of the stack		
 //		//	First, the document defaults are applied
 //		
 //			RPr effectiveRPr = (RPr)XmlUtils.deepCopy(documentDefaultRPr);
 //			
 //			// Apply DefaultParagraphFont.  We only do it explicitly
 //			// here as per conditions, because if there is a run style,
 //			// walking the hierarchy will include this if it is needed
 //			if (expressRPr == null || expressRPr.getRStyle() == null ) {
 //				applyRPr(resolvedStyleRPrComponent.get(defaultCharacterStyleId), effectiveRPr);								
 //			}
 		
 		RPr effectiveRPr = null;		
 		if (pPrLevelRunStyle==null) {
 			effectiveRPr = Context.getWmlObjectFactory().createRPr();
 		} else {
 			effectiveRPr=(RPr)XmlUtils.deepCopy(pPrLevelRunStyle);
 		}
 		
 //    	System.out.println("start\n" + XmlUtils.marshaltoString(effectiveRPr, true, true));
 		
 		
 		//	Next, the table style properties are applied to each table in the document, 
 		//	following the conditional formatting inclusions and exclusions specified 
 		//	per table. 
 		
 			// TODO - if the paragraph is in a table?
 				
 		//	Next, numbered item and paragraph properties are applied to each paragraph 
 		//	formatted with a *numbering *style**.
 		
 //			 TODO - who uses numbering styles (as opposed to numbering
 			// via a paragraph style or direct formatting)?
 		
 		//  Next, paragraph and run properties are 
 		//	applied to each paragraph as defined by the paragraph style
 		// (this includes run properties defined in a paragraph style,
 		//  but not run properties directly included in a pPr in the
 		//  document (those only apply to a paragraph mark).
 //		applyRPr(pPrLevelRunStyle, effectiveRPr);
 					
 		//	Next, run properties are applied to each run with a specific character style 
 		//	applied. 		
 		RPr resolvedRPr = null;
 		String runStyleId;
 		if (expressRPr != null && expressRPr.getRStyle() != null ) {
 			runStyleId = expressRPr.getRStyle().getVal();
 			resolvedRPr = getEffectiveRPr(runStyleId);
 			StyleUtil.apply(resolvedRPreffectiveRPr);
 //	    	System.out.println("resolved=\n" + XmlUtils.marshaltoString(resolvedRPr, true, true));
 			
 		}
 //    	System.out.println("effective is now\n" + XmlUtils.marshaltoString(effectiveRPr, true, true));
 				
 		//	Finally, we apply direct formatting (run properties not from 
 		//	styles).		
 		if (hasDirectRPrFormatting(expressRPr) ) {			
 			//effectiveRPr = (RPr)XmlUtils.deepCopy(effectiveRPr);			
 //	    	System.out.println("applying express\n" + XmlUtils.marshaltoString(expressRPr, true, true));
 			StyleUtil.apply(expressRPreffectiveRPr);
 		} 
 		return effectiveRPr;
 		
 	}
 	
 	public RPr getEffectiveRPr(String styleId) {
 		// styleId passed in could be a run style
 		// or a *paragraph* style
 		
 		RPr resolvedRPr = .get(styleId);
 		
 		if (resolvedRPr!=null) {
 			return resolvedRPr;
 		}
 		
 		// Hmm, have to do the work
 		Style s = .get(styleId);
 		
 		if (s==null) {
 			.error("Couldn't find style: " + styleId);
 			return null;
 		}
 
 		// Comment out - this style might not have rPr,
 		// but an ancestor might!
 		
 //		RPr expressRPr = s.getRPr();
 //		if (expressRPr==null) {
 //			log.error("style: " + runStyleId + " has no RPr");
 //			resolvedRPr = resolvedStyleRPrComponent.get(defaultCharacterStyleId);
 //			return resolvedRPr;
 //		}
 
 		
 		//	Next, run properties are applied to each run with a specific character style 
 		//	applied. 		
 		Stack<RPrrPrStack = new Stack<RPr>();
 		// Haven't done this one yet				
 		fillRPrStack(styleIdrPrStack);
 		// Finally, on top
 						
 		resolvedRPr = .createRPr();			
 		// Now, apply the properties starting at the top of the stack
 		while (!rPrStack.empty() ) {
 			RPr rPr = rPrStack.pop();
 			applyRPr(rPrresolvedRPr);
 		}
 		.put(styleIdresolvedRPr);
 		return resolvedRPr;
 	}
 	
 	
 	private BooleanDefaultTrue newBooleanDefaultTrue(boolean val) {
 		
 		BooleanDefaultTrue newBooleanDefaultTrue = .createBooleanDefaultTrue();
 		newBooleanDefaultTrue.setVal(Boolean.valueOf(val));
 		return newBooleanDefaultTrue;
 	}
 	
 	private boolean hasDirectPPrFormatting(PPr pPrToApply) {
 		
 		// NB, any rPr is intentionally ignored,
 		// since pPr/rPr is not applicable to anything
 		// except the paragraph mark
 		
 		if (pPrToApply==null) {
 			return false;
 		}
 		
 		// Here is where we do the real work.  
 		// There are a lot of paragraph properties
 		// The below list is taken directly from PPrBase.
 		
 		//PPrBase.PStyle pStyle;
 		
 			// Ignore
 		
 		//BooleanDefaultTrue keepNext;
 		if (pPrToApply.getKeepNext()!=null) {
 			return true;		
 		}
 		
 	
 		//BooleanDefaultTrue keepLines;
 		if (pPrToApply.getKeepLines()!=null) {
 			return true;		
 		}
 	
 		//BooleanDefaultTrue pageBreakBefore;
 		if (pPrToApply.getPageBreakBefore()!=null) {
 			return true;		
 		}
 	
 		//CTFramePr framePr;
 		//BooleanDefaultTrue widowControl;
 		if (pPrToApply.getWidowControl()!=null) {
 			return true;		
 		}
 	
 		//PPrBase.NumPr numPr;
 		//NumPr numPr;
 		if (pPrToApply.getNumPr()!=null) {
 			return true;		
 		}
 	
 		//BooleanDefaultTrue suppressLineNumbers;
 		if (pPrToApply.getSuppressLineNumbers()!=null) {
 			return true;		
 		}
 		
 		// PBdr pBdr;
 		if (pPrToApply.getPBdr()!=null) {
 			return true;		
 		}
 	
 		//CTShd shd;
 		if (pPrToApply.getShd()!=null) {
 			return true;		
 		}
 			
 		//Tabs tabs;
 		if (pPrToApply.getTabs()!=null) {
 			return true;		
 		}
 	
 		//BooleanDefaultTrue suppressAutoHyphens;
 		//BooleanDefaultTrue kinsoku;
 		//BooleanDefaultTrue wordWrap;
 		//BooleanDefaultTrue overflowPunct;
 		//BooleanDefaultTrue topLinePunct;
 		//BooleanDefaultTrue autoSpaceDE;
 		//BooleanDefaultTrue autoSpaceDN;
 		//BooleanDefaultTrue bidi;
 		//BooleanDefaultTrue adjustRightInd;
 		//BooleanDefaultTrue snapToGrid;
 		//PPrBase.Spacing spacing;
 		if (pPrToApply.getSpacing()!=null) {
 			return true;		
 		}
 	
 		//PPrBase.Ind ind;
 		if (pPrToApply.getInd()!=null) {
 			return true;		
 		}
 	
 		//BooleanDefaultTrue contextualSpacing;
 		//BooleanDefaultTrue mirrorIndents;
 		//BooleanDefaultTrue suppressOverlap;
 		//Jc jc;
 		if (pPrToApply.getJc()!=null) {
 			return true;		
 		}
 	
 		//TextDirection textDirection;
 		//PPrBase.TextAlignment textAlignment;
 		if (pPrToApply.getTextAlignment()!=null ) {
 			return true;		
 		}
 	
 		//CTTextboxTightWrap textboxTightWrap;
 		//PPrBase.OutlineLvl outlineLvl;
 		if (pPrToApply.getOutlineLvl()!=null ) {
 			return true;		
 		}
 		//PPrBase.DivId divId;
 		//CTCnf cnfStyle;
 		return false;
 		
 	}
 	
 	
 	protected void applyPPr(PPr pPrToApplyPPr effectivePPr) {
 		
 		.debug"apply " + XmlUtils.marshaltoString(pPrToApply,  truetrue)
 			+ "\n\r to " + XmlUtils.marshaltoString(effectivePPr,  truetrue) );
 		
 		if (pPrToApply==null) {
 			return;
 		}
 		
     	List<Propertyproperties = PropertyFactory.createProperties(pPrToApply); 
     	forProperty p :  properties ) {
 			if (p!=null) {
 //				log.debug("applying pPr " + p.getClass().getName() );
 				((AbstractParagraphProperty)p).set(effectivePPr);  // NB, this new method does not copy. TODO?
 			}
     	}
 
 		.debug"result " + XmlUtils.marshaltoString(effectivePPr,  truetrue) );
     	
 	}
 	
 	private boolean hasDirectRPrFormatting(RPr rPrToApply) {
 		
 		if (rPrToApply==null) {
 			return false;
 		}
 		
 		// Here is where we do the real work.  
 		// There are a lot of run properties
 		// The below list is taken directly from RPr, and so
 		// is comprehensive.
 		
 		//RStyle rStyle;
 		//RFonts rFonts;
 		if (rPrToApply.getRFonts()!=null ) {
 			return true;
 		}
 
 		//BooleanDefaultTrue b;
 		if (rPrToApply.getB()!=null) {
 			return true;			
 		}
 
 		//BooleanDefaultTrue bCs;
 		//BooleanDefaultTrue i;
 		if (rPrToApply.getI()!=null) {
 			return true;			
 		}
 
 		//BooleanDefaultTrue iCs;
 		//BooleanDefaultTrue caps;
 		if (rPrToApply.getCaps()!=null) {
 			return true;			
 		}
 
 		//BooleanDefaultTrue smallCaps;
 		if (rPrToApply.getSmallCaps()!=null) {
 			return true;			
 		}
 
 		//BooleanDefaultTrue strike;
 		if (rPrToApply.getStrike()!=null) {
 			return true;			
 		}
 		//BooleanDefaultTrue dstrike;
 		//BooleanDefaultTrue outline;
 		//BooleanDefaultTrue shadow;
 		//BooleanDefaultTrue emboss;
 		//BooleanDefaultTrue imprint;
 		//BooleanDefaultTrue noProof;
 		//BooleanDefaultTrue snapToGrid;
 		//BooleanDefaultTrue vanish;
 		//BooleanDefaultTrue webHidden;
 		//Color color;
 		if (rPrToApply.getColor()!=null ) {
 			return true;			
 		}
 
 		//CTSignedTwipsMeasure spacing;
 		//CTTextScale w;
 		//HpsMeasure kern;
 		//CTSignedHpsMeasure position;
 		//HpsMeasure sz;
 		if (rPrToApply.getSz()!=null ) {
 			return true;			
 		}
 
 		//HpsMeasure szCs;
 		//Highlight highlight;
 		if (rPrToApply.getHighlight()!=null ) {
 			return true;			
 		}
 		//U u;
 		if (rPrToApply.getU()!=null ) {
 			return true;			
 		}
 
 		//CTTextEffect effect;
 		//CTBorder bdr;
 		if (rPrToApply.getBdr()!=null ) {
 			return true;			
 		}
 		//CTShd shd;
 		if (rPrToApply.getShd()!=null ) {
 			return true;			
 		}
 		//CTFitText fitText;
 		//CTVerticalAlignRun vertAlign;
 		//BooleanDefaultTrue rtl;
 		//BooleanDefaultTrue cs;
 		//CTEm em;
 		//CTLanguage lang;
 		//CTEastAsianLayout eastAsianLayout;
 		//BooleanDefaultTrue specVanish;
 		//BooleanDefaultTrue oMath;
 		//CTRPrChange rPrChange;
 		
 		// If we got here...
 		return false;
 	}
 	
 	private boolean hasDirectRPrFormatting(ParaRPr rPrToApply) {
 		
 		if (rPrToApply==null) {
 			return false;
 		}
 		
 		// Here is where we do the real work.  
 		// There are a lot of run properties
 		// The below list is taken directly from RPr, and so
 		// is comprehensive.
 		
 		//RStyle rStyle;
 		//RFonts rFonts;
 		if (rPrToApply.getRFonts()!=null ) {
 			return true;
 		}
 
 		//BooleanDefaultTrue b;
 		if (rPrToApply.getB()!=null) {
 			return true;			
 		}
 
 		//BooleanDefaultTrue bCs;
 		//BooleanDefaultTrue i;
 		if (rPrToApply.getI()!=null) {
 			return true;			
 		}
 
 		//BooleanDefaultTrue iCs;
 		//BooleanDefaultTrue caps;
 		if (rPrToApply.getCaps()!=null) {
 			return true;			
 		}
 
 		//BooleanDefaultTrue smallCaps;
 		if (rPrToApply.getSmallCaps()!=null) {
 			return true;			
 		}
 
 		//BooleanDefaultTrue strike;
 		if (rPrToApply.getStrike()!=null) {
 			return true;			
 		}
 		//BooleanDefaultTrue dstrike;
 		//BooleanDefaultTrue outline;
 		//BooleanDefaultTrue shadow;
 		//BooleanDefaultTrue emboss;
 		//BooleanDefaultTrue imprint;
 		//BooleanDefaultTrue noProof;
 		//BooleanDefaultTrue snapToGrid;
 		//BooleanDefaultTrue vanish;
 		//BooleanDefaultTrue webHidden;
 		//Color color;
 		if (rPrToApply.getColor()!=null ) {
 			return true;			
 		}
 
 		//CTSignedTwipsMeasure spacing;
 		//CTTextScale w;
 		//HpsMeasure kern;
 		//CTSignedHpsMeasure position;
 		//HpsMeasure sz;
 		if (rPrToApply.getSz()!=null ) {
 			return true;			
 		}
 
 		//HpsMeasure szCs;
 		//Highlight highlight;
 		//U u;
 		if (rPrToApply.getU()!=null ) {
 			return true;			
 		}
 
 		//CTTextEffect effect;
 		//CTBorder bdr;
 		//CTShd shd;
 		//CTFitText fitText;
 		//CTVerticalAlignRun vertAlign;
 		//BooleanDefaultTrue rtl;
 		//BooleanDefaultTrue cs;
 		//CTEm em;
 		//CTLanguage lang;
 		//CTEastAsianLayout eastAsianLayout;
 		//BooleanDefaultTrue specVanish;
 		//BooleanDefaultTrue oMath;
 		//CTRPrChange rPrChange;
 		
 		// If we got here...
 		return false;
 	}
 	
 	protected void applyRPr(RPr rPrToApplyRPr effectiveRPr) {
 		
 		if (rPrToApply==null) {
 			return;
 		}
 		
 		StyleUtil.apply(rPrToApplyeffectiveRPr);
 		
 //    	List<Property> properties = PropertyFactory.createProperties(null, rPrToApply); // wmlPackage null
 //    	
 //    	for( Property p :  properties ) {
 //			if (p!=null) {    		
 //				((AbstractRunProperty)p).set(effectiveRPr);  // NB, this new method does not copy. TODO?
 //			}
 //    	}
 		
 	}	
 	
 	protected void applyRPr(ParaRPr rPrToApplyRPr effectiveRPr) {
 		
 		if (rPrToApply==null) {
 			return;
 		}
 
 		StyleUtil.apply(rPrToApplyeffectiveRPr);
 		
 //    	List<Property> properties = PropertyFactory.createProperties(null, rPrToApply); // wmlPackage null
 //    	
 //    	for( Property p :  properties ) {
 //			if (p!=null) {    		
 //				((AbstractRunProperty)p).set(effectiveRPr);  // NB, this new method does not copy. TODO?
 //			}
 //    	}
 	}	


Ascend the style hierarchy, capturing the pPr bit

Parameters:
stylename
effectivePPr
 
 	private void fillPPrStack(String styleIdStack<PPrpPrStack) {
 		// The return value is the style on which styleId is based.
 		// It is purely for the purposes of ascertainNumId.
 		
 		// get the style
 		Style style = .get(styleId);
 		
 		// add it to the stack
 		if (style==null) {
 			// No such style!
 			// For now, just log it..
 			if (styleId.equals("DocDefaults")) {
 				
 				// Don't worry about this.
 				// SDP.createVirtualStylesForDocDefaults()
 				// creates a DocDefaults style, and makes Normal based on it
 				// (and so if a different approach to handling
 				//  DocDefaults ... we really should do it one
 				//  way consistently).
 				// The problem here is, that is typically done
 				// after the PropertyResolver is created,
 				// so as far as this PropertyResolver is 
 				// concerned, the style doesn't exist.
 				// And we don't really want to always
 				// do createVirtualStylesForDocDefaults() before
 				// or during init of PropertyResolver, since that
 				// mean any docx saved would contain those
 				// virtual styles.
 				// Anyway, we don't need to worry about it
 				// here, because the doc defaults are still handled...
 				
 			} else {
 				.error("Style definition not found: " + styleId);
 			}
 			return;
 		}
 		pPrStack.push(style.getPPr());
 		.debug("Added " + styleId + " to pPr stack");
 		
		// Some styles contain numPr, without specifying
		// their numId!  In this case you have to get it
		// from the numPr in their basedOn style.
		// To save numbering emulator from having to do
		// that work, we make the numId explicit here.
		boolean ascertainNumId = false;
		if (style.getPPr()!=null 
				&& style.getPPr().getNumPr()!=null
				&& style.getPPr().getNumPr().getNumId()==null) {
			ascertainNumId = true;			
			.debug(styleId +" ascertainNumId: " + ascertainNumId);
else {
			.debug(styleId +" ascertainNumId: " + ascertainNumId);			
		// if it is based on, recurse
    	if (style.getBasedOn()==null) {
			.debug("Style " + styleId + " is a root style.");
    	} else if (style.getBasedOn().getVal()!=null) {
        	String basedOnStyleName = style.getBasedOn().getVal();           	
			.debug("Style " + styleId + " is based on " + basedOnStyleName);
        	fillPPrStackbasedOnStyleNamepPrStack);
        	Style basedOnStyle = .get(basedOnStyleName);
        	if (ascertainNumId && basedOnStyle!=null) {
        		// This works via recursion        		
        		//log.debug( XmlUtils.marshaltoString(basedOnStyle, true, true));
        		if (basedOnStyle.getPPr()!=null 
        				&& basedOnStyle.getPPr().getNumPr()!=null
        				&& basedOnStyle.getPPr().getNumPr().getNumId()!=null) {
        			NumId numId = basedOnStyle.getPPr().getNumPr().getNumId();
        			// Attach it at this level - for this to work,
        			// you can't have a style in the basedOn hierarchy
        			// which doesn't have a numPr element, because
        			// in that case there is nowhere to hang the style
        			style.getPPr().getNumPr().setNumId(numId);
        			.info("Injected numId " + numId);
        		}
        	}
    	} else {
    		.debug("No basedOn set for: " + style.getStyleId() );
    	}
	}

Ascend the style hierarchy, capturing the rPr bit

Parameters:
stylename
effectivePPr
	private void fillRPrStack(String styleIdStack<RPrrPrStack) {
		// get the style
		Style style = .get(styleId);
		// add it to the stack
		if (style==null) {
			// No such style!
			// For now, just log it..
			.error("Style definition not found: " + styleId);
			return;
		rPrStack.push(style.getRPr());
		.debug("Added " + styleId + " to rPr stack");
		// if it is based on, recurse
    	if (style.getBasedOn()==null) {
			.debug("Style " + styleId + " is a root style.");
    	} else if (style.getBasedOn().getVal()!=null) {
        	String basedOnStyleName = style.getBasedOn().getVal();           	
        	fillRPrStackbasedOnStyleNamerPrStack);
    	} else {
    		.debug("No basedOn set for: " + style.getStyleId() );
    	}
    private void initialiseLiveStyles() {
    	
    	.debug("initialiseLiveStyles()");
		for ( org.docx4j.wml.Style s : .getStyle() ) {				
			.debug("live style: " + s.getStyleId() );
    	
    }
    public boolean activateStyleString styleId  ) {
    	
    	if (.get(styleId)!=null) {
    		// Its already live - nothing to do
    		return true;    		
    	}
    	
    	java.util.Map<Stringorg.docx4j.wml.StyleknownStyles 
    		= StyleDefinitionsPart.getKnownStyles();
    	
    	org.docx4j.wml.Style s = knownStyles.get(styleId);
    	
    	if (s==null) {
    		.error("Unknown style: " + styleId);
    		return false;
    	}
    	    	
    	return activateStyle(sfalse); 
    		// false -> don't replace an existing live style with a template
    	
    }
    
    public boolean activateStyle(org.docx4j.wml.Style s) {
    	return activateStyle(strue);
    	
    }
    private boolean activateStyle(org.docx4j.wml.Style sboolean replace) {
    	
    	if (.get(s.getStyleId())!=null) {
    		// Its already live
    		
    		if (!replace) {    			
    			return false;
    		}
    		
    		// Remove existing entry
    	}
    	
    	// Add it
    	// .. to the JAXB object
    	.getStyle().add(s);
    	// .. here
    	.put(s.getStyleId(), s);
    	
    	// Now, recursively check that what it is based on is present
    	boolean result1;
    	if (s.getBasedOn()!=null) {
    		String basedOn = s.getBasedOn().getVal();
    		result1 = activateStylebasedOn );
    		
    	} else if ( s.getStyleId().equals()
    	{
    		// stop condition
    		result1 = true;
    	} else {
    		
    		.error("Expected " + s.getStyleId() + " to have <w:basedOn ??");
    		// Not properly activated
    		result1 = false;
    	}
    	
    	// Also add the linked style, if any
    	// .. Word might expect it to be there
    	boolean result2 = true;
    	if (s.getLink()!=null) {
    		
    		org.docx4j.wml.Style.Link link = s.getLink();
    		result2 = activateStyle(link.getVal());
    		
    	}
    	
    	return (result1 & result2);
    	    	
    }
    
    public org.docx4j.wml.Style getStyle(String styleId) {
    	
    	return .get(styleId);
    }
//		/*
//		a paragraph style does not inherit anything from its linked character style.
//		A linked character style seems to be just a Word 2007 user interface
//		hint.  ie if you select some characters in a paragraph and select to
//		apply "Heading 1", what you are actually doing is applying "Heading 1
//		char".  This is determined by looking at the definition of the
//		"Heading 1" style to see what its linked style is.
//		
//		(Interestingly, in Word 2007, if you right click to modify something 
//		 which is Heading 1 char, it modifies both the Heading 1 style and the
//		 Heading 1 char style!.  Haven't looked to see what happens to Heading 1 char
//		 style if you right click to modify a Heading 1 par.)
//		 The algorithm Word 2007 seems to use is:
//		    look at the specified style:
//		        1 does it have its own rPr which contains rFonts?
//		        2 if not, what does this styles basedOn style say? (Ignore
//		any linked char style)
//				3 look at styles/rPrDefault 
//				3.1 if there is an rFonts element, do what it says (it may refer you to the theme part, 
//				    in which case if there is no theme part, default to "internally stored settings"
//					(there is no normal.dot; see http://support.microsoft.com/kb/924460/en-us ) 
//					in this case Calibri and Cambria)
//				3.2 if there is no rFonts element, default to Times New Roman.
//		
    //        // 1 does it have its own rPr which contains rFonts?
//    	org.docx4j.wml.RPr rPr = style.getRPr();
//    	if (rPr!=null && rPr.getRFonts()!=null) {
//    		if (rPr.getRFonts().getAscii()!=null) {
//        		return rPr.getRFonts().getAscii();
//    		} else if (rPr.getRFonts().getAsciiTheme()!=null 
//    					&& themePart != null) {
//    			log.debug("Encountered rFonts/AsciiTheme: " + rPr.getRFonts().getAsciiTheme() );
//    			
//				org.docx4j.dml.Theme theme = (org.docx4j.dml.Theme)themePart.getJaxbElement();
//				org.docx4j.dml.BaseStyles.FontScheme fontScheme = themePart.getFontScheme();
//				if (rPr.getRFonts().getAsciiTheme().equals(org.docx4j.wml.STTheme.MINOR_H_ANSI)) {
//					if (fontScheme != null && fontScheme.getMinorFont().getLatin() != null) {
//						fontScheme = theme.getThemeElements().getFontScheme();
//						org.docx4j.dml.TextFont textFont = fontScheme.getMinorFont().getLatin();
//						log.info("minorFont/latin font is " + textFont.getTypeface());
//						return (textFont.getTypeface());
//					} else {
//						// No minorFont/latin in theme part - default to Calibri
//						log.info("No minorFont/latin in theme part - default to Calibri");
//						return ("Calibri");
//					}
//				} else if (rPr.getRFonts().getAsciiTheme().equals(org.docx4j.wml.STTheme.MAJOR_H_ANSI)) {
//					if (fontScheme != null && fontScheme.getMajorFont().getLatin() != null) {
//						fontScheme = theme.getThemeElements().getFontScheme();
//						org.docx4j.dml.TextFont textFont = fontScheme.getMajorFont().getLatin();
//						log.debug("majorFont/latin font is " + textFont.getTypeface());
//						return (textFont.getTypeface());
//					} else {
//						// No minorFont/latin in theme part - default to Cambria
//						log.info("No majorFont/latin in theme part - default to Cambria");
//						return ("Cambria");
//					}
//				} else {
//					log.error("Don't know how to handle: "
//							+ rPr.getRFonts().getAsciiTheme());
//				}
//    		}
//    	}
//        		
//        // 2 if not, what does this styles basedOn style say? (recursive)
//    	
//    	if (style.getBasedOn()!=null && style.getBasedOn().getVal()!=null) {
//        	String basedOnStyleName = style.getBasedOn().getVal();    		
//    		//log.debug("recursing into basedOn:" + basedOnStyleName);
//            org.docx4j.wml.Style candidateStyle = (org.docx4j.wml.Style)stylesDefined.get(basedOnStyleName);
//            if (candidateStyle != null && candidateStyle.getStyleId().equals(basedOnStyleName)) {
//            	return getFontnameFromStyle(stylesDefined, themePart, candidateStyle);
//            }
//    	     // If we get here the style is missing!
//     		log.error("couldn't find basedOn:" + basedOnStyleName);    	     
//    	     return null;
//    	} else {
//    		//log.debug("No basedOn set for: " + style.getStyleId() );
//    		return null;
//    	}
//    	
//    }
New to GrepCode? Check out our FAQ X