Courses/CS 491ab/Winter 2008/Kanokwan Chansamorn
From CSWiki
Contents |
[edit] Week 1 - January 4, 2008
- Explore about how to use cswiki.
- Read about course description and objective.
- Create cswiki account.
- Create course page.
[edit] Week 2 - January 11, 2008
ZK is an Ajax framework for developing UI for Web application without Javascript. This is a list of its features and benefits.
- Ajax-based Rich User Interface
- Event-driven Model
- XUL-based Components
- ZK User-interface Markup Language
- Server-Centric Processing
- Script in Java and EL Expressions
- Model Dialogs
- Simple Thread Model
- Live Data
- GPL
[edit] Week 3 - January 18, 2008
Last week, I was in Thailand to attend my brother's wedding, so I didn't have much time to find out about AJAX and ZK framework.
The reason I decided to explore about these topics is because I am interested in web programming and I want to do a web application as my project.
First, I will explain a little bit about AJAX.
[edit] AJAX
AJAX (Asynchronous JavaScript And XML) is a technique to develop web application. It makes webpage interact with the user faster without having to reload web page again everytime user click on something. Ajax is based on Javascipt.
For example, when you want to add an item to a shopping cart, you will be navigated to another page. And checkout in another page as well. It's too slow. By AJAX, you can do it all in one page.
[edit] AJAX Demo
You can see the example of AJAX from this website http://demos.openrico.org/
[edit] Sample AJAX Application
- Chat room http://chat.plasticshore.com/index.html
- Shopping cart
- Chess game http://www.jesperolsen.net/PChess/
- ...
[edit] ZK
Instead of developing AJAX code from scratch, we can use AJAX frameworks to help developing AJAX a lot more easier because frameworks do the programming part for us.
ZK is one of the AJAX framework I am interested. It can be used to develop an AJAX application without Javascript.
Before using ZK...
- Install Apache Tomcat
- Download ZK
- Download ZK demo or play around with live demo
- Install ZK by copying the JAR files to the WEB-INF/lib directory of your Web application
- Make ZK works with eclipse (how to)
Example. To display messages when a user clicks buttons.
This is the code without using ZK.
<html>
<head><title>Ajax at work</title>
<script language = "javascript">
var XMLHttpRequestObject = false;
if (window.XMLHttpRequest) {
XMLHttpRequestObject = new XMLHttpRequest();
} else if (window.ActiveXObject) {
XMLHttpRequestObject = new ActiveXObject("Microsoft.XMLHTTP");
}
function getData(dataSource, divID)
{
if(XMLHttpRequestObject){
var obj = document.getElementById(divID);
XMLHttpRequestObject.open("GET", dataSource);
XMLHttpRequestObject.onreadystatechange = function()
{
if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200) {
obj.innerHTML = XMLHttpRequestObject.responseText;
}
}
XMLHttpRequestObject.send(null);
}
}
</script></head>
<body>
<form>
<input type = "button" value = "Display Message" onclick = "getData
('http://localhost:8080/helloworld/data.txt','targetDiv')">
</form>
< div id="targetDiv">< /div>
</body>
</html>
This is the code using ZK.
<window title="Label" border="normal">
<vbox>
<hbox>
<button label="Hi" onClick="label.value = self.label"/>
<button label="How are you?" onClick="label.value = self.label"/>
</hbox>
<label id="label"/>
</vbox>
</window>
You can see that with ZK the code is a lot more easier.
Next week, I will think about the topic of my project and I may explore more about another AJAX framework.
[edit] Week 4 - January 25, 2008
This week, I am working on another AJAX framework and my project idea.
[edit] Prototype Javascript Framework
Prototype is a javascript framework for developing dynamic web application. It provides a lot of functions including AJAX framework.
These are some examples of its functions...
[edit] $() function
This function returns an element that has the id passed as an argument.
element = $("elementID");
It is the same as document.getElementById() function.
element = document.getElementById("elementID");
It can also use to retrieve more than one element.
elements = $("elementID1", "elementID2");
for (i=0; i<elements.length; i++){
alert(elements[i].innerHTML;
}
[edit] $F() funtion
This function returns the value of any field in the form that has the id passed as an argument.
value = $F("textFieldID"); // returns the value in the text field
value = $F("checkboxID"); // returns undefined if it is unchecked
value = $F("textAreaID"); // returns the contents in the text area
[edit] Ajax.Request()
This is one form of AJAX object which is return an XML response from an AJAX call.
var url = "server_script_file";
var myAjax = new Ajax.Request(url, {method: 'get',
parameters: {value1: $F("ID1")},
onSuccess: responseFunction
});
[edit] Ajax.Updater()
This function uses when the server can return information in an HTML format. It will return to a specific element in a HTML file.
var url = "server_script_file";
var myAjax = new Ajax.Updater('elementID', url, {method: 'get',
parameters: {value1: $F("ID1")},
});
[edit] Example
HelloWorld.html
Hello World!!!
AjaxTest.html
<html>
<head>
<title>AJAX Example with Prototype framework</title>
<script type="text/javascript" src="prototype.js"></script>
<script type="text/javascript" language="javascript">
var ajaxReq = new Ajax.Updater('hello', 'HelloWorld.html', {method: 'get'});
</script>
</head>
<body>
< div id="hello">
</div>
</body>
</html>
[edit] Conference Listing Website
Currently, the list of conferences is kept on Conference.
I will modify it by adding some features to make it easier to maintain and easier for the user to use.
[edit] Possible Functions
- Add an event
- Edit an event
- View the conference list
- Past events, Current events, Future events
- Summary by years or months
- Order the conference list by...
- event date
- calls for papers deadline
- location
- area of specialization
- sponsorship
- Search the conference list by...
- event date
- calls for papers deadline
- location
- area of specialization
- sponsorship
- Transform calls for papers into events automatically
- Register to be notified when conferences of interest to them are posted
- Etc.
Most of the main functions will be processed at the server and I will use Javascript (maybe AJAX) to deal with User Interface.
[edit] Possible Development Tools
- Server side developing language
- Java Server Page (JSP)
- Client side developing language
- HTML
- Javascript
- Web Server
- Database
- Other possible tools
- Eclipse
- Some Ajax framework
- PHPMyAdmin
- ...
- Hibernate
- Lucene
Next week, I will focus on the overall idea of this project and probably database design.
[edit] Week 5 - February 1, 2008
The only thing I've done this week is creating a database for conference listing application.
First, I tried to think about information I should keep in the database.
Events
- title
- event start date
- event end date
- location
- submission deadline
- sponsor
- website
- area of specialization (tags)
- ...
- calls for papers (example CFP list)
Users
- name
- email address
- area of interest (tags)
- ...
- address
- phone number
[edit] phpMyAdmin
phpMyAdmin is an open source tool for managing MySQL database over the internet.
The reason I use phpMyAdmin is because I used to use it once, so I can use it without reading many documentations.
[edit] Getting Started
Before you install phpMyAdmin, make sure you have all programs listed below installed correctly.
- Apache Tomcat or any other Web server
- MySQL
- PHP
This is an instruction how to install phpMyAdmin
- Download phpMyAdmin from here
- Extract the file into the Web server's document root folder
- Configure the installation by making some changes in config.php.inc file
<? $cfg['PmaAbsoluteUri'] = 'http://localhost/phpMyAdmin'; ... $cfg['Servers'][$i]['host'] = 'localhost'; // MySQL hostname or IP address ... $cfg['Servers'][$i]['user'] = 'root'; // MySQL user $cfg['Servers'][$i]['password'] = '1234'; // MySQL password ?>
- Type http://localhost/phpMyAdmin in the Web browser
- This is how the page will look like...
[edit] Database
So far, I've created 5 tables in my database
Events table
CREATE TABLE `events` ( `eventId` int(11) NOT NULL auto_increment, `title` varchar(100) NOT NULL, `startDate` date NOT NULL, `endDate` date NOT NULL, `deadline` date NOT NULL, `location` text NOT NULL, `sponsor` text NOT NULL, `website` text NOT NULL, PRIMARY KEY (`eventId`) )
Users table
CREATE TABLE `users` ( `userId` int(11) NOT NULL auto_increment, `firstname` varchar(30) NOT NULL, `lastname` varchar(30) NOT NULL, `email` varchar(30) NOT NULL, `address` text, `phone` int(10) default NULL, PRIMARY KEY (`userId`) )
Tags table
CREATE TABLE `tags` ( `tagId` int(11) NOT NULL auto_increment, `tagName` varchar(30) NOT NULL, PRIMARY KEY (`tagId`) )
Event-Tag table
CREATE TABLE `eventtag` ( `eventId` int(11) NOT NULL, `tagId` int(11) NOT NULL )
User-Tag table
CREATE TABLE `usertag` ( `userId` int(11) NOT NULL, `tagId` int(11) NOT NULL )
[edit] Week 6 - February 8, 2008
This week, I've learned about Hibernate Annotations, which is an object-relational mapping framework that uses annotations instead of XML mapping file.
[edit] Hibernate Annotations
[edit] Requirement
- Java 5.0 or higher version .
- Hibernate Core 3.2.0GA and above.
- Hibernate-Annotations jar file.
In order to create a Hibernate application, I need to create...
- Hibernate configuration file
- Utility file to startup Hibernate
- Mapping file (doesn't need for Hibernate Annotations)
- Java Object Class
- The application that manipulate Java object
[edit] Configurations
We need a configuration file for Hibernate. Here is an example of confuguration file.
hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="connection.url">jdbc:mysql://localhost/testhibernate</property> <property name="connection.username">root</property> <property name="connection.password">9414</property> <property name="connection.pool_size">1</property> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <property name="current_session_context_class">thread</property> <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property> <property name="show_sql">true</property> <property name="hbm2ddl.auto">none</property> <mapping class="event.Event"/> <mapping resource="user.hbm.xml"/> </session-factory> </hibernate-configuration>
We also need the utility file to startup Hibernate.
HibernateUtil.java
package util;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
public class HibernateUtil {
private static final SessionFactory sessionFactory;
static {
try {
// Create the SessionFactory
sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
} catch (Throwable ex) {
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
[edit] Entity Bean
[edit] Hibernate
For the regular Hibernate, you just create a normal Java bean class.
User.java
package event;
public class User {
private int userId = 0 ;
private String firstName = "";
private String lastName = "";
private String email = "";
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
}
You also need a XML mapping file for this object.
user.hbm.xml
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" > <hibernate-mapping> <class name="event.User" table="users" > <id name="userId" column="user_id" > <generator class="increment" /> </id> <property name="firstName" type="java.lang.String" column="first_name" length="20" /> <property name="lastName" type="java.lang.String" column="last_name" length="20" /> <property name="email" type="java.lang.String" column="email" length="40" /> </class> </hibernate-mapping>
This object will map to the following table
CREATE TABLE 'users' (
'user_id' int(11) NOT NULL auto_increment,
'first_name' varchar(20) default NULL,
'last_name' varchar(20) default NULL,
'email' varchar(40) default NULL,
PRIMARY KEY ('user_id')
);
[edit] Hibernate Annotations
For the Hibernate Annotations, you don't need XML mapping files. But you have to add annotaions to the Java object class. Here is an example.
Event.java
package event;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "event")
public class Event {
public Event() {
}
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name = "eventId")
Integer id;
@Column(name = "title")
String title;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
This object will map to the following table.
CREATE TABLE 'event' (
'eventId' int(11) NOT NULL auto_increment,
'title' varchar(255) default NULL,
PRIMARY KEY ('eventId')
) ;
[edit] Example
We need another Java class to manipulate those objects.
Test.java
package event;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import util.HibernateUtil;
public class Test {
public static void main(String[] args) {
// Getting the Session Factory and session
SessionFactory session = HibernateUtil.getSessionFactory();
Session sess = session.getCurrentSession();
// Starting the Transaction
sess.beginTransaction();
// Create Java Objects
Event ev = new Event();
ev.setTitle("Computing and Philosophy");
User u = new User();
u.setFirstName("Kanokwan");
u.setLastName("Chansamorn");
u.setEmail("kwang_girlie@hotmail.com");
// Save
sess.save(ev);
sess.save(u);
// Commit the changes
sess.getTransaction().commit();
System.out.println("Completed");
session.close();
}
}
After run this program, those two objects are inserted into my database successfully.
This is the event table.
This is the user table.
Next week, I will start to implement some functions.
[edit] Week 7 - February 15, 2008
[edit] This week...
the things I've done so far is...
- Listing page (same as old conference listing page)
- list all the events in the database
- list in form of table
- orderd by the date that event was added
- link the event's homepage by clicking the title of the event
- show calls for papers deadline, title, the start and end date, and the location
- Login page
- for admin or whoever has a right to add, edit, and delete events
- after login the listing page will show ...
- the link to add events
- the icon to edit each event
- the icon to delete each event
[edit] Next week...
I will continue implementing some other functions.
[edit] Week 8 - February 22, 2008
[edit] This week...
- Detail
- when click the titile of the page, the user will be redirected to detail page (instead of event's web site)
- show all details of the event that we keep in the database
- if the user is login, show the link to edit
- Add
- insert information for an event
- tile
- cfp deadline
- start date
- end date
- sponsor
- website
- for deadline, start date, and end date, user can choose from the calendar
- insert information for an event
- Edit
- change information for a particular event
- same as add page
- Delete
- can delete only one event at a time
[edit] Next week...
- continue implementing other functions
- delete
- the user can delete more than one event at a time
- add
- one event can have more than one sponsor
- add tags for events
[edit] Week 9 - February 29, 2008
In order to implement search function, I've learned about Apache Lucene.
[edit] Lucene
Apache Lucene is a full-text search engine library written entirely in Java. It is an open source project.
Suppose I keep the information of an events in a text file in /exampleFolder.
I want to do the indexing the information in all these files, so I can perform a search.
First, I need to create a Lucene Index.
[edit] Creating a Lucene Index
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import java.io.File;
import java.io.FileReader;
public class MakeIndex {
public MakeIndex() throws Exception {
IndexWriter indexWriter = new IndexWriter("index", new StandardAnalyzer(), true);
File dir = new File("./exampleFolder");
String[] filename = dir.list();
if (filename == null || filename.length == 0)
return;
for (int i = 0; i < filename.length; i++) {
String path = "./exampleFolder" + "/" + filename[i];
Document document = new Document();
document.add(Field.Text("text", new FileReader(path)));
document.add(Field.UnIndexed("path", path));
indexWriter.addDocument(document);
System.out.println("Write file " + path + " to index.");
}
indexWriter.optimize();
indexWriter.close();
}
public static void main(String[] args) throws Exception {
new MakeIndex();
}
}
- A Document class is a container for fields.
- A Field is a name and a value associated with that name.
- Field.Keyword - The data is stored and indexed but not tokenized
- Field.Text - The data is stored, indexed, and tokenized.
- This should not be used for large amounts of data.
- Field.UnStored - The data is not stored but it is indexed and tokenized.
- Large amounts of data such as the text of the article.
- Field.UnIndexed - The data is stored but not indexed or tokenized.
- This is used with data that you want returned with the results of a search but you won't actually be searching on this data.
Output...
Write file ./exampleFolder/Artificial General Intelligence.txt to index. Write file ./exampleFolder/Artificial Intelligence.txt to index. Write file ./exampleFolder/ETHICOMP.txt to index. Write file ./exampleFolder/WORLDCOMP.txt to index.
[edit] Performing a search
import org.apache.lucene.document.Document;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Searcher;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.analysis.Analyzer;
public class SearchIndex {
public static void main(String[] args) throws Exception {
Searcher searcher = new IndexSearcher("index");
Analyzer analyzer = new StandardAnalyzer();
Query query = QueryParser.parse("Artificial Intelligence", "text", analyzer);
System.out.println("Searching for: " + query.toString("text"));
Hits hits = searcher.search(query);
System.out.println("Number of matching documents = " + hits.length());
for (int i = 0; i < hits.length(); i++) {
Document doc = hits.doc(i);
System.out.println("File: " + doc.get("path"));
}
searcher.close();
}
}
Output...
Searching for: artificial intelligence Number of matching documents = 2 File: ./exampleFolder/Artificial General Intelligence.txt File: ./exampleFolder/Artificial Intelligence.txt
[edit] Lucene & MySQL
This is an example how to use Lucene with the data in the database.
Suppose I have these events store in my database.
[edit] Creating a Lucene index (DB)
public class MakeIndexDB {
public MakeIndexDB() throws Exception {
Connection c = null;
try {
String userName = "root";
String password = "9414";
String url = "jdbc:mysql://localhost/lucenetest";
Class.forName ("com.mysql.jdbc.Driver").newInstance ();
c = DriverManager.getConnection (url, userName, password);
String sql = "select * from events";
Statement stmt = c.createStatement();
ResultSet rs = stmt.executeQuery(sql);
IndexWriter indexWriter = new IndexWriter("index2", new StandardAnalyzer(), true);
while(rs.next())
{
Document document = new Document();
String title = rs.getString("title");
document.add(Field.Text("title", title));
document.add(Field.Keyword("startDate", rs.getString("startDate")));
document.add(Field.Keyword("endDate", rs.getString("endDate")));
document.add(Field.Keyword("deadline", rs.getString("deadline")));
document.add(Field.Text("location", rs.getString("location")));
document.add(Field.Text("sponsor", rs.getString("sponsor")));
indexWriter.addDocument(document);
System.out.println("Write file " + title + " to index.");
}
indexWriter.optimize();
indexWriter.close();
}
catch (Exception e){
System.err.println ("Cannot connect to database server");
}
finally{
if (c != null){
try{
c.close ();
}
catch (Exception e) { /* ignore close errors */ }
}
}
}
public static void main(String[] args) throws Exception {
new MakeIndexDB();
}
}
Output...
Write Artificial General Intelligence to index. Write Artificial Intelligence to index. Write WORLDCOMP to index. Write Logic, Language, Information and Computation to index. Write ETHICOMP to index. Write Automated Reasoning to index. Write MORS Symposium to index.
[edit] Performing a Search (DB)
public class SearchIndexDB {
public static void main(String[] args) throws Exception {
Searcher searcher = new IndexSearcher("index2");
Analyzer analyzer = new StandardAnalyzer();
Query query = QueryParser.parse("Artificial Intelligence", "title", analyzer);
System.out.println("Searching for: " + query.toString("title"));
Hits hits = searcher.search(query);
System.out.println("Number of matching documents = " + hits.length());
for (int i = 0; i < hits.length(); i++) {
Document doc = hits.doc(i);
System.out.println("Event: " + doc.get("title"));
}
searcher.close();
}
}
Output...
Searching for: artificial intelligence Number of matching documents = 2 Event: Artificial Intelligence Event: Artificial General Intelligence
[edit] Problems
I keep track of problems I havent solved.
- delete multiple events at once.
- an event can have more than one sponsor.
- special case...
- abstract deadline
- co-event
- ...
- personal preference
Next week, I will implement search function using Lucene in JSP pages.
[edit] Week 10 - March 7, 2008
[edit] This week...
This week I've been working on a final report. I also implemented search function using Lucene is my JSP page.
I added this field to the index and perform a search on this field. This field consists of every information for an event.
String fullText = title + " " + rs.getString("startDate") + " "+ rs.getString("endDate")
+ " "+ rs.getString("deadline") + " "+ rs.getString("location") + " "+ rs.getString("sponsor")
+ " "+ rs.getString("website");
document.add(Field.Text("text", fullText));
I also looked into the Lucene query syntax.
- you can either specify a field, or use the default field
title: "Artificial Intelligence" location: "Las Vegas"
- single and multiple character wildcard searches within single terms
- a single character wildcard search
te?t
- a multiple character wildcard search
te*
- boolean operators: AND, OR, NOT
- OR: The OR operator is the default operator. It matches document if either of the terms exist.
Artificial Intelligence Artificial OR Intelligence
- AND: The AND operator matches documents where both terms exist
Artificial AND Intelligence
- NOT: The NOT operator matches documents that doesn't contain the term after NOT
Artificial NOT Intelligence
- The NOT operator CANNOT be used with just one term.
NOT Artificial // returns no results
Reference: http://lucene.apache.org/java/2_3_1/queryparsersyntax.html
[edit] Next week...
I will revise my final report and continue working on the project.
[edit] Final Report
[edit] Brief project description
A web application that keeps track of conferences. This system will keep information of each event such as calls-for-papers deadline, sponsor, and topic, and allow users to view conferences in many ways such as users can sort the conferences by tile or event date. The area of specification (tags) will be added to each event in order to perform a search.
[edit] Anticipated users
The users will be the Conferences website users (for example, faculty and student) or whoever wants to know about conferences of thier interest.
[edit] Main conceptual objects
There are two main objects for this application.
- Event
- Basicly, I will keep these information
- Title
- Event date
- Calls for papers deadline
- Location
- Sponsors
- Website
- Areas of specification (tags)
- In addition, some events have special information
- Some events are co-located with others
- Some events have an abstract deadline
- Some events have workshops and tutorials
- User
- Areas of interest (tags)
- Username and password
[edit] Primary conceptual operations
- Anybody can add and edit a conference
- Restore the older versions of an entry in case someone make a mistake
- Tranform a calls-for-papers into an event entry
- User can register to be notified when conferences of thier interest are added
- User can sort and view conference listing in different way (table or calendar)
- User can search using any information
- User can set their preference (to show only the event that they are interested)
[edit] Why I am interested in this project
After I took CS320 last quarter, I have been interested in web programming and want to learn more about it, so I've decided to do a web application as my project in this class. At first, I still had no idea which application I should do, so I looked into the professor's project ideas in a CSWiki page. I think it is good to have a chance to develop a website that can be useful for the faculty or other students, so I picked this project, the conference listing apllication.
[edit] Status
I've created a very simple version of the project consist of these opeartions.
- add/edit/delete an event
- search (using Lucene)




