Package org.fto.jthink.jdbc

Source Code of org.fto.jthink.jdbc.SQLExecutor

/*
* SQLExecutor.java  2005-7-15
*
* 版权所有: 自由思考组织(FTO)软件团队 2000-2005, 保留所有权利.
* 这个软件是自由思考组织(FTO)软件团队开发的,如果要使用这个软件,请首先阅读并接受许可协议。
*
* Copyright 2000-2005 FTO Software Team, Inc. All Rights Reserved.
* This software is the proprietary information of FTO Software Team, Inc.
* Use is subject to license terms.
*
* FTO站点:http://www.free-think.org
*/
package org.fto.jthink.jdbc;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

import org.fto.jthink.exception.JThinkErrorCode;
import org.fto.jthink.exception.JThinkRuntimeException;
import org.fto.jthink.lang.ObjectBuffered;
import org.fto.jthink.util.ReflectHelper;
import org.jdom.Element;

/**
* 此类型的实例负责执行SQL语句。
*
* <p><pre><b>
* 历史更新记录:</b>
* 2005-07-16  创建此类型
* 2008-10-24  增加方法:setTimeout()和getTimeout()方法,设置在执行SQL时的超时时间
* 2008-10-27  对于更新操作的返回结果,以前是返回null,现在调整为返回Integer类型的更新计数
* 2008-10-27  增加批量执行SQL方法executeBatch()
* </pre></p>
*
*
* @author   wenjian
* @version  1.0
* @since    JThink 1.0
*
*/

public class SQLExecutor {
  private String connId;
  private JDBCTransaction transaction;
  /* 设置执行SQL超时时间,单位:秒,默认值0,0表式不做超时处理 */
  private int timeout=0;
 
  /* 将此 Statement 对象生成的所有 ResultSet 对象可以包含的最大行数限制设置为给定数。如果超过了该限制,则直接撤消多出的行 */
  private int maxrows=0;
 
//  /* 请求将 Statement 池化或非池化,值:1=true/0=false/-1=默认, 需要在jre 1.6及以后版本支持 */
//  private int poolable=-1;
 
  /* 用于存储SQLExecutor监听器 */
  private List listeners = new ArrayList();
  /* 结果集生成器 */
  private ResultMaker resultMaker = null;
 
  /**
   * 创建SQLExecutor的实例
   *
   * @param transaction JDBC事务对象
   * @param connId 数据库连接ID
   */
  public SQLExecutor(JDBCTransaction transaction, String connId)  {
    this.transaction = transaction;
    this.connId = connId;
   
    /* 返回SQLExecutor的配置信息 */
    Element config = (Element)transaction.removeAttribute(connId);
    if(config!=null){
      Element maker = config.getChild("result-maker");
      if(maker!=null){
        String factoryClass = maker.getChildTextTrim("factory-class");
        Class factoryCls = ReflectHelper.forName(factoryClass);
        ResultMakerFactory mackerFactory = (ResultMakerFactory)ReflectHelper.newInstance(factoryCls);
        resultMaker = mackerFactory.create();
      }
      String timeout = config.getChildTextTrim("timeout");
      if(timeout!=null){
        setTimeout(Integer.parseInt(timeout));
      }
      String maxrows = config.getChildTextTrim("max-rows");
      if(maxrows!=null){
        setMaxrows(Integer.parseInt(maxrows));
      }
//      String poolable = config.getChildTextTrim("poolable");
//      if(poolable!=null){
//        setPoolable(new Boolean(poolable).booleanValue());
//      }
    }
  }
 
//  public boolean isPoolable() {
//    return poolable==1;
//  }
//
//  public void setPoolable(boolean flag) {
//    this.poolable = flag?1:0;
//  }

 
  public int getTimeout() {
    return timeout;
  }



  public void setTimeout(int seconds) {
    if(seconds<0){
      throw new JThinkRuntimeException(JThinkErrorCode.ERRCODE_SYS_RUNTIME, "不被支持的值,只允许大于等于0的值!");
    }
    this.timeout = seconds;
  }
  public int getMaxrows() {
    return maxrows;
  }

