Package center.task.prm.alg

Source Code of center.task.prm.alg.Sel

package center.task.prm.alg;

import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.*;
import java.util.Map.Entry;

import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import ru.vassaev.core.base.Null;
import ru.vassaev.core.container.ApplicationManager;
import ru.vassaev.core.db.Manager;
import ru.vassaev.core.db.Sttmnt;
import ru.vassaev.core.thread.*;
import ru.vassaev.core.exception.SysException;
import ru.vassaev.core.exception.SysRuntimeException;
import ru.vassaev.core.io.OutputByteBuffer;
import ru.vassaev.core.types.StringList;
import ru.vassaev.core.types.TimeList;
import ru.vassaev.core.util.Strings;
import ru.vassaev.core.util.Xml;

import center.task.CalculateException;
import center.task.Context;
import center.task.Record;
import center.task.prm.Alg;
import center.task.prm.Dif;

/**
* Параметр - набор значений по SELECT
*
* @author Vassaev A.V.
* @version 1.1 03/08/2011
*/
public final class Sel extends Alg implements Dif {

//  private Map<String, ArrayList<Integer>> param_positions;
//  private ArrayList<Object> query;
  private String db;
/*
  private void addPosition(String name, int pos) {
    if (param_positions == null)
      param_positions = new HashMap<String, ArrayList<Integer>>();
    ArrayList<Integer> list = param_positions.get(name);
    if (list == null) {
      list = new ArrayList<Integer>();
      param_positions.put(name, list);
    }
    list.add(pos);
  }
*/
  private class EventForEachRow {
    private Map<String, String> into_map = new TreeMap<String, String>();
    private String dbfer = null;
    private Element update = null;
    private Sttmnt stmt = null;
    private EventForEachRow(Element fr) throws SysException {
      NodeList nl = Xml.getElementsByTagName(fr, "into");
      for (int i = 0; i < nl.getLength(); i++) {
        Element into = (Element) nl.item(i);
        into_map.put(into.getAttribute("from"), into.getTextContent());
      }

      dbfer = Strings.getXMLValue(fr, "update/db");
      if (dbfer == null)
        throw new SysException("There is no update/db for-each-row element");
      update = (Element) Strings.getXMLObject(fr, "update/sql");
      if (update == null)
        throw new SysException("There is no update/sql for-each-row element");
      stmt = new Sttmnt(dbfer, update, "i", "p", "o");
    }

    void start() throws SysException {
//      if (stmt == null) {
//        stmt = new Sttmnt(dbfer, update, "i", "p", "o");
//      }
    }

    void exec(Context cntx) throws SysException {
      Connection con = Manager.getConnection(dbfer);
      CallableStatement st = null;
      try {
        st = stmt.getCallStatement(con);
        StringList ls = stmt.getBindParamNames();
        for (String n : ls) {
          String o = Strings.getString(cntx.getPrmByFullName(n));
          stmt.setParam(st, n, o, Types.CHAR);
        }
        try {
          st.execute();
          Manager.commit(con);
        } catch (SQLException e) {
          throw new SysException(e);
        }
      } catch (SysException e) {
        stmt.freeStatement(st);
        throw e;
      } finally {
        Manager.freeConnection(con);
      }
    }

    void finish() throws SysException {
//      if (stmt != null) {
//        stmt.close();
//      }
    }

    public Set<String> depedentOn() {
      StringList ls = stmt.getBindParamNames();
      Set<String> s = null;
      if (ls.size() > 0)
        s = new HashSet<String>(ls);
      return s;
    }
  }

  private EventForEachRow on_calculate;

  private void loadONCalculate(Element e) throws SysException {
    Element fr = (Element) Strings.getXMLObject(e, "for-each-row");
    if (fr == null)
      return;
    on_calculate = new EventForEachRow(fr);
  }

  private void loadON(Element e) throws SysException {
    Element on = (Element) Strings.getXMLObject(e, "on");
    if (on == null)
      return;
    NodeList nl = on.getChildNodes();
    for (int i = 0; i < nl.getLength(); i++) {
      Node n = nl.item(i);
      if (Node.ELEMENT_NODE != n.getNodeType())
        continue;
      Element ne = (Element) n;
      String nn = ne.getNodeName();
      if ("calculate".equals(nn)) {
        loadONCalculate(ne);
      }
    }
  }
  private PoolThread prcpool = null;
  private Sttmnt st;
/*
  * TODO пока не используется
  */
  private int parallel_max;
  public Sel(center.task.prm.Type tp, String owner, Element e) throws SysException {
    super(tp, owner);
    // Загрузить обработчики событий
    loadON(e);
    // Работа с базой
    db = Strings.getXMLValue(e, "db");
    // DQL
    Element select = (Element) Strings.getXMLObject(e, "select");
    if (select == null)
      return;
    st = new Sttmnt(db, select, "i", "p", "o");
    /*
    query = new ArrayList<Object>();
    NodeList nl = select.getChildNodes();
    StringBuffer sb = new StringBuffer();
    int pos = 1;
    for (int i = 0; i < nl.getLength(); i++) {
      Node n = nl.item(i);
      short t = n.getNodeType();
      if (t == Node.ELEMENT_NODE) {
        Element el = (Element) n;
        String name = el.getTextContent();
        if (el.getNodeName().equals("p")) {
          sb.append('?');
          addPosition(name, pos);
          pos++;
        } else if (el.getNodeName().equals("i")) {
          if (sb.length() > 0) {
            query.add(sb.toString());
            sb = new StringBuffer();
          }
          query.add(new Inline(name));
        }
      } else if (t == Node.TEXT_NODE) {
        Text txt = (Text) n;
        sb.append(txt.getData());
      }
    }
    if (sb.length() > 0)
      query.add(sb.toString());
    */
    String sprcpool = Strings.getXMLValue(e, "parallel#prcpool");
    if (sprcpool != null) {
      prcpool = (PoolThread) ApplicationManager.getPoolByName(sprcpool, ru.vassaev.core.thread.Process.class);
      String max = Strings.getXMLValue(e, "parallel#max");
      this.parallel_max = Strings.parseIntegerNvl(max, 0);
    }
  }

