• OAF日志使用总结


        本文的完成感谢葛严大神授权使用LogUtil类,其次感谢Tavor大神的EBS OAF开发日志(见: EBS OAF开发中日志(Logging) )。

        日志的使用是一门极大的学问,若读者有兴趣,可以自行选择阅读以下参考:

        最佳日志实践(v2.0)

        Java 日志管理最佳实践

        Logging 最佳实践

        首先,尽量不要在代码中使用System.out.println()方法直接打印日志,虽然这在开发过程中极其便捷,但是也带来了以下影响

        1.大量的 sop  将产生大量的IO操作   同时在生产环境中 无法合理的控制是否需要输出

        2.专门的日志框架可以合理的控制日志 实现 文件  DB 控制分片容量 Email预警等。

        OAF 框架本身也提供了日志级别,同时提供了日志输出方法fnd_log.STRING和writeDiagnostics方法,但是我觉得不太好用,日志级别倒是极好用的。

        参考:Logging in OAF Pages – A Technical Note!

                 OAF: How to add logging / debug messages in Oracle Application Framework(需翻|墙)

                 writeDiagnostics() method of OAF(需翻|墙)

        所以,只需要开启了FND 诊断(配置文件:FND 诊断),在地址栏输入 &AFLOG_LEVEL=ERROR(或其他日志级别)

        如:http://devapp.xxxxxx.com:8080/OA_HTML/OAHOMEPAGE&AFLOG_LEVEL=ERROR即可在网页下方看到输出的日志了,在网页中显示日志使用的writeDiagnostics()方法。

        关于JDeveloper集成log4j可参考我的另一篇博客:(OAF)jdeveloper集成log4j并将日志输出到指定文件并写入数据库

        集成Logback同理,两种方式需要的配置文件也自行百度。

        LogUtil类如下

    package cux.oracle.apps.cux.common.util;
    
    import java.sql.CallableStatement;
    import java.sql.SQLException;
    
    import java.text.SimpleDateFormat;
    
    import java.util.Date;
    
    import oracle.apps.fnd.framework.OAException;
    import oracle.apps.fnd.framework.OAFwkConstants;
    import oracle.apps.fnd.framework.server.OADBTransaction;
    import oracle.apps.fnd.framework.server.OAEntityImpl;
    import oracle.apps.fnd.framework.server.OAViewObjectImpl;
    import oracle.apps.fnd.framework.server.OAViewRowImpl;
    import oracle.apps.fnd.framework.webui.OAPageContext;
    
    import oracle.jbo.ApplicationModule;
    import oracle.jbo.Row;
    import oracle.jbo.ViewObject;
    
    
    
    /**
     * LogUtil 实现Log输出的核心逻辑,它可以在CO,AM,EO,VO中,以及
     * 任何可以获得OADBTransaction的地方使用。
     *
     * 静态工程方法of负责初始化log的内容,内容分为类名称和详细内容,详细内容
     * 可以是一个String,也可以是一个二维数组。内容经过格式化后,通过print输出。
     * print方法在输出的时候,必须依靠LogContext参数,来确定输出方式和输出层次上。
     *
     * 对于LogContext参数,传入的是一个实现了LogContext接口的一个calss,通常,
     * 对于特定的功能开发最好新建一个这样的calss,这样此功能开发的log输出就可以
     * 很好地和其他log输出分离,且可以独立地控制输出方式和输出层次。
     *
     * Log内容包含三种信息:类名称,必须具有。方法名称和变量的值,非必须。
     *
     * GEYAN 2010-01-06
     */
    
    /**
     * 2010-06-05 改进建议:
     * 是否命令行输出,可通过 isDeveloperMode;诊断输出也没有必要依靠一个开关,因为它本身就具有开关。
     * 因而完全可以将 LogUtil 和 LogContext 构成的手柄模式合并为单类,或者至少可以进一步简化。
     */
    
    /**
     * 2010-06-08  
     * 新的版本不再依赖 LogContext ,代之以 logLevel 默认值,以及可以改变此默认值的 Builder 模式实现。
     * 而输出开关则依赖Oracle本身的机制,isDeveloperMode 和 isLoggingEnabled ,
     * 这样更加合理,且不会影响性能。
     * 
     */
    public class LogUtil
    {
    
      private String[][] output = new String[1][2];
      private String className;
      
        //private final static org.slf4j.Logger logger = LoggerFactory.getLogger(LogUtil.class.getName());
    
      /**
       * 输出层次定义, logLevel, 
       * 是 oracle.apps.fnd.framework.OAFwkConstants 的六个常量, 值依次从1到6.
       * OAFwkConstants.STATEMENT
       * OAFwkConstants.PROCEDURE
       * OAFwkConstants.EVENT
       * OAFwkConstants.EXCEPTION
       * OAFwkConstants.ERROR
       * OAFwkConstants.UNEXPECTED
       * 
       * 系统中默认的是 OAFwkConstants.UNEXPECTED,故默认层次不能选择UNEXPECTED。
       * 
       * 这里默认为 OAFwkConstants.ERROR,通过logLevel方法来更改其所需的值。
       * 
       * &aflog_level=ERROR
       */
      private int logLevel = OAFwkConstants.ERROR;
    
      private LogUtil(String str,
                      Object object)
      {
        output = new String[1][2];
        output[0][0] = str;
    
        this.className = getClassName(object);
      }
    
      private LogUtil(String[][] stra,
                      Object object)
      {
        output = new String[stra.length][2];
        System.arraycopy(stra, 0, output, 0, output.length);
    
        this.className = getClassName(object);
      }
    
      public LogUtil logLevel(int logLevel)
      {
        this.logLevel = logLevel;
        return this;
      }
    
      /**
       * object的作用是得到类的名称,它可以是this指针,也可以是String形式的类名称。
       * 
       * 通常object的参数的值是this,通过this.getClass().getName()来获取类名称。
       * 但是在static方法里,this指针不可用,只有以String形式传入类名称。
       */
      private static String getClassName(Object object)
      {
        if (java.lang.String.class.equals(object.getClass()))
        {
          return object.toString();
        }
        return object.getClass().getName();
      }
    
      /**
       * 两个静态工厂方法of,分别构造单个字符串和二维字符串数组类型的 LogUtil 实例。
       * 
       * object参数应该传入当前调用所在的类的this指针,通过this得到类名称。
       * 在static方法中,则以String形式传入类名称。
       */
      public static LogUtil of(String str,
                               Object object)
      {
        return new LogUtil(str, object);
      }
    
      public static LogUtil of(String[][] stra,
                               Object object)
      {
        return new LogUtil(stra, object);
      }
      
      private String getCurrentTime()
      {
        Date currentTime = new Date(System.currentTimeMillis());
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS").format(currentTime);
      }
    
      private String getOutput()
      {
    //    String result = 
    //      "
    -------------------------------------------------> log : [" + getCurrentTime() + "]
    ";
    //
    //    result = result + " & " + "class" + "  is  " + "[" + className + "]
    ";
    //
    //    if (output.length == 1 && (output[0][1] == null || "".equals(output[0][1])))
    //    {
    //      return result + " " + output[0][0] + "
    ";
    //    }
    //
    //    for (int i = 0; i < output.length; i++)
    //    {
    //      if (output[i] != null)
    //      {
    //        result = result + " & " + output[i][0] + "  is  " + output[i][1] + "
    ";
    //      }
    //    }
    //
    //    return result;
             StringBuffer result = new StringBuffer();
             result.append("
    -------------------------------------------------> log : ["
                             + getCurrentTime() + "]
    ");
                             
             result.append(" & " + "class" + "  is  " + "[" + className + "]
    ");
             
             //等价
    //         StackTraceElement[] trace = new Throwable().getStackTrace();
             StackTraceElement[] trace = Thread.currentThread().getStackTrace();
             for (int len=0; len<trace.length; len++){
                 // trace的长度为从函数入口到print方法执行过的函数层数
                 // 下标为0的元素是上一行语句的信息, 下标为1的才是调用print的地方的信息
                 StackTraceElement tmp = trace[len];
                 
                 if(tmp.getClassName().length()>=6 && "oracle".equals(tmp.getClassName().substring(0,6)))
                 //函数的入口为java.lang.Thread.run
                 //中间的层次结构太长
                 //故循环到标准方法即停止,仅显示客户化调用
                    break;
                 
                 result.append(" & "+ tmp.getClassName() + "." + tmp.getMethodName() 
                     + "(" + tmp.getFileName() + ":" + tmp.getLineNumber() + ")
    " );
             }
        
             if (output.length == 1 && (output[0][1] == null || "".equals(output[0][1]))) {
                 return result + " " + output[0][0] + "
    ";
             }
        
             for (int i = 0; i < output.length; i++) {
                 if (output[i] != null) {
                         result.append(" & " + output[i][0] + "  is  "
                                         + output[i][1] + "
    ");
                 }
             }
        
             return result.toString();
    
      }
    
      //  /**
      //   * 2010-06-08 
      //   * 不再推荐以下的委托LogContext对象的几个版本,推荐使用不带LogContext的版本。
      //   * 
      //   * 提供在CO,AM,VO,EO,中常用的版本,和一个通用版本OADBTransaction tsn。
      //   * 
      //   * */
      //  public void print(OAPageContext pageContext, LogContext logContext)
      //  {
      //    String output = getOutput();
      //    
      //    if(logContext.isCommandLineLog())
      //    {
      //      System.out.print(output);
      //    }
      //    
      //    if(logContext.isDiagnosticLog())
      //    {
      //      if(pageContext.isLoggingEnabled(logContext.getLogLevel()))
      //      {
      //        pageContext.writeDiagnostics(this.className, output, logContext.getLogLevel());
      //      }
      //    }
      //  
      //  }
      //
      //  public void print(OADBTransaction tsn, LogContext logContext)
      //  {
      //    String output = getOutput();
      //  
      //    if (logContext.isCommandLineLog())
      //    {
      //      System.out.print(output);
      //    }
      //
      //    if(logContext.isDiagnosticLog())
      //    {
      //      if(tsn.isLoggingEnabled(logContext.getLogLevel()))
      //      {
      //         tsn.writeDiagnostics(this.className, output, logContext.getLogLevel());
      //      }
      //    }
      //  
      //  }
      //
      //  public void print(OAApplicationModule am, LogContext logContext)
      //  {
      //    OADBTransaction tsn = am.getOADBTransaction();
      //    print(tsn, logContext);
      //  }
      //  
      //  public void print(OAViewObjectImpl vo, LogContext logContext)
      //  {
      //    OADBTransaction tsn = (OADBTransaction)vo.getDBTransaction();
      //    print(tsn, logContext);
      //  }
      //
      //  public void print(OAViewRowImpl voRow, LogContext logContext)
      //  {
      //    OAViewObjectImpl vo = (OAViewObjectImpl)voRow.getViewObject();
      //    OADBTransaction tsn = (OADBTransaction)vo.getDBTransaction();
      //    print(tsn, logContext);
      //  }
      //
      //  public void print(OAEntityImpl eo, LogContext logContext)
      //  {
      //    OADBTransaction tsn = (OADBTransaction)eo.getDBTransaction();
      //    print(tsn, logContext);
      //  }  
    
      /**
       * 2010-06-08 推荐使用以下几个不带LogContext的版本。
       * 
       * 提供在 CO,AM,VO,EO,中常用的版本,和一个通用版本 OADBTransaction tsn。
       */
      public void print(OAPageContext pageContext)
      {
        OADBTransaction tsn = pageContext.getRootApplicationModule().getOADBTransaction();
        print(tsn);
      }
    
      public void print(OADBTransaction tsn)
      {
        String output = getOutput();
    
        
        //开发者模式
        if (tsn.isDeveloperMode())
        {
        
          System.out.print(output);
    
          //Update By hongbo
        //不再使用System.out.print方法,代之以LogBack
    // logger.info(className);
    //System.out.println("className is "+className);
    // logger.info(output);
    
    //        org.slf4j.Logger log = LoggerFactory.getLogger(className);
    //        log.info(output);
     //End
            
        }
    
        if (tsn.isLoggingEnabled(this.logLevel))
        {
          tsn.writeDiagnostics(this.className, output, this.logLevel);
          cux_log_messages(tsn, output);
          
        }
          //Add By hongbo,20160525
          //此处使用集成slf4j实现日志输出,具体实现可自行百度
          //将Logback或者log4j相关jar包引入工程目录 (服务器放入$JAVA_TOP目录)
          //并配置相关配置文件logback.xml或log4j.propertites 放入工程根目录,即myprojects目录
    //       org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(className);
    //       log.info(output);
           //此处直接使用log4j实现日志输出
    //      org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(className); 
    //      logger.info(output);
          //End
           
           
    
        //    /*
        //     * 通过配置文件 CUX_LOG_MESSAGES_FILE,取得log文件的全路径。
        //     * 例如 /usr/tmp/user_log_temp.log,再将日志写入此文件。
        //     */
        //    String logFile = tsn.getProfile("CUX_LOG_MESSAGES_FILE");
        //    if (logFile != null && !"".equals(logFile))
        //    {
        //      FileUtil.write(logFile, getOutput());
        //    }
    
      }
    
      private void cux_log_messages(OADBTransaction tsn,
                                    String output)
      {
        try
        {
            //cux_common_util_pkg各位自己去实现,此处就不罗列了
          String sql = 
            "begin cux_common_util_pkg.cux_log_messages(p_log_sequence => :1,
    " + "                                   p_module => :2,
    " + 
            "                                   p_log_level => :3,
    " + 
            "                                   p_message_text => :4); end;";
    
          CallableStatement cs = tsn.createCallableStatement(sql, 1);
          cs.setLong(1, System.currentTimeMillis());
          cs.setString(2, this.className);
          cs.setInt(3, this.logLevel);
          cs.setString(4, output);
          cs.execute();
          cs.close();
        }
        catch (SQLException e)
        {
          throw OAException.wrapperException(e);
        }
      }
    
      public void print(ApplicationModule am)
      {
        OADBTransaction tsn = (OADBTransaction) am.getTransaction();
        print(tsn);
      }
    
      public void print(ViewObject vo)
      {
        OADBTransaction tsn = (OADBTransaction) ((OAViewObjectImpl) vo).getDBTransaction();
        print(tsn);
      }
    
      public void print(Row row)
      {
        OAViewObjectImpl vo = (OAViewObjectImpl) ((OAViewRowImpl) row).getViewObject();
        OADBTransaction tsn = (OADBTransaction) vo.getDBTransaction();
        print(tsn);
      }
    
      public void print(OAEntityImpl eo)
      {
        OADBTransaction tsn = (OADBTransaction) eo.getDBTransaction();
        print(tsn);
      }
    
        public void printScreen(OAPageContext pageContext) {
                OADBTransaction tsn = 
                    pageContext.getRootApplicationModule().getOADBTransaction();
                printScreen(tsn);
            }
        
            public void printScreen(ApplicationModule am) {
                OADBTransaction tsn = (OADBTransaction)am.getTransaction();
                printScreen(tsn);
            }
        
            public void printScreen(OADBTransaction tsn) {
                String output = getOutput();
        
                if (tsn.isDeveloperMode()) {
                    System.out.print(output);
                }
        
                if (tsn.isLoggingEnabled(this.logLevel)) {
                    tsn.writeDiagnostics(this.className, output, this.logLevel);
                }
            }
    }

    调用方法如下:

    CO中LogUtil.of(stringContent or String[][] , this ).print(pageContext);

    其他如EO,AM,VO等直接LogUtil.of(String or String[][], this).print(this);

    网页显示日志在开启诊断之后在地址栏后加入 &aflog_level=error(日志级别自定义)即可。

    VO对象常用类:ModelUtil

    package cuxA.oracle.apps.cux.common.util;
    
    
    import java.sql.SQLException;
    
    import oracle.apps.fnd.common.MessageToken;
    import oracle.apps.fnd.framework.OAApplicationModule;
    import oracle.apps.fnd.framework.OAException;
    import oracle.apps.fnd.framework.OANLSServices;
    import oracle.apps.fnd.framework.server.OADBTransaction;
    import oracle.apps.fnd.framework.server.OAViewObjectImpl;
    import oracle.apps.fnd.framework.webui.OAPageContext;
    
    import oracle.jbo.ApplicationModule;
    import oracle.jbo.Row;
    import oracle.jbo.ViewLink;
    import oracle.jbo.ViewObject;
    
    
    /**
     * 提供mvc之Model端的常用工具。
     * 
     * geyan 2010-01-06
     */
    public class ModelUtil {
        private ModelUtil() {
        }
    
        public static final String CLASS_NAME = 
            "com.ncgc.oracle.apps.cux.por.util.ModelUtil";
    
        /**
         * 以一种简短的方式获得 OANLSServices,进而获得OANLSServices提供的一系列服务。
         */
        public static OANLSServices getNls(OAApplicationModule am) {
            return am.getOADBTransaction().getOANLSServices();
        }
    
        public static OANLSServices getNls(OADBTransaction tsn) {
            return tsn.getOANLSServices();
        }
    
        public static oracle.jbo.domain.Number stringToNumber(String str) {
            try {
                return new oracle.jbo.domain.Number(str);
            } catch (SQLException e) {
                throw OAException.wrapperException(e);
            }
        }
    
        public static void clearVoCache(ViewObject vo) {
            vo.clearCache();
            vo.setMaxFetchSize(-1);
            vo.setWhereClauseParams(null);
            vo.setWhereClause("1=2");
            vo.executeQuery();
        }
    
        public static void clearVoCache(ApplicationModule am, String voName) {
            ViewObject vo = findVo(am, voName);
            clearVoCache(vo);
        }
    
        public static ApplicationModule getChildAm(ApplicationModule parentAm, 
                                                   String childAmName) {
            String[] amNames = parentAm.getApplicationModuleNames();
            for (int i = 0; i < amNames.length; i++) {
                if (amNames[i].endsWith(childAmName)) {
                    return parentAm.findApplicationModule(amNames[i]);
                } else {
                    ApplicationModule childAm = 
                        parentAm.findApplicationModule(amNames[i]);
                    ApplicationModule am = getChildAm(childAm, childAmName);
                    if (am != null) {
                        return am;
                    }
                }
            }
    
            return null;
        }
    
        public static ApplicationModule getChildAm(OAPageContext pageContext, 
                                                   String childAmName) {
            ApplicationModule parentAm = pageContext.getRootApplicationModule();
            return ModelUtil.getChildAm(parentAm, childAmName);
        }
    
        public static ViewObject findVo(ApplicationModule am, String voName) {
            ViewObject vo = am.findViewObject(voName);
    
            if (vo == null) {
                MessageToken[] errTokens = 
                { new MessageToken("OBJECT_NAME", voName), };
                throw new OAException("AK", "FWK_TBX_OBJECT_NOT_FOUND", errTokens);
            }
    
            return vo;
        }
    
        public static ApplicationModule findAm(ApplicationModule parentAm, 
                                               String amName) {
            ApplicationModule am = parentAm.findApplicationModule(amName);
    
            if (am == null) {
                MessageToken[] errTokens = 
                { new MessageToken("OBJECT_NAME", amName), };
                throw new OAException("AK", "FWK_TBX_OBJECT_NOT_FOUND", errTokens);
            }
    
            return am;
        }
    
        /**
         * 此方法返回 vo 当前 fetch 的所有行。
         */
        public static Row[] getVoFetchedRows(ApplicationModule am, String voName) {
            ViewObject vo = findVo(am, voName);
            return getVoFetchedRows(vo);
        }
    
        public static Row[] getVoFetchedRows(ViewObject vo) {
            String[][] stra = 
            { { "method", "getVoFetchedRows" }, { "vo.getName()", vo.getName() }, 
              { "vo.isExecuted()", vo.isExecuted() + "" }, 
              { "vo.getFetchedRowCount()", vo.getFetchedRowCount() + "" }, };
            LogUtil.of(stra, CLASS_NAME).print(vo);
    
            if (!vo.isExecuted()) {
                return new Row[0];
            }
    
            vo.setRangeStart(0);
            vo.setRangeSize(-1);
    
            return vo.getAllRowsInRange() != null ? vo.getAllRowsInRange() : 
                   new Row[0];
        }
    
        /**
         * 通过 attributeValue 删除Vo当前Fetch到的行,一行或多行。
         */
        public static void removeVoFetchedRow(ViewObject vo, String attributeName, 
                                              String attributeValue) {
            Row[] rows = getVoFetchedRows(vo);
    
            String[][] stra = 
            { { "method", "removeVoFetchedRow" }, { "attributeName", 
                                                    attributeName }, 
              { "attributeValue", attributeValue }, 
              { "rows.length", rows.length + "" }, };
            LogUtil.of(stra, CLASS_NAME).print(vo);
    
            for (int i = 0; i < rows.length; i++) {
                String value$row = rows[i].getAttribute(attributeName).toString();
                if (value$row.equals(attributeValue)) {
                    rows[i].remove();
                }
            }
        }
    
        public static void removeVoFetchedRow(ApplicationModule am, String voName, 
                                              String pkAttributeName, 
                                              String pkValue) {
            ViewObject vo = findVo(am, voName);
            removeVoFetchedRow(vo, pkAttributeName, pkValue);
        }
    
        /**
         * 返回 "多选框"选择的行。
         * 此方法简化了"未选择行","返回行为空"的处理。
         */
        public static Row[] getVoFilteredRows(ApplicationModule am, String voName, 
                                              String attribute) {
            ViewObject vo = findVo(am, voName);
            return getVoFilteredRows(vo, attribute);
        }
    
        /**
         * 返回 "多选框"选择的行。
         * 此方法简化了"未选择行","返回行为空"的处理。
         */
        public static Row[] getFilteredRows(OAApplicationModule am, String voName, 
                                            String attribute) {
            ViewObject vo = findVo(am, voName);
    
            // 若vo尚无任何行,则返回 0长度数组
            vo.reset();
            if (!vo.hasNext()) {
                return new Row[0];
            }
    
            Row[] rows = vo.getFilteredRows(attribute, "Y");
    
            return rows != null && rows.length > 0 ? rows : new Row[0];
        }
    
        public static Row[] getVoFilteredRows(ViewObject vo, String attribute) {
            // 若vo尚无任何行,则返回 0长度数组
            vo.reset();
            if (!vo.hasNext()) {
                return new Row[0];
            }
    
            Row[] rows = vo.getFilteredRows(attribute, "Y");
    
            return rows != null && rows.length > 0 ? rows : new Row[0];
        }
    
        public static Row getVoFirstFilteredRow(ApplicationModule am, 
                                                String voName, String attribute) {
            OAViewObjectImpl vo = (OAViewObjectImpl)findVo(am, voName);
            return getVoFirstFilteredRow(vo, attribute);
        }
    
        public static Row getVoFirstFilteredRow(OAViewObjectImpl vo, 
                                                String attribute) {
            return vo.getFirstFilteredRow(attribute, "Y");
        }
    
        /**
         * remove当前am中的一个vo。
         */
        public static void removeVo(ApplicationModule am, String voName) {
            ViewObject vo = findVo(am, voName);
            vo.remove();
        }
    
        /**
         * 返回"下一个"序号,给定当前VO和其序号所在的列,返回现有列最大值加1的数字。
         */
        public static Integer getNextSeqNum(ViewObject vo, String attributeName) {
            Row[] rows = getVoFetchedRows(vo);
            if (rows == null || rows.length == 0) {
                return 1;
            }
    
            // 否则,依次比较并返回 "最大值 + 1"
            int result = 0;
            for (int i = 0; i < rows.length; i++) {
                Object seqNum$row = rows[i].getAttribute(attributeName);
                if (seqNum$row == null) {
                    continue;
                }
    
                int seqNumRowInt = Integer.valueOf(seqNum$row.toString());
                result = seqNumRowInt > result ? seqNumRowInt : result;
            }
    
            return result + 1;
        }
    
        public static Integer getNextSeqNum(ApplicationModule am, String voName, 
                                            String attributeName) {
            ViewObject vo = ModelUtil.findVo(am, voName);
            return getNextSeqNum(vo, attributeName);
        }
    
        public static void commit(OAApplicationModule am, boolean isClearEoCache) {
            OADBTransaction tsn = am.getOADBTransaction();
            commit(tsn, isClearEoCache);
        }
    
        public static void commit(OADBTransaction tsn, boolean isClearEoCache) {
            boolean isClearCacheOnCommit = tsn.isClearCacheOnCommit();
    
            // ClearCacheOnCommit
            tsn.setClearCacheOnCommit(isClearEoCache);
            try {
                tsn.commit();
            } catch (OAException e) {
                throw e;
            }
    
            // 恢复原先设置
            tsn.setClearCacheOnCommit(isClearCacheOnCommit);
        }
    
        public static void rollback(OAApplicationModule am, 
                                    boolean isClearEoCache) {
            OADBTransaction tsn = am.getOADBTransaction();
            rollback(tsn, isClearEoCache);
        }
    
        public static void rollback(OADBTransaction tsn, boolean isClearEoCache) {
            boolean isClearCacheOnRollback = tsn.isClearCacheOnRollback();
    
            // ClearCacheOnRollback
            tsn.setClearCacheOnRollback(isClearEoCache);
            if (tsn.isDirty()) {
                tsn.rollback();
            }
    
            // 恢复原先设置
            tsn.setClearCacheOnRollback(isClearCacheOnRollback);
        }
    
        public static ViewObject createVo(ApplicationModule am, String voName, 
                                          String voDefine) {
            ViewObject vo = am.findViewObject(voName);
            if (vo != null) {
                return vo;
            }
    
            return am.createViewObject(voName, voDefine);
        }
    
        public static Object[] getVoWhereClauseParams(ViewObject vo) {
            Object[] objects = vo.getWhereClauseParams();
            if (objects == null) {
                return null;
            }
    
            Object[] result = new Object[objects.length];
            for (int i = 0; i < objects.length; i++) {
                if (objects[i].getClass().isArray()) {
                    Object[] params = (Object[])objects[i];
                    Object param$index = params[0];
                    Object param$value = params[1];
    
                    result[i] = param$value;
                } else {
                    Object param$value = objects[i];
    
                    result[i] = param$value;
                }
            }
    
            return result;
        }
    
        public static void outputVo(ViewObject vo) {
            String[][] stra = 
            { { "method", "outputVo" }, { "vo.getName()", vo.getName() }, 
              { "vo.getFullName()", vo.getFullName() }, 
              { "vo.getDefFullName()", vo.getDefFullName() }, 
              { "vo.isExecuted()", vo.isExecuted() + "" }, 
              { "vo.getRangeSize()", vo.getRangeSize() + "" }, 
              { "vo.getRangeStart()", vo.getRangeStart() + "" }, 
              { "vo.getFetchedRowCount()", vo.getFetchedRowCount() + "" }, 
              { "vo.getCurrentRowIndex()", vo.getCurrentRowIndex() + "" }, 
              { "vo.getMaxFetchSize()", vo.getMaxFetchSize() + "" }, 
              { "vo.getWhereClause()", vo.getWhereClause() }, 
              { "getVoWhereClauseParams(vo)", 
                arrayToString(getVoWhereClauseParams(vo)) }, 
              { "vo.getOrderByClause()", vo.getOrderByClause() }, 
              { "vo.getQuery()", vo.getQuery() }, };
            LogUtil.of(stra, CLASS_NAME).print(vo);
        }
    
        public static void outputVo(ApplicationModule am, String voName) {
            ViewObject vo = ModelUtil.findVo(am, voName);
            outputVo(vo);
        }
    
        public static String arrayToString(Object[] arrary) {
            if (arrary == null || arrary.length == 0) {
                return null;
            }
    
            String result = "";
            for (int i = 0; i < arrary.length; i++) {
                result = result + arrary[i] + " , ";
            }
    
            return " [ " + result + " ] ";
        }
    
        public static void displayModels(ApplicationModule am) {
            String[] ams = am.getApplicationModuleNames();
            for (int i = 0; i < ams.length; i++) {
                ApplicationModule am$i = am.findApplicationModule(ams[i]);
                String[][] stra = 
                { { "method", "displayModels" }, { "for", i + " --> display ApplicationModule" }, 
                  { "parent AM", am.getFullName() }, 
                  { "child AM Name", am$i.getName() }, 
                  { "child AM FullName", am$i.getFullName() }, 
                  { "child AM DefFullName", am$i.getDefFullName() }, };
                LogUtil.of(stra, CLASS_NAME).print(am);
            }
    
            String[] vos = am.getViewObjectNames();
            for (int i = 0; i < vos.length; i++) {
                ViewObject vo$i = am.findViewObject(vos[i]);
                String[][] stra = 
                { { "method", "displayModels" }, { "for", i + " --> display ViewObject" }, 
                  { "parent AM", am.getFullName() }, 
                  { "child VO Name", vo$i.getName() }, 
                  { "child VO FullName", vo$i.getFullName() }, 
                  { "child VO DefFullName", vo$i.getDefFullName() }, };
                LogUtil.of(stra, CLASS_NAME).print(am);
            }
    
            String[] vls = am.getViewLinkNames();
            for (int i = 0; i < vls.length; i++) {
                ViewLink vl$i = am.findViewLink(vls[i]);
                String[][] stra = 
                { { "method", "displayModels" }, { "for", i + " --> display ViewLink" }, 
                  { "parent AM", am.getFullName() }, 
                  { "child VL Name", vl$i.getName() }, 
                  { "child VL FullName", vl$i.getFullName() }, 
                  { "child VL DefFullName", vl$i.getDefFullName() }, };
                LogUtil.of(stra, CLASS_NAME).print(am);
            }
    
            for (int i = 0; i < ams.length; i++) {
                displayModels(am.findApplicationModule(ams[i]));
            }
        }
    
    
    }

    输出VO对象信息:ModelUtil.outputVo(voInstance);

                 

  • 相关阅读:
    MVC3.0 如何点击点击一张图片连接到另一地址
    什么是SMTP?
    ASP.NET MVC中 Jquery AJAX 获取数据利用MVC模型绑定实现输出
    MVC HTML控件扩展例子
    连接局域网内的mysql服务
    python loger 模板
    培养正确的编程态度和方法转
    Chrome不支持showModalDialog模态对话框和无法返回returnValue的问题
    SQL中时间与秒互转
    VS开发好用的扩展
  • 原文地址:https://www.cnblogs.com/huanghongbo/p/7466304.html
Copyright © 2020-2023  润新知