PageRenderTime 41ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/projects/compiere-330/print/src/org/compiere/print/PrintData.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 793 lines | 474 code | 70 blank | 249 comment | 91 complexity | 1c61d13775e4109fbaad81135559bd6c MD5 | raw file
  1. /******************************************************************************
  2. * Product: Compiere ERP & CRM Smart Business Solution *
  3. * Copyright (C) 1999-2007 ComPiere, Inc. All Rights Reserved. *
  4. * This program is free software, you can redistribute it and/or modify it *
  5. * under the terms version 2 of the GNU General Public License as published *
  6. * by the Free Software Foundation. This program is distributed in the hope *
  7. * that it will be useful, but WITHOUT ANY WARRANTY, without even the implied *
  8. * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
  9. * See the GNU General Public License for more details. *
  10. * You should have received a copy of the GNU General Public License along *
  11. * with this program, if not, write to the Free Software Foundation, Inc., *
  12. * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
  13. * For the text or an alternative of this public license, you may reach us *
  14. * ComPiere, Inc., 3600 Bridge Parkway #102, Redwood City, CA 94065, USA *
  15. * or via info@compiere.org or http://www.compiere.org/license.html *
  16. *****************************************************************************/
  17. package org.compiere.print;
  18. import java.io.*;
  19. import java.util.*;
  20. import java.util.logging.*;
  21. import javax.xml.parsers.*;
  22. import javax.xml.transform.*;
  23. import javax.xml.transform.dom.*;
  24. import javax.xml.transform.stream.*;
  25. import org.compiere.*;
  26. import org.compiere.common.constants.*;
  27. import org.compiere.model.*;
  28. import org.compiere.util.*;
  29. import org.w3c.dom.*;
  30. /**
  31. * Print Data Structure.
  32. * Created by DataEngine
  33. * A Structure has rows, wich contain elements.
  34. * Elements can be end nodes (PrintDataElements) or data structures (PrintData).
  35. * The row data is sparse - i.e. null if not existing.
  36. * A Structure has optional meta info about content (PrintDataColumn).
  37. *
  38. * @author Jorg Janke
  39. * @version $Id: PrintData.java,v 1.3 2006/07/30 00:53:02 jjanke Exp $
  40. */
  41. public class PrintData implements Serializable
  42. {
  43. /**
  44. *
  45. */
  46. private static final long serialVersionUID = 1L;
  47. /**
  48. * Data Parent Constructor
  49. * @param ctx context
  50. * @param name data element name
  51. */
  52. public PrintData (Ctx ctx, String name)
  53. {
  54. if (name == null)
  55. throw new IllegalArgumentException("Name cannot be null");
  56. m_ctx = ctx;
  57. m_name = name;
  58. } // PrintData
  59. /**
  60. * Data Parent Constructor
  61. * @param ctx context
  62. * @param name data element name
  63. * @param nodes ArrayList with nodes (content not checked)
  64. */
  65. public PrintData (Ctx ctx, String name, ArrayList<Object> nodes)
  66. {
  67. if (name == null)
  68. throw new IllegalArgumentException("Name cannot be null");
  69. m_ctx = ctx;
  70. m_name = name;
  71. if (nodes != null)
  72. m_nodes = nodes;
  73. } // PrintData
  74. /** Context */
  75. private Ctx m_ctx;
  76. /** Data Structure Name */
  77. private String m_name;
  78. /** Data Structure rows */
  79. private ArrayList<ArrayList<Object>> m_rows = new ArrayList<ArrayList<Object>>();
  80. /** Current Row Data Structure elements */
  81. private ArrayList<Object> m_nodes = null;
  82. /** Current Row */
  83. private int m_row = -1;
  84. /** List of Function Rows */
  85. private ArrayList<Integer> m_functionRows = new ArrayList<Integer>();
  86. /** Table has LevelNo */
  87. private boolean m_hasLevelNo = false;
  88. /** Level Number Indicator */
  89. private static final String LEVEL_NO = "LEVELNO";
  90. /** Optional Column Meta Data */
  91. private PrintDataColumn[] m_columnInfo = null;
  92. /** Optional sql */
  93. private String m_sql = null;
  94. /** Optional TableName */
  95. private String m_TableName = null;
  96. /** XML Element Name */
  97. public static final String XML_TAG = "compiereData";
  98. /** XML Row Name */
  99. public static final String XML_ROW_TAG = "row";
  100. /** XML Attribute Name */
  101. public static final String XML_ATTRIBUTE_NAME = "name";
  102. /** XML Attribute Count */
  103. public static final String XML_ATTRIBUTE_COUNT = "count";
  104. /** XML Attribute Number */
  105. public static final String XML_ATTRIBUTE_NO = "no";
  106. /** XML Attribute Function Row */
  107. public static final String XML_ATTRIBUTE_FUNCTION_ROW = "function_row";
  108. /** Logger */
  109. private static CLogger log = CLogger.getCLogger(PrintData.class);
  110. /**
  111. * Get Context
  112. * @return context
  113. */
  114. public Ctx getCtx()
  115. {
  116. return m_ctx;
  117. } // getName
  118. /**
  119. * Get Name
  120. * @return name
  121. */
  122. public String getName()
  123. {
  124. return m_name;
  125. } // getName
  126. /*************************************************************************/
  127. /**
  128. * Set optional Column Info
  129. * @param newInfo Column Info
  130. */
  131. public void setColumnInfo (PrintDataColumn[] newInfo)
  132. {
  133. m_columnInfo = newInfo;
  134. } // setColumnInfo
  135. /**
  136. * Get optional Column Info
  137. * @return Column Info
  138. */
  139. public PrintDataColumn[] getColumnInfo()
  140. {
  141. return m_columnInfo;
  142. } // getColumnInfo
  143. /**
  144. * Set SQL (optional)
  145. * @param sql SQL
  146. */
  147. public void setSQL (String sql)
  148. {
  149. m_sql = sql;
  150. } // setSQL
  151. /**
  152. * Get optional SQL
  153. * @return SQL
  154. */
  155. public String getSQL()
  156. {
  157. return m_sql;
  158. } // getSQL
  159. /**
  160. * Set TableName (optional)
  161. * @param TableName TableName
  162. */
  163. public void setTableName (String TableName)
  164. {
  165. m_TableName = TableName;
  166. } // setTableName
  167. /**
  168. * Get optional TableName
  169. * @return TableName
  170. */
  171. public String getTableName()
  172. {
  173. return m_TableName;
  174. } // getTableName
  175. /**
  176. * String representation
  177. * @return info
  178. */
  179. @Override
  180. public String toString()
  181. {
  182. StringBuffer sb = new StringBuffer("PrintData[");
  183. sb.append(m_name).append(",Rows=").append(m_rows.size());
  184. if (m_TableName != null)
  185. sb.append(",TableName=").append(m_TableName);
  186. sb.append("]");
  187. return sb.toString();
  188. } // toString
  189. /**************************************************************************
  190. * Returns true if no Nodes in row
  191. * @return true if no Nodes in row
  192. */
  193. public boolean isEmpty()
  194. {
  195. if (m_nodes == null)
  196. return true;
  197. return m_nodes.size() == 0;
  198. } // isEmpty
  199. /**
  200. * Return Number of nodes in row
  201. * @return number of nodes in row
  202. */
  203. public int getNodeCount()
  204. {
  205. if (m_nodes == null)
  206. return 0;
  207. return m_nodes.size();
  208. } // getNodeCount
  209. /**************************************************************************
  210. * Add Row
  211. * @param functionRow true if function row
  212. * @param levelNo Line detail Level Number 0=Normal
  213. */
  214. public void addRow (boolean functionRow, int levelNo)
  215. {
  216. m_nodes = new ArrayList<Object>();
  217. m_row = m_rows.size();
  218. m_rows.add (m_nodes);
  219. if (functionRow)
  220. m_functionRows.add(new Integer(m_row));
  221. if (m_hasLevelNo && levelNo != 0)
  222. addNode(new PrintDataElement(LEVEL_NO, new Integer(levelNo), DisplayTypeConstants.Integer));
  223. } // addRow
  224. /**
  225. * Set Row Index
  226. * @param row row index
  227. * @return true if success
  228. */
  229. public boolean setRowIndex (int row)
  230. {
  231. if (row < 0 || row >= m_rows.size())
  232. return false;
  233. m_row = row;
  234. m_nodes = m_rows.get(m_row);
  235. return true;
  236. }
  237. /**
  238. * Set Row Index to next
  239. * @return true if success
  240. */
  241. public boolean setRowNext()
  242. {
  243. return setRowIndex(m_row+1);
  244. } // setRowNext
  245. /**
  246. * Get Row Count
  247. * @return row count
  248. */
  249. public int getRowCount()
  250. {
  251. return m_rows.size();
  252. } // getRowCount
  253. /**
  254. * Get Current Row Index
  255. * @return row index
  256. */
  257. public int getRowIndex()
  258. {
  259. return m_row;
  260. } // getRowIndex
  261. /**
  262. * Is the Row a Function Row
  263. * @param row row no
  264. * @return true if function row
  265. */
  266. public boolean isFunctionRow (int row)
  267. {
  268. return m_functionRows.contains(new Integer(row));
  269. } // isFunctionRow
  270. /**
  271. * Is the current Row a Function Row
  272. * @return true if function row
  273. */
  274. public boolean isFunctionRow ()
  275. {
  276. return m_functionRows.contains(new Integer(m_row));
  277. } // isFunctionRow
  278. /**
  279. * Is the current Row a Function Row
  280. * @return true if function row
  281. */
  282. public boolean isPageBreak ()
  283. {
  284. // page break requires function and meta data
  285. if (isFunctionRow() && m_nodes != null)
  286. {
  287. for (int i = 0; i < m_nodes.size(); i++)
  288. {
  289. Object o = m_nodes.get(i);
  290. if (o instanceof PrintDataElement)
  291. {
  292. PrintDataElement pde = (PrintDataElement)o;
  293. if (pde.isPageBreak())
  294. return true;
  295. }
  296. }
  297. }
  298. return false;
  299. } // isPageBreak
  300. /**
  301. * PrintData has Level No
  302. * @param hasLevelNo true if sql contains LevelNo
  303. */
  304. public void setHasLevelNo (boolean hasLevelNo)
  305. {
  306. m_hasLevelNo = hasLevelNo;
  307. } // hasLevelNo
  308. /**
  309. * PrintData has Level No
  310. * @return true if sql contains LevelNo
  311. */
  312. public boolean hasLevelNo()
  313. {
  314. return m_hasLevelNo;
  315. } // hasLevelNo
  316. /**
  317. * Get Line Level Number for current row
  318. * @return line level no 0 = default
  319. */
  320. public int getLineLevelNo ()
  321. {
  322. if (m_nodes == null || !m_hasLevelNo)
  323. return 0;
  324. for (int i = 0; i < m_nodes.size(); i++)
  325. {
  326. Object o = m_nodes.get (i);
  327. if (o instanceof PrintDataElement)
  328. {
  329. PrintDataElement pde = (PrintDataElement)o;
  330. if (LEVEL_NO.equals (pde.getColumnName()))
  331. {
  332. Integer ii = (Integer)pde.getValue();
  333. return ii.intValue();
  334. }
  335. }
  336. }
  337. return 0;
  338. } // getLineLevel
  339. /*************************************************************************/
  340. /**
  341. * Add Parent node to Data Structure row
  342. * @param parent parent
  343. */
  344. public void addNode (PrintData parent)
  345. {
  346. if (parent == null)
  347. throw new IllegalArgumentException("Parent cannot be null");
  348. if (m_nodes == null)
  349. addRow(false, 0);
  350. m_nodes.add (parent);
  351. } // addNode
  352. /**
  353. * Add node to Data Structure row
  354. * @param node node
  355. */
  356. public void addNode (PrintDataElement node)
  357. {
  358. if (node == null)
  359. throw new IllegalArgumentException("Node cannot be null");
  360. if (m_nodes == null)
  361. addRow(false, 0);
  362. m_nodes.add (node);
  363. } // addNode
  364. /**
  365. * Get Node with index in row
  366. * @param index index
  367. * @return PrintData(Element) of index or null
  368. */
  369. public Object getNode (int index)
  370. {
  371. if (m_nodes == null || index < 0 || index >= m_nodes.size())
  372. return null;
  373. return m_nodes.get(index);
  374. } // getNode
  375. /**
  376. * Get Node with Name in row
  377. * @param name name
  378. * @return PrintData(Element) with Name or null
  379. */
  380. public Object getNode (String name)
  381. {
  382. int index = getIndex (name);
  383. if (index < 0)
  384. return null;
  385. return m_nodes.get(index);
  386. } // getNode
  387. /**
  388. * Get Node with AD_Column_ID in row
  389. * @param AD_Column_ID AD_Column_ID
  390. * @return PrintData(Element) with AD_Column_ID or null
  391. */
  392. public Object getNode (Integer AD_Column_ID)
  393. {
  394. int index = getIndex (AD_Column_ID.intValue());
  395. if (index < 0)
  396. return null;
  397. return m_nodes.get(index);
  398. } // getNode
  399. /**
  400. * Get Primary Key in row
  401. * @return PK or null
  402. */
  403. public PrintDataElement getPKey()
  404. {
  405. if (m_nodes == null)
  406. return null;
  407. for (int i = 0; i < m_nodes.size(); i++)
  408. {
  409. Object o = m_nodes.get(i);
  410. if (o instanceof PrintDataElement)
  411. {
  412. PrintDataElement pde = (PrintDataElement)o;
  413. if (pde.isPKey())
  414. return pde;
  415. }
  416. }
  417. return null;
  418. } // getPKey
  419. /**
  420. * Get Index of Node in Structure (not recursing) row
  421. * @param columnName name
  422. * @return index or -1
  423. */
  424. public int getIndex (String columnName)
  425. {
  426. if (m_nodes == null)
  427. return -1;
  428. for (int i = 0; i < m_nodes.size(); i++)
  429. {
  430. Object o = m_nodes.get(i);
  431. if (o instanceof PrintDataElement)
  432. {
  433. if (columnName.equals(((PrintDataElement)o).getColumnName()))
  434. return i;
  435. }
  436. else if (o instanceof PrintData)
  437. {
  438. if (columnName.equals(((PrintData)o).getName()))
  439. return i;
  440. }
  441. else
  442. log.log(Level.SEVERE, "Element not PrintData(Element) " + o.getClass().getName());
  443. }
  444. // As Data is stored sparse, there might be lots of NULL values
  445. // log.log(Level.SEVERE, "PrintData.getIndex - Element not found - " + name);
  446. return -1;
  447. } // getIndex
  448. /**
  449. * Get Index of Node in Structure (not recursing) row
  450. * @param AD_Column_ID AD_Column_ID
  451. * @return index or -1
  452. */
  453. public int getIndex (int AD_Column_ID)
  454. {
  455. if (m_columnInfo == null)
  456. return -1;
  457. for (PrintDataColumn element : m_columnInfo) {
  458. if (element.getAD_Column_ID() == AD_Column_ID)
  459. return getIndex(element.getColumnName());
  460. }
  461. // OK for virtual Columns with TableDirect, Search
  462. MColumn col = MColumn.get (getCtx(), AD_Column_ID);
  463. if (col != null && col.isVirtualColumn())
  464. return -1; // not found, but OK
  465. log.log(Level.WARNING, "Column not found - AD_Column_ID=" + AD_Column_ID);
  466. if (AD_Column_ID == 0)
  467. Trace.printStack();
  468. return -1;
  469. } // getIndex
  470. /**************************************************************************
  471. * Dump All Data - header and rows
  472. */
  473. public void dump()
  474. {
  475. dump(this);
  476. } // dump
  477. /**
  478. * Dump All Data
  479. */
  480. public void dumpHeader()
  481. {
  482. dumpHeader(this);
  483. } // dumpHeader
  484. /**
  485. * Dump All Data
  486. */
  487. public void dumpCurrentRow()
  488. {
  489. dumpRow(this, m_row);
  490. } // dump
  491. /**
  492. * Dump all PrintData - header and rows
  493. * @param pd print data
  494. */
  495. private static void dump (PrintData pd)
  496. {
  497. dumpHeader(pd);
  498. for (int i = 0; i < pd.getRowCount(); i++)
  499. dumpRow(pd, i);
  500. } // dump
  501. /**
  502. * Dump PrintData Header
  503. * @param pd print data
  504. */
  505. private static void dumpHeader (PrintData pd)
  506. {
  507. log.info(pd.toString());
  508. if (pd.getColumnInfo() != null)
  509. {
  510. for (int i = 0; i < pd.getColumnInfo().length; i++)
  511. log.config(i + ": " + pd.getColumnInfo()[i]);
  512. }
  513. } // dump
  514. /**
  515. * Dump Row
  516. * @param pd print data
  517. * @param row row
  518. */
  519. private static void dumpRow (PrintData pd, int row)
  520. {
  521. log.info("Row #" + row);
  522. if (row < 0 || row >= pd.getRowCount())
  523. {
  524. log.warning("- invalid -");
  525. return;
  526. }
  527. pd.setRowIndex(row);
  528. if (pd.getNodeCount() == 0)
  529. {
  530. log.config("- n/a -");
  531. return;
  532. }
  533. for (int i = 0; i < pd.getNodeCount(); i++)
  534. {
  535. Object obj = pd.getNode(i);
  536. if (obj == null)
  537. log.config("- NULL -");
  538. else if (obj instanceof PrintData)
  539. {
  540. log.config("- included -");
  541. dump((PrintData)obj);
  542. }
  543. else if (obj instanceof PrintDataElement)
  544. {
  545. log.config(((PrintDataElement)obj).toStringX());
  546. }
  547. else
  548. log.config("- INVALID: " + obj);
  549. }
  550. } // dumpRow
  551. /**************************************************************************
  552. * Get XML Document representation
  553. * @return XML document
  554. */
  555. public Document getDocument()
  556. {
  557. Document document = null;
  558. try
  559. {
  560. DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
  561. // System.out.println(factory.getClass().getName());
  562. DocumentBuilder builder = factory.newDocumentBuilder();
  563. document = builder.newDocument();
  564. document.appendChild(document.createComment(Compiere.getSummaryAscii()));
  565. }
  566. catch (Exception e)
  567. {
  568. System.err.println(e);
  569. e.printStackTrace();
  570. }
  571. // Root
  572. Element root = document.createElement(PrintData.XML_TAG);
  573. root.setAttribute(XML_ATTRIBUTE_NAME, getName());
  574. root.setAttribute(XML_ATTRIBUTE_COUNT, String.valueOf(getRowCount()));
  575. document.appendChild(root);
  576. processXML (this, document, root);
  577. return document;
  578. } // getDocument
  579. /**
  580. * Process PrintData Tree
  581. * @param pd Print Data
  582. * @param document document
  583. * @param root element to add to
  584. */
  585. private static void processXML (PrintData pd, Document document, Element root)
  586. {
  587. for (int r = 0; r < pd.getRowCount(); r++)
  588. {
  589. pd.setRowIndex(r);
  590. Element row = document.createElement(PrintData.XML_ROW_TAG);
  591. row.setAttribute(XML_ATTRIBUTE_NO, String.valueOf(r));
  592. if (pd.isFunctionRow())
  593. row.setAttribute(XML_ATTRIBUTE_FUNCTION_ROW, "yes");
  594. root.appendChild(row);
  595. //
  596. for (int i = 0; i < pd.getNodeCount(); i++)
  597. {
  598. Object o = pd.getNode(i);
  599. if (o instanceof PrintData)
  600. {
  601. PrintData pd_x = (PrintData)o;
  602. Element element = document.createElement(PrintData.XML_TAG);
  603. element.setAttribute(XML_ATTRIBUTE_NAME, pd_x.getName());
  604. element.setAttribute(XML_ATTRIBUTE_COUNT, String.valueOf(pd_x.getRowCount()));
  605. row.appendChild(element);
  606. processXML (pd_x, document, element); // recursive call
  607. }
  608. else if (o instanceof PrintDataElement)
  609. {
  610. PrintDataElement pde = (PrintDataElement)o;
  611. if (!pde.isNull())
  612. {
  613. Element element = document.createElement(PrintDataElement.XML_TAG);
  614. element.setAttribute(PrintDataElement.XML_ATTRIBUTE_NAME, pde.getColumnName());
  615. if (pde.hasKey())
  616. element.setAttribute(PrintDataElement.XML_ATTRIBUTE_KEY, pde.getValueKey());
  617. element.appendChild(document.createTextNode(pde.getValueDisplay(null, -1))); // not formatted
  618. row.appendChild(element);
  619. }
  620. }
  621. else
  622. log.log(Level.SEVERE, "Element not PrintData(Element) " + o.getClass().getName());
  623. } // columns
  624. } // rows
  625. } // processTree
  626. /**
  627. * Create XML representation to StreamResult
  628. * @param result StreamResult
  629. * @return true if success
  630. */
  631. public boolean createXML (StreamResult result)
  632. {
  633. try
  634. {
  635. DOMSource source = new DOMSource(getDocument());
  636. TransformerFactory tFactory = TransformerFactory.newInstance();
  637. Transformer transformer = tFactory.newTransformer();
  638. transformer.transform (source, result);
  639. }
  640. catch (Exception e)
  641. {
  642. log.log(Level.SEVERE, "(StreamResult)", e);
  643. return false;
  644. }
  645. return true;
  646. } // createXML
  647. /**
  648. * Create XML representation to File
  649. * @param fileName file name
  650. * @return true if success
  651. */
  652. public boolean createXML (String fileName)
  653. {
  654. try
  655. {
  656. File file = new File(fileName);
  657. file.createNewFile();
  658. StreamResult result = new StreamResult(file);
  659. createXML (result);
  660. }
  661. catch (Exception e)
  662. {
  663. log.log(Level.SEVERE, "(file)", e);
  664. return false;
  665. }
  666. return true;
  667. } // createXMLFile
  668. /**************************************************************************
  669. * Create PrintData from XML
  670. * @param ctx context
  671. * @param input InputSource
  672. * @return PrintData
  673. */
  674. public static PrintData parseXML (Ctx ctx, File input)
  675. {
  676. log.config(input.toString());
  677. PrintData pd = null;
  678. try
  679. {
  680. PrintDataHandler handler = new PrintDataHandler(ctx);
  681. SAXParserFactory factory = SAXParserFactory.newInstance();
  682. SAXParser parser = factory.newSAXParser();
  683. parser.parse(input, handler);
  684. pd = handler.getPrintData();
  685. }
  686. catch (Exception e)
  687. {
  688. log.log(Level.SEVERE, "", e);
  689. }
  690. return pd;
  691. } // parseXML
  692. public ArrayList<ArrayList<Object>> getRows(){
  693. return m_rows;
  694. }
  695. /**************************************************************************
  696. * Test
  697. * @param args test
  698. */
  699. public static void main(String[] args)
  700. {
  701. PrintData pd = new PrintData(new Ctx(), "test1");
  702. pd.addNode(new PrintDataElement("test1element1","testvalue<1>",0));
  703. pd.addNode(new PrintDataElement("test1element2","testvalue&2&",0));
  704. PrintData pdx = new PrintData(new Ctx(), "test2");
  705. pdx.addNode(new PrintDataElement("test2element1-1","testvalue11",0));
  706. pdx.addNode(new PrintDataElement("test2element1-2","testvalue12",0));
  707. pdx.addRow(false, 0);
  708. pdx.addNode(new PrintDataElement("test2element2-1","testvalue21",0));
  709. pdx.addNode(new PrintDataElement("test2element2-2","testvalue22",0));
  710. pd.addNode(pdx);
  711. pd.addNode(new PrintDataElement("test1element3","testvalue/3/",0));
  712. pd.createXML("C:\\Temp\\printData.xml");
  713. pd.createXML(new StreamResult(System.out));
  714. System.out.println("");
  715. pd.dump();
  716. // parse
  717. System.out.println("");
  718. PrintData pd1 = parseXML (new Ctx(), new File("C:\\Temp\\printData.xml"));
  719. pd1.createXML(new StreamResult(System.out));
  720. System.out.println("");
  721. pd1.dump();
  722. } // main
  723. } // PrintData