关于 SCORM 2004 3rd Edition Sample Run-Time Environment 的二次开发(-)跨平台解决方案

最近几天一直忙于 SCORM 2004 3rd Edition Sample Run-Time Environment 的二次开发。今天基本结束了。明天会提交到另外一个项目组做一下应用测试。现在顺便记下开发过程中的一些经验

首先:解决adl的跨平台

  adl给出的这个开发平台采用了access数据库。而对于具体的learner学习sco的状态信息则都是以java序列化对象的形式保存在文件里,所以要想跨平台只需要更换掉access。目前我采用的hsqldb。第一:他是一个基于java的数据库,属于平台无关。第二:因为adl的开发平台对于数据库的交互并不频繁。而且在数据库存储的相关数据也不多。所以hsqldb完全可以支持adl的基本需求。第三:hsqldb非常小巧。并不需要单独安装。只需要拷贝一个jar包即可。所以对于应用的发布非常方便。在web应用里加一个监听器用来部署hsql即可。可以做到直接拷贝war包就可以运行。下面给出部署hsqldb和启动hsqldb的监听器类(在网上搜到的稍作修改)

 

package  org.adl.hsqllistener;

import  java.io.File;
import  java.io.FileInputStream;
import  java.io.FileOutputStream;
import  java.sql.Connection;
import  java.sql.DriverManager;
import  java.sql.Statement;

import  javax.servlet.ServletContextEvent;
import  javax.servlet.ServletContextListener;

import  org.hsqldb.Server;

/**
 * 该类的职责是在WebApp启动时自动开启HSQL服务. 依然使用Server方式,不受AppServer的影响.
 * 
 * 
@author frank
 * 
@author calvin
 
*/