  public void setMaxrows(int maxrows) {
    if(maxrows<0){
      throw new JThinkRuntimeException(JThinkErrorCode.ERRCODE_SYS_RUNTIME, "不被支持的值,只允许大于等于0的值!");
    }
    this.maxrows = maxrows;
  }
  /**
   * 返回一个可用连接
   */
  protected Connection getConnection() {
    return transaction.getConnection(connId);
 
 
  /**
   * 加入SQLExecutor监听器
   *
   * @param listener SQLExecutor监听器
   */
  public void addSQLExecutorListener(SQLExecutorListener listener){
    listeners.add(listener);
  }
 
  /**
   * 返回所有SQLExecutor监听器
   */
  public SQLExecutorListener[] getSQLExecutorListeners(){
    return (SQLExecutorListener[])listeners.toArray(new SQLExecutorListener[listeners.size()]);
  }
 
  /**
   * 移除指定的SQLExecutor监听器
   *
   * @param listener SQLExecutor监听器
   */
  public void removeSQLExecutorListener(SQLExecutorListener listener){
    listeners.remove(listener);
  }
 
  /**
   * 设置结果集生成器,ResultMaker的实现
   *
   * @param resultMaker ResultMaker的具体实现
   */
  public void setResultMaker(ResultMaker resultMaker){
    this.resultMaker = resultMaker;
  }
 
  /**
   * 返回结果集生成器,如果不存在,创建一个默认的XML结果集生成器
   *
   * @return 结果集生成器
   */
  public ResultMaker getResultMaker(){
    if(resultMaker==null){
      resultMaker = new ElementResultMaker();
    }
    return resultMaker;
  }


  /**
   * 释放Statement资源
   */
  protected void releaseStatement(Statement statement)
       {
    try {
      if (statement != null) {
        statement.close();
      }
    } catch (SQLException ex) {
      throw new JThinkRuntimeException(JThinkErrorCode.ERRCODE_DB_CLOSE_PSTMT_FAILURE,
          ex);
    }
  }
  /**
   * 释放PreparedStatement资源
   */
  protected void releasePreparedStatement(PreparedStatement statement)
       {
    try {
      if (statement != null) {
        statement.close();
      }
    } catch (SQLException ex) {
      throw new JThinkRuntimeException(JThinkErrorCode.ERRCODE_DB_CLOSE_PSTMT_FAILURE,
          ex);
    }
  }

  /**
   * 释放CallableStatement资源
   */
  protected void releaseCallableStatement(CallableStatement cstmt)
       {
    try {
      if (cstmt != null) {
        cstmt.close();
      }
    } catch (SQLException ex) {
      throw new JThinkRuntimeException(JThinkErrorCode.ERRCODE_DB_CLOSE_PSTMT_FAILURE,
          ex);
    }
  }
 
 
  /**
   * 释放ResultSet资源
   */
  protected void releaseResultSet(ResultSet resultset)  {
    try {
      if (resultset != null) {
        resultset.close();
      }
    } catch (SQLException ex) {
      throw new JThinkRuntimeException(JThinkErrorCode.ERRCODE_DB_CLOSE_RS_FAILURE, ex);
    }
  }

  /**
   * 准备PreparedStatement
   * @param sql SQL语句
   */
  protected PreparedStatement prepareStatement(String sql) throws SQLException{
    PreparedStatement statement = getConnection().prepareStatement(sql);
    configStatement(statement);
    return statement;
  }
  /**
   * 准备CallableStatement
   * @param sql SQL语句
   */
  protected CallableStatement prepareCall(String sql) throws SQLException{
    CallableStatement statement = getConnection().prepareCall(sql);
    configStatement(statement);
    return statement;   
 
 
  private void configStatement(Statement statement) throws SQLException{
    statement.setQueryTimeout(timeout);
    statement.setMaxRows(maxrows);
  }
 
  //*****************************STATEMENT AND EXECUTE****************************

  /**
   * 批量执行SQL, 注意:有的JDBC驱动对批量处理不支持事务,比如微软的MSSQL JDBC驱动!衰
   * @param sqls SQL语句数组
   * @return 更新计数所组成的数组
   */
  public int[] executeBatch(String[] sqls){
    int len = sqls.length;
    Statement stmt = null;
    ResultSet rs = null;
    try {
      stmt = getConnection().createStatement();
      configStatement(stmt);
      stmt.setEscapeProcessing(false);     
      for(int i=0;i<len;i++){
        String sql = sqls[i];
        executeCommand(sql, SQL.UNDEFINED);
        stmt.addBatch(sql);
      }
      return stmt.executeBatch();
     
    } catch (SQLException ex) {
      throw new JThinkRuntimeException(JThinkErrorCode.ERRCODE_DB_EXEC_SQL_EXCEPTION,
          ex);
    } finally {
      releaseResultSet(rs);
      releaseStatement(stmt);
    }
  }
 
  /**
   * 执行SQL语句,如果此SQL语句不会产生结果集,返回null, 比如Insert, Update,Delete等更新操作的SQL。
   * 如果是执行Select等查询操作的SQL,在Object中返回结果集, 结果集的数据结构由ResultMaker来决定
   *
   * @param sql    SQL语句串
   * @param doClazz 数据对象类型,只有采用DataObjectResultMaker时此参数才有意义
   *
   * @return 结果集或null
   *
   */
  public Object execute(String sql, Class doClazz)  {
    PreparedStatement pstmt = null;
    ResultSet rs = null;
    try {
      executeCommand(sql, SQL.UNDEFINED);
      pstmt = prepareStatement(sql);
      pstmt.execute();
      rs = pstmt.getResultSet();
      if (rs != null) {
//        if(doClazz==null){
//          return getResultMaker().create(rs);
//        }else{
          return getResultMaker().create(rs, doClazz);
//        }
      } else {
        return null;
      }
    } catch (SQLException ex) {
      throw new JThinkRuntimeException(JThinkErrorCode.ERRCODE_DB_EXEC_SQL_EXCEPTION,
          "执行SQL失败!", ex);
    } finally {
      releaseResultSet(rs);
      releaseStatement(pstmt);
    }
  }
  /**
   * 执行SQL语句,如果此SQL语句不会产生结果集,返回null, 比如Insert, Update,Delete等更新操作的SQL。
   * 如果是执行Select等查询操作的SQL,在Object中返回结果集, 结果集的数据结构由ResultMaker来决定
   *
   * @param sql    SQL语句串
   *
   * @return 结果集或null
   *
   */
  public Object execute(String sql)  {
    return execute(sql, (Class)null);
  }
  /**
   * 执行SQL语句,如果此SQL语句不会产生结果集,返回null, 比如Insert, Update,Delete等更新操作的SQL。
   * 如果是执行Select等查询操作的SQL,在Object中返回结果集, 结果集的数据结构由ResultMaker来决定
   *
   * @param sql      SQL语句串
   * @param values  SQL语句串中需要的值, values中的值将用于替换SQL语句串中的"?"
   * @param doClazz 数据对象类型,只有采用DataObjectResultMaker时此参数才有意义
   *
   * @return 结果集对象或null
   *
   */
  public Object execute(String sql, Object[] values, Class doClazz)  {
    PreparedStatement pstmt = null;
    ResultSet rs = null;
    try {
      executeCommand(sql, values, SQL.UNDEFINED);
      pstmt = prepareStatement(sql);
      if(values!=null){
        for (int i = 0; i < values.length; i++) {
          pstmt.setObject(i + 1, values[i]);
        }
      }
      pstmt.execute();
      rs = pstmt.getResultSet();
      if (rs != null) {
//        if(doClazz==null){
//          return getResultMaker().create(rs);
//        }else{
          return getResultMaker().create(rs, doClazz);
//        }
      } else {
        return new Integer(pstmt.getUpdateCount());
      }
    } catch (SQLException ex) {
      throw new JThinkRuntimeException(JThinkErrorCode.ERRCODE_DB_EXEC_SQL_EXCEPTION,
          ex);
    } finally {
      releaseResultSet(rs);
      releaseStatement(pstmt);
    }
  }

  /**
   * 执行SQL语句,如果此SQL语句不会产生结果集,返回null, 比如Insert, Update,Delete等更新操作的SQL。
   * 如果是执行Select等查询操作的SQL,在Object中返回结果集, 结果集的数据结构由ResultMaker来决定
   *
   * @param sql     SQL语句串
   * @param values  SQL语句串中需要的值, values中的值将用于替换SQL语句串中的"?"
   *
   * @return 结果集对象或null
   *
   */
  public Object execute(String sql, Object[] values)  {
    return execute(sql, values, (Class)null);
  }
  /**
   * 执行更新操作的SQL,比如:Insert, Update等操作
   *
   * @param sql    SQL语句串
   *
   * @return 被更新的数据行数量
   *
   */
  public int executeUpdate(String sql)  {
    PreparedStatement pstmt = null;
    ResultSet rs = null;
    try {
      executeCommand(sql, SQL.UPDATE);
      pstmt = prepareStatement(sql);
      return pstmt.executeUpdate();
    } catch (SQLException ex) {
      throw new JThinkRuntimeException(JThinkErrorCode.ERRCODE_DB_EXEC_SQL_EXCEPTION,
          "执行SQL失败!", ex);
    } finally {
      releaseResultSet(rs);
      releaseStatement(pstmt);
    }
  }

  /**
   * 执行更新操作的SQL,比如:Insert, Update等操作
   *
   * @param sql      更新操作的SQL串
   * @param values   更新的值数据,用于替换sql中的?号
   *
   * @return 被更新的数据行数量
   */
  public int executeUpdate(String sql, Object[] values)  {
    PreparedStatement pstmt = null;
    ResultSet rs = null;
    try {
      executeCommand(sql, values, SQL.UPDATE);
      pstmt = prepareStatement(sql);
      if(values!=null){
        for (int i = 0; i < values.length; i++) {
          pstmt.setObject(i + 1, values[i]);
        }
      }
      return pstmt.executeUpdate();
    } catch (SQLException ex) {
      throw new JThinkRuntimeException(JThinkErrorCode.ERRCODE_DB_EXEC_SQL_EXCEPTION,
          ex);
    } finally {
      releaseResultSet(rs);
      releaseStatement(pstmt);
    }
  }

  /**
   * 执行查询操作的SQL,比如:Select等操作
   *
   * @param sql   查询操作的SQL串
   * @param values  值数据,用于替换sql中的?号
   * @param doClazz 数据对象类型,只有采用DataObjectResultMaker时此参数才有意义
   *  
   * @return  结果集, 结果集的数据结构由ResultMaker来决定           
   *
   */
  public Object executeQuery(String sql, Object[] values, Class doClazz) {
    PreparedStatement pstmt = null;
    ResultSet rs = null;

    try {
      executeCommand(sql, values, SQL.SELECT);
      pstmt = prepareStatement(sql);
      if(values!=null){
        for (int i = 0; i < values.length; i++) {
          pstmt.setObject(i + 1, values[i]);
        }
      }
      rs = pstmt.executeQuery();
//      if(doClazz==null){
//        return getResultMaker().create(rs);
//      }else{
        return getResultMaker().create(rs, doClazz);
//      }
    } catch (SQLException ex) {
      throw new JThinkRuntimeException(JThinkErrorCode.ERRCODE_DB_EXEC_SQL_EXCEPTION,
          ex);
    } finally {
      releaseResultSet(rs);
      releaseStatement(pstmt);
    }
  }
  /**
   * 执行查询操作的SQL,比如:Select等操作
   *
   * @param sql   查询操作的SQL串
   * @param values  值数据,用于替换sql中的?号
   *  
   * @return  结果集, 结果集的数据结构由ResultMaker来决定           
   *
   */
  public Object executeQuery(String sql, Object[] values) {
    return executeQuery(sql, values, (Class)null);
  }
  /**
   * 执行查询操作的SQL
   *
   * @param sql SQL语句串
   * @param doClazz 数据对象类型,只有采用DataObjectResultMaker时此参数才有意义
   *
   * @return 结果集, 结果集的数据结构由ResultMaker来决定
   */
  public Object executeQuery(String sql, Class doClazz){
    PreparedStatement pstmt = null;
    ResultSet rs = null;

    try {
      executeCommand(sql, SQL.SELECT);
      pstmt = prepareStatement(sql);
      rs = pstmt.executeQuery();
//      if(doClazz==null){
//        return getResultMaker().create(rs);
//      }else{
        return getResultMaker().create(rs, doClazz);
//      }
     
    } catch (SQLException ex) {
      throw new JThinkRuntimeException(JThinkErrorCode.ERRCODE_DB_EXEC_SQL_EXCEPTION,
          ex);
    } finally {
      releaseResultSet(rs);
      releaseStatement(pstmt);
    }
  }
  /**
   * 执行查询操作的SQL
   *
   * @param sql SQL语句串
   *
   * @return 结果集, 结果集的数据结构由ResultMaker来决定
   */
  public Object executeQuery(String sql){
    return executeQuery(sql, (Class)null);
  }

  /**
   * 执行查询操作的SQL,比如:Select等操作, 用此查询方法可实现数据分页。
   *
   * @param sql 查询操作的SQL语句
   * @param startIndex 结果集的开始索引位置
   * @param len 需要选择出的结果集的长度
   *
   * @return 结果集, 结果集的数据结构由ResultMaker来决定
   *
   * @see SQLExecutor#executeQuery(String, Object[], int, int)
   */
 
  public Object executeQuery(String sql, int startIndex, int len)  {
    return executeQuery(sql, null, startIndex, len);
  }

  /**
   * 执行查询操作的SQL,比如:Select等操作, 用此查询方法可实现数据分页。
   * 此方法必须要在实际应用中根据具体数据库在此类的子类型中覆盖,以便实现分页功能
   *
   * @param sql 查询操作的SQL语句
   * @param values 值数组,用于替换SQL语句中的?, values可以为null对象
   * @param startIndex 结果集的开始索引位置
   * @param rowlen 需要选择出的结果集的长度
   *
   * @return 结果集, 结果集的数据结构由ResultMaker来决定
   */
  public Object executeQuery(String sql, Object[] values, int startIndex, int rowlen)  {
    return executeQuery(sql, values, startIndex, rowlen, null);
  }

  /**
   * 执行查询操作的SQL,比如:Select等操作, 用此查询方法可实现数据分页。
   * 此方法必须要在实际应用中根据具体数据库在此类的子类型中覆盖,以便实现分页功能
   *
   * @param sql 查询操作的SQL语句
   * @param values 值数组,用于替换SQL语句中的?, values可以为null对象
   * @param startIndex 结果集的开始索引位置
   * @param rowlen 需要选择出的结果集的长度
   * @param doClazz 数据对象类型,只有采用DataObjectResultMaker时此参数才有意义
   *
   * @return 结果集, 结果集的数据结构由ResultMaker来决定
   */
  public Object executeQuery(String sql, Object[] values, int startIndex, int rowlen, Class doClazz)  {
    throw new java.lang.UnsupportedOperationException(
        "Method executeQuery() not yet implemented.");
  }
 
  /**
   * 执行存储过程
   *
   * @param name 过程名称
   * @param parameters 参数
   * @param doClazz 数据对象类型,只有采用DataObjectResultMaker时此参数才有意义
   *
   * @return 结果集或null
   */
  public Object executeStoredProcedure(String name, Object[] parameters, Class doClazz){
    CallableStatement cstmt = null;
    ResultSet rs = null;
    try {
      String qsign = "";
      if(parameters!=null){
        int len = parameters.length;
        for(int i=0;i<len;i++){
          qsign += ",?";
        }
        if(len>0){
          qsign = qsign.substring(1);
        }
      }
      String sql = "{call "+name+" ("+qsign+")}";
      executeCommand(sql, SQL.UNDEFINED);
      cstmt = prepareCall(sql);
      if(parameters!=null){
        int len = parameters.length;
        for (int i = 0; i < len; i++) {
          cstmt.setObject(i + 1, parameters[i]);
        }
      }
      cstmt.execute();
      rs = cstmt.getResultSet();
      if (rs != null) {
//        if(doClazz==null){
//          return getResultMaker().create(rs);
//        }else{
          return getResultMaker().create(rs, doClazz);
//        }
      } else {
        return new Integer(cstmt.getUpdateCount());
      }
    } catch (SQLException ex) {
      throw new JThinkRuntimeException(JThinkErrorCode.ERRCODE_DB_EXEC_SQL_EXCEPTION,
          ex);
    } finally {
      releaseResultSet(rs);
      releaseStatement(cstmt);
    }
  }
 
  /**
   * 执行存储过程
   *
   * @param name 过程名称
   * @param parameters 参数
   *
   * @return 结果集或null
   */
  public Object executeStoredProcedure(String name, Object[] parameters){
    return executeStoredProcedure(name, parameters, (Class)null);
  }
 
  /**
   * 执行SQL语句对象, sql是由SQLBuilder构建的SQL语句
   *
   *
   * @param sql SQL对象
   *
   * @return  结果集或null
   */
  public Object execute(SQL sql)  {
    return execute(sql, null);
  }

  /**
   * 执行SQL语句对象, sql是由SQLBuilder构建的SQL语句
   *
   *
   * @param sql SQL对象
   * @param doClazz 数据对象类型,只有采用DataObjectResultMaker时此参数才有意义,
   *                并且只针对SQL.type为SQL.SELECT或SQL.SELECT_SP

   * @return  结果集或Integer类型的更新记录数量
   */
  public Object execute(SQL sql, Class doClazz)  {
    int startIndex;
    int length;
    switch(sql.getType()){
      case SQL.UPDATE:
        int rs = executeUpdate(sql.getSQLString(), sql.getValues());
        return new Integer(rs);
      case SQL.SELECT:
        startIndex = sql.getRowStartIndex();
        length = sql.getRowLength();
        if(startIndex>=0 && length>=0){
          return executeQuery(sql.getSQLString(), sql.getValues(), startIndex, length, doClazz);
        }else{
          return executeQuery(sql.getSQLString(), sql.getValues(), doClazz);
        }
      case SQL.UNDEFINED:
        return execute(sql.getSQLString(), sql.getValues(), doClazz);
      case SQL.UPDATE_SP:
        return executeStoredProcedure(sql.getSQLString(), sql.getValues());
      case SQL.SELECT_SP:
        startIndex = sql.getRowStartIndex();
        length = sql.getRowLength();
        if(startIndex>=0 && length>=0){
          //List values = Arrays.asList(sql.getValues());
          ObjectBuffered values = sql.getValueBuffered();
          values.append(new Integer(startIndex));
          values.append(new Integer(length));
          return executeStoredProcedure(sql.getSQLString(), values.toArray(), doClazz);
        }else{
          return executeStoredProcedure(sql.getSQLString(), sql.getValues(), doClazz);
        }
      case SQL.UNDEFINED_SP:
        return executeStoredProcedure(sql.getSQLString(), sql.getValues(), doClazz);
    }
    throw new JThinkRuntimeException(JThinkErrorCode.ERRCODE_DB_EXEC_SQL_EXCEPTION, "错误的SQL类型!");
  }
 
 
//  /**
//   * 执行更新操作的SQL,只针对Insert
//   *
//   * @param doClazz 数据对象类型
//   *
//   * @return 被更新的数据行数量
//   *
//   */
//  public void insert(String tableName, DataObject dobj)  {
//    SQL sql = new SQLBuilder().constructSQLForInsert(tableName, dobj.getValues());
//    execute(sql);
//  } 
//  /**
//   * 执行更新操作的SQL,只针对Update
//   *
//   * @param doClazz 数据对象类型
//   *
//   * @return 被更新的数据行数量
//   *
//   */
//  public int update(String tableName, DataObject dobj)  {
//
//  }
 
    /**
     * 执行SQLExecutor监听器中的事件方法,执行SQL时调用此方法。
     *
     * @param sql 被执行的SQL语句串
     * @param type SQL语句的类型
     */
    protected void executeCommand(String sql, int type){
      int len = listeners.size();
      for(int i=0;i<len;i++){
        ((SQLExecutorListener)listeners.get(i)).executeSQLCommand(new SQLExecutorEvent(this, sql, type));
      }
    }
   
    /**
     * 执行SQLExecutor监听器中的事件方法,执行SQL时调用此方法。
     */
    protected void executeCommand(String sql, Object[] values, int type){
      int len = listeners.size();
      for(int i=0;i<len;i++){
        ((SQLExecutorListener)listeners.get(i)).executeSQLCommand(new SQLExecutorEvent(this, sql, values, type));
      }
    }
   
    /**
     * 执行SQLExecutor监听器中的事件方法,执行SQL时调用此方法。
     */
    protected void executeCommand(SQL sql){
      int len = listeners.size();
      for(int i=0;i<len;i++){
        ((SQLExecutorListener)listeners.get(i)).executeSQLCommand(new SQLExecutorEvent(this, sql));
      }
    }


   
}
TOP

Related Classes of org.fto.jthink.jdbc.SQLExecutor

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.