星期四, 10月 11, 2007

Wicket lab5 備忘記

Wicket lab 5 為實作 簡單問答FAQ系統,
這裡使用了 AjaxLink 及 AjaxSubmitButton(AjaxButton) 元件,
實作了 ModelWindow 及 Panel, 並製作可重用的元件,
Wicket 提供了 WICKET AJAX DEBUG WINDOW, 這使用 ajax 的 debug 更方便.

執行畫面如下圖所示:





開始備忘記:
[1] 實作 lab 5

[1] 實作 lab 5:
<!------------- web.xml ----------------->
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>CM269</display-name>

<filter>
<filter-name>WicketLab1</filter-name>
<filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
<init-param>
<param-name>applicationClassName</param-name>
<param-value>cm269.lab1.MyApp</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>WicketLab1</filter-name>
<url-pattern>/lab1/*</url-pattern>
</filter-mapping>

<filter>
<filter-name>WicketLab2</filter-name>
<filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
<init-param>
<param-name>applicationClassName</param-name>
<param-value>cm269.lab2.MyApp</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>WicketLab2</filter-name>
<url-pattern>/lab2/*</url-pattern>
</filter-mapping>

<filter>
<filter-name>WicketLab3</filter-name>
<filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
<init-param>
<param-name>applicationClassName</param-name>
<param-value>cm269.lab3.MyApp</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>WicketLab3</filter-name>
<url-pattern>/lab3/*</url-pattern>
</filter-mapping>

<filter>
<filter-name>WicketLab4</filter-name>
<filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
<init-param>
<param-name>applicationClassName</param-name>
<param-value>cm269.lab4.MyApp</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>WicketLab4</filter-name>
<url-pattern>/lab4/*</url-pattern>
</filter-mapping>

<filter>
<filter-name>WicketLab5</filter-name>
<filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
<init-param>
<param-name>applicationClassName</param-name>
<param-value>cm269.lab5.MyApp</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>WicketLab5</filter-name>
<url-pattern>/lab5/*</url-pattern>
</filter-mapping>

</web-app>
<!------------- web.xml ----------------->

/************** MyApp.java **************/
package cm269.lab5;

import org.apache.wicket.protocol.http.WebApplication;

public class MyApp extends WebApplication {

public Class getHomePage() {
return ListFAQ.class;
}

}
/************** MyApp.java **************/

/************** ListFAQ.java **************/
package cm269.lab5;

import java.util.ArrayList;
import java.util.List;

import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;

public class ListFAQ extends WebPage {
private static List questions;
private static List answers;

public ListFAQ() {
questions = new ArrayList();
questions.add("How to run Eclipse?");
questions.add("How to run NetBeans?");
questions.add("How to run Tomcat?");
answers = new ArrayList();
answers.add("Double click its icon.");
answers.add("Type netbeans at the command line.");
answers.add("Run startup.bat.");
ListView eachQuestion = new ListView("eachQuestion", questions) {
protected void populateItem(ListItem item) {
int idx = item.getIndex();
item.add(new Question("question", (String) questions.get(idx),
(String) answers.get(idx)));
}
};
add(eachQuestion);
}
}

/************** ListFAQ.java **************/

<!------------- ListFAQ.html --------------->
<html>
<body>
<div wicket:id="eachQuestion">
<div wicket:id="question"/>
</div>
</body>
</html>
<!------------- ListFAQ.html --------------->

/************** Question.java **************/
package cm269.lab5;

import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.AbstractReadOnlyModel;

public class Question extends Panel {

private Label answer;
private Rating r = new Rating();
private Label question;
private ModalWindow modal;
private ModalWindow modifyAnswerModal;
private NewAnswer newAnswer = new NewAnswer();

public Question(String id, final String questionText,
final String answerText) {
super(id);
AjaxLink link = new AjaxLink("link") {
public void onClick(AjaxRequestTarget target) {
answer.setVisible(!answer.isVisible());
target.addComponent(answer);
}
};
add(link);
question = new Label("question", new AbstractReadOnlyModel() {
public Object getObject() {
return questionText + " (" + r.getAverageRating() + ")";
}
});
question.setOutputMarkupId(true);
link.add(question);
answer = new Label("answer", new AbstractReadOnlyModel() {
public Object getObject() {
if(newAnswer.getNewAnswer() == null){
return answerText;
}
return newAnswer.getNewAnswer();
}
});
answer.setVisible(false);
answer.setOutputMarkupPlaceholderTag(true);
add(answer);
AjaxLink rate = new AjaxLink("rate") {
public void onClick(AjaxRequestTarget target) {
modal.show(target);
}
};
add(rate);
modal = new ModalWindow("modal");
modal.setInitialWidth(200);
modal.setInitialHeight(100);
add(modal);

GetRating getRating = new GetRating(modal.getContentId(), r, question, modal);
modal.setContent(getRating);

AjaxLink modifyAnswer = new AjaxLink("modifyAnswer") {
public void onClick(AjaxRequestTarget target) {
modifyAnswerModal.show(target);
}
};
add(modifyAnswer);
modifyAnswerModal = new ModalWindow("modifyAnswerModal");
modifyAnswerModal.setInitialWidth(400);
modifyAnswerModal.setInitialHeight(100);
add(modifyAnswerModal);

GetAnswer getAnswer = new GetAnswer(modifyAnswerModal.getContentId(), newAnswer, answer, modifyAnswerModal);
modifyAnswerModal.setContent(getAnswer);
}
}

}
/************** Question.java **************/

