OpenClinica: Towards Database Abstraction, Part 1

Similar documents
ServletConfig Interface

Advanced Internet Technology Lab # 4 Servlets

Web based Applications, Tomcat and Servlets - Lab 3 -

The Basic Web Server CGI. CGI: Illustration. Web based Applications, Tomcat and Servlets - Lab 3 - CMPUT 391 Database Management Systems 4

CS506 Web Design & Development Final Term Solved MCQs with Reference

JAVA SERVLET. Server-side Programming INTRODUCTION

Tutorial: Developing a Simple Hello World Portlet

XML to Lucene to SRW

Introduction. This course Software Architecture with Java will discuss the following topics:

Table of Contents. Tutorial API Deployment Prerequisites... 1

Copyright 2005, by Object Computing, Inc. (OCI). All rights reserved. Database to Web

sessionx Desarrollo de Aplicaciones en Red A few more words about CGI CGI Servlet & JSP José Rafael Rojano Cáceres

Java Servlets. Preparing your System

JAVA SYLLABUS FOR 6 WEEKS

THIS IS ONLY SAMPLE RESUME - DO NOT COPY AND PASTE INTO YOUR RESUME. WE ARE NOT RESPONSIBLE Name: xxxxxx

Supplement IV.E: Tutorial for Tomcat For Introduction to Java Programming By Y. Daniel Liang

Introduction. Literature: Steelman & Murach, Murach s Java Servlets and JSP. Mike Murach & Associates Inc, 2003

Servlets. How to use Apache FOP in a Servlet $Revision: $ Table of contents

ThingWorx Relational Databases Connectors Extension User Guide

This tutorial will teach you how to use Java Servlets to develop your web based applications in simple and easy steps.

Welcome To PhillyJUG. 6:30-7:00 pm - Network, eat, find a seat 7:00-7:15 pm - Brief announcements 7:15-8:30 pm - Tom Janofsky's presentation

Peers Techno log ies Pv t. L td. Core Java & Core Java &Adv Adv Java Java

Session 9. Introduction to Servlets. Lecture Objectives

Servlets. How to use Apache FOP in a Servlet $Revision: $ Table of contents

LAB 1 PREPARED BY : DR. AJUNE WANIS ISMAIL FACULTY OF COMPUTING UNIVERSITI TEKNOLOGI MALAYSIA

Introduction to Servlets. After which you will doget it

CS433 Technology Overview

JAVA 2 ENTERPRISE EDITION (J2EE)

Java Training Center, Noida - Java Expert Program

文字エンコーディングフィルタ 1. 更新履歴 2003/07/07 新規作成(第 0.1 版) 版 数 第 0.1 版 ページ番号 1

2. Follow the installation directions and install the server on ccc. 3. We will call the root of your installation as $TOMCAT_DIR

APIs - what are they, really? Web API, Programming libraries, third party APIs etc

JSP. Common patterns

A- Core Java Audience Prerequisites Approach Objectives 1. Introduction

Servlets by Example. Joe Howse 7 June 2011

CSC309: Introduction to Web Programming. Lecture 10

Chapter 1 GETTING STARTED. SYS-ED/ Computer Education Techniques, Inc.

Getting started with Winstone. Minimal servlet container

Downloading Tweet Streams and Parsing

Session 8. Introduction to Servlets. Semester Project

Cisco Unity Express JSP, Servlet, and VoiceXML Web Application Development Guide

Writing Portable Applications for J2EE. Pete Heist Compoze Software, Inc.

The Servlet Life Cycle

Developing a Mobile Web-based Application with Oracle9i Lite Web-to-Go

Configuring a JDBC Resource for IBM DB2 for z/os in Metadata Manager

Lab 10. Google App Engine. Tomas Lampo. November 11, 2010

This page discusses topic all around using FOP in a servlet environment. 2. Example Servlets in the FOP distribution

Database Applications Recitation 6. Project 3: CMUQFlix CMUQ s Movies Recommendation System

Java Training For Six Weeks

Webservices In Java Tutorial For Beginners Using Netbeans Pdf

The propeties file will contain a main.class property, maybe an optional main.method property, and a set of description properties.

[Course Overview] After completing this module you are ready to: Develop Desktop applications, Networking & Multi-threaded programs in java.

Servlets. An extension of a web server runs inside a servlet container

Course Content for Java J2EE

Using Properties for runtime ICAN 5.0.x JCD Configuration

JAVA SYLLABUS FOR 6 MONTHS

