| 1 | /* |
|---|
| 2 | * Copyright 2007-2008, Plutext Pty Ltd. |
|---|
| 3 | * |
|---|
| 4 | * This file is part of docx4j. |
|---|
| 5 | |
|---|
| 6 | docx4j is licensed under the Apache License, Version 2.0 (the "License"); |
|---|
| 7 | you may not use this file except in compliance with the License. |
|---|
| 8 | |
|---|
| 9 | You may obtain a copy of the License at |
|---|
| 10 | |
|---|
| 11 | http://www.apache.org/licenses/LICENSE-2.0 |
|---|
| 12 | |
|---|
| 13 | Unless required by applicable law or agreed to in writing, software |
|---|
| 14 | distributed under the License is distributed on an "AS IS" BASIS, |
|---|
| 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|---|
| 16 | See the License for the specific language governing permissions and |
|---|
| 17 | limitations under the License. |
|---|
| 18 | |
|---|
| 19 | */ |
|---|
| 20 | |
|---|
| 21 | |
|---|
| 22 | package org.docx4j.wml; |
|---|
| 23 | |
|---|
| 24 | import javax.xml.bind.JAXBElement; |
|---|
| 25 | import javax.xml.bind.Unmarshaller; |
|---|
| 26 | import javax.xml.bind.annotation.XmlAccessType; |
|---|
| 27 | import javax.xml.bind.annotation.XmlAccessorType; |
|---|
| 28 | import javax.xml.bind.annotation.XmlRootElement; |
|---|
| 29 | import javax.xml.bind.annotation.XmlTransient; |
|---|
| 30 | import javax.xml.bind.annotation.XmlType; |
|---|
| 31 | |
|---|
| 32 | import org.apache.log4j.Logger; |
|---|
| 33 | import org.jvnet.jaxb2_commons.ppp.Child; |
|---|
| 34 | |
|---|
| 35 | |
|---|
| 36 | /** |
|---|
| 37 | * <p>Java class for sdt element declaration. |
|---|
| 38 | * |
|---|
| 39 | * <p>The following schema fragment specifies the expected content contained within this class. |
|---|
| 40 | * |
|---|
| 41 | * <pre> |
|---|
| 42 | * <element name="sdt"> |
|---|
| 43 | * <complexType> |
|---|
| 44 | * <complexContent> |
|---|
| 45 | * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> |
|---|
| 46 | * <sequence> |
|---|
| 47 | * <element name="sdtPr" type="{http://schemas.openxmlformats.org/wordprocessingml/2006/main}CT_SdtPr" minOccurs="0"/> |
|---|
| 48 | * <element name="sdtEndPr" type="{http://schemas.openxmlformats.org/wordprocessingml/2006/main}CT_SdtEndPr" minOccurs="0"/> |
|---|
| 49 | * <element name="sdtContent" type="{http://schemas.openxmlformats.org/wordprocessingml/2006/main}CT_SdtContentBlock" minOccurs="0"/> |
|---|
| 50 | * </sequence> |
|---|
| 51 | * </restriction> |
|---|
| 52 | * </complexContent> |
|---|
| 53 | * </complexType> |
|---|
| 54 | * </element> |
|---|
| 55 | * </pre> |
|---|
| 56 | * |
|---|
| 57 | * |
|---|
| 58 | */ |
|---|
| 59 | @XmlAccessorType(XmlAccessType.FIELD) |
|---|
| 60 | @XmlType(name = "", propOrder = { |
|---|
| 61 | "sdtPr", |
|---|
| 62 | "sdtEndPr", |
|---|
| 63 | "sdtContent" |
|---|
| 64 | }) |
|---|
| 65 | @XmlRootElement(name = "sdt") |
|---|
| 66 | public class SdtBlock implements SdtElement, Child |
|---|
| 67 | { |
|---|
| 68 | |
|---|
| 69 | private static Logger log = Logger.getLogger(SdtBlock.class); |
|---|
| 70 | |
|---|
| 71 | protected SdtPr sdtPr; |
|---|
| 72 | protected CTSdtEndPr sdtEndPr; |
|---|
| 73 | protected SdtContentBlock sdtContent; |
|---|
| 74 | @XmlTransient |
|---|
| 75 | private Object parent; |
|---|
| 76 | |
|---|
| 77 | /** |
|---|
| 78 | * Gets the value of the sdtPr property. |
|---|
| 79 | * |
|---|
| 80 | * @return |
|---|
| 81 | * possible object is |
|---|
| 82 | * {@link SdtPr } |
|---|
| 83 | * |
|---|
| 84 | */ |
|---|
| 85 | public SdtPr getSdtPr() { |
|---|
| 86 | return sdtPr; |
|---|
| 87 | } |
|---|
| 88 | |
|---|
| 89 | /** |
|---|
| 90 | * Sets the value of the sdtPr property. |
|---|
| 91 | * |
|---|
| 92 | * @param value |
|---|
| 93 | * allowed object is |
|---|
| 94 | * {@link SdtPr } |
|---|
| 95 | * |
|---|
| 96 | */ |
|---|
| 97 | public void setSdtPr(SdtPr value) { |
|---|
| 98 | this.sdtPr = value; |
|---|
| 99 | } |
|---|
| 100 | |
|---|
| 101 | /** |
|---|
| 102 | * Gets the value of the sdtEndPr property. |
|---|
| 103 | * |
|---|
| 104 | * @return |
|---|
| 105 | * possible object is |
|---|
| 106 | * {@link CTSdtEndPr } |
|---|
| 107 | * |
|---|
| 108 | */ |
|---|
| 109 | public CTSdtEndPr getSdtEndPr() { |
|---|
| 110 | return sdtEndPr; |
|---|
| 111 | } |
|---|
| 112 | |
|---|
| 113 | /** |
|---|
| 114 | * Sets the value of the sdtEndPr property. |
|---|
| 115 | * |
|---|
| 116 | * @param value |
|---|
| 117 | * allowed object is |
|---|
| 118 | * {@link CTSdtEndPr } |
|---|
| 119 | * |
|---|
| 120 | */ |
|---|
| 121 | public void setSdtEndPr(CTSdtEndPr value) { |
|---|
| 122 | this.sdtEndPr = value; |
|---|
| 123 | } |
|---|
| 124 | |
|---|
| 125 | /** |
|---|
| 126 | * Gets the value of the sdtContent property. |
|---|
| 127 | * |
|---|
| 128 | * @return |
|---|
| 129 | * possible object is |
|---|
| 130 | * {@link SdtContentBlock } |
|---|
| 131 | * |
|---|
| 132 | */ |
|---|
| 133 | public ContentAccessor getSdtContent() { |
|---|
| 134 | return sdtContent; |
|---|
| 135 | } |
|---|
| 136 | |
|---|
| 137 | /** |
|---|
| 138 | * Sets the value of the sdtContent property. |
|---|
| 139 | * |
|---|
| 140 | * @param value |
|---|
| 141 | * allowed object is |
|---|
| 142 | * {@link SdtContentBlock } |
|---|
| 143 | * |
|---|
| 144 | */ |
|---|
| 145 | public void setSdtContent(SdtContentBlock value) { |
|---|
| 146 | this.sdtContent = value; |
|---|
| 147 | } |
|---|
| 148 | |
|---|
| 149 | /** |
|---|
| 150 | * Gets the parent object in the object tree representing the unmarshalled xml document. |
|---|
| 151 | * |
|---|
| 152 | * @return |
|---|
| 153 | * The parent object. |
|---|
| 154 | */ |
|---|
| 155 | public Object getParent() { |
|---|
| 156 | return this.parent; |
|---|
| 157 | } |
|---|
| 158 | |
|---|
| 159 | public void setParent(Object parent) { |
|---|
| 160 | this.parent = parent; |
|---|
| 161 | } |
|---|
| 162 | |
|---|
| 163 | /** |
|---|
| 164 | * This method is invoked by the JAXB implementation on each instance when unmarshalling completes. |
|---|
| 165 | * |
|---|
| 166 | * @param parent |
|---|
| 167 | * The parent object in the object tree. |
|---|
| 168 | * @param unmarshaller |
|---|
| 169 | * The unmarshaller that generated the instance. |
|---|
| 170 | */ |
|---|
| 171 | public void afterUnmarshal(Unmarshaller unmarshaller, Object parent) { |
|---|
| 172 | setParent(parent); |
|---|
| 173 | } |
|---|
| 174 | |
|---|
| 175 | /* Replace any nested content controls with their content. */ |
|---|
| 176 | public void flatten() { |
|---|
| 177 | |
|---|
| 178 | /* |
|---|
| 179 | <w:sdt xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"> |
|---|
| 180 | <w:sdtPr><w:tag w:val="30" /><w:id w:val="871785936" /></w:sdtPr> |
|---|
| 181 | <w:sdtContent> |
|---|
| 182 | <w:p w:rsidR="00283267" w:rsidRDefault="00E8712C"> |
|---|
| 183 | <w:r><w:t>S</w:t></w:r> |
|---|
| 184 | <w:sdt><w:sdtPr><w:tag w:val="0" /><w:id w:val="589321610" /></w:sdtPr><w:sdtContent><w:r><w:t>Para1</w:t></w:r></w:sdtContent></w:sdt> |
|---|
| 185 | </w:p> |
|---|
| 186 | </w:sdtContent> |
|---|
| 187 | </w:sdt> |
|---|
| 188 | */ |
|---|
| 189 | |
|---|
| 190 | log.info("Flattening sdt: " + sdtPr.getId().toString() ); |
|---|
| 191 | boolean startAgain; |
|---|
| 192 | do { |
|---|
| 193 | startAgain = false; |
|---|
| 194 | // java.util.Iterator it = sdtContent.getBlockLevelElements().iterator(); |
|---|
| 195 | // while ( it.hasNext() ) { |
|---|
| 196 | // |
|---|
| 197 | // Object o = it.next(); |
|---|
| 198 | |
|---|
| 199 | for (Object o : sdtContent.getEGContentBlockContent() ) { |
|---|
| 200 | |
|---|
| 201 | if (o instanceof SdtBlock) { // A block level SDT - but this doesn't happen |
|---|
| 202 | log.debug("Interesting .. detected BLOCK level nested sdt: " + ((SdtBlock)o).sdtPr.getId().toString() ); |
|---|
| 203 | sdtContent.replaceElement(o, ((SdtBlock)o).getSdtContent().getContent() ); |
|---|
| 204 | // need to refresh the list we are iterating |
|---|
| 205 | startAgain = true; |
|---|
| 206 | break; |
|---|
| 207 | } else if ( o instanceof org.docx4j.wml.P ) { |
|---|
| 208 | log.debug( "Paragraph object: "); |
|---|
| 209 | org.docx4j.wml.P p = (org.docx4j.wml.P)o; |
|---|
| 210 | flattenP(p); |
|---|
| 211 | } else if (o instanceof javax.xml.bind.JAXBElement) { |
|---|
| 212 | |
|---|
| 213 | // if ( ((JAXBElement)o).getDeclaredType().getName().equals("org.docx4j.wml.P") ) { |
|---|
| 214 | // log.debug( "Paragraph object: "); |
|---|
| 215 | // org.docx4j.wml.P p = (org.docx4j.wml.P)((JAXBElement)o).getValue(); |
|---|
| 216 | // |
|---|
| 217 | // flattenP(p); |
|---|
| 218 | // // Is this necessary? |
|---|
| 219 | // ((JAXBElement)o).setValue(p); |
|---|
| 220 | // } else { |
|---|
| 221 | |
|---|
| 222 | log.debug( "JAXB: " + ((JAXBElement)o).getValue().getClass().getName() ); |
|---|
| 223 | |
|---|
| 224 | // } |
|---|
| 225 | |
|---|
| 226 | } else { |
|---|
| 227 | log.debug(o.getClass().getName() + ".. not an sdt"); |
|---|
| 228 | } |
|---|
| 229 | } |
|---|
| 230 | } while (startAgain); |
|---|
| 231 | } |
|---|
| 232 | |
|---|
| 233 | public void flattenP(org.docx4j.wml.P p) { |
|---|
| 234 | |
|---|
| 235 | /* |
|---|
| 236 | <w:p w:rsidR="00283267" w:rsidRDefault="00E8712C"> |
|---|
| 237 | <w:r><w:t>S</w:t></w:r> |
|---|
| 238 | <w:sdt><w:sdtPr><w:tag w:val="0" /><w:id w:val="589321610" /></w:sdtPr><w:sdtContent><w:r><w:t>Para1</w:t></w:r></w:sdtContent></w:sdt> |
|---|
| 239 | </w:p> |
|---|
| 240 | */ |
|---|
| 241 | |
|---|
| 242 | log.info("Flattening nested p " ); |
|---|
| 243 | boolean startAgain; |
|---|
| 244 | do { |
|---|
| 245 | startAgain = false; |
|---|
| 246 | for (Object o : p.getContent() ) { |
|---|
| 247 | |
|---|
| 248 | if (o instanceof SdtRun) { // This code path not used |
|---|
| 249 | log.debug(".. detected nested sdt " ); |
|---|
| 250 | p.replaceElement(o, ((SdtRun)o).getSdtContent().getContent() ); |
|---|
| 251 | // need to refresh the list we are iterating |
|---|
| 252 | startAgain = true; |
|---|
| 253 | break; |
|---|
| 254 | } else if (o instanceof javax.xml.bind.JAXBElement) { |
|---|
| 255 | |
|---|
| 256 | if ( ((JAXBElement)o).getDeclaredType().getName().equals("org.docx4j.wml.SdtRun") ) { |
|---|
| 257 | log.debug( ((JAXBElement)o).getDeclaredType().getName() + ".. detected SdtRun"); |
|---|
| 258 | org.docx4j.wml.SdtRun sdtRun = (org.docx4j.wml.SdtRun)((JAXBElement)o).getValue(); |
|---|
| 259 | p.replaceElement(o, sdtRun.getSdtContent().getContent() ); |
|---|
| 260 | } else { |
|---|
| 261 | log.debug( ((JAXBElement)o).getDeclaredType().getName() + ".. not an sdt"); |
|---|
| 262 | } |
|---|
| 263 | |
|---|
| 264 | } else { |
|---|
| 265 | log.debug(o.getClass().getName() + ".. not an sdt"); |
|---|
| 266 | } |
|---|
| 267 | } |
|---|
| 268 | } while (startAgain); |
|---|
| 269 | |
|---|
| 270 | |
|---|
| 271 | } |
|---|
| 272 | |
|---|
| 273 | |
|---|
| 274 | } |
|---|