<!------------- Question.html ------------->
<html>
<wicket:panel>
<div>
<a wicket:id="link">
<span wicket:id="question">Q: abc</span>
</a>
<a wicket:id="rate">Rate</a>

<a wicket:id="modifyAnswer">Modify Answer</a>
<div wicket:id="modal"/>
</div>
<div wicket:id="answer">A: xyz</div>
<div wicket:id="modifyAnswerModal"/>
</wicket:panel>
</html>
<!------------- Question.html ------------->

/************** GetRating.java **************/
package cm269.lab5;

import org.apache.wicket.Component;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.form.AjaxSubmitButton;
import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.CompoundPropertyModel;

public class GetRating extends Panel {
private int rating = 5;

public GetRating(String id, final Rating r , final Component toBeRegreshed, final ModalWindow modal) {
super(id);
Form f = new Form("f", new CompoundPropertyModel(this));
add(f);
f.add(new TextField("rating", Integer.class));
f.add(new AjaxSubmitButton("rate", f) {
protected void onSubmit(AjaxRequestTarget target, Form form) {
r.add(rating);
target.addComponent(toBeRegreshed);
modal.close(target);
}
});
}
}
/************** GetRating.java **************/

<!------------- GetRating.html ------------->
<html>
<wicket:panel>
<form wicket:id="f" style="float:right">
<input type="text" wicket:id="rating" size="2">
<input type="submit" wicket:id="rate" value="Rate">
</form>
</wicket:panel>
</html>
<!------------- GetRating.html ------------->

/************** GetAnswer.java **************/
package cm269.lab5;

import org.apache.wicket.Component;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.form.AjaxSubmitButton;
import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.CompoundPropertyModel;

public class GetAnswer extends Panel {
private String newAnswer;

public GetAnswer(String id, final NewAnswer n, final Component toBeRegreshed, final ModalWindow modal) {
super(id);
Form f = new Form("f", new CompoundPropertyModel(this));
add(f);
f.add(new TextField("newAnswer", String.class));
f.add(new AjaxSubmitButton("modify", f) {
protected void onSubmit(AjaxRequestTarget target, Form form) {
n.setNewAnswer(getNewAnswer());
target.addComponent(toBeRegreshed);
modal.close(target);
}
});
}

public String getNewAnswer() {
return newAnswer;
}

public void setNewAnswer(String newAnswer) {
this.newAnswer = newAnswer;
}
}
/************** GetAnswer.java **************/

<!------------- GetAnswer.html ------------->
<html>
<wicket:panel>
<form wicket:id="f" style="float:left">
<table border="0" align="left">
<tr>
<td align="left">
New Answer:<input type="text" wicket:id="newAnswer" size="30">
</td>
</tr>
<tr>
<td align="left">
<input type="submit" wicket:id="modify" value="Modify">
</td>
</tr>
</table>
</form>
</wicket:panel>
</html>
<!------------- GetAnswer.html ------------->

/************** Rating.java **************/
package cm269.lab5;

import java.io.Serializable;

public class Rating implements Serializable {
private int totalRating = 0;
private int noRatings = 0;

public int getAverageRating() {
return noRatings == 0 ? 0 : totalRating / noRatings;
}

public void add(int rating) {
totalRating += rating;
noRatings++;
}
}
/************** Rating.java **************/

/************** NewAnswer.java **************/
package cm269.lab5;

import java.io.Serializable;

public class NewAnswer implements Serializable{
private String newAnswer;

public String getNewAnswer() {
return newAnswer;
}

public void setNewAnswer(String newAnswer) {
this.newAnswer = newAnswer;
}
}
/************** NewAnswer.java **************/

項目結構如下圖所示:


參考資料:
http://wicket.apache.org/

星期二, 10月 09, 2007

Wicket lab4 備忘記

Wicket lab 4 為實作 電子購物系統,
與 Wicket lab 3 一樣, 使用靜態的 map 模擬資料庫存取動作,
在 WebApplication 的實作中重寫了 newSession 及 init,
並實作 WebSession, 將登入資訊及選擇的購物車貨品暫存至 session 裡,
這裡使用了新的元件 PasswordTextField 隱藏輸入的密碼,


