1 28 29 33 package net.sf.jasperreports.engine.data; 34 35 import java.io.File ; 36 import java.io.FileInputStream ; 37 import java.io.InputStream ; 38 import java.util.Date ; 39 import java.util.Locale ; 40 import java.util.TimeZone ; 41 42 import javax.xml.transform.TransformerException ; 43 44 import net.sf.jasperreports.engine.JRException; 45 import net.sf.jasperreports.engine.JRField; 46 import net.sf.jasperreports.engine.JRRewindableDataSource; 47 import net.sf.jasperreports.engine.design.JRDesignField; 48 import net.sf.jasperreports.engine.util.JRDateLocaleConverter; 49 import net.sf.jasperreports.engine.util.JRXmlUtils; 50 51 import org.apache.commons.beanutils.locale.LocaleConvertUtilsBean; 52 import org.apache.xpath.CachedXPathAPI; 53 import org.apache.xpath.objects.XObject; 54 import org.w3c.dom.Document ; 55 import org.w3c.dom.Node ; 56 import org.w3c.dom.NodeList ; 57 import org.xml.sax.InputSource ; 58 59 131 public class JRXmlDataSource implements JRRewindableDataSource { 132 133 private Document document; 135 136 private String selectExpression; 138 139 private NodeList nodeList; 141 142 private int nodeListLength; 144 145 private Node currentNode; 147 148 private int currentNodeIndex = - 1; 150 151 private CachedXPathAPI xpathAPI = new CachedXPathAPI(); 153 154 private LocaleConvertUtilsBean convertBean = null; 155 156 private Locale locale = null; 157 private String datePattern = null; 158 private String numberPattern = null; 159 private TimeZone timeZone = null; 160 161 164 171 public JRXmlDataSource(Document document) throws JRException { 172 this(document, "."); 173 } 174 175 184 public JRXmlDataSource(Document document, String selectExpression) 185 throws JRException { 186 this.document = document; 187 this.selectExpression = selectExpression; 188 moveFirst(); 189 } 190 191 192 198 public JRXmlDataSource(InputStream in) throws JRException { 199 this(in, "."); 200 } 201 202 208 public JRXmlDataSource(InputStream in, String selectExpression) 209 throws JRException { 210 this(JRXmlUtils.parse(new InputSource (in)), selectExpression); 211 } 212 213 220 public JRXmlDataSource(String uri) throws JRException { 221 this(uri, "."); 222 } 223 224 230 public JRXmlDataSource(String uri, String selectExpression) 231 throws JRException { 232 this(JRXmlUtils.parse(uri), selectExpression); 233 } 234 235 241 public JRXmlDataSource(File file) throws JRException { 242 this(file, "."); 243 } 244 245 251 public JRXmlDataSource(File file, String selectExpression) 252 throws JRException { 253 this(JRXmlUtils.parse(file), selectExpression); 254 } 255 256 259 264 public void moveFirst() throws JRException { 265 if (document == null) 266 throw new JRException("document cannot be null"); 267 if (selectExpression == null) 268 throw new JRException("selectExpression cannot be null"); 269 270 try { 271 currentNode = null; 272 currentNodeIndex = -1; 273 nodeListLength = 0; 274 nodeList = xpathAPI.selectNodeList(document, 275 selectExpression); 276 nodeListLength = nodeList.getLength(); 277 } catch (TransformerException e) { 278 throw new JRException("XPath selection failed. Expression: " 279 + selectExpression, e); 280 } 281 } 282 283 288 public boolean next() { 289 if(currentNodeIndex == nodeListLength - 1) 290 return false; 291 292 currentNode = nodeList.item(++ currentNodeIndex); 293 return true; 294 } 295 296 301 public Object getFieldValue(JRField jrField) throws JRException { 302 if(currentNode == null) 303 return null; 304 305 String expression = jrField.getDescription(); 306 if (expression == null || expression.length() == 0) 307 return null; 308 309 Object value = null; 310 311 Class valueClass = jrField.getValueClass(); 312 313 if(Object .class != valueClass) { 314 String text = null; 315 316 try { 317 XObject list = xpathAPI.eval(currentNode, expression); 318 if (list.getType() == XObject.CLASS_NODESET) { 319 Node node = list.nodeset().nextNode(); 320 if (node != null) { 321 text = getText(node); 322 } 323 } else { 324 text = list.str(); 325 } 326 } catch (TransformerException e) { 327 throw new JRException("XPath selection failed. Expression: " 328 + expression, e); 329 } 330 331 if(text != null) { 332 if (String .class.equals(valueClass)) 333 { 334 value = text; 335 } 336 else if (Number .class.isAssignableFrom(valueClass)) 337 { 338 value = getConvertBean().convert(text.trim(), valueClass, locale, numberPattern); 339 } 340 else if (Date .class.isAssignableFrom(valueClass)) 341 { 342 value = getConvertBean().convert(text.trim(), valueClass, locale, datePattern); 343 } 344 345 } 346 } 347 return value; 348 } 349 350 360 public JRXmlDataSource subDataSource(String selectExpr) 361 throws JRException { 362 Document doc = subDocument(); 364 JRXmlDataSource subDataSource = new JRXmlDataSource(doc, selectExpr); 365 subDataSource.setLocale(locale); 366 subDataSource.setDatePattern(datePattern); 367 subDataSource.setNumberPattern(numberPattern); 368 subDataSource.setTimeZone(timeZone); 369 return subDataSource; 370 } 371 372 382 public JRXmlDataSource subDataSource() throws JRException { 383 return subDataSource("."); 384 } 385 386 387 393 public Document subDocument() throws JRException 394 { 395 if(currentNode == null) 396 { 397 throw new JRException("No node available. Iterate or rewind the data source."); 398 } 399 400 Document doc = JRXmlUtils.createDocument(currentNode); 402 return doc; 403 } 404 405 406 416 public JRXmlDataSource dataSource(String selectExpr) 417 throws JRException { 418 JRXmlDataSource subDataSource = new JRXmlDataSource(document, selectExpr); 419 subDataSource.setLocale(locale); 420 subDataSource.setDatePattern(datePattern); 421 subDataSource.setNumberPattern(numberPattern); 422 subDataSource.setTimeZone(timeZone); 423 return subDataSource; 424 } 425 426 435 public JRXmlDataSource dataSource() throws JRException { 436 return dataSource("."); 437 } 438 439 452 public String getText(Node node) { 453 if (!node.hasChildNodes()) 454 return node.getNodeValue(); 455 456 StringBuffer result = new StringBuffer (); 457 458 NodeList list = node.getChildNodes(); 459 for (int i = 0; i < list.getLength(); i++) { 460 Node subnode = list.item(i); 461 if (subnode.getNodeType() == Node.TEXT_NODE) { 462 String value = subnode.getNodeValue(); 463 if(value != null) 464 result.append(value); 465 } else if (subnode.getNodeType() == Node.CDATA_SECTION_NODE) { 466 String value = subnode.getNodeValue(); 467 if(value != null) 468 result.append(value); 469 } else if (subnode.getNodeType() == Node.ENTITY_REFERENCE_NODE) { 470 String value = getText(subnode); 473 if(value != null) 474 result.append(value); 475 } 476 } 477 478 return result.toString(); 479 } 480 481 public static void main(String [] args) throws Exception { 482 JRXmlDataSource ds = new JRXmlDataSource(new FileInputStream ("northwind.xml"), "/Northwind/Customers"); 483 JRDesignField field = new JRDesignField(); 484 field.setDescription("CustomerID"); 485 field.setValueClass(String .class); 486 487 ds.next(); 488 String v = (String ) ds.getFieldValue(field); 489 System.out.println(field.getDescription() + "=" + v); 490 491 JRXmlDataSource subDs = ds.dataSource("/Northwind/Orders"); 492 493 JRDesignField field1 = new JRDesignField(); 494 field1.setDescription("OrderID"); 495 field1.setValueClass(String .class); 496 497 subDs.next(); 498 String v1 = (String ) subDs.getFieldValue(field1); 499 System.out.println(field1.getDescription() + "=" + v1); 500 501 } 502 503 protected LocaleConvertUtilsBean getConvertBean() 504 { 505 if (convertBean == null) 506 { 507 convertBean = new LocaleConvertUtilsBean(); 508 if (locale != null) 509 { 510 convertBean.setDefaultLocale(locale); 511 convertBean.deregister(); 512 } 514 convertBean.register( 515 new JRDateLocaleConverter(timeZone), 516 java.util.Date .class, 517 locale 518 ); 519 } 520 return convertBean; 521 } 522 523 public Locale getLocale() { 524 return locale; 525 } 526 527 public void setLocale(Locale locale) { 528 this.locale = locale; 529 convertBean = null; 530 } 531 532 public String getDatePattern() { 533 return datePattern; 534 } 535 536 public void setDatePattern(String datePattern) { 537 this.datePattern = datePattern; 538 convertBean = null; 539 } 540 541 public String getNumberPattern() { 542 return numberPattern; 543 } 544 545 public void setNumberPattern(String numberPattern) { 546 this.numberPattern = numberPattern; 547 convertBean = null; 548 } 549 550 public TimeZone getTimeZone() { 551 return timeZone; 552 } 553 554 public void setTimeZone(TimeZone timeZone) { 555 this.timeZone = timeZone; 556 convertBean = null; 557 } 558 559 } 560 | Popular Tags |