quinta-feira, 2 de julho de 2009

Eclipse Galileo + Tapestry5 part 2

Ok, now everyone, run your Eclipse IDE and follow the steps below:

1) Go to Help >> Install New software and create (Add...) the following locations:

name: jetty
location: http://jettylauncher.sourceforge.net/updates/

name: maven
location: http://m2eclipse.codehaus.org/update/
http://m2eclipse.sonatype.org/update/

2) select File >> import... >> General >> Maven Projects

Select your project (tutorial1) and import it to eclipse.

3) to run the project, you must execute by selecting "Run as..." >> "Maven build..." and specify the goal "jetty:run":



After that, you just have to open a browser windows and your Tapestry 5 development environment is all set:

Eclipse Galileo + Tapestry5

Hi everyone, remember our beloved T5? So let's configure a test application from the start:

1) Download this guy -> eclipse-jee-galileo-win32.rar and set your OS environment to work with Java (if you don't know how to do that..., well, just go here).

2) Ok, now download Jetty (5.1) and Maven (2.0.10) and place them in a folder and create the MAVEN_HOME and the JETTY_HOME environments variables.

3) After doing that, run the following command (remove the line breaks) from the desired place where you want to create your first project:

mvn archetype:generate -DarchetypeCatalog=http://tapestry.formos.com/maven-repository -DarchetypeGroupId=org.apache.tapestry -DarchetypeArtifactId=quickstart -DgroupId=org.apache.tapestry -DartifactId=tutorial1 -DpackageName=org.apache.tapestry5.tutorial1

4) To avoid a Jetty plugin error, create a file called "settings.xml" inside the Maven root folder:

example: "C:\Documents and Settings\marcelo\.m2\"

and put the following configuration:

<. pluginGroups >
<.
pluginGroup > org.mortbay.jetty < / pluginGroup >
< / pluginGroups >


You will also have to add some missing folders under:
tutorial1\src\main

add the "webapp" folder and inside it, add the "WEB-INF" folder and create a standard "web.xml" file.

5) Now navigate through your prompt until you reach your project's home directory (tutorial1)
and issue the following command:

mvn jetty:run

This way, you have just compiled and started your first Tapestry 5 application that is running on yor Jetty app server. (http://localhost/tutorial1).

The repositories are providing a lame test application (the old one was way better), to see real action you will have to create some more files. But, for now, just create a file called "index.jsp" under "tutorial1\src\main\webapp" and put some text in it and refresh your browser.

Next post, we will configure our Eclipse IDE and create a simple web application.

See ya!

domingo, 31 de agosto de 2008

T5: Using the TinyMCE (WYSIWYG) with Tapestry

Put this code between the 'head' tags of your form page:
< language="javascript" type="text/javascript" src="assets/js/tiny_mce/tiny_mce.js">< /script >
< language="javascript" type="text/javascript">
tinyMCE.init({
mode : "textareas"
});
< /script >
Now, to show the content properly you will have to use the 'outputraw' tag:

<.t:.outputraw..value="produto.descricao"./.>

T5: Uploading an image file

Try to create a UploadedFile Object in the java of your form page like this one, remeber the getters and setters (please):

private UploadedFile _productPhoto;


And then put this tag in the page to do the trick:

< id="productPhoto" type="upload">

Now you just have to treat it like a file:

public String onSuccess() throws ClassNotFoundException, SQLException, IllegalAccessException, InstantiationException
{
if (_productPhoto!=null)
{
File arq_productPhoto = new File("src/main/webapp/assets/photos/" + _productPhoto.getFileName());
_productPhoto.write(arq_productPhoto);

T5: Pagination

In my pagination I've created a component (my own component, pretty cool, right?) that I'd like to call: "The repeater", with this smart fellow I can set my "pagination" value and create links for the pagination:

< t:repeater end="${numberOfPages}" valor="page" >
< div id="page_box" >< a href="#" type="actionLink" id="link" context="page" >${page}< /a >< /div >< /t:repeater >


Here's the component:

package br.com.myPaginationExample.components;

import org.apache.tapestry.annotations.AfterRender;
import org.apache.tapestry.annotations.Parameter;
import org.apache.tapestry.annotations.SetupRender;

public class Repeater {
//You always have at least one page right?
@Parameter
private int start = 1;

//this one its required, we to know how many pages are going to have a link.
@Parameter(required = true)
private int end;

//This will hold the current value of the page.
@Parameter
private int valor;

//This will tell when the component should stop creating links
private boolean increments;

@SetupRender
void initializeValue()
{
//The current value starts with 1
value = start;
//This statement must be true, so the start should be less than the end.
increments = start < newvalue=" value+" value =" newValue;" newvalue =" value">= end)
{
value = newValue;
return false;
}
}

return true;
}
}

With this code you can delimit the content that you want (in this case my page its showing 10 products by page), check it out:

void pageAttached() throws SQLException, ClassNotFoundException, IllegalAccessException, InstantiationException
{
ProductPst prodPst = new ProductPst();

int x = prodPst.getNumberOfContentFromThatCategory(category);
this.setTotalCategory(x);
this.setNameCategory(String.valueOf(this.category));

int y = (int) Math.round((x+10)/10);
this.setNumberOfPages(y);

//if its 1, 1-1=0, 0*10=0, 0+1=1. From page 1 to 10
//if its 2, 2-1=1, 1*10=10, 10+1=11. From page 11 to 20
this.setFromPage(1+((pagination-1)*10));
this.setToPage(pagination*10);

this.setLkProductsByCategory(prodPst.selectProductsByCategory(this.category,this.pagination));
}


Now check the select method:

public LinkedList selectProductsByCategory(Category category, int pagination) throws SQLException, ClassNotFoundException, IllegalAccessException, InstantiationException
{
String category_str = String.valueOf(category);
//pagination
int numberOfProductsByPage = 10;
int inicio = 0;
if (pagination==0)
{
pagination= 1;
}
else
{
start = (pagination-1) * numberOfProductsByPage;
}

bd = new DBConnection();
con = bd.getConnection();

LinkedList prods = new LinkedList();

try {
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM products WHERE category = '"+ category_str +"' LIMIT " + start + ","+ numberOfProductsByPage);

while(rs.next())
{
Product prod = new Product();
prod.setId(rs.getInt("id"));
prod.setName(rs.getString("name"));

...
//filling each product instance and putting into the List.
prods.add(prod);


This way you always get only the required amount for each page.

T5: Providing role base access to the screens

1) Use a ProtectedPage to check for the navigation level of the user:

"public class InsertProduct extends ProtectedPage {"


And put your logic in the ProtectedPage:

public abstract class ProtectedPage {

@ApplicationState
private Visit _visit;

public Visit getVisit() { return _visit; }
public void setVisit(Visit _visit) { this._visit = _visit; }

public Object onActivate()
{
if (!_visit.thisUserCanSeeThisPage())
return "Login"; // Redirects the user to the Login page

return null; // Returning null or true allows the user to see the page
}
}
Every page that you extends the ProtectedPage will verify the user.