Introduction to Java Servlets. SWE 432 Design and Implementation of Software for the Web

XmlEngine user s manual

Setup of HELIO Components Definition of Required Capabilities V0.8

a. Jdbc:ids://localhost:12/conn?dsn=dbsysdsn 21. What is the Type IV Driver URL? a. 22.

Index. Symbols. /**, symbol, 73 >> symbol, 21

Introduction. This course Software Architecture with Java will discuss the following topics:

Database Explorer Quickstart

JAVA. 1. Introduction to JAVA

Database Assignment 2

The Servlet as Client

WebServices - Axis 1.1. ## 1.2. #### 1.3. ######## API. 1. Axis ######### ##### 1.2 #######:

/* Copyright 2012 Robert C. Ilardi

Page 1

Call: JSP Spring Hibernate Webservice Course Content:35-40hours Course Outline

RadBlue s S2S Quick Start Package (RQS) Developer s Guide. Version 0.1

5/23/2015. Core Java Syllabus. VikRam ShaRma

Advanced Java Exercises

An Application for Monitoring Solr

AutoVue Integration SDK Technical Guide

CHAPTER 44. Java Stored Procedures

JAVA Training Overview (For Demo Classes Call Us )

Strut2 jasper report plugin - War deployment

Writing Servlets and JSPs p. 1 Writing a Servlet p. 1 Writing a JSP p. 7 Compiling a Servlet p. 10 Packaging Servlets and JSPs p.

Call: Core&Advanced Java Springframeworks Course Content:35-40hours Course Outline

com Spring + Spring-MVC + Spring-Boot + Design Pattern + XML + JMS Hibernate + Struts + Web Services = 8000/-

Schema Null Cannot Be Resolved For Table Jpa

Servlet. 1.1 Web. 1.2 Servlet. HTML CGI Common Gateway Interface Web CGI CGI. Java Applet JavaScript Web. Java CGI Servlet. Java. Apache Tomcat Jetty

System resources. Security Manager.

Application Development in JAVA. Data Types, Variable, Comments & Operators. Part I: Core Java (J2SE) Getting Started

CIS-CAT Pro Dashboard Documentation

Oracle Developer Depot Technical Review

Enterprise Java Technologies (Part 1 of 3) Component Architecture. Overview of Java EE. Java Servlets

Course Description. Learn To: : Intro to JAVA SE7 and Programming using JAVA SE7. Course Outline ::

Servlets1. What are Servlets? Where are they? Their job. Servlet container. Only Http?

Configuring a JDBC Resource for IBM DB2/ iseries in Metadata Manager HotFix 2

Interview Questions I received in 2017 and 2018

Servlet Fudamentals. Celsina Bignoli

/ / JAVA TRAINING

Simple Data Source Crawler Plugin to Set the Document Title

DOC // JAVA TOMCAT WEB SERVICES TUTORIAL EBOOK

CBRN Data Import/Export Tool (CDIET) Presented by: Darius Munshi

J2EE Technologies. Industrial Training

Full Stack Developer (FSD) JAVA

Installation Instructions for spamtracker components:

Transcription:

OpenClinica: Towards Database Abstraction, Part 1 Author: Tom Hickerson, Akaza Research Date Created: 8/26/2004 4:17 PM Date Updated: 6/10/2005 3:22 PM, Document Version: v0.3 Document Summary This document was originally intended as an internal draft to be distributed to developers early on in the development phase of the OpenClinica platform. Up until 2004, we had developed OpenClinica to run on top of an Oracle 10g database, and then started on a version running on the PostgreSQL open source database. To merge these into a common (more manageable) code-base we were looking for that magic abstraction layer. That layer would be independent of a database, but allow us to access to the same data schema and data stored in different relational databases without a plethora of different configuration files or file structures. This first part of a two-part document is going to talk about an open source package, the Apache Commons Digester, which allows easy storing and importing of variables in XML. Using the Digester, we can store all our database-specific SQL outside of the application. In the second half, we will show source code from the new package org.akaza.openclinica.dao.core, which will take most of the plumbing code out of creating Data Access Objects in OpenClinica. Revision History Date Version Description of Document Updates Author 8/26/2004 0.1 Creation of document, describe example code and Apache Commons Digester thickerson 9/16/04 0.2 Addition of SqlInitServlet and description of how to use the digester in OpenClinica thickerson 6/10/05 0.3 Lots of updates since March, including some textual edits thickerson Page 1/7

The Story So Far OpenClinica serves as an interface for a large, protected database; with the need to create intricate data structures and permissions, also comes the need to create an interface to manage data in a seamless and comprehensive fashion. In developing a version of OpenClinica which can exist on top of either an Oracle or a PostgreSQL database (with porting to DB2 and SQL Server planned in forthcoming releases), we felt there was a need to make our J2EE code database-agnostic; in examining the open-source project known as Apache Commons Digester, most of the pain has been taken out of parsing XML and we can put SQL queries there, virtually eliminating the need to create database-specific classes. Installing Apache Commons Digester Most of the examples in this document are based on the article in Java World, Simplify XML File Processing with the Jakarta Commons Digester (see link below). To have this working on your own system, you will have to import the jars from Digester, together with some of the other commons jars, namely commons-beanutils, commons-collections-2.1.1, and commons-logging-api. As of the writing of this document, they should be part of lib.tar which is available on the OpenClinica Portal website. Note that these jars will have to be present in your Eclipse project classpath, your Ant classpath, and your Tomcat 5.0 classpath in order for you to compile, deploy and test. Once you have these resources available, you can create xml files like the following: <?xml version="1.0"?> <queries> <name>userinsertquery</name> <sql>insert INTO USER (USER_ID, USER_NAME, USER_PASS) VALUES (USER_SEQ.NEXTVAL,?,?)</sql> <name>userselectquery</name> <sql>select USER_NAME, USER_EMAIL, PERSON_ID FROM PERSON_USER</sql> <name>userselectquerybyproject</name> <sql>select USER_NAME, USER_EMAIL, PERSON_ID FROM PERSON_USER WHERE DEFAULT_PROJ=?</sql> </queries> And then begin to parse them with code like this: FileInputStream fis = new FileInputStream(".." + File.separator + "webapps" + File.separator + "OpenClinicaDemo" + File.separator + "properties" + File.separator + "user_dao.xml"); Digester digester = new Digester(); Digester.addObjectCreate( queries/query, Query ); digester.addcallmethod( queries/query/name, setqueryname ); digester.addcallmethod( queries/query/sql, setsqlstatement ); digester.parse(fis); Page 2/7

As the Java World article describes, the Digester is tricky, since only the last object popped off the stack remains after it has parsed a file. You can avoid this by pushing the object to the stack to be processed by a second method, as in the example below: public void run() throws IOException, SAXException { Digester digester = new Digester(); digester.push(this); digester.addcallmethod("queries/query","setquery",2); digester.addcallparam("queries/query/name", 0); digester.addcallparam("queries/query/sql",1); digester.parse( user_dao.xml ); //this method gets called by the digester public void setquery(string name, String query) { queries.put(name, query); //hash map that stores the query Digester Usage in OpenClinica Loading the digester in every command servlet would be a little performance hit, so instead of allowing that to happen, our current structure allow for us to have all the digesters set up in a servlet that runs when Tomcat starts up, loading the digesters into a static resource that can then be used later. All the developer will have to do is put the following lines in his or her code: private SqlFactory factory = new SqlFactory(); OpenClinicatypeDAO rdao = new OpenClinicatypeDAO(sm.getDataSource(),factory.getDigester("OpenClinicatype_dao.xml")); The factory should already have the digester contained in memory; an example of the startup servlet and the static resource, SqlFactory, is included in the appendix. By using a static resource in the Tomcat servlet container, we are able to hold the queries in the application s memory, and not have to read the file every time a user logs in or uses the database. Conclusions Use of the Digester helped us by not having to write an entirely new data layer to support PostgreSQL, and it may allow us to use more external files in the future and trim down code. In the Appendix, we show examples of code which has been deployed on OpenClinica, and can be accessed via CVS to review and deploy as desired. In Part 2 of this report, we describe how to abstract out a lot of code from our current system of Data Access Objects and begin to use the queries stored in XML. Resources Erik Swenson s Java World Article: http://www.javaworld.com/javaworld/jw-10-2002/jw-1025-opensourceprofile.html Digester Home Page: http://jakarta.apache.org/commons/digester/ Page 3/7

Appendix 1: Source Code for DaoDigester.java / Created on Aug 25, 2004 / package org.akaza.openclinica.dao.core; import org.apache.commons.digester.; import java.io.; import java.util.hashmap; import org.xml.sax.saxexception; / <P>DaoDigester.java, by Tom Hickerson 8/25/2004 <P>Creates an Apache Commons Digester, which parses SQL queries in XML and then stores them in a hashmap, to be accessed later. Idea is to create one XML file per Data Access Object, so that SQL syntax can be abstracted out of the Java JDBC code.</p> @author thickerson TODO / public class DaoDigester { private HashMap queries = new HashMap(); private FileInputStream fis; public void run() throws IOException, SAXException { Digester digester = new Digester(); digester.push(this); //set up a simple format for grabbing queries through XML / <queries> <name>userdaoinsert</name> <sql>insert INTO USER (USER_ID, USER_NAME, USER_PASS) VALUES (USER_ID_SEQ.NEXTVAL,?,?);</sql> </queries> / digester.addcallmethod("queries/query","setquery",2); digester.addcallparam("queries/query/name", 0); digester.addcallparam("queries/query/sql",1); digester.parse(fis); public void setquery(string name, String query) { queries.put(name, query); public String getquery(string name) { return (String)queries.get(name); public void setinputstream(fileinputstream fis) { this.fis = fis; Page 4/7

Appendix 2: Source code for datainfo,properties: dburl=jdbc:oracle:thin:@192.168.1.100:1521:openclinicadb filepath=c:\\temp\\ database=oracle Appendix 3: Source code for user_dao.xml <?xml version="1.0"?> <queries> <name>userinsertquery</name> <sql>insert INTO USER (USER_ID, USER_NAME, USER_PASS) VALUES (USER_SEQ.NEXTVAL,?,?)</sql> <name>userselectquery</name> <sql>select USER_NAME, USER_EMAIL, PERSON_ID FROM PERSON_USER</sql> <name>userselectquerybyproject</name> <sql>select USER_NAME, USER_EMAIL, PERSON_ID FROM PERSON_USER WHERE DEFAULT_PROJ=?</sql> </queries> Appendix 4: Source code of SqlInitServlet.java, which loads the digesters on Tomcat startup: / Created on Sep 8, 2004 / package org.akaza.openclinica.dao.core; import javax.servlet.http.; import javax.servlet.; import java.io.file; import java.io.fileinputstream; import java.io.ioexception; import java.util.; / <P><b>SqlInitServlet.java</b>, servlet designed to run on startup, gathers all the SQL queries and stores them in memory. Runs the static object SqlFactory, which reads the properties file and then processes all the DAO-based XML files. @author thickerson / public class SqlInitServlet extends HttpServlet { private Properties params = new Properties(); public void init() throws ServletException { try { params.load(new FileInputStream( ".." + File.separator + "webapps" + File.separator + "OpenClinicaDemo" + File.separator + "properties" + File.separator + "datainfo.properties")); Page 5/7

String dbname = params.getproperty("database"); SqlFactory factory = new SqlFactory(); factory.run(dbname);//loads ALL QUERY FILES HERE catch (IOException ioe) { ioe.printstacktrace(); Appendix 5: Partial code from SqlFactory.java: / Created on Sep 8, 2004 / package org.akaza.openclinica.dao.core; import java.io.file; import java.io.fileinputstream; import java.io.ioexception; import java.util.; import org.xml.sax.saxexception; / @author thickerson / public class SqlFactory { private static Hashtable digesters = new Hashtable(); private String dbname = ""; public SqlFactory() { //creator, do nothing here public void adddigester(string name, DaoDigester dig) { digesters.put(name, dig); public DaoDigester getdigester(string name) { return (DaoDigester)digesters.get(name); public void run(string dbname) { //we get the type of the database and run the factory, picking //up all the queries. NOTE that this should only be run //during the init servlets' action, and then it will //remain in static memory. tbh 9/8/04 ArrayList filelist = new ArrayList(); if ("oracle".equals(dbname)) { filelist.add("user_dao.xml"); filelist.add("openclinicatype_dao.xml"); //currently hard-coded, but could be in a file else if ("postgres".equals(dbname)) { //filelist.add("pg_user_dao.xml"); // //add files here as we port over to postgres, tbh //should be either oracle or postgres, but what if the file is gone? for (Iterator fileit = filelist.iterator(); fileit.hasnext(); ) { String filename = (String)fileIt.next(); DaoDigester newdaodigester = new DaoDigester(); try { newdaodigester.setinputstream(new FileInputStream(".." + Page 6/7

try { File.separator + "webapps" + File.separator + "OpenClinicaDemo" + File.separator + "properties" + File.separator + filename)); newdaodigester.run(); digesters.put(filename,newdaodigester); catch (SAXException saxe) { saxe.printstacktrace(); //end try block for xml catch (IOException ioe) { ioe.printstacktrace(); //end try block for files //end for loop Page 7/7