貨品列表以 ListView 及 ListItem 顯示於頁面,
Link 的 onClick 動作作為轉頁功能, 而 PageLink 則直接轉至頁面,
並以 Button 的 onSubmit 動作將選擇的貨品加入購物車中,
最後在 WebPage 裡呼叫 getSession().invalidate() 作為登出動作.


執行畫面如下圖所示:


開始備忘記:
[1] 實作 lab 4


[1] 實作 lab 4:
<!------------- web.xml ----------------->
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>CM269</display-name>


<filter>
<filter-name>WicketLab1</filter-name>
<filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
<init-param>
<param-name>applicationClassName</param-name>
<param-value>cm269.lab1.MyApp</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>WicketLab1</filter-name>
<url-pattern>/lab1/*</url-pattern>
</filter-mapping>

<filter>
<filter-name>WicketLab2</filter-name>
<filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
<init-param>
<param-name>applicationClassName</param-name>
<param-value>cm269.lab2.MyApp</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>WicketLab2</filter-name>
<url-pattern>/lab2/*</url-pattern>
</filter-mapping>

<filter>
<filter-name>WicketLab3</filter-name>
<filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
<init-param>
<param-name>applicationClassName</param-name>
<param-value>cm269.lab3.MyApp</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>WicketLab3</filter-name>
<url-pattern>/lab3/*</url-pattern>
</filter-mapping>

<filter>
<filter-name>WicketLab4</filter-name>
<filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
<init-param>
<param-name>applicationClassName</param-name>
<param-value>cm269.lab4.MyApp</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>WicketLab4</filter-name>
<url-pattern>/lab4/*</url-pattern>
</filter-mapping>


<filter>
<filter-name>WicketLab5</filter-name>
<filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
<init-param>
<param-name>applicationClassName</param-name>
<param-value>cm269.lab5.MyApp</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>WicketLab5</filter-name>
<url-pattern>/lab5/*</url-pattern>
</filter-mapping>


</web-app>
<!------------- web.xml ----------------->


/************** MyApp.java **************/
package cm269.lab4;


import org.apache.wicket.Request;
import org.apache.wicket.Response;
import org.apache.wicket.Session;
import org.apache.wicket.authorization.strategies.page.SimplePageAuthorizationStrategy;
import org.apache.wicket.protocol.http.WebApplication;


public class MyApp extends WebApplication {
public Class getHomePage() {
return ShowCatalog.class;
}


public Session newSession(Request request, Response response) {
return new MySession(this, request);
}


protected void init() {
getSecuritySettings().setAuthorizationStrategy(
new SimplePageAuthorizationStrategy(AuthenticatedPage.class,
Login.class) {
protected boolean isAuthorized() {
return ((MySession) Session.get()).getLoggedInUser() != null;
}
});
}
}
/************** MyApp.java **************/


/************** ShowCatalog.java **************/
package cm269.lab4;


import java.util.List;


import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.link.PageLink;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.model.CompoundPropertyModel;


public class ShowCatalog extends WebPage {
public ShowCatalog() {
List products = Catalog.globalCatalog.getProducts();
ListView eachProduct = new ListView("eachProduct", products) {
protected void populateItem(ListItem item) {
final Product p = (Product) item.getModelObject();
item.setModel(new CompoundPropertyModel(p));
item.add(new Label("id"));
Link detailsLink = new Link("detailsLink") {
public void onClick() {
ProductDetails details = new ProductDetails(p);
setResponsePage(details);
}
};
detailsLink.add(new Label("name"));
item.add(detailsLink);
item.add(new Label("price"));
}
};
add(eachProduct);
add(new PageLink("loginLink", Login.class));
add(new Link("logoutLink"){
public void onClick() {
getSession().invalidate();
setResponsePage(ShowCatalog.class);
}
});
}
}
/************** ShowCatalog.java **************/


<!------------- ShowCatalog.html --------------->
<html>
<h1>Product listing</h1>
<table border="1">
<tr wicket:id="eachProduct">
<td wicket:id="id">p01</td>
<td><a wicket:id="detailsLink"><span wicket:id="name">Pencil</span></a></td>
<td wicket:id="price">1.20</td>
</tr>
</table>
<p><a wicket:id="loginLink">Login</a>
<a wicket:id="logoutLink">Logout</a>
</html>
<!------------- ShowCatalog.html --------------->


/************** ProductDetails.java **************/
package cm269.lab4;


import java.util.List;


import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.Form;


public class ProductDetails extends WebPage {
public ProductDetails(final Product p) {
add(new Label("title", p.getName()));
add(new Label("heading", p.getName()));
add(new Label("desc", p.getDesc()));
Form form = new Form("productActionForm");
add(form);
form.add(new Button("addToCart") {
public void onSubmit() {
List cart = ((MySession) getSession()).getCart();
cart.add(p.getId());
setResponsePage(ShowCart.class);
}
});
form.add(new Button("continueShopping") {
public void onSubmit() {
setResponsePage(ShowCatalog.class);
}
});
}
}
/************** ProductDetails.java **************/


