miercuri, 2 septembrie 2009

Richfaces and JQuery

Richface is a JSF based framework which offers a large collection of "ajax-enabled" components. These components use prototype javascript library. This is the main reason you have to be really careful when you want to use JQuery. I needed JQuery to create a photo gallery and combine it with dataScroller component. I was really surprised when I saw that dataScroller component was not working(page links were raising a javascript error). After I had searched for the cause of the issue and I had read the official guide from Exadel/RedHat I found out that JQuery must be imported using the following syntax:


<a4j:loadScript src="resource://jquery.js" />

In javascript functions you cand use jQuery(...) function instead of $(...). This solution make both javascript libraries, JQuery and prototype, work together.

luni, 24 august 2009

Python SQLAlchemy ORM

A couple of days ago I implemented some Python classes which were supposed to map tables from an Oracle DB. In Java, we can use Hibernate for achieving this. In Python, I chose to use SQLAlchemy framework. In the beginning, I had found the syntax a little confusing but after I understood it everything went smoothly. In the following paragraphs, I'll show how a one-to-may relation can be implemented and also how to use composite keys in SQLAlchemy.
I assume that classes are implemented in da package.

1. In __init__.py file I instantiate sqlalchemy dependency objects.

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

BaseEntity = declarative_base()
strDbURL = "oracle://db_tes:xxx@xe"
objDbEngine = create_engine(strDbURL, echo=False)

Session = sessionmaker(bind=objDbEngine)
Session.configure(bind=objDbEngine)

def getConnection():
return Session()

In this moment, we can start implementing the entities. Every entity can extend BaseEntity. Every time we need a database connection we use getConnection() method. A SQLAlchemy session is similar to a Hibernate session.