  public Object calculate(TimeList tl, Context cntx) throws CalculateException {
    try {
      tl.addPointTime(TimeList.Type.START);
      Set<String> sl = st.getInParamNames();
      HashMap<String, Object> param_values = new HashMap<String, Object>();
      for (String n : sl) {
        Object x;
        tl.addPointTime(TimeList.Type.WAIT);
        if (prcpool == null)
          x = cntx.getPrmByFullName(n);
        else
          x = cntx.getPrmAsync(prcpool, n);
        tl.addPointTime(TimeList.Type.END_WAIT);
        if (x == null)
          x = Null.NULL;
        param_values.put(n, x);
      }
      tl.addPointTime(TimeList.Type.WAIT);
      for (Entry<String, Object> n : param_values.entrySet()) {
        String k = n.getKey();
        Object o = n.getValue();
        if (o instanceof Context.WaitValue)
          try {
            st.setParam(k, ((Context.WaitValue)o).getValueWait(), java.sql.Types.OTHER);
          } catch (Throwable e) {
            throw new CalculateException(getOwner(), e);
          }
        else
          st.setParam(k, o, java.sql.Types.OTHER);
      }
      tl.addPointTime(TimeList.Type.END_WAIT);

      Connection con = Manager.getConnection(db);
      PreparedStatement stm = null;
      try {
        try {
          stm = st.getStatement(con);
        } catch (Exception ex) {
          con = Manager.reInitConnection(con);
          stm = st.getStatement(con);
        }
        Record result;
        ResultSet rs = stm.executeQuery();
        if (rs.next()) {
          ResultSetMetaData md = stm.getMetaData(); // TODO надо оптимизировать
          result = new Record();
          for (int i = 1; i <= md.getColumnCount(); i++) {
            result.name.put(md.getColumnName(i), i - 1);
            Object x = rs.getObject(i);
            if (x == null)
              result.value.addLast(Null.NULL);
            else {
              if (x instanceof Blob) {
                InputStream r = ((Blob)x).getBinaryStream();
                OutputByteBuffer wr = ru.vassaev.core.thread.Process
                    .getByteBuffer(8000);
                byte[] buf = new byte[1024];
                int l;
                try {
                while ((l = r.read(buf)) > 0) {
                  wr.write(buf, 0, l);
                }
                wr.close();
                r.close();
                } catch (IOException e) {
                  throw new CalculateException(owner, e);
                }
                x = wr;
              }
              result.value.addLast(x);
            }
          }
          // обработка события
          if (on_calculate != null) {
            on_calculate.start();
            do {
              // Регестрируем переменные в памяти потока
              for (int i = 1; i <= md.getColumnCount(); i++) {
                Object obj = rs.getObject(i);
                String nm = on_calculate.into_map.get(md.getColumnName(i));
                ru.vassaev.core.thread.Process.currentProcess()
                        .regResourceName(obj, nm);
              }
              on_calculate.exec(cntx);
            } while (rs.next());
            on_calculate.finish();
          }
        } else
          result = null;
        rs.close();
        return result;
      } catch (SQLException e) {
        e.printStackTrace();
        return null;
      } finally {
        st.closeStatement(stm);
        Manager.freeConnection(con);
      }
    } catch(SysException ex) {
      throw new SysRuntimeException(ex);
    } finally {
      tl.addPointTime(TimeList.Type.END);
    }
  }

  public Object getValueByIndex(Object v, String index) {
    try {
      int i = Integer.parseInt(index);
      LinkedList<?> list = ((Record) v).value;
      if (list.size() <= i)
        return null;
      return list.get(i);
    } catch (NumberFormatException e) {
      LinkedList<?> list = ((Record) v).value;
      Integer i = ((Record) v).name.get(index);
      if (i == null)
        return null;
      return list.get(i);
    }
  }

  public Set<String> depedentOn() {
    Set<String> s = null;
    Set<String> params = st.getInParamNames();
    if ((params != null) && params.size() > 0)
      s = new HashSet<String>(params);
    if (on_calculate != null) {
      s = Strings.addAllToSet(s,  on_calculate.depedentOn());
    }
    return s;
  }

  public Set<String> depedentOnParent() {
    return null;
  }
}
TOP

Related Classes of center.task.prm.alg.Sel

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.