<!------------- ProductDetails.html ------------->
<html>
<head>
<title wicket:id="title">Pencil</title>
</head>
<body>
<h1 wicket:id="heading">Pencil</h1>
<span wicket:id="desc">xxx</span>
<form wicket:id="productActionForm">
<input type="submit"
value="Add to cart" wicket:id="addToCart" />
<input type="submit"
value="Continue shopping" wicket:id="continueShopping" />
</form>
</body>
</html>
<!------------- ProductDetails.html ------------->


/************** ShowCart.java **************/
package cm269.lab4;


import java.util.List;


import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.model.CompoundPropertyModel;


public class ShowCart extends WebPage {
public ShowCart() {
List cart = ((MySession) getSession()).getCart();
ListView eachProduct = new ListView("eachProduct", cart) {
protected void populateItem(ListItem item) {
String id = (String) item.getModelObject();
Product p = loadProduct(id);
item.setModel(new CompoundPropertyModel(p));
item.add(new Label("id"));
item.add(new Label("name"));
item.add(new Label("price"));
}
};
add(eachProduct);
Form form = new Form("cartActionForm");
add(form);
form.add(new Button("checkout") {
public void onSubmit() {
setResponsePage(Checkout.class);
}
});
form.add(new Button("continueShopping") {
public void onSubmit() {
setResponsePage(ShowCatalog.class);
}
});
}


private Product loadProduct(String id) {
return Catalog.globalCatalog.lookup(id);
}
}
/************** ShowCart.java **************/


<!------------- ShowCart.html ------------->
<html>
<h1>Shopping cart</h1>
<table border="1">
<tr wicket:id="eachProduct">
<td wicket:id="id">p01</td>
<td wicket:id="name">Pencil</td>
<td wicket:id="price">1.20</td>
</tr>
</table>
<form wicket:id="cartActionForm"><input type="submit"
value="Checkout" wicket:id="checkout" /> <input type="submit"
value="Continue shopping" wicket:id="continueShopping" /></form>
</html>
<!------------- ShowCart.html ------------->


/************** Checkout.java **************/
package cm269.lab4;


import java.util.Iterator;


import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.Form;


public class Checkout extends AuthenticatedPage {
public Checkout() {
MySession session = ((MySession) getSession());
double total = 0;
for (Iterator iter = session.getCart().iterator(); iter.hasNext();) {
String productId = (String) iter.next();
total += Catalog.globalCatalog.lookup(productId).getPrice();
}
User loggedInUser = session.getLoggedInUser();


add(new Label("total", Double.toString(total)));
add(new Label("creditCardNo", loggedInUser.getCreditCardNo()));
Form form = new Form("confirmForm");
add(form);
form.add(new Button("confirm") {
public void onSubmit() {
setResponsePage(ThankYou.class);
};
});
form.add(new Button("continueShopping") {
public void onSubmit() {
setResponsePage(ShowCatalog.class);
};
});
}
}
/************** Checkout.java **************/


<!------------- Checkout.html ------------->
<html>
<h1>Confirm your order</h1>
You're going to pay
<span wicket:id="total">100</span>
with your credit card
<span wicket:id="creditCardNo">xxxx yyyy zzzz</span>
.
<p>
<form wicket:id="confirmForm"><input type="submit"
value="Confirm" wicket:id="confirm" /> <input type="submit"
value="Continue shopping" wicket:id="continueShopping" /></form>
</html>
<!------------- Checkout.html ------------->


/************** Login.java **************/
package cm269.lab4;


import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.PasswordTextField;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.model.CompoundPropertyModel;


public class Login extends WebPage {
private String email;
private String password;


public Login() {
add(new FeedbackPanel("errorMsg"));
Form form = new Form("loginForm", new CompoundPropertyModel(this)) {
protected void onSubmit() {
try {
User user = Users.getKnownUsers().getUser(email, password);
((MySession)getSession()).setLoggedInUser(user);
if(!continueToOriginalDestination()){
setResponsePage(ShowCatalog.class);
}
setResponsePage(ShowCatalog.class);
} catch (AuthenticationException e) {
error("Login failed. Try again.");
}
}
};
add(form);
form.add(new TextField("email"));
form.add(new PasswordTextField("password"));
}


public String getEmail() {
return email;
}


public void setEmail(String email) {
this.email = email;
}


public String getPassword() {
return password;
}


public void setPassword(String password) {
this.password = password;
}
}
/************** Login.java **************/


<!------------- Login.html ------------->
<html>
<h1>Login</h1>
<span wicket:id="errorMsg" />
<form wicket:id="loginForm">
<table border="0">
<tr>
<td>Email:</td>
<td><input type="text" wicket:id="email"></td>
</tr>
<tr>
<td>Password:</td>
<td><input type="password" wicket:id="password"></td>
</tr>
<tr>
<td></td>
<td><input type="submit" value="Login"></td>
</tr>
</table>
</form>
</html>
<!------------- Login.html ------------->