2. I define User class which has a composite chei(username and password ---- don't do this in practice: you can safely choose to use serial number as primary key). In this example, I want to show how composite keys are implemented.

from da import BaseEntity
from sqlalchemy import Column,Integer,String,Numeric,DateTime,ForeignKey,Sequence
from sqlalchemy.orm import relation, backref

class User(BaseEntity):
username = Column("username", String, primary_key=True)
password = Column("password", String, primary_key=True)
descriere = Column("descriere", String)

def __init__(self, strUsername, strPassword, strDesc):
self.username = strUsername
self.password = strPassword
self.descriere = strDesc

3. I implement the Address class.

from da import BaseEntity
from sqlalchemy import Column,Integer,String,Numeric,DateTime,ForeignKey,Sequence
from sqlalchemy.orm import relation, backref

class Adress(BaseEntity):
id = Column("id", Integer, Sequence("seq_xxx_id"), primary_key=True)
fk_username = Column("fk_username", String, ForeignKey("utilizatori.username"))
fk_password = Column("fk_password", String, ForeignKey("utilizatori.password"))
street = Column("street", String)
number = Column("number", String)

user = relation("User",
foreign_keys=[fk_username, fk_password],
primaryjoin="User.username == Address.fk_username and "
"User.password == Address.fk_password",
backref="adresses")

def __init__(self, strUser, strPasswd, strStreet, strNumber):
self.fk_username = strUser
self.fk_password = strPassword
self.street = strStreet
self.number = strNumber

Comments: in this example, I try to show the power and flexibility provided by SQLAlchemy. First of all, in every SQLAlchemy entity we'll define the mapped table structure to attributes of the class. Using relation function, we can implement links(foreign keys) to other entities:
  • one-to-one relation
  • one-to-many relation
  • many-to-many relation
We can also use the backref keyword argument to indicate that we want a reference at the other end of relation.

4. After we implemented all the entities, we have to use them. In the folloing example, I show several lines of code that prove the entities functionality:

import da
from da import User, Address

# I select all user from the database
objSes = da.getConnection()
for objUsr, in objSes.query(User).all():
print(objUsr.addresses)

# filter that returns the user with a specific address
for objUsr in objSes.query(User, Address).filter(User.username == Address.fk_username and User.password == Address.fk_password).filter(Address.id == 1).all():
print(objUsr.username)

In conclusion, SQLAlchemy easily maps relational logic to object logic(the scope of any ORM) but it doesn't require a configuration file or annotations(like Hibernate). In addition, writting a query is extremely easy. What was not covered in this tutorial but it is intuitive is entity saving(persist). We use add method of an opened session for adding and updating an entity.

luni, 10 august 2009

Java si Mocking - PowerMock

In previous posts I talked about testing python code through injected dependencies. The same idea can be achieved in Java even if it's a little trickier. After I had studied a couple of mocking libraries for java I decided to use PowerMock because it is very close to mocker library for python. This library improves EasyMock and in the latest release it supports integration with Mockito. It worth mentioning some unique features of this library:
  • mocking static functions/methods
  • mocking private functions/methods
These features are extremely important but hard to implement in other testing frameworks. For a better understanding of PowerMock I present a small example.

class Calculator {
public static int add(int a1, int a2) {
return a1 + a2;
}
}

class Operatii {
public int operatieComplexa(int a1, a2) {
int a = Calculator.add(a1, a2);
return ++a;
}
}

@RunWith(PowerMockRunner.class)
@PrepareForTest({Calculator.class})
class TestOperatii {
@Test
public void testOperatieComplexa() {
PowerMock.mockStatic(Calculator.class);
EasyMock.expect(Calculator.add(1, 2).andReturn(3);

PowerMock.replayAll();

Operatii obj = new Operatii();
int ret = obj.operatieComplexa(1, 2);

PowerMock.verifyAll();

Assert.assertEquals(4, ret);
}
}

This is all. When you run the test the code will use an injected method instead of using the static method from Calculator class. Some elements need to be explained:

  • @RunWith(PowerMockRunner.class). It tells JUnit to use PowerMockRunner class for running the tests(it won't work without this line because PowerMock implements a custom class loader).
  • @PrepareForTest({Calculator.class}). This annotation describe the class which static methods will be mocked using mockStatic method.
In conclusion, PowerMock is a powerful testing framework which implements record/replay/verify phases in a similar manner as mocker. For more details, please visit: http://code.google.com/p/powermock/w/list

miercuri, 5 august 2009

Python invoking web services

Recently, I had to invoke a webservice method from python. One solution found was to build a SOAP request. After the request is built, I use httplib for sending request and receiving an answer from the webservice. For this demo, I'll use www.infovalutar.ro webservice(an exchange rate service from Romania).

------------------------------------------------------------------------------------------------
import httplib

HOST = "www.infovalutar.ro"
URL = "/curs.asmx"

def SOAP_GetMoneda(strMoneda):
strReq = """<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
<getlatestvalue xmlns="http://www.infovalutar.ro/">
<Moneda>%s</Moneda>
</getlatestvalue>
</soap12:Body>
</soap12:Envelope>"""

return strReq % strMoneda

if __name__ == "__main__":
data = SOAP_GetMoneda("USD")

dctHeaders = {"Host" : HOST,
"Content-Type" : "text/xml; charset=utf-8",
"Content-Length" : len(data),
"SOAPAction" : "http://www.infovalutar.ro/getlatestvalue"}

con = httplib.HTTPConnection(HOST)

con.request("POST", URL, data, dctHeaders)
resp = con.getresponse()
print(resp.read())

con.close()
--------------------------------------------------------------------------------

What I don't show in this answer is how to parse the response. This should be a simple fact regarding the fact that soap response is a xml document. In the above presented code, I just print the response on the standard output.

vineri, 31 iulie 2009

JSF Localization

Localizations is the process through which an application(web or desktop) can present its' content in multiple languages. This is a hot subject nowadays and a standard is not yet defined for how to properly implement localization. In Java/JSF we can use ResourceBundle class from java.util. A simple example is shown below.

1. We create two resource files(english and romanian).
In each of them we add lbWelcome key with english(romanian) text.

2. We modify faces-config.xml for indicating the supported languages.

<application>
<locale-config>
<default-locale>ro< /default-locale>
<supported-locale>ro< /supported-locale>
<supported-locale>en< /supported-locale>
</ locale-config>
</application>

3. We create a jsp page for presenting the content.

<%@page pageEncoding="UTF-8" contentType="text/html; charset=ISO-8859-2" %>
<%@taglib prefix="f" uri="http://java.sun.com/jsf/core" %>
<%@taglib prefix="h" uri="http://java.sun.com/jsf/html" %>

<f:view>


<h:form>
<h:commandLink action="#{languageBean.changeLanguage}" value="Romana">
<f:param name="lang" value="ro">
</h:commandLink>
|
<h:commandLink action="#{languageBean.changeLanguage}" value="English">
<f:param name="lang" value="en">
</h:commandLink><>

<h:outputText value="#{msg.lbWelcome}">
</h:form>
</f:view>

4. We create a backbean in which the method for changing the language is implemented


package ro.testlocalization.traduceri;

import java.util.Locale;
import java.util.Map;

import javax.faces.application.Application;
import javax.faces.application.ViewHandler;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;

public class LanguageBean {
public void changeLanguage() {
Map req = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
String lang = req.get("lang").toString();

Locale newLocale = new Locale(lang);
FacesContext context = FacesContext.getCurrentInstance();
context.getViewRoot().setLocale(newLocale);
}
}

5. We map the backbean in faces-config.xml.

miercuri, 29 iulie 2009

JAX-WS Webservices: Part 2

This post continues previous one for offering new information about jax-ws webservices. One issue which is often met is related to return types of the web service. For instance: We implement an EJB component which models a person. How can I return this? I might try to specify for one of the webservice methods the EJB as a return type. This is so wrong. The EJB might have a collection resulting from a OneToMany relation. When the client will try to access an element of this collections an exception will be raised complaining about "session closed". To avoid this, we implement a new class(wrapper) which will be serializable. We make sure we don't use Java Collection types like Set, List, Hash, ..... We'll use arrays instead([]). In the web service method we populate all attributes of the wrapper class. The following example demonstrates this:

@Entity
public class Persoana {
@Id
private long cnp;

@OneToMany(mappedBy="parinte")
private List rude;


//metode getter/setter
}


public class PersoanaWrapper implements Serializable {
private long cnp;

private PersoanaWrapper[] rude;

//metode getter/setter
}


Metoda din webservice care doreste sa returneze o persoana ar putea fi implementat de maniera urmatoare:

public PersoanaWrapper getPersoana(long cnp) {
//cod prin care incarc ejb-ul persoanei dorite. => Persoana persEJB;
PersoanaWrapper pers = new PersoanaWrapper();
int nrRude = persEJB.getRude().size();

pers.setCNP(persEJB.getCNP());
pers.setRude(new PersoanaWrapper[nrRude]);

for(int i = 0; i < nrRude; i++) {
PersoanaWrapper tmp = new PersoanaWrapper();
tmp.setCNP(persEJB.getRude().get(i).getCNP());
pers.getRude()[i] = tmp;
}

return pers;
}

One enhancement of the example is to add a new method/constructor which accepts an argument with the EJB type. Using wrapper classes you cand return whatever custom data type you want.
I mentioned in a previous post that when deploying a java web service in a container it will be exposed as a web service and as a Session bean. I strongly encourage you to invoke it as a web service or as a Session bean(not both). If you intend to make your application interoperable then use just web services.

How can we inject resources in a web service?

It is common to use resources in a web service. For instance, we might need to use a DataSource from the container. We might want to inject an EntityManager in the webservice. Both situation are easily solved in Java EE:

@PersistenContext(unitName="myPersistence")
private EntityManager em;

@Resource(mappedName="java:jdbc/MyDS")
private DataSource ds;

We can use @Resource annotation to inject various resources like:
  • Mail session
  • Custom data sources
  • Other resources

luni, 27 iulie 2009

JAX-WS Webservices

In one of the recent projects I worked on I was supposed to implement a SOA arhitectue. The business logic was exposed through web services. This solution was developed because one of its components was written in C# and the rest of components were written in Java. The chosen container for the business layer was JBoss 5(web services, ejb) and Tomcat 6 for front-end(web application). The first major issue was raised by the JBoss 5 version downloaded from the jboss.org site.

Obs: !!!!!!!!!If you use jre/jdk 6 download the jboss version compiled with jdk 6. Otherwise you will get weird errors when you try to access the webservice.

I assume that you downloaded the correct version of jboss on your computer. Java EE/jax-ws makes webservices creation a formality.

@WebService
@SOAPBinding(style=Style.RPC)
@Stateless
public interface ServiciuTest {
@WebMethod
public String sayHello(@WebParameter(name="message")String msg);
}

@Stateless
@WebService(endpointInterface="ServiciuTest")
public class ServiciuTestBean {
public String sayHello(String msg) {
return msg;
}
}

This is all you have to do for creating a functional web service. In this moment the webservice can be deployed on a container that supports jax-ws. In Java EE, the above mentioned class will be exposed as a web service and as a session bean. The interface described is an endpoint(spec) for the web service. The annotation used in the method declaration alter the way the wsdl file is generated. You must keep in mind that you won't be able to return classes which aren't serializable.

In the following paragraphs I present how a complex web service can be implemented. This web service downloads a file from server.

@WebService
@SOAPBinding(style=Style.RPC)
@Stateless
public interface ServiciuFilesTest {
@WebMethod
public byte[] getFile(@WebParam(name="file_name")String fName);
}

@Stateless
@WebService(endpointInterface="ServiciuFilesTest")
public class ServiciuFilesTestBean {
public byte[] getFile(String fName) {
   byte[] deRet = new byte[(int)(new File(fName)).length()];
try {
FileInputStream file = new FileInputStream(fName);
file.read(deRet);
file.close();
}
catch(IOException ioe) {
ioe.printStackTrace();
return null;
}
return deRet;
}
}

This is all you have to do. In this manner you can send files to a client through the web service. Usually, it is recommended that you encode the content sent using Base64.

vineri, 12 iunie 2009

java.util.logging and a wrapper log class

In this post, I show how can we easily implement a logger class which has three types of messages:
  • info
  • warning
  • error
This messages are saved in a file in the following format: err-"currentdate". This logger stile is inspired by classic unix/linux log style. The following class uses java.util.logging and it should be enough for most applications. The class has singleton pattern assigned to it because I need to instantiate it only once.

package ro.example;

import java.io.FileOutputStream;
import java.io.PrintStream;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.logging.*;

public class LoggerSingleton {
private static Logger logger;
private static LoggerSingleton selfInst = null;
private String msgFile = "err%s.log";

private LoggerSingleton() throws Exception {
logger = Logger.getLogger("MyApplication");

this.switchStdErr(this.msgFile);
}

private void switchStdErr(String fName) throws Exception {
Calendar cal = GregorianCalendar.getInstance();
String file = String.format(fName, cal.get(Calendar.YEAR) + "-" + cal.get(Calendar.MONTH) + "-" + cal.get(Calendar.DAY_OF_MONTH));

PrintStream err = new PrintStream(new FileOutputStream(file, true));

System.setErr(err);
}

public static LoggerSingleton getInstance() throws Exception {
if(selfInst == null)
selfInst = new LoggerSingleton();

return selfInst;
}

public void writeInfo(String msg) {
try {
logger.log(Level.INFO, msg);
}
catch(Exception ex) {
ex.printStackTrace();
}
}


public void writeWarning(String msg) {
try {
logger.log(Level.WARNING, msg);
}
catch(Exception ex) {
ex.printStackTrace();
}
}

public void writeWarning(Exception excp) {
try {
logger.log(Level.WARNING, excp.getMessage(), excp);
}
catch(Exception ex) {
ex.printStackTrace();
}
}


public void writeError(String msg) {
try {
logger.log(Level.SEVERE, msg);
}
catch(Exception ex) {
ex.printStackTrace();
}
}

public void writeError(Exception excp) {
try {
logger.log(Level.SEVERE, excp.getMessage(), excp);
}
catch(Exception ex) {
ex.printStackTrace();
}
}
}

Comment: The log method from Logger class writes all messages to System.err stream. Because of this. the first thing I do is to redirect System.err to a specified file.

In the following section I show a possible test file which uses all available methods.

package ro.example;

public class TestLoggerSingleton {
public static void main(String[] args) throws Exception {
LoggerSingleton log = LoggerSingleton.getInstance();

log.writeInfo("Just for fun");
log.writeWarning("Only a warning");
log.writeError("Only an error message");

try {
throw new Exception("Nice error.");
}
catch(Exception ex) {
log.writeWarning(ex);
log.writeError(ex);
}
}
}


The obtained file is presented below.

Jun 4, 2009 3:27:01 PM ro.example.LoggerSingleton writeInfo
INFO: Just for fun
Jun 4, 2009 3:27:01 PM ro.example.LoggerSingleton writeWarning
WARNING: Only a warning
Jun 4, 2009 3:27:01 PM ro.example.LoggerSingleton writeError
SEVERE: Only an error message
Jun 4, 2009 3:27:01 PM ro.example.LoggerSingleton writeWarning
WARNING: O eroare draguta
java.lang.Exception: Nice error.
at ro.example.TestLoggerSingleton.main(TestLoggerSingleton.java:16)
Jun 4, 2009 3:27:01 PM ro.example.LoggerSingleton writeError
SEVERE: Nice error.
java.lang.Exception: Nice error.
at ro.example.TestLoggerSingleton.main(TestLoggerSingleton.java:16)

Every day in which we use the logger class a new file is generated with yyyy-mm-dd.log name. In this way we can see how application evolved in an extremely simple manner. In a future post I'll show how can we generate an xml log file instead of a plain text file.

miercuri, 3 iunie 2009

Hibernate session in web applications

In this article, I show a method in which we can avoid using EAGER fetch type in hibernate entities. For opening a hibernate session in web application we can use a filter that is mapped for /* url pattern. This filter will open a hibernate session and make it available for the current request. In this way, every Collection attribute from an entity can be easily accessed during the request. Some common problems met when not using this method is related to session being closed when trying to access an element from a collection. The session will be put as an request attribute and we call it OPENED_CONNECTION. The following code should give an idea of how we open and use a hibernate session in this way.

public class ManageConnection implements Filter {

private FilterConfig filterConfig;

public void destroy() {}

public void init(FilterConfig fConfig) {

this.filterConfig = fConfig;

}

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {

Object obj = request.getAttribute("OPENED_CONNECTION");

Session ses = null;

if(obj != null) {

ses = (Session)obj;

try {

ses.close();

}

catch(HibernateException ex) {

ex.printStackTrace(); //just print the stack trace into log files

}

}

ses = HibernateSingleton.getInstance().openSession();

request.setAttribute("OPENED_CONNECTION", ses);

chain.doFilter(request, response);

}

}


I use a helper class called HibernateSingleton. The code for this class is presented bellow:


public class HibernateSingleton {

private static SessionFactory sessionFactory;

static

{

sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();

}

public static SessionFactory getInstance()

{

return sessionFactory;

}

public static Session getRequestSession() {

return (Session)Contexts.getRequest().getAttribute("OPENED_CONNECTION");

}

}


Basically, the class build a Hibernate session factory and provides two static methods. One of them help as to get a Hibernate session instance. The other method returns the opened_connection attribute from the request. In my case Contexts.getRequest() method is just a wrapper method which has the code: return (HttpRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();
Of course this is an example from a JSF application.
Now, everytime you need a hibernate session in your application you just use HibernateSingleton.getRequestSession() method. If you have used other methods for managing hibernate sessions you will definitely "love" this one. It also improves performance.

miercuri, 20 mai 2009

Python mocking __new__

In acest tutorial voi prezenta o facilitate python extrem de interesanta: inlocuirea metodei speciale __new__. Acest lucru mi-a fost util in momentul in care am scris o suita de teste pentru o clasa. Problema era ca aceasta clasa era Singleton si in concluzie era dificil sa ma asigur ca resursele injectate sunt corecte de la un test la altul. Solutia de compromis a fost sa elimin comportamentul Singleton al clasei doar pentru teste.

In this tutorial I will show you an unsual feature of python: replacing special method __new__. This seemed extremely useful to me in the moment I wrote some unit tests for a class. Adding the fact the class was a Singleton makes the problem even more interesting. It was difficult for me, to make sure every test was injecting the correct resources. The solution I came up with was to eliminate the "singleton" behavior just for tests.

class TestedClass(float):
def mockedNew(cls, *args, **kwds):
print("Mocked new")
self = float.__new__(*args, **kwds)
return self

def deleteNew(cls):
cls.__new__ = cls.mockedNew

def __new__(cls, arg=0.0):
print("Normal new")
return float.__new__(cls, arg*0.0254)

def __init__(self, arg=0.0):
print("Not working")

deleteNew = classmethod(deleteNew)
mockedNew = classmethod(mockedNew)

if __name__ == "__main__":
TestedClass.deleteNew()
print(TestedClass(12))

In mod normal, in exemplul de mai sus, daca nu as apela deleteNew rezultatul ar fi:
Usually, if I don't invoke deleteNew the result would be:
  • Normal new
  • Not working
  • 0.3048
Calling deleteNew changes the result to:
  • Mocked new
  • Not working
  • 12
In this manner I managed to change __new__ method behavior dynamically.

Python and Mocker

In this tutorial I'll show you how you can test your algorithms by eliminating dependencies(filesystem, database, ldap, and so on). Doing like this, you can easily follow the business logic and assert for the expected results. In the following example, I'll show you how to eliminate filesystem dependency.

def complex_algorithm(objOpen=open):
#here comes the business logic

#here comes the filesystem dependency
f = objOpen("test_file.txt", "w")
f.write("simple test")
f.close()

We can easily see that I provided an argument(objOpen) with default value of open builtin. In this manner, I can inject a mocked function for testing and in a production environment, open builtin will be used. In the following paragraph, I present the "mocking" part:

def test_ComplexAlgorithm():
controller = Mocker()
objOpen = controller.mock()
fMocked = controller.mock()

objOpen.open("test_file.txt", "w")
controller.result(fMocked)

fMocked.write("simple test")

fMocked.close()

controller.replay()

complex_algorithm(objOpen.open)

This is all you need. If the function had returned a result you could have easily asserted it. For more informations about mocking visit the site http://labix.org/mocker.

Python and static methods

At my new working place I had to learn Python so I discovered some features that are hard to understand for someone with Java background. One of these features is definition of static methods.

In Java, you can write something like:

public static void helloWorld() { System.out.println("Hello world"); }

In python lucrurile sunt mai complicate si depinde si de versiune folosita. De exemplu, daca folosim o versiune de python anterioara 2.4 atunci vom defini o metoda statica in felul urmator:

In Python, it's more difficult to define class/static methods. If we use a version earlier than 2.4 we will define a static method like this:

def helloWorld(cls):
print("Salutari")

helloWorld = classmethod(helloWorld)

If we use a version newer than 2.4, the implementation of static methods is simpler because we use a decorator:
@staticmethod
def helloWorld(cls):
print("Hello world")

In both cases, defining a static method in Python is harder than in Java.

miercuri, 22 aprilie 2009

Richfaces panelMenu

Richfaces is a JSF framework extremely powerful. It offers lots of ajax enabled components. In this post I will show how to create a left side navigation bar.

Step 1: We create an eclipse Dynamic Web Project with version 2.5. We activate JSF 1.2. We also have to configure Richfaces as described in: http://www.jboss.org/file-access/default/members/jbossrichfaces/freezone/docs/devguide/en/html_single/index.html.

Step 2: We create a .jsp file in the previously created project with the following code:

<%@page pageEncoding="UTF8" contentType="text/html; charset=ISO-8859-2" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://richfaces.org/a4j" prefix="a4j" %>
<%@ taglib uri="http://richfaces.org/rich" prefix="rich" %>

<f:view>
<h:form>

<rich:panelmenu event="onclick" mode="ajax" width="300">
<rich:panelmenugroup label="Meniu test">
<rich:panelmenuitem label="Optiune 1" onclick="window.location.href='test.jsf';">
<rich:panelmenuitem label="Optiune 2" onclick="window.location.href='test.jsf';">
<rich:panelmenuitem label="Optiune 3" onclick="window.location.href='test.jsf';">
</rich:panelMenuGroup>
</rich:panelMenu>

</h:form>
</f:view>

Comments:

In this moment, we have a navigation bar without any action implemented. In most common cases we'll have to redirect to another page when clicking an item. We can achieve this in many ways, but I think the easiest one is to use javascript code and onclick attribute. We also have to explain what event="onclick" and mode="ajax" means.
Onclick tells richfaces to generate a floating menu which folds/unfolds when an item is clicked. Another value could be onmouseover. The second attribute, mode, defines the submit mode. The default value for this attribute is server, which means that everytime an item is clicked, the page is reloaded. We can also bind panelMenuXXX(XXX stands for: {"" | Item | Group}), to a java object. Data type for attribute is HtmlPanelMenuXXX(XXX stands for: {"" | Item | Group}). The package for this data type is org.richfaces.component.html. Most components that you will use are defined in this package.

joi, 16 aprilie 2009

Configuring subversion + apache2 + ldap

In this post, I describe how I can create subversion repositories authentication using mod_dav_svn and ldap. I suppose we have a virtual path created for out repo: /svn/repos/repo_virtual

We need to have the following structure for ldap nodes:

dc=example,dc=com
ou=Groups,dc=example,dc=com
cn=group_svn_repo,ou=Groups,dc=example,dc=com
ou=Users,dc=example,dc=com
cn=user1,ou=Users,dc=example,dc=com
cn=user2,ou=Users,dc=example,dc=com


Normally the below mentioned structure is enough for configuring apache. In short, we authenticate users on Users node. After that, we check that the user belongs to a specified group. We also need to configure a virtual host for apache(this is the most common scenario used) .

ServerName svn1.example.com
ServerAdmin rcosnita@example.com
ErrorLog /var/log/apache2/error_svn.log
CustomLog /var/log/apache2/access_svn.log combined


DAV svn
SVNPath /svn/repos/repo_virtual/
SVNListParentPath on

AuthBasicProvider ldap

AuthType Basic
AuthName "Example server"
AuthzLDAPAuthoritative off

AuthLDAPURL ldap://svn1.example.com:389/OU=Users,DC=informatix,DC=ro?cn?sub
AuthLDAPBindDN CN=root,DC=example,DC=com
AuthLDAPBindPassword parolamea

AuthLDAPGroupAttribute member
AuthLDAPGroupAttributeIsDN on

Require group cn=group_svn_repo,ou=Groups,dc=informatix,dc=ro


This should do the trick. After you finish configuring the vhost you need to restart apache web server.

It's important to keep in mind that apache webserver cache the connection with ldap server(after first connection). This mean that every entry you add after apache make its first connection won't be "seen" by apache till the next restart(of apache or ldap server).

I don't really know why the solution from this post didn't work with apache + openldap. So if you use openldap you have to cheat a little. You add an attribute to every user from ldap existing schema in which we mention the ldap group. In my case, I have used labeledURI. When I finished adding the above mentioned attribute, I have modified the vhost as:

"Require group cn=group_svn_repo,ou=Groups,dc=informatix,dc=ro"
is replaced by
"Require ldap-attribute labeledURI=cn=group_svn_repo,ou=Groups,dc=informatix,dc=ro".


After this, everything worked just fine.

Oracle and Java Stored Procedure

Starting with Oracle 8i, Oracle RDBMS server has a Java Virtual Machine integrated in it. This means that it can run stored procedures/programs written in java directly in the database. This has huge benefits for PL/SQL language. We can easily add new functionalities in Oracle. In the following paragraphs I'll create a simple class which has a method with one parameter of type java.lang.String. This method will be used as an Oracle stored procedure.

I suppose you use eclipse IDE. Create a Java project. Add a library reference for ojdbc14.jar(this is oracle jdbc driver). Now, we can start writting the class.

Step 1:

package ro.teste.sp;

public class TesteSP
{
public static void WriteMessage(String msg) throws SQLException
{
Connection con = DriverManager.getConnection("jdbc:default:connection");

System.out.println("We received from PL/SQL: " + msg);
}
}

Step 2:

loadjava -user user/passwd@db TesteSP.java

Step 3:

Se creaza un wrapper in baza de date.

We create a wrapper procedure in PL/SQL. We do this so we can invoke the previous java stored procedure natively.

CREATE OR REPLACE PROCEDURE WrapJava1(msg VARCHAR2)
AS
LANGUAGE java
NAME 'ro.teste.sp.TesteSP.WriteMessage(java.lang.String)';

Step 4:

CALL WrapJava1('Hello world');

Comments:

This example is extremely simple. You can create very complicated java stored procedure. For instance, I have managed to write a stored procedure that was generating a jpg image base on received parameters. I have also written a stored procedure to get latest currency from a specified web service. The list of examples can continue indefinitely. I hope you can find this feature of Oracle useful.

joi, 9 aprilie 2009

Oracle forms and Java Bean

In this post I will show how a java component can be plugged in to an Oracle Form. The main problem in achieving this, it's Oracle poor reference for the framework that allows this kind of integration. All you can do it's search the internet and look for as many articles as possible. In the following article I'll create a simple JavaBean component which will send a string to Oracle Forms.

Pasul 1 este sa adaugati o referinta catre frmall.jar care se gaseste in locul in care ati instala Oracle Developer Suite/forms/java.

Step 1: you have to add frmall.jar library reference to your classpath. You can find this library in $ORACLE_HOME/forms/java(in case you installed only Oracle Developer Home) or in $DevSuiteHome_x/forms/java(in case you have installed the Oracle DB and Oracle Developer Suite).

Step 2: You have to compile the following class:

package ro.javabeans;

import oracle.forms.handler.IHandler;
import oracle.forms.properties.ID;
import oracle.forms.ui.CustomEvent;
import oracle.forms.ui.VBean;

public class HelloWorld extends VBean
{
private static IHandler myHandler;
protected static final ID MESAJ = ID.registerProperty("MESAJ");
private String msg;
public void setMsg(String s)
{
this.msg = s;
}
public String getMsg()
{
return this.msg;
}

public void init(IHandler handler)
{
myHandler = handler;
super.init(handler);
}

public boolean setProperty(ID property, Object value)
{
if(property == MESAJ)
{
this.setMsg((String)value);
return true;
}

return super.setProperty(property, value);
}

public Object getProperty(ID property)
{
if(property == MESAJ)
return this.getMsg();

return super.getProperty(property);
}

public void dispatchEvent(ID id)
{
CustomEvent ce = new CustomEvent(myHandler, id);
dispatchCustomEvent(ce);
}
}

Comments:
I think I have to explain the code a little. First of all, every JavaBean which has to run in Oracle Forms has to subclass VBean. We set myHandler, because this object give us methods to access Oracle Forms environment.

protected static final ID MESAJ = ID.registerProperty("MESAJ"). This line register a bean property which can be used in PL/SQL code using set_custom_property/get_custom_property functions. The name of the property is case sensitive, so I recommend you use just capital letters or lower letters(it's up to you).

setProperty/getProperty method are callback functions invoked by the framework to return a property or set a property from Oracle Forms.

dispatchEvent method is used to implement custom events that can be raised/received from Oracle Forms.

Step 4: exporting the project to a jar archive in $DevsuiteHome/forms/java.

Step 5: You need to modify under DevsuiteHome/forms/server/formsweb.cfg, entry archive=....,exported_project.jar

Step 6: We create a new form and we add a JavaBean item. We change its implementation class property to ro.javabeans.HelloWorld

Step 7: We add a when-new-form-instance trigger with the following code:

declare
msg VARCHAR2(200) := 'Va pup pe toti';
begin
SET_CUSTOM_PROPERTY('BLOCK3.BEAN4', 1, 'MESAJ', 'SALUTARI');
end;

Comments:

I assume that JavaBean item it's located unde BLOCK3 and it's named BEAN4. SET_CUSTOM_ATTRIBUTE is a builtin used to set attributes for a bean.

Step 8: We add a button on the canvas.

Step 9:
We add trigger when-mouse-click, with the following code:

declare
msg VARCHAR2(2000) := GET_CUSTOM_PROPERTY('BLOCK3.BEAN4', 1, 'MESAJ');
begin
MESSAGE(msg);
end;

Step 10: We ran the application as a normal Oracle Forms application.

That's all. It's easier than it looks like. I hope this post helped you in your work.

marți, 7 aprilie 2009

Oracle and functions which return a resultset

I knew it was possible to do this. But what I want in fact is to use that function in a select clause. Almost all examples found on Internet explain how to return a result set from a function using SYS_REFCURSOR. In that manner you won't be able to use select statements on the resultset. In addition, problems appear when you want to create a report base on a certain stored function/procedure. Fo instance, I have tried using Crystal Reports for Java with a stored procedure which returns a resultset. Instead of getting the dataset, Crystal Reports returned an error complaining about the stored procedure.

The alternative would to use a select statement in crystal reports which hides my stored function/procedure. To achieve this, I will use pipelined functions.

Step 1:

create or replace type tp_Person is object(SN NUMBER,
FirstName VARCHAR2(200),
LastName VARCHAR2(200));

Step 2:

create or replace type tp_TblPersons is table of tp_person index by binary_integer;

Step 3:

create or replace function fc_TestPersons return tp_tblpersons pipelined
as
cursor c is select * from persons;
rec tp_Person;
begin
OPEN c;

rec := tp_Person(null, null, null);

LOOP
FETCH c INTO rec.sn, rec.firstname, rec.lastname;
exit when c%notfound;

pipe row(rec);
END LOOP;

CLOSE c;
return;
end fc_TestPersons;

Step 4:

In the end all you have to do is to write a select statement like the following one:

SELECT * FROM table(fc_TestPersons());

Final words:

This feature of Oracle PL/SQL language is extremely useful. You must use it when you are sure there are no others options. It uses oracle buffers and memory, so intense use of it might result in low performance.

Hibernate and Composite Keys

Hibernate is a powerful ORM(object relational mapping) very populat nowadays. In latest version, Hibernate comes with Hibernate Annotations. Using annotations you can avoid writting addition xml files for object mapping. In Java, we use hibernate for moving relational model to objective model.Above diagram descibe the following situation: we have several webhosting packages and several tehnology. Between them, we have a many-to-many relation. It's obvious in the database we have a composite primary key: (pachet,tehnologie). Below I write the code for describing the relation from image in terms of hibernate.

@Entity
@Table(name="tblpachete")
public class PachetGazduire
{
@Id
private int id;

@OneToMany(fetch=FetchType.EAGER, mappedBy="id.pachet")
private ArrayList tehnologii;

/* here we add other properties/methods */
}


@Entity
@Table(name="tbltehnologii")
public class Tehnologie
{
@Id
private int id;

/* here comes getter/setter */
}



/* This class implements the composite key */
@Embeddable
public class TehnologiiPachetPK
{
@ManyToOne
@JoinColumn(name="fk_pachet", referencedColumnName="id")
private PachetGazduire pachet;


@ManyToOne
@JoinColumn(name="fk_tehnologie", referencedColumnName="id")
private Tehnologie tehnologie;

/* here come other methods/properties */
}



@Entity
@Table(name="tbltehnologiipachet")
public class TehnologiiPachet
{
@Id
private TehnologiiPachetPK id;

int laCerere;
int nrConturi;
int pretLaCerere;

/* here comes other methods/properties */
}

You might test this code by generating getter/setter methods for every class. You also have to create the underlying tables. One simple solution it's to let hibernate create them for you: hibernate.hbm2ddl.auto = true(in hibernate.cfg.xml)

After you create the tables you populate them with data and everything should be just fine. Good luck.

Accesing web services from Oracle

This problem represent a tough challenge even in modern programming languages(Java, C#) if you don't have a stub generator based on wsdl. I must say that Oracle 10g2 has a nice feature implemented in utl_dbws. This PL/SQL package has lots of function which allow programmer to use web services without using any java wrapper class. Unfortunately, this package is not very well documented by Oracle(it's not the only package in this situation). When I had to write a PL/SQL package which create a SOAP request for a web service and returns the result I spent many hours on google. Enough talking.

In the first part of this tutorial, I create a web service using J2EE tehnology(it's very easy).

ro.anaf.ws.HelloWorldWS

package ro.anaf.ws;

import javax.ejb.Remote;
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;

@WebService
@SOAPBinding(style = Style.RPC)
@Remote
public interface HelloWorldWS
{
@WebMethod
public String helloWorld();

@WebMethod
public String receiveBinary(String s);
}



package ro.anaf.ws;

import javax.ejb.Stateless;
import javax.jws.WebService;

@Stateless
@WebService(endpointInterface = "ro.anaf.ws.HelloWorldWS")
public class HelloWorldWSBean implements HelloWorldWS
{
public String helloWorld()
{
return Hello fromWS";
}

public String receiveBinary(String s)
{
return "I have your message: \"" + s + "\"";
}
}


Now, you deploy your webservice on JBoss/Weblogic or whatever J2EE container you like. After this, we describe the Oracle stuff.

You have to download dbws-callout-utility-10131.zip. After this, you have to load the package into Oracle database.

# 10gR2
loadjava -u scott/tiger -r -v -f -genmissing dbwsclientws.jar dbwsclientdb102.jar
# 11g
loadjava -u scott/tiger -r -v -f -genmissing dbwsclientws.jar

If you don't have Oracle Developer Suite, then it's very probable that you won't be
able to run loadjava. We will suppose that you have Oracle Developer Suite and everything worked fine till now.

declare
webservice utl_dbws.service;
webserviceCall utl_dbws.call;

wsdlURL VARCHAR2(1000) := 'http://10.18.14.32:8080/TestareServiciiEAR-ServiciiWeb/HelloWorldWSBean?wsdl';
webserviceNS VARCHAR2(1000) := 'http://ws.anaf.ro/';
webserviceName utl_dbws.qname;
webservicePort utl_dbws.qname;
webserviceOperation utl_dbws.qname;
params utl_dbws.anydata_list;
results anydata;
begin
webserviceName := utl_dbws.to_qname(webserviceNS, 'HelloWorldWSBeanService');
webservicePort := utl_dbws.to_qname(webserviceNS, 'HelloWorldWSBeanPort');
webserviceOperation := utl_dbws.to_qname(webserviceNS, 'helloWorld');

webservice := utl_dbws.create_service(wsdl_document_location => HTTPURITYPE(wsdlURL),
service_name => webservicename);

webserviceCall := utl_dbws.create_call(service_handle => webservice,
port_name => webservicePort,

operation_name => webserviceOperation);

results := utl_dbws.invoke(call_handle => webserviceCall, input_params => params);

utl_dbws.release_service(webservice);
utl_dbws.release_call(webserviceCall);

DBMS_OUTPUT.PUT_LINE(ANYDATA.AccessVarchar2(results));
end;


Above script shows an example of how you can access the webservice you have created in the first part of this tutorial.
Before the end, you have to know that in some cases you'll want to pass certain parameters to the webservice. In these cases
params(0):=ANYDATA.ConvertVarchar2('Cosnita Radu Viorel'); and of course you can add other parameters.