1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  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,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 package com.sun.star.report.pentaho.output;
24 
25 import com.sun.star.report.pentaho.OfficeNamespaces;
26 import com.sun.star.report.pentaho.model.DataStyle;
27 import com.sun.star.report.pentaho.model.FontFaceDeclsSection;
28 import com.sun.star.report.pentaho.model.FontFaceElement;
29 import com.sun.star.report.pentaho.model.OfficeMasterPage;
30 import com.sun.star.report.pentaho.model.OfficeMasterStyles;
31 import com.sun.star.report.pentaho.model.OfficeStyle;
32 import com.sun.star.report.pentaho.model.OfficeStyles;
33 import com.sun.star.report.pentaho.model.OfficeStylesCollection;
34 import com.sun.star.report.pentaho.model.PageLayout;
35 import com.sun.star.report.pentaho.model.RawText;
36 
37 import java.io.IOException;
38 import java.io.Writer;
39 
40 import java.util.Iterator;
41 import java.util.Map;
42 import java.util.TreeMap;
43 
44 import org.jfree.layouting.namespace.Namespaces;
45 import org.jfree.layouting.util.AttributeMap;
46 import org.jfree.report.JFreeReportBoot;
47 import org.jfree.report.JFreeReportInfo;
48 import org.jfree.report.ReportProcessingException;
49 import org.jfree.report.structure.Element;
50 import org.jfree.report.structure.Node;
51 import org.jfree.report.structure.Section;
52 import org.jfree.report.structure.StaticText;
53 
54 import org.pentaho.reporting.libraries.xmlns.common.AttributeList;
55 import org.pentaho.reporting.libraries.xmlns.writer.DefaultTagDescription;
56 import org.pentaho.reporting.libraries.xmlns.writer.XmlWriter;
57 import org.pentaho.reporting.libraries.xmlns.writer.XmlWriterSupport;
58 
59 
60 /**
61  * This class writes the style collection into a 'styles.xml' document.
62  *
63  * @author Thomas Morgner
64  * @since 09.03.2007
65  */
66 public class StylesWriter
67 {
68 
69     private final XmlWriter xmlWriter;
70     private final boolean writeOpeningTag;
71 
StylesWriter(final Writer writer)72     public StylesWriter(final Writer writer)
73     {
74         final DefaultTagDescription tagDescription = new DefaultTagDescription();
75         tagDescription.configure(JFreeReportBoot.getInstance().getGlobalConfig(),
76                 OfficeDocumentReportTarget.TAG_DEF_PREFIX);
77 
78         this.xmlWriter = new XmlWriter(writer, tagDescription);
79         this.xmlWriter.setAlwaysAddNamespace(true);
80         this.writeOpeningTag = true;
81     }
82 
StylesWriter(final XmlWriter xmlWriter)83     public StylesWriter(final XmlWriter xmlWriter)
84     {
85         this.xmlWriter = xmlWriter;
86         this.writeOpeningTag = false;
87     }
88 
writeContentStyles(final OfficeStylesCollection predefined, final OfficeStylesCollection globals)89     public void writeContentStyles(final OfficeStylesCollection predefined,
90             final OfficeStylesCollection globals)
91             throws IOException, ReportProcessingException
92     {
93         writeFontFaces(new OfficeStylesCollection[]
94                 {
95                     globals
96                 });
97         writeAutomaticStylesSection(new OfficeStylesCollection[]
98                 {
99                     globals
100                 });
101     }
102 
writeGlobalStyles(final OfficeStylesCollection predefined, final OfficeStylesCollection globals)103     public void writeGlobalStyles(final OfficeStylesCollection predefined,
104             final OfficeStylesCollection globals)
105             throws IOException, ReportProcessingException
106     {
107         if (writeOpeningTag)
108         {
109             performWriteRootTag();
110         }
111 
112         writeFontFaces(new OfficeStylesCollection[]
113                 {
114                     globals
115                 });
116         writeCommonStylesSection(new OfficeStylesCollection[]
117                 {
118                     globals
119                 });
120         writeAutomaticStylesSection(new OfficeStylesCollection[]
121                 {
122                     globals
123                 });
124         writeMasterStylesSection(new OfficeStylesCollection[]
125                 {
126                     globals
127                 });
128 
129         if (writeOpeningTag)
130         {
131             xmlWriter.writeCloseTag();
132         }
133     }
134 
writeMasterStylesSection(final OfficeStylesCollection[] osc)135     private void writeMasterStylesSection(final OfficeStylesCollection[] osc)
136             throws IOException
137     {
138         xmlWriter.writeTag(OfficeNamespaces.OFFICE_NS, "master-styles", XmlWriterSupport.OPEN);
139         for (int sci = 0; sci < osc.length; sci++)
140         {
141             final OfficeStylesCollection collection = osc[sci];
142             final OfficeMasterStyles officeStyles = collection.getMasterStyles();
143             final OfficeMasterPage[] officeMasterPages = officeStyles.getAllMasterPages();
144             for (int i = 0; i < officeMasterPages.length; i++)
145             {
146                 final OfficeMasterPage masterPage = officeMasterPages[i];
147                 writeSection(masterPage);
148             }
149 
150             writeSectionChilds(officeStyles.getOtherNodes().getNodeArray());
151         }
152 
153         xmlWriter.writeCloseTag();
154     }
155 
writeCommonStylesSection(final OfficeStylesCollection[] osc)156     private void writeCommonStylesSection(final OfficeStylesCollection[] osc)
157             throws IOException
158     {
159         xmlWriter.writeTag(OfficeNamespaces.OFFICE_NS, "styles", XmlWriterSupport.OPEN);
160 
161         for (int sci = 0; sci < osc.length; sci++)
162         {
163             final OfficeStylesCollection collection = osc[sci];
164             final OfficeStyles officeStyles = collection.getCommonStyles();
165             writeStyles(officeStyles);
166         }
167 
168         xmlWriter.writeCloseTag();
169     }
170 
writeAutomaticStylesSection(final OfficeStylesCollection[] osc)171     private void writeAutomaticStylesSection(final OfficeStylesCollection[] osc)
172             throws IOException
173     {
174         xmlWriter.writeTag(OfficeNamespaces.OFFICE_NS, "automatic-styles", XmlWriterSupport.OPEN);
175         for (int sci = 0; sci < osc.length; sci++)
176         {
177             final OfficeStylesCollection collection = osc[sci];
178             final OfficeStyles officeStyles = collection.getAutomaticStyles();
179             writeStyles(officeStyles);
180         }
181 
182         xmlWriter.writeCloseTag();
183     }
184 
writeFontFaces(final OfficeStylesCollection[] osc)185     private void writeFontFaces(final OfficeStylesCollection[] osc)
186             throws IOException
187     {
188         xmlWriter.writeTag(OfficeNamespaces.OFFICE_NS, "font-face-decls", XmlWriterSupport.OPEN);
189 
190         final TreeMap fontFaces = new TreeMap();
191         for (int sci = 0; sci < osc.length; sci++)
192         {
193             final OfficeStylesCollection collection = osc[sci];
194             final FontFaceDeclsSection fontFaceDecls = collection.getFontFaceDecls();
195             final FontFaceElement[] fontFaceElements = fontFaceDecls.getAllFontFaces();
196             for (int i = 0; i < fontFaceElements.length; i++)
197             {
198                 final FontFaceElement element = fontFaceElements[i];
199                 fontFaces.put(element.getStyleName(), element);
200             }
201         }
202 
203         final Iterator values = fontFaces.values().iterator();
204         while (values.hasNext())
205         {
206             final FontFaceElement element = (FontFaceElement) values.next();
207             writeElement(element);
208         }
209 
210         xmlWriter.writeCloseTag();
211     }
212 
writeStyles(final OfficeStyles styles)213     private void writeStyles(final OfficeStyles styles)
214             throws IOException
215     {
216         final OfficeStyle[] allStyles = styles.getAllStyles();
217         for (int i = 0; i < allStyles.length; i++)
218         {
219             final OfficeStyle style = allStyles[i];
220             writeSection(style);
221         }
222 
223         final DataStyle[] allDataStyles = styles.getAllDataStyles();
224         for (int i = 0; i < allDataStyles.length; i++)
225         {
226             final DataStyle style = allDataStyles[i];
227             writeSection(style);
228         }
229 
230         final PageLayout[] allPageStyles = styles.getAllPageStyles();
231         for (int i = 0; i < allPageStyles.length; i++)
232         {
233             final PageLayout style = allPageStyles[i];
234             writeSection(style);
235         }
236 
237         writeSectionChilds(styles.getOtherStyles());
238     }
239 
writeElement(final Element element)240     private void writeElement(final Element element)
241             throws IOException
242     {
243         final String type = element.getType();
244         final String namespace = element.getNamespace();
245         final AttributeList attrList = buildAttributeList(element.getAttributeMap());
246         xmlWriter.writeTag(namespace, type, attrList, XmlWriterSupport.CLOSE);
247     }
248 
writeSection(final Section section)249     private void writeSection(final Section section)
250             throws IOException
251     {
252         final String type = section.getType();
253         final String namespace = section.getNamespace();
254         final AttributeList attrList = buildAttributeList(section.getAttributeMap());
255         if (section.getNodeCount() == 0)
256         {
257             xmlWriter.writeTag(namespace, type, attrList, XmlWriterSupport.CLOSE);
258             return;
259         }
260 
261         xmlWriter.writeTag(namespace, type, attrList, XmlWriterSupport.OPEN);
262         writeSectionChilds(section.getNodeArray());
263 
264         xmlWriter.writeCloseTag();
265     }
266 
writeSectionChilds(final Node[] nodes)267     private void writeSectionChilds(final Node[] nodes)
268             throws IOException
269     {
270         for (int i = 0; i < nodes.length; i++)
271         {
272             final Node node = nodes[i];
273             if (node instanceof Section)
274             {
275                 writeSection((Section) node);
276             }
277             else if (node instanceof Element)
278             {
279                 writeElement((Element) node);
280             }
281             else if (node instanceof RawText)
282             {
283                 final RawText text = (RawText) node;
284                 xmlWriter.writeText(text.getText());
285             }
286             else if (node instanceof StaticText)
287             {
288                 final StaticText text = (StaticText) node;
289                 xmlWriter.writeTextNormalized(text.getText(), false);
290             }
291         }
292     }
293 
buildAttributeList(final AttributeMap attrs)294     protected AttributeList buildAttributeList(final AttributeMap attrs)
295     {
296         final AttributeList attrList = new AttributeList();
297         final String[] namespaces = attrs.getNameSpaces();
298         for (int i = 0; i < namespaces.length; i++)
299         {
300             final String attrNamespace = namespaces[i];
301             if (isFilteredNamespace(attrNamespace))
302             {
303                 continue;
304             }
305 
306             final Map localAttributes = attrs.getAttributes(attrNamespace);
307             final Iterator entries = localAttributes.entrySet().iterator();
308             while (entries.hasNext())
309             {
310                 final Map.Entry entry = (Map.Entry) entries.next();
311                 final String key = String.valueOf(entry.getKey());
312                 attrList.setAttribute(attrNamespace, key, String.valueOf(entry.getValue()));
313             }
314         }
315         return attrList;
316     }
317 
isFilteredNamespace(final String namespace)318     protected boolean isFilteredNamespace(final String namespace)
319     {
320         if (Namespaces.LIBLAYOUT_NAMESPACE.equals(namespace))
321         {
322             return true;
323         }
324         if (JFreeReportInfo.REPORT_NAMESPACE.equals(namespace))
325         {
326             return true;
327         }
328         if (JFreeReportInfo.COMPATIBILITY_NAMESPACE.equals(namespace))
329         {
330             return true;
331         }
332         if (OfficeNamespaces.OOREPORT_NS.equals(namespace))
333         {
334             return true;
335         }
336         return false;
337     }
338 
performWriteRootTag()339     private void performWriteRootTag()
340             throws IOException
341     {
342         final AttributeList rootAttributes = new AttributeList();
343         rootAttributes.addNamespaceDeclaration("office",
344                 OfficeNamespaces.OFFICE_NS);
345         rootAttributes.addNamespaceDeclaration("style", OfficeNamespaces.STYLE_NS);
346         rootAttributes.addNamespaceDeclaration("text", OfficeNamespaces.TEXT_NS);
347         rootAttributes.addNamespaceDeclaration("table", OfficeNamespaces.TABLE_NS);
348         rootAttributes.addNamespaceDeclaration("draw", OfficeNamespaces.DRAWING_NS);
349         rootAttributes.addNamespaceDeclaration("fo", OfficeNamespaces.FO_NS);
350         rootAttributes.addNamespaceDeclaration("xlink", OfficeNamespaces.XLINK_NS);
351         rootAttributes.addNamespaceDeclaration("dc", OfficeNamespaces.PURL_NS);
352         rootAttributes.addNamespaceDeclaration("meta", OfficeNamespaces.META_NS);
353         rootAttributes.addNamespaceDeclaration("number",
354                 OfficeNamespaces.DATASTYLE_NS);
355         rootAttributes.addNamespaceDeclaration("svg", OfficeNamespaces.SVG_NS);
356         rootAttributes.addNamespaceDeclaration("chart", OfficeNamespaces.CHART_NS);
357         rootAttributes.addNamespaceDeclaration("chartooo", OfficeNamespaces.CHARTOOO_NS);
358         rootAttributes.addNamespaceDeclaration("dr3d", OfficeNamespaces.DR3D_NS);
359         rootAttributes.addNamespaceDeclaration("math", OfficeNamespaces.MATHML_NS);
360         rootAttributes.addNamespaceDeclaration("form", OfficeNamespaces.FORM_NS);
361         rootAttributes.addNamespaceDeclaration("script",
362                 OfficeNamespaces.SCRIPT_NS);
363         rootAttributes.addNamespaceDeclaration("ooo", OfficeNamespaces.OO2004_NS);
364         rootAttributes.addNamespaceDeclaration("ooow", OfficeNamespaces.OOW2004_NS);
365         rootAttributes.addNamespaceDeclaration("oooc", OfficeNamespaces.OOC2004_NS);
366         rootAttributes.addNamespaceDeclaration("dom",
367                 OfficeNamespaces.XML_EVENT_NS);
368         rootAttributes.addNamespaceDeclaration("xforms",
369                 OfficeNamespaces.XFORMS_NS);
370         rootAttributes.addNamespaceDeclaration("xsd", OfficeNamespaces.XSD_NS);
371         rootAttributes.addNamespaceDeclaration("xsi", OfficeNamespaces.XSI_NS);
372         rootAttributes.addNamespaceDeclaration("grddl", OfficeNamespaces.GRDDL_NS);
373         rootAttributes.setAttribute(OfficeNamespaces.OFFICE_NS, "version",
374                 OfficeDocumentReportTarget.ODF_VERSION);
375 
376         this.xmlWriter.writeXmlDeclaration("UTF-8");
377         this.xmlWriter.writeTag(OfficeNamespaces.OFFICE_NS,
378                 "document-styles", rootAttributes, XmlWriterSupport.OPEN);
379     }
380 
close()381     public void close()
382             throws IOException
383     {
384         xmlWriter.close();
385     }
386 }
387