/************** ThankYou.java **************/
package cm269.lab4;


import org.apache.wicket.markup.html.WebPage;


public class ThankYou extends WebPage {
}
/************** ThankYou.java **************/


<!------------- ThankYou.html ------------->
<html>
Thank you for your order!
</html>
<!------------- ThankYou.html ------------->


/*********** Catalog.java *********/
package cm269.lab4;


import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;


public class Catalog {
private List products;


public Catalog() {
products = new ArrayList();
products.add(new Product("p01", "Pencil", "a", 1.20));
products.add(new Product("p02", "Eraser", "b", 2.00));
products.add(new Product("p03", "Ball pen", "c", 3.50));
}


public List getProducts() {
return products;
}


public Product lookup(String id) {
for (Iterator iter = products.iterator(); iter.hasNext();) {
Product p = (Product) iter.next();
if (p.getId().equals(id)) {
return p;
}
}
return null;
}


public static Catalog globalCatalog = new Catalog();
}
/*********** Catalog.java *********/


/*********** AuthenticationException.java *********/
package cm269.lab4;


public class AuthenticationException extends RuntimeException {
}
/*********** AuthenticationException.java *********/


/*********** AuthenticatedPage.java *********/
package cm269.lab4;


import org.apache.wicket.markup.html.WebPage;


public class AuthenticatedPage extends WebPage {
}
/*********** AuthenticatedPage.java *********/


/************** Product.java **************/
package cm269.lab4;


import java.io.Serializable;


public class Product implements Serializable {
private String id;
private String name;
private String desc;
private double price;


public Product(String id, String name, String desc, double price) {
this.id = id;
this.name = name;
this.desc = desc;
this.price = price;
}


public String getId() {
return id;
}


public void setId(String id) {
this.id = id;
}


public String getName() {
return name;
}


public void setName(String name) {
this.name = name;
}


public String getDesc() {
return desc;
}


public void setDesc(String desc) {
this.desc = desc;
}


public double getPrice() {
return price;
}


public void setPrice(double price) {
this.price = price;
}
}
/************** Product.java **************/


/************** User.java **************/
package cm269.lab4;


import java.io.Serializable;


public class User implements Serializable {
private String id;
private String email;
private String password;
private String creditCardNo;


public User(String id, String email, String password, String creditCardNo) {
this.id = id;
this.email = email;
this.password = password;
this.creditCardNo = creditCardNo;
}


public boolean authenticate(String email, String password) {
return this.email.equals(email) && this.password.equals(password);
}


public String getCreditCardNo() {
return creditCardNo;
}


public String getId() {
return id;
}


public void setId(String id) {
this.id = id;
}


public String getEmail() {
return email;
}


public void setEmail(String email) {
this.email = email;
}


public String getPassword() {
return password;
}


public void setPassword(String password) {
this.password = password;
}


public void setCreditCardNo(String creditCardNo) {
this.creditCardNo = creditCardNo;
}
}
/************** User.java **************/


/************** Users.java **************/
package cm269.lab4;


import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;


public class Users {
private List users;
private static Users knownUsers;


public Users() {
users = new ArrayList();
}


public void add(User user) {
users.add(user);
}


public User getUser(String email, String password) {
for (Iterator iter = users.iterator(); iter.hasNext();) {
User user = (User) iter.next();
if (user.authenticate(email, password)) {
return user;
}
}
throw new AuthenticationException();
}


public static Users getKnownUsers() {
if (knownUsers == null) {
knownUsers = new Users();
knownUsers.add(new User("u001", "paul@yahoo.com", "aaa",
"1111 2222 3333 4444"));
knownUsers.add(new User("u002", "john@hotmail.com", "bbb",
"2222 3333 4444 5555"));
knownUsers.add(new User("u003", "mary@gmail.com", "aaa",
"3333 4444 5555 6666"));
}
return knownUsers;
}
}
/************** Users.java **************/


/************** MySession.java **************/
package cm269.lab4;


import java.util.ArrayList;
import java.util.List;


import org.apache.wicket.Application;
import org.apache.wicket.Request;
import org.apache.wicket.protocol.http.WebSession;


public class MySession extends WebSession {
private List cart;
private User loggedInUser;


public MySession(Application application, Request request) {
super(application, request);
cart = new ArrayList();
}


public List getCart() {
return cart;
}


public User getLoggedInUser() {
return loggedInUser;
}


public void setLoggedInUser(User loggedInUser) {
this.loggedInUser = loggedInUser;
}
}
/************** MySession.java **************/


項目結構如下圖所示:


參考資料:
http://wicket.apache.org/


星期一, 10月 08, 2007

Wicket lab3 備忘記

Wicket lab3 主要是實作 簡單的結帳系統,
使用靜態的 map 模擬資料庫存取動作,

