001/*
002 * Copyright (c) 2003-2010 The Regents of the University of California.
003 * All rights reserved.
004 *
005 * '$Author: crawl $'
006 * '$Date: 2015-08-24 22:44:14 +0000 (Mon, 24 Aug 2015) $' 
007 * '$Revision: 33630 $'
008 * 
009 * Permission is hereby granted, without written agreement and without
010 * license or royalty fees, to use, copy, modify, and distribute this
011 * software and its documentation for any purpose, provided that the above
012 * copyright notice and the following two paragraphs appear in all copies
013 * of this software.
014 *
015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
019 * SUCH DAMAGE.
020 *
021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
026 * ENHANCEMENTS, OR MODIFICATIONS.
027 *
028 */
029
030package org.kepler.reporting.rio.fop;
031
032//Java
033import java.io.File;
034import java.io.IOException;
035import java.util.Iterator;
036
037import org.apache.commons.logging.Log;
038import org.apache.commons.logging.LogFactory;
039import org.kepler.reporting.rio.Item;
040import org.kepler.reporting.rio.ItemLabel;
041import org.kepler.reporting.rio.ItemProperties;
042import org.kepler.reporting.rio.ItemValue;
043import org.kepler.reporting.rio.fop.tools.AbstractObjectReader;
044import org.kepler.reporting.rio.util.ImageUtil;
045import org.kepler.reporting.roml.ReportLayout;
046import org.xml.sax.InputSource;
047import org.xml.sax.SAXException;
048import org.xml.sax.helpers.AttributesImpl;
049
050import net.sourceforge.iharder.Base64;
051import ptolemy.data.StringToken;
052import ptolemy.data.Token;
053
054/**
055 * XMLReader implementation for the Report class. This class is used to generate
056 * SAX events from the Report class.
057 */
058public class ReportXMLReader extends AbstractObjectReader {
059
060        public static Log log = LogFactory.getLog(ReportXMLReader.class);
061        
062        /**
063         * @see org.xml.sax.XMLReader#parse(InputSource)
064         */
065        public void parse(InputSource input) throws IOException, SAXException {
066                if (input instanceof ReportInputSource) {
067                        parse(((ReportInputSource) input).getReport());
068                } else {
069                        throw new SAXException("Unsupported InputSource specified. "
070                                        + "Must be a ReportInputSource");
071                }
072        }
073
074        /**
075         * Starts parsing the Report object.
076         * 
077         * @param report
078         *            The object to parse
079         * @throws SAXException
080         *             In case of a problem during SAX event generation
081         */
082        public void parse(ReportLayout report) throws SAXException {
083                if (report == null) {
084                        throw new NullPointerException("Parameter report must not be null");
085                }
086                if (handler == null) {
087                        throw new IllegalStateException("ContentHandler not set");
088                }
089
090                // Start the document
091                handler.startDocument();
092
093                // Generate SAX events for the Report
094                generateFor(report);
095
096                // End the document
097                handler.endDocument();
098        }
099
100        /**
101         * Generates SAX events for a Report object.
102         * 
103         * @param report
104         *            Report object to use
105         * @throws SAXException
106         *             In case of a problem during SAX event generation
107         */
108        protected void generateFor(ReportLayout report) throws SAXException {
109                if (report == null) {
110                        throw new NullPointerException("Parameter report must not be null");
111                }
112                if (handler == null) {
113                        throw new IllegalStateException("ContentHandler not set");
114                }
115
116                handler.startElement("report");
117                handler.element("title", report.getTitle());
118                handler.element("headerGraphic", report.getHeaderGraphic());
119                
120                String lsid = null;
121                if (report.getLsid() != null) {
122                        lsid = report.getLsid().toString();
123                }
124                handler.element("lsid", lsid);
125                
126                String wfLsid = null;
127                if (report.getWorkflowLSID() != null) {
128                        wfLsid = report.getWorkflowLSID().toString();
129                }
130                handler.element("workflow", wfLsid);
131                
132                Iterator i = report.getSections().get(0).getColumns().get(0).getItems()
133                                .iterator();
134                while (i.hasNext()) {
135                        Item item = (Item) i.next();
136                        generateFor(item);
137                }
138                handler.endElement("report");
139        }
140
141        /**
142         * Generates SAX events for a ProjectMember object.
143         * 
144         * @param projectMember
145         *            ProjectMember object to use
146         * @throws SAXException
147         *             In case of a problem during SAX event generation
148         */
149        protected void generateFor(Item item) throws SAXException {
150
151                if (item == null) {
152                        throw new NullPointerException("Parameter item must not be null");
153                }
154                if (handler == null) {
155                        throw new IllegalStateException("ContentHandler not set");
156                }
157
158                AttributesImpl attrs = new AttributesImpl();
159                attrs.addAttribute("", "name", "name", "string", item.getName());
160                attrs.addAttribute("", "type", "type", "string", item.getType());
161                attrs.addAttribute("", "class", "class", "string", item.getClass()
162                                .getName());
163
164                handler.startElement("item", attrs);
165
166                // do properties
167                if (item.getItemProperties() != null) {
168                        generateFor(item.getItemProperties());
169                }
170
171                // do labels
172                if (item.getLabels() != null) {
173                        Iterator labels = item.getLabels().iterator();
174                        while (labels.hasNext()) {
175                                ItemLabel label = (ItemLabel) labels.next();
176                                generateFor(label);
177                        }
178                }
179
180                // do values
181                Iterator i = item.getValues().iterator();
182                while (i.hasNext()) {
183                        ItemValue value = (ItemValue) i.next();
184                        generateFor(value);
185                }
186
187                handler.endElement("item");
188        }
189
190        protected void generateFor(ItemProperties itemProperties)
191                        throws SAXException {
192                handler.startElement("properties");
193
194                Iterator i = itemProperties.getProperties().iterator();
195                while (i.hasNext()) {
196                        String key = (String) i.next();
197                        String value = itemProperties.getProperty(key);
198                        AttributesImpl attrs = new AttributesImpl();
199                        attrs.addAttribute("", "name", "name", "string", key);
200                        handler.element("property", value, attrs);
201                }
202
203                handler.endElement("properties");
204        }
205
206        protected void generateFor(ItemLabel itemLabel) throws SAXException {
207                AttributesImpl attrs = new AttributesImpl();
208                attrs.addAttribute("", "position", "position", "string", itemLabel
209                                .getPosition());
210                handler.element("label", itemLabel.getValue(), attrs);
211        }
212
213        /**
214         * Generates SAX events for a ProjectMember object.
215         * 
216         * @param projectMember
217         *            ProjectMember object to use
218         * @throws SAXException
219         *             In case of a problem during SAX event generation
220         */
221        protected void generateFor(ItemValue itemValue) throws SAXException {
222
223                if (itemValue == null) {
224                        throw new NullPointerException("Parameter value must not be null");
225                }
226                if (handler == null) {
227                        throw new IllegalStateException("ContentHandler not set");
228                }
229
230                handler.startElement("value");
231
232                // do the value
233                Token token = itemValue.getValue();
234                
235                String value = token.toString();
236                // strings are special, of course
237                if (token instanceof StringToken) {
238                        value = ((StringToken) token).stringValue();
239                        value = value.replaceFirst("^\"", "");
240                        value = value.replaceFirst("\"$", "");
241                }
242                
243                //and the class so that we can reconstruct the data
244                AttributesImpl attrs = new AttributesImpl();
245                attrs.addAttribute("", "type", "type", "string", token.getClass().getName());
246                
247                //store the string representation of the token
248                handler.element("token", value, attrs);
249
250                //check for file pointers
251                if (token instanceof StringToken) {
252                        
253                        // check if this is a file path
254                        File tempFile = null;
255                        try {
256                                tempFile = new File(value);
257                                if (!tempFile.exists()) {
258                                        tempFile = null;
259                                }
260                        } catch (Exception e) {
261                                // do nothing for this exception, there is no file
262                        }
263                        // if we do have a file here, deal with it
264                        if (tempFile != null) {
265                                // convert pdf to png
266                                if (tempFile.getAbsolutePath().endsWith("pdf")) {
267                                        String fName = tempFile.getAbsolutePath();
268                                        fName = fName.substring(0, fName.lastIndexOf("."));
269                                        fName += ".png";
270                                        File png = new File(fName);
271                                        ImageUtil.pdf2png(tempFile, png);
272                                        tempFile = png;
273                                }
274                                handler.element("external-graphic", tempFile.getAbsolutePath());
275                                handler.element("base64data", Base64.encodeFromFile(tempFile.getAbsolutePath()));
276                        }
277                        else{
278                                //no file, just data, and the original path
279                                if (itemValue.getBase64data() != null){
280                                        handler.element("external-graphic", value);
281                                        handler.element("base64data", itemValue.getBase64data());
282                                }
283                        }
284                }
285
286                handler.endElement("value");
287        }
288
289}