public   class  HsqlListener  implements  ServletContextListener  {

    
public void contextInitialized(ServletContextEvent sce) {
        String dbName 
= sce.getServletContext().getInitParameter("hsql.dbName");
        String path 
= sce.getServletContext().getInitParameter("hsql.dbPath");
        path 
= sce.getServletContext().getRealPath("/"+ path;
        System.out.println(
"path:" + path);
        
int port = -1;
        
try {
            port 
= Integer.parseInt(sce.getServletContext().getInitParameter(
                    
"hsql.port"));
        }
 catch (Exception e) {
            port 
= 9001;
        }

        
if (dbName == null || dbName.equals("")) {
            System.out
                    .println(
"Cant' get hsqldb.dbName from web.xml Context Param");
            
return;
        }

        String scriptFile 
= path + File.separator + dbName + ".script";// 源hsqldb
        
// *.script文件
        String propertiesFile = path + File.separator + dbName + ".properties";// 源hsqldb
        
// *.properties文件
        String dsqlFilePath = File.separator + "scorm" + File.separator
                
+ "hsqldb";
        File dsqlFileDir 
= new File(dsqlFilePath);
        String dsqlFileScript 
= dsqlFilePath + File.separator + dbName
                
+ ".script";// 目标hsqldb *.script文件(最终使用的hsql数据库)
        String dsqlFileProperties = dsqlFilePath + File.separator + dbName
                
+ ".properties";// 目标hsqldb *.properties文件(最终使用的hsql数据库)
        File dsqlFileS = new File(dsqlFileScript);
        File dsqlFileP 
= new File(dsqlFileProperties);
        System.out.println(
" 源Hsql文件:" + scriptFile + "," + propertiesFile
                
+ " ");
        System.out.println(
" 目标Hsql文件:" + dsqlFileScript + ","
                
+ dsqlFileProperties);
        
try {
            
if (dsqlFileP.exists() && dsqlFileS.exists()) {// 判断数据文件是否存在
                System.out.println("数据库文件已存在");
                
this.startServer(dsqlFilePath + File.separator, dbName, port);
            }
 else {
                System.out.println(
"创建数据库文件");
                
if (!dsqlFileDir.exists()) {// 判断数据库目录是否存在
                    dsqlFileDir.mkdirs();
                }

                
if (HsqlListener.copy(scriptFile, dsqlFileScript)) {
                    
if (HsqlListener.copy(propertiesFile, dsqlFileProperties)) {
                        System.out.println(
"hsql部署成功");
                        
this.startServer(dsqlFilePath + File.separator, dbName,
                                port);
                    }

                }

            }

        }
 catch (Exception e) {
            e.printStackTrace();
        }

    }


    
/**
     * * 启动Hsqldb服务的方法。 *
     * 
     * 
@param dbPath
     *            数据库路径 *
     * 
@param dbName
     *            数据库名称 *
     * 
@param port
     *            所使用的端口号
     
*/

    
private void startServer(String dbPath, String dbName, int port) {

        Server server 
= new Server();// 它可是hsqldb.jar里面的类啊。
        server.setDatabaseName(0, dbName);
        server.setDatabasePath(
0, dbPath + dbName);
        
if (port != -1{
            server.setPort(port);
        }

        server.setSilent(
true);
        server.start();
        System.out.println(
"hsqldb started...");
        
// 等待Server启动
        try {
            Thread.sleep(
800);
        }
 catch (InterruptedException e) {
            
// do nothing
        }

    }


    
/**
     * * Listener销毁方法,在Web应用终止的时候执行"shutdown"命令关闭数据库.
     
*/

    
public void contextDestroyed(ServletContextEvent arg0) {
        
// 这里就不用说了,自然是关闭数据库操作
        Connection conn = null;
        
try {
            System.out.println(
"ADL应用终止");
            Class.forName(
"org.hsqldb.jdbcDriver");
            conn 
= DriverManager.getConnection(
                    
"jdbc:hsqldb:hsql://localhost:9002/samplerte""sa""");
            Statement stmt 
= conn.createStatement();
            stmt.executeUpdate(
"SHUTDOWN;");
            System.out.println(
"持久化hsqldb");
        }
 catch (Exception e) {
            e.printStackTrace();
            
// do nothing
        }

    }


    
/**
     * 将指定文件复制到目标文件
     * 
     * 
@param file1
     *            源文件
     * 
@param file2
     *            目标文件
     * 
@return 复制是否成功
     
*/

    
public static boolean copy(String file1, String file2) {
        
try // must try and catch,otherwide will compile error
        {
            
// instance the File as file_in and file_out
            java.io.File file_in = new java.io.File(file1);
            java.io.File file_out 
= new java.io.File(file2);
            FileInputStream in1 
= new FileInputStream(file_in);
            FileOutputStream out1 
= new FileOutputStream(file_out);
            
byte[] bytes = new byte[1024];
            
int c;
            
while ((c = in1.read(bytes)) != -1)
                out1.write(bytes, 
0, c);
            in1.close();
            out1.close();
            
return (true); // if success then return true
        }
 catch (Exception e) {
            e.printStackTrace();
            System.out.println(
"Error!");
            
return (false); // if fail then return false
        }

    }

}

接着是hsqldb的初始化script

 

CREATE   SCHEMA   PUBLIC   AUTHORIZATION  DBA
CREATE   SCHEMA  SAMPLERTE  AUTHORIZATION  DBA
CREATE  MEMORY  TABLE  APPLICATIONDATA(DATANAME  VARCHAR ( 50 NOT   NULL   PRIMARY   KEY ,MEMORYVALUE  VARCHAR ( 50 ),NUMBERVALUE  INTEGER )
CREATE  MEMORY  TABLE  COURSEINFO(COURSEID  VARCHAR ( 50 NOT   NULL   PRIMARY   KEY ,COURSETITLE  VARCHAR ( 200 ),ACTIVE BOOLEAN  NOT   NULL ,IMPORTDATETIME  VARCHAR ( 50 ),START BOOLEAN  NOT   NULL ,TOC BOOLEAN  NOT   NULL )
CREATE  MEMORY  TABLE  ITEMINFO(COURSEID  VARCHAR ( 255 ),ORGANIZATIONIDENTIFIER  VARCHAR ( 255 ),ITEMIDENTIFIER  VARCHAR ( 255 ),RESOURCEIDENTIFIER  VARCHAR ( 255 ),LAUNCH  VARCHAR ( 255 ),TYPE  VARCHAR ( 255 ),TITLE  VARCHAR ( 255 ),PARAMETERSTRING  VARCHAR ( 255 ),PERSISTSTATE  VARCHAR ( 255 ),DATAFROMLMS  VARCHAR ( 255 ),MINNORMALIZEDMEASURE  VARCHAR ( 255 ),ATTEMPTABSOLUTEDURATIONLIMIT  VARCHAR ( 255 ),TIMELIMITACTION  VARCHAR ( 255 ),COMPLETIONTHRESHOLD  VARCHAR ( 255 )," Next " BOOLEAN  NOT   NULL ,PREVIOUS BOOLEAN  NOT   NULL , EXIT  BOOLEAN  NOT   NULL ,EXITALL BOOLEAN  NOT   NULL ,ABANDON BOOLEAN  NOT   NULL ,ACTIVITYID  INTEGER  GENERATED  BY   DEFAULT   AS   IDENTITY (START  WITH   1 NOT   NULL   PRIMARY   KEY ,SUSPEND BOOLEAN  NOT   NULL )
CREATE  MEMORY  TABLE  SCOCOMMENTS(ACTIVITYID  INTEGER   NOT   NULL ,COMMENTID  INTEGER  GENERATED  BY   DEFAULT   AS   IDENTITY (START  WITH   1 NOT   NULL   PRIMARY   KEY ,COMMENT  VARCHAR ( 255 ),COMMENTDATETIME DATE,COMMENTLOCATION  VARCHAR ( 255 ))
CREATE  MEMORY  TABLE  USERCOURSEINFO(USERID  VARCHAR ( 50 ),COURSEID  VARCHAR ( 50 ),SUSPENDALL BOOLEAN  NOT   NULL )
CREATE  MEMORY  TABLE  USERINFO(USERID  VARCHAR ( 50 NOT   NULL   PRIMARY   KEY ,LASTNAME  VARCHAR ( 50 ),FIRSTNAME  VARCHAR ( 50 ),ADMIN BOOLEAN  NOT   NULL ,PASSWORD  VARCHAR ( 50 ),ACTIVE BOOLEAN  NOT   NULL ,AUDIOLEVEL  VARCHAR ( 50 ),AUDIOCAPTIONING  INTEGER ,DELIVERYSPEED  VARCHAR ( 50 ),LANGUAGE  VARCHAR ( 50 ))
ALTER   TABLE  ITEMINFO  ALTER   COLUMN  ACTIVITYID RESTART  WITH   1
ALTER   TABLE  SCOCOMMENTS  ALTER   COLUMN  COMMENTID RESTART  WITH   1
CREATE   USER  SA PASSWORD ""
GRANT  DBA  TO  SA
SET  WRITE_DELAY  10
SET   SCHEMA  SAMPLERTE
INSERT   INTO  APPLICATIONDATA  VALUES ( ' nextCourseID ' , NULL , 0 )

 

这样就解决adl的跨平台了。下篇会解决如何提取rte环境里的业务系统关心的learner学习sco的状态信息

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值