這裡並沒有使用 PropertyModel,
而使用更簡單的 CompoundPropertyModel(自動對應 form 及 pojo 的 property),
並在 TextField 裡使用 built-in validators,
以及使用 properties file 自定 wicket 的錯誤訊息,

在 validation 方便, 實作了 AbstractValidator 及 AbstractFormValidator 介面.
實作 AbstractValidator 主要對單個 form property 作自定 validation.
而 AbstractFormValidator 則可對多個 form property 作自定 validation.

利用 WebMarkupContainer 實作動態 css 錯誤顯示.

開始備忘記:

[1] Requirement in lab3
[2] 實作 lab3

[1] Requirement in lab3:
– Lab3 can be accessed by http://127.0.0.1:8080/CM269/lab3/
– There are 2 build-in Tables in the system for lookup

Customer Table
Customer ID Deposit %
c1 10
c2 15
c3 20

Item Table
Item Code Price
a1 100
a2 120
a3 150

– The first page of Lab3 is an Html Input Form
(The words in blue color indicates user input fields)
Order Input Form
Customer Id c1
Item Code a1
Quantity 10
Deposit 150
『Submit』
– On validation of the Input Values
1. Customer Id : must input, must exist in the Customer Table.
2. Item Code : must input, must exist in the Item Table.
3. Quantity : must >0 and <= 100
4. Deposit : must > 0
5. Whole Form Validation : deposit >= (quantity * price) * depositPercent / 100
(price is the got from Item Table, depositPrecent is got from Customer Table)
– If the inputs can pass all the validation rules, a Simple result page is shown.
(1000, 150, 850 calculated from the Demo Inputs)
Your orde is accepted, thank you !
Total Amount = 1000, Deposit = 150, Remaining Balance = 850.

[2] 實作 lab3:

<!----------- web.xml --------------------->

<?xml version="1.0" encoding="UTF-8"?>

<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

<display-name>CM269</display-name>



<filter>

<filter-name>WicketLab1</filter-name>

<filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>

<init-param>

<param-name>applicationClassName</param-name>

<param-value>cm269.lab1.MyApp</param-value>

</init-param>

</filter>

<filter-mapping>

<filter-name>WicketLab1</filter-name>

<url-pattern>/lab1/*</url-pattern>

</filter-mapping>



<filter>

<filter-name>WicketLab2</filter-name>

<filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>

<init-param>

<param-name>applicationClassName</param-name>

<param-value>cm269.lab2.MyApp</param-value>

</init-param>

</filter>

<filter-mapping>

<filter-name>WicketLab2</filter-name>

<url-pattern>/lab2/*</url-pattern>

</filter-mapping>



<filter>

<filter-name>WicketLab3</filter-name>

<filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>

<init-param>

<param-name>applicationClassName</param-name>

<param-value>cm269.lab3.MyApp</param-value>

</init-param>

</filter>

<filter-mapping>

<filter-name>WicketLab3</filter-name>

<url-pattern>/lab3/*</url-pattern>

</filter-mapping>


</web-app>

<!----------- web.xml --------------------->



/************** MyApp.java *************/

package cm269.lab3;



import org.apache.wicket.protocol.http.WebApplication;



public class MyApp extends WebApplication {



public Class getHomePage() {

return Lab3.class;

}



}

/************** MyApp.java *************/



/************** Lab3.java *************/

package cm269.lab3;



import org.apache.wicket.markup.html.WebPage;

import org.apache.wicket.markup.html.form.Form;

import org.apache.wicket.markup.html.form.TextField;

import org.apache.wicket.markup.html.panel.FeedbackPanel;

import org.apache.wicket.model.CompoundPropertyModel;

import org.apache.wicket.validation.validator.NumberValidator;



public class Lab3 extends WebPage {

private Order order = new Order("","",0,0);



public Lab3() {

add(new FeedbackPanel("feedback"));

Form form = new Form("form", new CompoundPropertyModel(order)){

protected void onSubmit() {

setResponsePage(new Lab3Result(order.getTotalAmount(), order.getDeposit()));

}

};



TextField customerId = new TextField("customerId");

customerId.setRequired(true);

customerId.add(new CustomerIdValidator());

form.add(customerId);

FeedbackLabel customerIdLabel = new FeedbackLabel("customerIdLabel",customerId);

form.add(customerIdLabel);



TextField itemCode = new TextField("itemCode");

itemCode.setRequired(true);

itemCode.add(new ItemCodeValidator());

form.add(itemCode);

FeedbackLabel itemCodeLabel = new FeedbackLabel("itemCodeLabel",itemCode);

form.add(itemCodeLabel);



TextField quantity = new TextField("quantity",Integer.class);

quantity.setRequired(true);

quantity.add(NumberValidator.minimum(1));

quantity.add(NumberValidator.maximum(100));

form.add(quantity);

FeedbackLabel quantityLabel = new FeedbackLabel("quantityLabel",quantity);

form.add(quantityLabel);



TextField deposit = new TextField("deposit",Integer.class);

deposit.setRequired(true);

deposit.add(NumberValidator.minimum(1));

form.add(deposit);

FeedbackLabel depositLabel = new FeedbackLabel("depositLabel",deposit);

form.add(depositLabel);



form.add(new LightValidator(customerId,itemCode,quantity,deposit));



add(form);

}



}

