source: trunk/docx4j/src/main/java/org/docx4j/openpackaging/parts/WordprocessingML/StyleDefinitionsPart.java @ 1262

Revision 1262, 11.7 KB checked in by jharrop, 20 months ago (diff)

Use style0 as default para style for docx from OO

  • Property svn:eol-style set to native
  • Property svn:executable set to *
Line 
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
21package org.docx4j.openpackaging.parts.WordprocessingML;
22
23import java.io.IOException;
24
25import org.apache.log4j.Logger;
26import org.docx4j.XmlUtils;
27import org.docx4j.jaxb.Context;
28import org.docx4j.openpackaging.exceptions.Docx4JException;
29import org.docx4j.openpackaging.exceptions.InvalidFormatException;
30import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
31import org.docx4j.openpackaging.parts.JaxbXmlPart;
32import org.docx4j.openpackaging.parts.PartName;
33import org.docx4j.openpackaging.parts.relationships.Namespaces;
34import org.docx4j.wml.DocDefaults;
35import org.docx4j.wml.PPr;
36import org.docx4j.wml.RPr;
37import org.docx4j.wml.Style;
38import org.docx4j.wml.Styles;
39import org.docx4j.wml.Style.BasedOn;
40
41import javax.xml.bind.JAXBContext;
42import javax.xml.bind.JAXBException;
43import javax.xml.bind.Unmarshaller;
44
45
46public final class StyleDefinitionsPart extends JaxbXmlPart<Styles> {
47       
48        private static Logger log = Logger.getLogger(StyleDefinitionsPart.class);               
49       
50        public StyleDefinitionsPart(PartName partName) throws InvalidFormatException {
51                super(partName);
52                init();
53        }
54
55        public StyleDefinitionsPart() throws InvalidFormatException {
56                super(new PartName("/word/styles.xml"));
57                init();
58        }
59       
60        public void init() {
61                // Used if this Part is added to [Content_Types].xml
62                setContentType(new  org.docx4j.openpackaging.contenttype.ContentType( 
63                                org.docx4j.openpackaging.contenttype.ContentTypes.WORDPROCESSINGML_STYLES));
64
65                // Used when this Part is added to a rels
66                setRelationshipType(Namespaces.STYLES);
67        }
68       
69        // A variety of pre-defined styles, available for use in a StyleDefinitionsPart.
70        private static java.util.Map<String, org.docx4j.wml.Style>  knownStyles = null;
71       
72        // private PropertyResolver propertyResolver;
73       
74       
75   
76//      @Override
77//    public Styles unmarshal(org.w3c.dom.Element el) throws JAXBException {
78//     
79//      // Note: This is used when we read in a pkg:package
80//
81//              try {
82//
83//                      Unmarshaller u = jc.createUnmarshaller();
84//                                             
85//                      u.setEventHandler(new org.docx4j.jaxb.JaxbValidationEventHandler());
86//
87//                      jaxbElement = (Styles) u.unmarshal( el );
88//                     
89//                      return jaxbElement;
90//                     
91//              } catch (JAXBException e) {
92//                      // TODO Auto-generated catch block
93//                      e.printStackTrace();
94//                      return null;
95//              }
96//      }
97
98   
99    /**
100     * Unmarshal a default set of styles, useful when creating this
101     * part from scratch.
102     *
103     * @return the newly created root object of the java content tree
104     *
105     * @throws JAXBException
106     *     If any unexpected errors occur while unmarshalling
107     */
108    public Object unmarshalDefaultStyles() throws JAXBException {
109       
110       
111//      Throwable t = new Throwable();
112//      t.printStackTrace();
113         
114                java.io.InputStream is = null;
115                        try {
116                                //Works in Eclipse if the resource is in source/main/java
117                                //is = getResource("styles.xml");
118                               
119                                // Works in Eclipse - not absence of leading '/'
120                                is = org.docx4j.utils.ResourceUtils.getResource(
121                                                "org/docx4j/openpackaging/parts/WordprocessingML/styles.xml");
122                               
123                                        // styles.xml defines a small subset of common styles
124                                        // (it is a much smaller set of styles than KnownStyles.xml)
125                               
126                        } catch (IOException e) {
127                                // TODO Auto-generated catch block
128                                e.printStackTrace();
129                        }               
130       
131        return unmarshal( is );    // side-effect is to set jaxbElement         
132    }
133   
134    private static void initKnownStyles() {
135
136//      Throwable t = new Throwable();
137//      t.printStackTrace();
138       
139                java.io.InputStream is = null;
140                try {
141                        is = org.docx4j.utils.ResourceUtils.getResource(
142                                        "org/docx4j/openpackaging/parts/WordprocessingML/KnownStyles.xml");                                             
143                       
144                        JAXBContext jc = Context.jc;
145                        Unmarshaller u = jc.createUnmarshaller();                       
146                        u.setEventHandler(new org.docx4j.jaxb.JaxbValidationEventHandler());
147
148                        org.docx4j.wml.Styles styles = (org.docx4j.wml.Styles)u.unmarshal( is );                       
149                       
150                        knownStyles = new java.util.HashMap<String, org.docx4j.wml.Style>();
151                       
152                        for ( org.docx4j.wml.Style s : styles.getStyle() ) {                           
153                                knownStyles.put(s.getStyleId(), s);                             
154                        }
155                       
156                } catch (Exception e) {
157                        // TODO Auto-generated catch block
158                        e.printStackTrace();
159                }               
160       
161               
162    }
163
164        public static java.util.Map<String, org.docx4j.wml.Style> getKnownStyles() {
165                if (knownStyles==null) {
166                        initKnownStyles();
167                }
168                return knownStyles;
169        }
170   
171        /*
172         * Manufacture styles from the following, so they can be used as the
173         * roots of our style trees.
174         *
175         *      <w:docDefaults>
176                        <w:rPrDefault>
177                                <w:rPr>
178                                        <w:rFonts w:asciiTheme="minorHAnsi" w:eastAsiaTheme="minorHAnsi" w:hAnsiTheme="minorHAnsi" w:cstheme="minorBidi" />
179                                        <w:sz w:val="22" />
180                                        <w:szCs w:val="22" />
181                                        <w:lang w:val="en-US" w:eastAsia="en-US" w:bidi="ar-SA" />
182                                </w:rPr>
183                        </w:rPrDefault>
184                        <w:pPrDefault>
185                                <w:pPr>
186                                        <w:spacing w:after="200" w:line="276" w:lineRule="auto" />
187                                </w:pPr>
188                        </w:pPrDefault>
189                </w:docDefaults>
190
191         */
192    protected void createVirtualStylesForDocDefaults() throws Docx4JException {
193       
194        Style pDefault = Context.getWmlObjectFactory().createStyle();
195       
196        String ROOT_NAME = "DocDefaults";
197       
198        pDefault.setStyleId(ROOT_NAME);
199        pDefault.setType("paragraph");
200                       
201                // Initialise docDefaults               
202                DocDefaults docDefaults = this.jaxbElement.getDocDefaults();           
203               
204                if (docDefaults == null) {
205                        // The only way this can happen is if the
206                        // styles definition part is missing the docDefaults element
207                        // (these are present in docs created from Word, and
208                        // in our default styles, so maybe the user created it using
209                        // some 3rd party program?)
210                        try {
211
212                                docDefaults = (DocDefaults) XmlUtils
213                                                .unmarshalString(docDefaultsString);
214                        } catch (JAXBException e) {
215                                throw new Docx4JException("Problem unmarshalling "
216                                                + docDefaultsString, e);
217                        }
218                }
219
220                // Setup documentDefaultPPr
221                PPr documentDefaultPPr;
222                if (docDefaults.getPPrDefault() == null) {
223                        try {
224                                documentDefaultPPr = (PPr) XmlUtils
225                                                .unmarshalString(pPrDefaultsString);
226                        } catch (JAXBException e) {
227                                throw new Docx4JException("Problem unmarshalling "
228                                                + pPrDefaultsString, e);
229                        }
230
231                } else {
232                        documentDefaultPPr = docDefaults.getPPrDefault().getPPr();
233                }
234
235                // Setup documentDefaultRPr
236                RPr documentDefaultRPr;
237                if (docDefaults.getRPrDefault() == null) {
238                        try {
239                                documentDefaultRPr = (RPr) XmlUtils
240                                                .unmarshalString(rPrDefaultsString);
241                        } catch (JAXBException e) {
242                                throw new Docx4JException("Problem unmarshalling "
243                                                + rPrDefaultsString, e);
244                        }
245                } else {
246                        documentDefaultRPr = docDefaults.getRPrDefault().getRPr();
247                }
248       
249                pDefault.setPPr(documentDefaultPPr);
250                pDefault.setRPr(documentDefaultRPr);
251               
252                // Now point Normal at this
253                Style normal = getDefaultParagraphStyle();
254                if (normal==null) {
255                        log.warn("No default paragraph style!!");
256                        normal = Context.getWmlObjectFactory().createStyle();
257                        normal.setType("paragraph");
258                        normal.setStyleId("Normal");
259                       
260                        org.docx4j.wml.Style.Name n = Context.getWmlObjectFactory().createStyleName();
261                        n.setVal("Normal");
262                        normal.setName(n);
263                        this.jaxbElement.getStyle().add(normal);                       
264                }
265               
266                BasedOn based = Context.getWmlObjectFactory().createStyleBasedOn();
267                based.setVal(ROOT_NAME);               
268                normal.setBasedOn(based);
269               
270                // Finally, add it to styles
271                this.jaxbElement.getStyle().add(pDefault);
272       
273    }
274   
275    private Style getStyleById(String id) {
276       
277                for ( org.docx4j.wml.Style s : this.jaxbElement.getStyle() ) {                         
278                        if( s.getStyleId().equals(id) ) {
279                                return s;
280                        }
281                }
282        return null;
283    }
284
285    private Style defaultCharacterStyle;
286    public Style getDefaultCharacterStyle() {
287       
288        if (defaultCharacterStyle==null) {
289                defaultCharacterStyle = getDefaultStyle("character");
290        }
291        // OpenOffice conversion to docx
292        // doesn't necessarily contain a default character style
293        // so manufacture one
294        if (defaultCharacterStyle==null) {
295                try {
296                                defaultCharacterStyle = (Style)XmlUtils.unmarshalString(DEFAULT_CHARACTER_STYLE_DEFAULT);
297                                this.jaxbElement.getStyle().add(defaultCharacterStyle);
298                        } catch (JAXBException e) {
299                                e.printStackTrace();
300                        }
301        }
302                return defaultCharacterStyle;
303    }
304   
305    private final static String DEFAULT_CHARACTER_STYLE_DEFAULT = "<w:style w:type=\"character\" w:default=\"1\" w:styleId=\"DefaultParagraphFont\" " + Namespaces.W_NAMESPACE_DECLARATION + "><w:name w:val=\"Default Paragraph Font\" /></w:style>";
306   
307   
308    private Style defaultParagraphStyle;
309    public Style getDefaultParagraphStyle() {
310       
311        if (defaultParagraphStyle==null) {
312                defaultParagraphStyle = getDefaultStyle("paragraph");
313        }
314        // OpenOffice conversion to docx
315        // doesn't set default, so use name
316        // (alternatively, could use id=style0)
317        if (defaultParagraphStyle==null) {
318                for ( org.docx4j.wml.Style s : this.jaxbElement.getStyle() ) {                         
319                        if( s.getType().equals("paragraph")
320                                        && s.getName().getVal().equals("Default") ) {
321                                log.info("Style with name " + s.getName().getVal() + ", id '" + s.getStyleId() + "' is default " + s.getType() + " style");
322                                defaultParagraphStyle=s;
323                                break;
324                        }
325                }               
326        }
327        // try using id=style0
328        if (defaultParagraphStyle==null) {
329                for ( org.docx4j.wml.Style s : this.jaxbElement.getStyle() ) {                         
330                        if( s.getType().equals("paragraph")
331                                        && s.getStyleId().equals("style0") ) {
332                                log.info("Style with name " + s.getName().getVal() + ", id '" + s.getStyleId() + "' is default " + s.getType() + " style");
333                                defaultParagraphStyle=s;
334                                break;
335                        }
336                }               
337        }
338       
339                return defaultParagraphStyle;
340    }
341    private Style getDefaultStyle(String type) {
342       
343                for ( org.docx4j.wml.Style s : this.jaxbElement.getStyle() ) {                         
344                        if( s.isDefault() && s.getType().equals(type)) {
345                                log.info("Style with name " + s.getName().getVal() + ", id '" + s.getStyleId() + "' is default " + s.getType() + " style");
346                                return s;
347                        }
348                }
349                return null;
350    }
351   
352   
353        final static String wNamespaceDec = " xmlns:w=\"" + Namespaces.NS_WORD12 + "\""; 
354
355        public final static String rPrDefaultsString = "<w:rPr" + wNamespaceDec + ">"
356                // Word 2007 still uses Times New Roman if there is no theme part, and we'd like to replicate that
357        // + "<w:rFonts w:asciiTheme=\"minorHAnsi\" w:eastAsiaTheme=\"minorHAnsi\" w:hAnsiTheme=\"minorHAnsi\" w:cstheme=\"minorBidi\" />"
358        + "<w:sz w:val=\"22\" />"
359        + "<w:szCs w:val=\"22\" />"
360        + "<w:lang w:val=\"en-US\" w:eastAsia=\"en-US\" w:bidi=\"ar-SA\" />"
361      + "</w:rPr>";
362        public final static String pPrDefaultsString = "<w:pPr" + wNamespaceDec + ">"
363                + "<w:spacing w:after=\"200\" w:line=\"276\" w:lineRule=\"auto\" />"
364              + "</w:pPr>";
365        public final static String docDefaultsString = "<w:docDefaults" + wNamespaceDec + ">"
366            + "<w:rPrDefault>"
367            +   rPrDefaultsString
368            + "</w:rPrDefault>"
369            + "<w:pPrDefault>"
370            +   pPrDefaultsString
371            + "</w:pPrDefault>"
372          + "</w:docDefaults>";
373       
374   
375   
376//      public static void main(String[] args) throws Exception {
377//             
378//              StyleDefinitionsPart sdp = new StyleDefinitionsPart ();         
379//              sdp.initKnownStyles();
380//   
381//      }   
382}
Note: See TracBrowser for help on using the repository browser.