Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   *  Copyright 2010-2011, Plutext Pty Ltd.
   *   
   *  This file is part of docx4j.
  
      docx4j is licensed under the Apache License, Version 2.0 (the "License"); 
      you may not use this file except in compliance with the License. 
  
      You may obtain a copy of the License at 
 
         http://www.apache.org/licenses/LICENSE-2.0 
 
     Unless required by applicable law or agreed to in writing, software 
     distributed under the License is distributed on an "AS IS" BASIS, 
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
     See the License for the specific language governing permissions and 
     limitations under the License.
 
  */
 package org.docx4j;
 
 import java.util.List;
 
 
Traverse a list of JAXB objects (eg document.xml's document/body children), and do something to them. This is similar to what one could do via XSLT, but avoids marshalling/unmarshalling. The downside is that not everything will necessarily get traversed here since visitChildren is not (yet) comprehensive. This utility might be redundant if we used http://code.google.com/p/jaxb-visitor/ or https://github.com/ops4j/org.ops4j.xvisitor at XJC time. Haven't tried them though. See also org.docx4j.utils.SingleTraversalUtilVisitorCallback and CompoundTraversalUtilVisitorCallback

Author(s):
jharrop, alberto
 
 public class TraversalUtil {
 
 	private static Logger log = LoggerFactory.getLogger(TraversalUtil.class);
 	
 	public interface Callback {
 
 		void walkJAXBElements(Object parent);
 
Visits a node in pre order (before its children have been visited). A node is visited only if all its parents have been traversed ( shouldTraverse(java.lang.Object)).

Implementations can have side effects.

 
Decide whether this node's children should be traversed.

Returns:
whether the children of this node should be visited
		boolean shouldTraverse(Object o);
		// TODO for next gen interface, add
		// List<Object> applyAfterWalkChildren(Object o);
	}	
	public static abstract class CallbackImpl implements Callback {
		// Depth first
		public void walkJAXBElements(Object parent) {
			List children = getChildren(parent);
			if (children != null) {
				for (Object o : children) {
					// if its wrapped in javax.xml.bind.JAXBElement, get its
					// value; this is ok, provided the results of the Callback
					// won't be marshalled
					o = XmlUtils.unwrap(o);
					// workaround for broken getParent (since 3.0.0)
					if (o instanceof Child) {
						if (parent instanceof SdtBlock) {
							((Child)o).setParent( ((SdtBlock)parent).getSdtContent() );
								/*
								 * getParent on eg a P in a SdtBlock should return SdtContentBlock, as
								 * illustrated by the following code:
								 * 
										SdtBlock sdtBloc = Context.getWmlObjectFactory().createSdtBlock();
										SdtContentBlock sdtContentBloc = Context.getWmlObjectFactory().createSdtContentBlock();
										sdtBloc.setSdtContent(sdtContentBloc);
										P p = Context.getWmlObjectFactory().createP();
										sdtContentBloc.getContent().add(p);
										String result = XmlUtils.marshaltoString(sdtBloc, true);
										System.out.println(result);
										SdtBlock rtp = (SdtBlock)XmlUtils.unmarshalString(result, Context.jc, SdtBlock.class);
										P rtr = (P)rtp.getSdtContent().getContent().get(0);
										System.out.println(rtr.getParent().getClass().getName() );
								 * 
								 * Similarly, P is the parent of R; the p.getContent() list is not the parent
								 * 
										P p = Context.getWmlObjectFactory().createP();
										R r = Context.getWmlObjectFactory().createR();
										p.getContent().add(r);
										String result = XmlUtils.marshaltoString(p, true);
										P rtp = (P)XmlUtils.unmarshalString(result);
										R rtr = (R)rtp.getContent().get(0);
										System.out.println(rtr.getParent().getClass().getName() );
								 */
						// TODO: other corrections
else {
							((Child)o).setParent(parent);
						}
					}
					this.apply(o);
					if (this.shouldTraverse(o)) {
					}
				}
			}
		}
		public List<ObjectgetChildren(Object o) {
			return TraversalUtil.getChildrenImpl(o);
		}

Visits a node in pre order (before its children have been visited). A node is visited only if all its parents have been traversed ( shouldTraverse(java.lang.Object)).

Implementations can have side effects.

		public abstract List<Objectapply(Object o);

Decide whether this node's children should be traversed.

Returns:
whether the children of this node should be visited
		public boolean shouldTraverse(Object o) {
			return true;
		}
	}
	public TraversalUtil(Object parentCallback cb) {
		this. = cb;
		cb.walkJAXBElements(parent);
	}
	static void visitChildrenImpl(Object o) {
	}
	private static List<ObjecthandleGraphicData(org.docx4j.dml.GraphicData graphicData) {
        // Added by Peter Buil
        List<ObjecttmpArtificialList = new ArrayList<Object>();
        if (graphicData.getPic() != null) {
            //GraphicData can have a hyperlink reference, which can be found this way
            CTNonVisualDrawingProps picNonVisual = graphicData.getPic().getNvPicPr().getCNvPr();
            if (picNonVisual != null) {
                handleCTNonVisualDrawingProps(picNonVisualtmpArtificialList);
            }
        }
        // Its not graphicData.getAny() we're typically interested in
        if (graphicData.getPic() != null && graphicData.getPic().getBlipFill() != null
                && graphicData.getPic().getBlipFill().getBlip() != null) {
            .info("found CTBlip");
            List<ObjectartificialList = new ArrayList<Object>();
            if (!tmpArtificialList.isEmpty())
                artificialList.addAll(tmpArtificialList);
            artificialList.add(graphicData.getPic().getBlipFill().getBlip());
            return artificialList;
        } else {
            // Chart is in here
            return graphicData.getAny();
        }
    }

 
There can be hyperlinks references in CTNonVisualDrawingProps.

Parameters:
drawingProps
artificialList
	private static void handleCTNonVisualDrawingProps(CTNonVisualDrawingProps drawingPropsList<ObjectartificialList){
      if (drawingProps != null) {
          CTHyperlink docPrHyperLink = drawingProps.getHlinkClick();
          if (docPrHyperLink != null)
              artificialList.add(docPrHyperLink);
      } 
	}
	public static List<ObjectgetChildrenImpl(Object o) {
		if (o==null) {
			.warn("null passed to getChildrenImpl");
			return null;
		}
		.debug("getting children of " + o.getClass().getName() );
		if (o instanceof org.docx4j.wml.Textreturn null;
		// Short circuit for common elements
		if (o instanceof List) {
			// Handy if you have your own list of objects you wish to process
			return (List<Object>) o;
else if (o instanceof org.docx4j.wml.ContentAccessor) {
else if (o instanceof org.docx4j.wml.SdtElement) {
else if (o instanceof org.docx4j.dml.wordprocessingDrawing.Anchor) {
            List<ObjectartificialList = new ArrayList<Object>();
            CTNonVisualDrawingProps drawingProps = anchor.getDocPr();
            if (drawingProps != null) {
                handleCTNonVisualDrawingProps(drawingPropsartificialList);
            }
            if (anchor.getGraphic() != null) {
                .info("found a:graphic");
                org.docx4j.dml.Graphic graphic = anchor.getGraphic();
                if (graphic.getGraphicData() != null) {
                    artificialList.addAll(handleGraphicData(graphic.getGraphicData()));
                }
            }
            if (!artificialList.isEmpty())
                return artificialList;
        } else if (o instanceof org.docx4j.dml.wordprocessingDrawing.Inline) {
            List<ObjectartificialList = new ArrayList<Object>();
            CTNonVisualDrawingProps drawingProps = inline.getDocPr();
            if (drawingProps != null) {
                handleCTNonVisualDrawingProps(drawingPropsartificialList);
            }
            if (inline.getGraphic() != null) {
                .info("found a:graphic");
                org.docx4j.dml.Graphic graphic = inline.getGraphic();
                if (graphic.getGraphicData() != null) {
                    artificialList.addAll(handleGraphicData(graphic.getGraphicData()));
                }
                return artificialList;
            }
            if (!artificialList.isEmpty())
                return artificialList;
        } else if (o instanceof Pict) {
			return ((Pict)o).getAnyAndAny(); // (why didn't the reflection below find this?)
else if (o instanceof org.docx4j.dml.picture.Pic) { // Post 2.7.1; untested
			if (dmlPic.getBlipFill()!=null
					&& dmlPic.getBlipFill().getBlip()!=null) {
					.info("found DML Blip");
					List<ObjectartificialList = new ArrayList<Object>();
					artificialList.add(dmlPic.getBlipFill().getBlip());
					return artificialList;
else {
				return null;						
			}		
else if (o instanceof org.docx4j.dml.CTGvmlPicture) {  // Post 2.7.1
			if (dmlPic.getBlipFill()!=null
					&& dmlPic.getBlipFill().getBlip()!=null) {
					.info("found DML Blip");
					List<ObjectartificialList = new ArrayList<Object>();
					artificialList.add(dmlPic.getBlipFill().getBlip());
					return artificialList;
else {
				return null;						
			}		
else if (o instanceof org.docx4j.vml.CTShape) {				
//			return ((org.docx4j.vml.CTShape)o).getAny();
			List<ObjectartificialList = new ArrayList<Object>();
//				System.out.println(XmlUtils.unwrap(j).getClass().getName() );
				artificialList.add(j);				
			}
			return artificialList;
else if (o instanceof CTDataModel) {
			CTDataModel dataModel = (CTDataModel)o;
			List<ObjectartificialList = new ArrayList<Object>();
			// We're going to create a list merging two children ..			
			artificialList.addAll(dataModel.getPtLst().getPt());
			artificialList.addAll(dataModel.getCxnLst().getCxn());			
			return artificialList;
else if (o instanceof org.docx4j.dml.diagram2008.CTDrawing) {
else if (o instanceof org.docx4j.vml.CTTextbox) {				
//			return ((org.docx4j.vml.CTTextbox)o).getAny();			
			if (textBox.getTxbxContent()==null) {
				return null;
else {
				// grandchildren
			}
//		} else if (o instanceof org.docx4j.wml.CTTxbxContent) {				
//			return ((org.docx4j.wml.CTTxbxContent)o).getEGBlockLevelElts();
else if (o instanceof CTObject) {
			CTObject ctObject = (CTObject)o;
			List<ObjectartificialList = new ArrayList<Object>();
			artificialList.addAll(ctObject.getAnyAndAny());
			if (ctObject.getControl()!=null) {
				artificialList.add(ctObject.getControl() ); // CTControl
			}
			return artificialList;
else if (o instanceof org.docx4j.dml.CTGvmlGroupShape) {
else if(o instanceof FldChar) {
			FldChar fldChar = ((FldChar)o);
			List<ObjectartificialList = new ArrayList<Object>();
			artificialList.add(fldChar.getFldCharType());
			if(fldChar.getFfData() != null) {
				artificialList.add(fldChar.getFfData());
			}
			if(fldChar.getFldData() != null) {
				artificialList.add(fldChar.getFldData());
			}
			if(fldChar.getNumberingChange() != null) {
				artificialList.add(fldChar.getNumberingChange());
			}
			return artificialList;
		}
		// OK, what is this? Use reflection ..
		// This should work for things including w:drawing
		.debug(".. looking for method which returns list "  );
		try {
			Method[] methods = o.getClass().getDeclaredMethods();
			for (int i = 0; i<methods.lengthi++) {
				Method m = methods[i];
				if (m.getReturnType().getName().equals("java.util.List") ) {					
					return (List<Object>)m.invoke(o);					
				}
			}
catch (Exception e) {
			// TODO Auto-generated catch block
		}
		.debug(".. no list member");
		return null;
	}
	public static void main(String[] argsthrows Exception {
		String inputfilepath = System.getProperty("user.dir")
"/sample-docs/sample-docx.xml";
		WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage
				.load(new java.io.File(inputfilepath));
		MainDocumentPart documentPart = wordMLPackage.getMainDocumentPart();
		org.docx4j.wml.Document wmlDocumentEl = (org.docx4j.wml.DocumentdocumentPart
		Body body = wmlDocumentEl.getBody();
		new TraversalUtil(body,
		new Callback() {
			String indent = "";
			public List<Objectapply(Object o) {
				String text = "";
				if (o instanceof org.docx4j.wml.Text)
					text = ((org.docx4j.wml.Text)o).getValue();
				..println( + o.getClass().getName() + "  \"" + text + "\"");
				return null;
			}
			public boolean shouldTraverse(Object o) {
				return true;
			}
			// Depth first
			public void walkJAXBElements(Object parent) {
				 += "    ";
				List children = getChildren(parent);
				if (children != null) {
					for (Object o : children) {
						// if its wrapped in javax.xml.bind.JAXBElement, get its
						// value; this is ok, provided the results of the Callback
						// won't be marshalled
						o = XmlUtils.unwrap(o);
						this.apply(o);
						if (this.shouldTraverse(o)) {
						}
					}
				}
			}
			public List<ObjectgetChildren(Object o) {
				return TraversalUtil.getChildrenImpl(o);
			}
		}
		);
	}
	public static void replaceChildren(Object oList<ObjectnewChildren) {
		// Available if you need something like this.  Would be used with
		// something like:
		/*
		 * 	  public void walkJAXBElements(Object parent){
		  // Breadth first
			  List<Object> newChildren = new ArrayList<Object>(); 
			  
				List children = getChildren(parent);
				if (children==null) {
					log.warn("no children: " + parent.getClass().getName() );
				} else {
					for (Object o : getChildren(parent) ) {
						// if its wrapped in javax.xml.bind.JAXBElement, get its value
						o = XmlUtils.unwrap(o);
						newChildren.addAll(this.apply(o));
					}
				}				
				// Replace list, so we'll traverse all the new sdts we've just created
				replaceChildren(parent, newChildren);
				for (Object o : getChildren(parent) ) {
					this.apply(o);
					if ( this.shouldTraverse(o) ) {
						walkJAXBElements(o);
					}
				}
			}
		 */
		.debug("Clearing " + o.getClass().getName() );
		if (o instanceof org.docx4j.wml.ContentAccessor) {
else if (o instanceof org.docx4j.wml.SdtElement) {
else if (o instanceof org.docx4j.wml.CTTxbxContent) {
else {
			.warn("Don't know how to replaceChildren in " + o.getClass().getName() ); 
			if (o instanceof org.w3c.dom.Node) {
				.warn(" IGNORED " + ((org.w3c.dom.Nodeo).getNodeName());
else {
//				log.warn(" IGNORED " + o.getClass().getName());
			}
		}
	}

Use this if there is only a single object type (eg just P's) you are interested in doing something with. This method allows you to traverse just the main document part, or also headers/footers, footnotes/endnotes, and comments as well.

Parameters:
wmlPackage
bodyOnly
visitor
	public static void visit(WordprocessingMLPackage wmlPackage
			boolean bodyOnlyTraversalUtilVisitor visitor) {
		if (visitor != null) {
			visit(wmlPackagebodyOnlynew SingleTraversalUtilVisitorCallback(visitor));
		}
	}

Use this if there is only a single object type (eg just P's) you are interested in doing something with. This method is for traversing an arbitrary WML object (eg a table), as opposed to eg the main document part, or a header.

Parameters:
parent
visitor
	public static void visit(Object parentTraversalUtilVisitor visitor) {
		if (visitor != null) {
		}
	}

Use this if there is more than one object type (eg Tables and Paragraphs) you are interested in doing something with during the traversal. This method allows you to traverse just the main document part, or also headers/footers, footnotes/endnotes, and comments as well.

Parameters:
wmlPackage
bodyOnly
visitorList
	public static void visit(WordprocessingMLPackage wmlPackage,
			boolean bodyOnlyList<TraversalUtilVisitorvisitorList) {
		if ((visitorList != null) && (!visitorList.isEmpty())) {
			if (visitorList.size() > 1) {
				visit(wmlPackagebodyOnly,
else {
				visit(wmlPackagebodyOnlyvisitorList.get(0));
			}
		}
	}

Use this if there is more than one object type (eg Tables and Paragraphs) you are interested in doing something with during the traversal. This method is for traversing an arbitrary WML object (eg a table), as opposed to eg the main document part, or a header.

Parameters:
parent
visitorList
	public static void visit(Object parent,
			List<TraversalUtilVisitorvisitorList) {
		if ((visitorList != null) && (!visitorList.isEmpty())) {
			if (visitorList.size() > 1) {
						visitorList));
else {
				visit(parentvisitorList.get(0));
			}
		}
	}
	public static void visit(Object parentCallback callback) {
		if ((parent != null) && (callback != null)) {
			callback.walkJAXBElements(parent);
		}
	}
	public static void visit(WordprocessingMLPackage wmlPackage,
			boolean bodyOnlyCallback callback) {
		MainDocumentPart mainDocument = null;
		RelationshipsPart relPart = null;
		List<RelationshiprelList = null;
		List<ObjectelementList = null;
		if ((wmlPackage != null) && (callback != null)) {
			mainDocument = wmlPackage.getMainDocumentPart();
			callback.walkJAXBElements(mainDocument.getJaxbElement().getBody());
			if (!bodyOnly) {
				relPart = mainDocument.getRelationshipsPart();
				relList = relPart.getRelationships().getRelationship();
				for (Relationship rs : relList) {
					elementList = null;
						elementList = ((HeaderPartrelPart.getPart(rs))
else if (..equals(rs.getType())) {
						elementList = ((FooterPartrelPart.getPart(rs))
else if (..equals(rs.getType())) {
						//elementList = ((EndnotesPart) relPart.getPart(rs)).getContent();
						elementList = new ArrayList();
						elementList.addAll(
else if (..equals(rs.getType())) {
						//elementList =  ((FootnotesPart) relPart.getPart(rs)).getContent();
						elementList = new ArrayList();
						elementList.addAll(
else if (..equals(rs.getType())) {
						elementList = new ArrayList();
						for (Comment comment : ((CommentsPartrelPart
							elementList.addAll(comment.getEGBlockLevelElts());
						}
					}
					if ((elementList != null) && (!elementList.isEmpty())) {
						.debug("Processing target: "
rs.getTarget() + ", type: " + rs.getType());
						callback.walkJAXBElements(elementList);
					}
				}
			}
		}
	}
	// private void describeDrawing( org.docx4j.wml.Drawing d) {
	//			
	// log.info("In wml.Drawing" );
	//			
	// if ( d.getAnchorOrInline().get(0) instanceof Anchor ) {
	//				
	// log.info(" ENCOUNTERED w:drawing/wp:anchor " );
	// // That's all for now...
	//				
	// } else if ( d.getAnchorOrInline().get(0) instanceof Inline ) {
	//				
	// // Extract
	// w:drawing/wp:inline/a:graphic/a:graphicData/pic:pic/pic:blipFill/a:blip/@r:embed
	//				
	// Inline inline = (Inline )d.getAnchorOrInline().get(0);
	//				
	// Pic pic = inline.getGraphic().getGraphicData().getPic();
	//					
	// if (pic!=null) {
	// log.info("image relationship: " + pic.getBlipFill().getBlip().getEmbed()
	// );
	// }
	//				
	//				
	// } else {
	//				
	// log.info(" Didn't get Inline :(  How to handle " +
	// d.getAnchorOrInline().get(0).getClass().getName() );
	// }
	//			
	// }
New to GrepCode? Check out our FAQ X