/************** Lab3.java *************/



<!----------- Lab3.html --------------------->

<html>

<head>

<title>Lab3</title>

<style type="text/css">

li.feedbackPanelERROR {

color: red;

font-weight: bold;

}

td.invalidField {

color: red;

font-weight: bold;

}

</style>

</head>

<body>



<span wicket:id="feedback" />



<form wicket:id="form">

<table border>

<tr><th colspan="2">Order Input Form</th></tr>

<tr>

<td wicket:id="customerIdLabel">Customer Id</td>

<td>

<input type="text" wicket:id="customerId" />

</td>

</tr>

<tr>

<td wicket:id="itemCodeLabel">Item Code</td>

<td>

<input type="text" wicket:id="itemCode" />

</td>

</tr>

<tr>

<td wicket:id="quantityLabel">Quantity</td>

<td>

<input type="text" wicket:id="quantity" />

</td>

</tr>

<tr>

<td wicket:id="depositLabel">Deposit</td>

<td>

<input type="text" wicket:id="deposit" />

</td>

</tr>

<tr>

<td colspan="2">

<input type="submit" value="Submit" />

</td>

</tr>

</table>

</form>



</body>

</html>

<!----------- Lab3.html --------------------->



############### Lab3.properties #############

form.customerId.CustomerIdValidator=Could not find customer: ${input}

form.itemCode.ItemCodeValidator=Could not find item: ${input}

form.quantity.NumberValidator.minimum=${label} must >= ${minimum}

form.quantity.NumberValidator.maximum=${label} must <= ${maximum}

form.deposit.NumberValidator.minimum=${label} must >= ${minimum}

form.deposit.LightValidator=${label3} must >= (${label2} * price of ${label1}) * deposit percent of ${label0} / 100

############### Lab3.properties #############



/************** Lab3Result.java *************/


package cm269.lab3;



import org.apache.wicket.markup.html.WebPage;

import org.apache.wicket.markup.html.basic.Label;



public class Lab3Result extends WebPage {



public Lab3Result(int totalAmount, int deposit) {

int remainBalance = totalAmount - deposit;

add(new Label("totalAmount",String.valueOf(totalAmount)));

add(new Label("deposit",String.valueOf(deposit)));

add(new Label("remainBalance",String.valueOf(remainBalance)));

}



}

/************** Lab3Result.java *************/



<!----------- Lab3Result.html ---------------->

<html>

<head>

<title>Lab3Result</title>

</head>

<body>



<table border="0">

<tr>

<td>Your order is accepted,thank you!</td>

</tr>

<tr>

<td>

Total Amount = <span wicket:id="totalAmount"></span>,

Deposit = <span wicket:id="deposit"></span>,

Remaining Balance = <span wicket:id="remainBalance"></span>.

</td>

</tr>



</table>



</body>

</html>

<!----------- Lab3Result.html ---------------->



/************** Order.java *************/

package cm269.lab3;



import java.io.Serializable;

import java.util.HashMap;

import java.util.Map;



public class Order implements Serializable{

private String customerId;

private String itemCode;

private int quantity;

private int deposit;

private static Map customerTable;

private static Map itemTable;



static{

customerTable = new HashMap();

customerTable.put("c1", new Integer(10));

customerTable.put("c2", new Integer(15));

customerTable.put("c3", new Integer(20));



itemTable = new HashMap();

itemTable.put("a1", new Integer(100));

itemTable.put("a2", new Integer(120));

itemTable.put("a3", new Integer(150));

}



public Order(String customerId, String itemCode, int quantity, int deposit) {

this.customerId = customerId;

this.itemCode = itemCode;

this.quantity = quantity;

this.deposit = deposit;

}



public int getTotalAmount(){

int price = ((Integer)getItemTable().get(itemCode)).intValue();

return quantity * price;

}



public static Map getCustomerTable() {

return customerTable;

}



public static Map getItemTable() {

return itemTable;

}



public static boolean isExistInCustomerTable(String customerId){

return customerTable.containsKey(customerId);

}



public static boolean isExistInItemTable(String itemCode){

return itemTable.containsKey(itemCode);

}



public String getCustomerId() {

return customerId;

}



public void setCustomerId(String customerId) {

this.customerId = customerId;

}



public String getItemCode() {

return itemCode;

}



public void setItemCode(String itemCode) {

this.itemCode = itemCode;

}



public int getQuantity() {

return quantity;

}



public void setQuantity(int quantity) {

this.quantity = quantity;

}



public int getDeposit() {

return deposit;

}



public void setDeposit(int deposit) {

this.deposit = deposit;

}



}

