1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package net.sf.jasperreports.jsf.engine.converters;
20
21 import net.sf.jasperreports.jsf.engine.JRDataSourceWrapper;
22 import java.io.File;
23 import java.io.FileInputStream;
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.net.URL;
27 import java.text.MessageFormat;
28 import java.util.ArrayList;
29 import java.util.List;
30 import java.util.logging.Level;
31 import java.util.logging.Logger;
32
33 import javax.faces.component.UIComponent;
34 import javax.faces.component.UIParameter;
35 import javax.faces.context.FacesContext;
36 import javax.xml.parsers.DocumentBuilder;
37 import javax.xml.parsers.DocumentBuilderFactory;
38 import javax.xml.parsers.ParserConfigurationException;
39 import javax.xml.transform.dom.DOMSource;
40 import javax.xml.transform.sax.SAXSource;
41 import javax.xml.transform.stream.StreamSource;
42
43 import net.sf.jasperreports.engine.JRDataSource;
44 import net.sf.jasperreports.engine.JREmptyDataSource;
45 import net.sf.jasperreports.engine.JRException;
46 import net.sf.jasperreports.engine.data.JRXmlDataSource;
47 import net.sf.jasperreports.jsf.Constants;
48 import net.sf.jasperreports.jsf.context.JRFacesContext;
49 import net.sf.jasperreports.jsf.engine.Source;
50 import net.sf.jasperreports.jsf.engine.SourceException;
51 import net.sf.jasperreports.jsf.resource.Resource;
52
53 import org.w3c.dom.Document;
54 import org.xml.sax.InputSource;
55 import org.xml.sax.SAXException;
56
57 import static net.sf.jasperreports.jsf.util.ComponentUtil.*;
58
59
60
61
62
63
64
65 public final class XmlSourceConverter extends SourceConverterBase {
66
67
68
69
70 private static final long serialVersionUID = -5512987093226353550L;
71 private static final Logger logger = Logger.getLogger(
72 XmlSourceConverter.class.getPackage().getName(),
73 Constants.LOG_MESSAGES_BUNDLE);
74
75 @Override
76 protected Source createSource(FacesContext context,
77 UIComponent component, Object value)
78 throws SourceException {
79 JRDataSource dataSource;
80
81 final Document xmlDocument;
82 try {
83 xmlDocument = getXmlDocument(context, component, value);
84 } catch (final ParserConfigurationException ex) {
85 throw new SourceException(ex);
86 } catch (final SAXException ex) {
87 throw new SourceException(ex);
88 } catch (final IOException ex) {
89 throw new SourceException(ex);
90 }
91
92 if (xmlDocument == null) {
93 if (logger.isLoggable(Level.WARNING)) {
94 logger.log(Level.WARNING, "JRJSF_0020",
95 component.getClientId(context));
96 }
97 dataSource = new JREmptyDataSource();
98 } else {
99 final String query = getStringAttribute(component, "query", null);
100 try {
101 if ((query != null) && (query.length() > 0)) {
102 dataSource = new JRXmlDataSource(xmlDocument,
103 parseQuery(component, query));
104 } else {
105 dataSource = new JRXmlDataSource(xmlDocument);
106 }
107 } catch (final JRException e) {
108 throw new SourceException(e);
109 }
110 }
111
112 return new JRDataSourceWrapper(dataSource);
113 }
114
115 protected Document getXmlDocument(final FacesContext context,
116 UIComponent component, Object value)
117 throws ParserConfigurationException, SAXException, IOException {
118 if (value == null) {
119 return null;
120 }
121
122 Document document;
123
124 if (value instanceof Document) {
125 document = (Document) value;
126 } else if (value instanceof DOMSource) {
127 final DOMSource source = (DOMSource) value;
128 final DocumentBuilder builder = getDocumentBuilder();
129 document = builder.newDocument();
130 document.appendChild(source.getNode());
131 } else if ((value instanceof InputSource)
132 || (value instanceof SAXSource)) {
133 InputSource inputSource;
134 if (value instanceof SAXSource) {
135 final SAXSource source = (SAXSource) value;
136 inputSource = source.getInputSource();
137 } else {
138 inputSource = (InputSource) value;
139 }
140 final DocumentBuilder builder = getDocumentBuilder();
141 document = builder.parse(inputSource);
142 } else {
143 InputStream stream = null;
144 boolean closeStream = true;
145 if (value instanceof StreamSource) {
146 final StreamSource source = (StreamSource) value;
147 stream = source.getInputStream();
148 } else if (value instanceof File) {
149 stream = new FileInputStream((File) value);
150 } else if (value instanceof URL) {
151 stream = ((URL) value).openStream();
152 } else if (value instanceof String) {
153 final JRFacesContext jrContext =
154 JRFacesContext.getInstance(context);
155 final Resource resource = jrContext.createResource(context,
156 component, (String) value);
157 stream = resource.getInputStream();
158 } else if (value instanceof InputStream) {
159 stream = (InputStream) value;
160 closeStream = false;
161 }
162
163 if (stream == null) {
164 throw new SourceException("Unrecognized XML "
165 + "value source type: " + value.getClass().getName());
166 }
167
168 try {
169 final DocumentBuilder builder = getDocumentBuilder();
170 document = builder.parse(stream);
171 } finally {
172 if (stream != null && closeStream) {
173 try {
174 stream.close();
175 } catch (final IOException e) { ; }
176 }
177 stream = null;
178 }
179 }
180
181 return document;
182 }
183
184 private String parseQuery(UIComponent component, final String query) {
185 final List<Object> params = new ArrayList<Object>();
186
187 for (final UIComponent kid : component.getChildren()) {
188 if (!(kid instanceof UIParameter)) {
189 continue;
190 }
191
192 final Object value = ((UIParameter) kid).getValue();
193 params.add(value);
194 }
195
196 return MessageFormat.format(query,
197 params.toArray(new Object[params.size()]));
198 }
199
200 private DocumentBuilder getDocumentBuilder()
201 throws ParserConfigurationException {
202 final DocumentBuilderFactory builderFactory =
203 DocumentBuilderFactory.newInstance();
204 return builderFactory.newDocumentBuilder();
205 }
206
207 }