/* * jPOS Project [http://jpos.org] * Copyright (C) 2000-2017 jPOS Software SRL * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.jpos.gl.tools; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.dom4j.DocumentException; import org.hibernate.HibernateException; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.Transaction; import org.jdom2.Document; import org.jdom2.Element; import org.jdom2.JDOMException; import org.jdom2.input.SAXBuilder; import org.jpos.core.ConfigurationException; import org.jpos.ee.DB; import org.jpos.gl.*; import org.xml.sax.EntityResolver; import org.xml.sax.InputSource; import java.io.IOException; import java.io.InputStream; import java.sql.SQLException; import java.text.ParseException; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; /** * Import an XML document as described in * <a href="http://jpos.org/minigl.dtd">minigl.dtd</a> * * @author <a href="mailto:apr@jpos.org">Alejandro Revilla</a> */ public class Import implements EntityResolver { Log log = LogFactory.getLog (Import.class); private static final String URL = "http://jpos.org/"; public Import () throws HibernateException, GLException, IOException, ConfigurationException { super(); } public static void usage () { System.out.println ("Usage: org.jpos.gl.Import filename"); System.exit (0); } private void createSchema () throws HibernateException, DocumentException { DB db = new DB(); db.open(); db.beginTransaction(); db.createSchema(null, true); db.commit(); db.close(); } private void createCharts (Session sess, Iterator iter) throws SQLException, HibernateException, ParseException { Transaction txn = sess.beginTransaction(); while (iter.hasNext()) { Element elem = (Element) iter.next (); CompositeAccount acct = new CompositeAccount (elem); sess.save (acct); acct.setRoot (acct); processChartChildren ( sess, acct, elem.getChildren().iterator() ); sess.flush (); } txn.commit(); } private void createCurrencies (Session sess, Iterator iter) throws SQLException, HibernateException, ParseException { Transaction txn = sess.beginTransaction(); while (iter.hasNext()) { Element elem = (Element) iter.next (); Currency currency = new Currency (elem); sess.save (currency); } txn.commit(); } private void createUsers (Session sess, Iterator iter) throws SQLException, HibernateException, ParseException { Transaction txn = sess.beginTransaction(); while (iter.hasNext()) { Element elem = (Element) iter.next (); GLUser user = new GLUser (elem); Iterator permIter = elem.getChildren ("grant").iterator(); while (permIter.hasNext()) { Element perm = (Element) permIter.next(); GLPermission p = new GLPermission (perm.getTextTrim()); sess.save (p); user.grant (p); } sess.save (user); } txn.commit(); } private void createJournals (Session sess, Iterator iter) throws SQLException, HibernateException, ParseException { Transaction txn = sess.beginTransaction(); while (iter.hasNext()) { Element elem = (Element) iter.next (); Journal journal = new Journal (elem); journal.setChart ( getChart (sess, elem.getChildTextTrim ("chart")) ); journal.setPermissions ( createPermissions ( sess, elem.getChildren ("grant").iterator() ) ); sess.save (journal); createJournalLayers ( sess, journal, elem.getChildren ("layer").iterator() ); createJournalRules ( sess, journal, elem.getChildren ("rule").iterator() ); } txn.commit(); } private void processChartChildren (Session sess, CompositeAccount parent, Iterator iter) throws SQLException, HibernateException, ParseException { while (iter.hasNext ()) { Element e = (Element) iter.next (); String name = e.getName(); if ("composite-account".equals (name)) createComposite (sess, parent, e); else if ("account".equals (name)) createFinal (sess, parent, e); } } private void createComposite (Session sess, CompositeAccount parent, Element elem) throws SQLException, HibernateException, ParseException { CompositeAccount acct = new CompositeAccount (elem, parent); acct.setRoot (parent.getRoot ()); sess.save (acct); acct.setParent (parent); parent.getChildren().add (acct); sess.flush (); processChartChildren (sess, acct, elem.getChildren().iterator()); } private void createFinal (Session sess, CompositeAccount parent, Element elem) throws SQLException, HibernateException, ParseException { FinalAccount acct = new FinalAccount (elem, parent); acct.setRoot (parent.getRoot ()); sess.save (acct); acct.setParent (parent); parent.getChildren().add (acct); } private void createTransactions (Session sess, Iterator iter) throws SQLException, HibernateException, ParseException { while (iter.hasNext()) { Transaction txn = sess.beginTransaction(); Element elem = (Element) iter.next (); GLTransaction glt = new GLTransaction (elem); Journal journal = getJournal ( sess, elem.getAttributeValue ("journal") ); glt.setJournal (journal); sess.save (glt); createEntries ( sess, glt, elem.getChildren("entry").iterator() ); txn.commit (); } } private void createEntries ( Session sess, GLTransaction glt, Iterator iter) throws SQLException, HibernateException, ParseException { Account chart = glt.getJournal().getChart (); while (iter.hasNext()) { Element elem = (Element) iter.next (); GLEntry entry = "credit".equals (elem.getAttributeValue ("type")) ? (new GLCredit ()) : (new GLDebit ()); entry.fromXML (elem); entry.setAccount (getFinalAccount (sess, chart, elem)); entry.setTransaction (glt); sess.save (entry); glt.getEntries().add (entry); } } private Account getAccount (Session sess, Account chart, Element elem) throws SQLException, HibernateException { Query q = sess.createQuery ( "from acct in class org.jpos.gl.Account where code = :code and acct.root = :chart"); q.setParameter ("code", elem.getAttributeValue ("account")); q.setLong ("chart", chart.getId()); List l = q.list(); return l.size() == 1 ? ((Account) l.get (0)) : null; } private FinalAccount getFinalAccount (Session sess, Account chart, Element elem) throws SQLException, HibernateException { Query q = sess.createQuery ( "from acct in class org.jpos.gl.FinalAccount where code = :code and acct.root = :root" ); q.setParameter ("code", elem.getAttributeValue ("account")); q.setLong ("root", chart.getId()); List l = q.list(); return l.size() == 1 ? ((FinalAccount) l.get (0)) : null; } private CompositeAccount getChart (Session sess, String chartCode) throws SQLException, HibernateException { Query q = sess.createQuery ( "from acct in class org.jpos.gl.CompositeAccount where code = :code and parent is null" ); q.setParameter ("code", chartCode); List l = q.list(); return (CompositeAccount) ((l.size() > 0) ? l.get (0) : null); } private void createJournalRules (Session session, Journal journal, Iterator iter) throws HibernateException, ParseException, SQLException { while (iter.hasNext()) { Element e = (Element) iter.next(); RuleInfo ri = new RuleInfo (e); ri.setJournal (journal); ri.setAccount (getAccount (session, journal.getChart(), e)); session.save (ri); } } private void createJournalLayers (Session session, Journal journal, Iterator iter) throws HibernateException, ParseException, SQLException { while (iter.hasNext()) { Element e = (Element) iter.next(); Layer layer = new Layer (e); layer.setJournal (journal); session.save (layer); } } private GLUser getUser (Session session, String nick) throws HibernateException { Query q = session.createQuery ("from GLUser u where u.nick=:nick"); q.setParameter ("nick", nick); List l = q.list(); if (l.size() == 0) { throw new IllegalArgumentException ( "Invalid nick '" + nick + "'" ); } return (GLUser) l.get(0); } private Set createPermissions (Session session, Iterator iter) throws HibernateException { Set permissions = new HashSet (); while (iter.hasNext()) { Element e = (Element) iter.next(); GLUser user = getUser (session, e.getAttributeValue ("user")); GLPermission p = new GLPermission (e.getTextTrim()); p.setUser (user); session.save (p); permissions.add (p); } return permissions; } private Journal getJournal (Session sess, String name) throws SQLException, HibernateException { Query q = sess.createQuery ( "from journal in class org.jpos.gl.Journal where name = :name" ); q.setParameter ("name", name); List l = q.list(); return (Journal) ((l.size() > 0) ? l.get (0) : null); } public InputSource resolveEntity (String publicId, String systemId) { if (systemId != null && systemId.startsWith (URL)) { log.debug ("trying to locate " + systemId + " in classpath"); ClassLoader classLoader = this.getClass().getClassLoader(); InputStream dtd = classLoader.getResourceAsStream ( systemId.substring (URL.length()) ); if (dtd == null) { log.debug (systemId + "not found in classpath"); return null; } else { log.debug ("found " + systemId + " in classpath"); return new InputSource (dtd); } } else return null; } public void parse (String file) throws JDOMException, SQLException, HibernateException, ParseException, IOException, GLException, DocumentException { SAXBuilder builder = new SAXBuilder (true); builder.setEntityResolver (this); Document doc = builder.build (file); Element root = doc.getRootElement (); if (!"minigl".equals (root.getName ())) { throw new IllegalStateException ( "Invalid root element "+root.getName () ); } if (root.getChild ("create-schema") != null) createSchema (); Session sess = new DB().open(); createUsers (sess, root.getChildren ("user").iterator()); createCurrencies (sess, root.getChildren ("currency").iterator()); createCharts (sess, root.getChildren ("chart-of-accounts").iterator()); createJournals (sess, root.getChildren ("journal").iterator()); createTransactions (sess, root.getChildren ("transaction").iterator()); sess.close (); } public static void main (String[] args) { if (args.length == 0) usage (); try { new Import().parse (args[0]); } catch (Exception e) { e.printStackTrace(); } } }