/************** Order.java *************/



/************** FeedbackLabel.java *************/

package cm269.lab3;



import org.apache.wicket.markup.ComponentTag;

import org.apache.wicket.markup.html.WebMarkupContainer;

import org.apache.wicket.markup.html.form.FormComponent;



public class FeedbackLabel extends WebMarkupContainer {

private FormComponent subject;



public FeedbackLabel(String id, FormComponent subject) {

super(id);

this.subject = subject;

}



protected void onComponentTag(ComponentTag tag){

if(!subject.isValid()){

tag.put("class", "invalidField");

}

super.onComponentTag(tag);

}



}

/************** FeedbackLabel.java *************/



/************** CustomerIdValidator.java *************/

package cm269.lab3;



import org.apache.wicket.validation.IValidatable;

import org.apache.wicket.validation.validator.AbstractValidator;



public class CustomerIdValidator extends AbstractValidator {



protected void onValidate(IValidatable validatable) {

if(!Order.isExistInCustomerTable((String)validatable.getValue())){

error(validatable);

}

}



}

/************** CustomerIdValidator.java *************/



/************** ItemCodeValidator.java *************/

package cm269.lab3;



import org.apache.wicket.validation.IValidatable;

import org.apache.wicket.validation.validator.AbstractValidator;



public class ItemCodeValidator extends AbstractValidator {



protected void onValidate(IValidatable validatable) {

if(!Order.isExistInItemTable((String)validatable.getValue())){

error(validatable);

}

}



}

/************** ItemCodeValidator.java *************/



/************** LightValidator.java *************/

package cm269.lab3;



import org.apache.wicket.markup.html.form.Form;

import org.apache.wicket.markup.html.form.FormComponent;

import org.apache.wicket.markup.html.form.TextField;

import org.apache.wicket.markup.html.form.validation.AbstractFormValidator;



public class LightValidator extends AbstractFormValidator {

private TextField customerId;

private TextField itemCode;

private TextField quantity;

private TextField deposit;



public LightValidator(TextField customerId, TextField itemCode,

TextField quantity, TextField deposit) {

super();

this.customerId = customerId;

this.itemCode = itemCode;

this.quantity = quantity;

this.deposit = deposit;

}



public FormComponent[] getDependentFormComponents() {

return new FormComponent[]{customerId, itemCode, quantity, deposit};

}



public void validate(Form form) {

int iDepositPercentage = ((Integer)Order.getCustomerTable().get(customerId.getConvertedInput())).intValue();

int iPrice = ((Integer)Order.getItemTable().get(itemCode.getConvertedInput())).intValue();

int iQuantity = ((Integer)this.quantity.getConvertedInput()).intValue();

int iDeposit = ((Integer)this.deposit.getConvertedInput()).intValue();

if(!(iDeposit >= (iQuantity * iPrice) * iDepositPercentage / 100)){

error(this.deposit);

}

}



}

/************** LightValidator.java *************/



項目結構如下圖所示:





執行畫面如下圖所示:



參考資料:

http://wicket.apache.org/

星期日, 10月 07, 2007

PDF 應用 備忘記

PDFCreator 及 CutePDF Writer 以列印功能般輸出 PDF.
PDFCreator:
http://sourceforge.net/projects/pdfcreator/

CutePDF Writer:
http://www.cutepdf.com/

Free PDF Compressor 壓縮 PDF:
http://www.nicepdf.com/products.html

PDF Watermark Creator 在 PDF 裡加入水印:
http://www.coolpdf.com/pdfwatermark.html

PDFHelper 將 PDF 文件分拆:
http://rptea.com/

PDF Bundle 在 PDF 裡加入其他檔案(如 Word):
http://www.coolpdf.com/products.html

Infix Pro 修改 PDF檔案:
http://www.iceni.com/

Superior Search 能夠在大量的 PDF 文件中搜尋訊息:
http://www.superiorsearch.com/en/products/

可以利用 FillOutAForm 及 Ghostscript 將 PDF form 轉成 BMP後填上資料.
FillOutAForm:
http://jdmcox.com/

Ghostscript:
http://www.ghostscript.com/awki

Easy PDF to Text Converter 將 PDF 檔案轉成文字, html, word 檔.
http://www.pdf-to-html-word.com/pdf-to-text/


PeaZip 為綠色壓縮軟件不用安裝, 適合放在 USB 裡使用.
http://peazip.sourceforge.net/
可建立: 7Z, BZ2, GZ, PAQ.LPAQ, PEA, QUAD, TAR, UPX, ZIP
可開啟: ACE, ARJ, CAB, DEB, ISO, LHA, RAR, RPM

7ZIP 免費的壓縮軟件.
http://www.7-zip.org/