/*
* Copyright: (C) Innovation Investments
* Version: $Revision: 1.3 $
* Modified: $Date: 2009/05/14 12:02:05 $
* By: $Author: toeukps $
*
* CXF http://cwiki.apache.org/CXF20DOC/index.html
*
http://cwiki.apache.org/CXF20DOC/jax-rs.html#JAX-RS-Dealingwithcontexts
* JAX-RS
http://wikis.sun.com/display/Jersey/Overview+of+JAX-RS+1.0+Features
* JAXB https://jaxb.dev.java.net/tutorial/
*/
package nl.knowledgeplaza.profiler.services;
import java.math.BigInteger;
import java.util.List;
import javax.persistence.EntityManager;
import org.fest.reflect.reference.TypeRef;
import org.tbee.util.ExceptionUtil;
import org.tbee.util.jpa.EntityManagerFinder;
/**
*
* @author toeu
*
*/
abstract public class AbstractServiceImpl<T, Ts>
{
// logger (http://www.slf4j.org/faq.html#declared_static)
transient final protected org.slf4j.Logger slf4j =
org.slf4j.LoggerFactory.getLogger(this.getClass());
//
=======================================================================
// CONSTRUCTOR
/**
*
*/
public AbstractServiceImpl(Class entityClass, Class collectionClass)
{
iEntityClass = entityClass;
iCollectionClass = collectionClass;
}
private Class iEntityClass = null;
private Class iCollectionClass = null;
//
=======================================================================
// SERVICES
/**
* list all
*/
@javax.ws.rs.GET
public Ts list()
{
try
{
if (slf4j.isDebugEnabled()) slf4j.debug("list {}",
iEntityClass.getSimpleName());
// find all
// example: List<T> lList = Entity.findAll();
List<T> lList =
org.fest.reflect.core.Reflection.staticMethod("findAll") //
http://docs.codehaus.org/display/FEST/Invoking+Static+Methods
.withReturnType( new
TypeRef<List<T>>(){} ) //
http://docs.codehaus.org/display/FEST/Overcoming+Type+Erasure
.in(iEntityClass)
.invoke()
;
if (slf4j.isDebugEnabled()) slf4j.debug("list {} size={}",
iEntityClass.getSimpleName(), lList.size());
// create a collection so JAXB knows what to do
// example: Entitys lTs = new Entitys(lList);
Ts lTs = (Ts)org.fest.reflect.core.Reflection.constructor() //
http://docs.codehaus.org/display/FEST/Invoking+Constructors
.withParameterTypes(java.util.Collection.class) // Due to type
erasure, there can only be one constructor with a List as the
parameter type
(http://java.sun.com/docs/books/tutorial/java/generics/erasure.html)
.in(iCollectionClass) //
TODO: why is TypeRef not possible here?
.newInstance(lList)
;
// done
return lTs;
}
catch (RuntimeException e)
{
slf4j.error(ExceptionUtil.describe(e), e);
throw e;
}
}
/**
* find one
*/
@javax.ws.rs.GET
@javax.ws.rs.Path("/{id}")
public T find(@javax.ws.rs.PathParam("id") long id)
{
try
{
if (slf4j.isDebugEnabled()) slf4j.debug("find {}={}",
iEntityClass.getSimpleName(), id);
// example: Entity lEntity = Entity.findByPK( BigInteger.valueOf(id) );
T lT = (T)org.fest.reflect.core.Reflection.staticMethod("findByPK")
// http://docs.codehaus.org/display/FEST/Invoking+Static+Methods
.withReturnType(
iEntityClass ) // why does this not work: new TypeRef<T>(){} //
http://docs.codehaus.org/display/FEST/Overcoming+Type+Erasure
.withParameterTypes( BigInteger.class )
.in(iEntityClass)
.invoke(
BigInteger.valueOf(id) )
;
if (slf4j.isDebugEnabled()) slf4j.debug("find {}={}",
iEntityClass.getSimpleName(), lT);
return lT;
}
catch (RuntimeException e)
{
slf4j.error(ExceptionUtil.describe(e), e);
throw e;
}
}
/**
* Insert new entity
* @param entity
*/
// we get an exception if this code is placed here and not in the
inheriting class
// @javax.ws.rs.POST
public void add(T entity)
{
try
{
if (slf4j.isDebugEnabled()) slf4j.debug("add {}={}",
iEntityClass.getSimpleName(), entity);
EntityManager lEntityManager = EntityManagerFinder.find();
try
{
lEntityManager.getTransaction().begin();
lEntityManager.persist(entity);
lEntityManager.getTransaction().commit();
}
catch (org.eclipse.persistence.exceptions.DatabaseException e)
{
slf4j.error(ExceptionUtil.describe(e), e);
throw new RuntimeException(e);
}
finally
{
// rollback if still active
if (lEntityManager != null &&
lEntityManager.getTransaction().isActive())
lEntityManager.getTransaction().rollback();
}
}
catch (RuntimeException e)
{
slf4j.error(ExceptionUtil.describe(e), e);
throw e;
}
}
/**
* Update an entity
* @param id
* @param entity
*/
// we get an exception if this code is placed here and not in the
inheriting class
// @javax.ws.rs.PUT
// @javax.ws.rs.Path("/{id}")
// public void update(@javax.ws.rs.PathParam("id") long id, T entity)
public void update(long id, T entity)
{
try
{
if (slf4j.isDebugEnabled()) slf4j.debug("update {} id={}",
iEntityClass, id);
EntityManager lEntityManager = EntityManagerFinder.find();
try
{
lEntityManager.getTransaction().begin();
// example: Entity lEntity = Entity.findByPK( BigInteger.valueOf(id) );
T lT = (T)org.fest.reflect.core.Reflection.staticMethod("findByPK")
// http://docs.codehaus.org/display/FEST/Invoking+Static+Methods
.withReturnType( iEntityClass ) // why does this not work: new
TypeRef<T>(){} //
http://docs.codehaus.org/display/FEST/Overcoming+Type+Erasure
.withParameterTypes( BigInteger.class )
.in(iEntityClass)
.invoke(
BigInteger.valueOf(id) )
;
if (lT == null) throw new
IllegalArgumentException(iEntityClass.getSimpleName() + " " + id + "
does not exist");
// example: Entity.shallowCopy(entity, lEntity);
org.fest.reflect.core.Reflection.staticMethod("shallowCopy") //
http://docs.codehaus.org/display/FEST/Invoking+Static+Methods
.withParameterTypes(
iEntityClass, iEntityClass )
.in(iEntityClass)
.invoke( entity, lT )
;
lEntityManager.getTransaction().commit();
}
finally
{
// rollback if still active
if (lEntityManager != null &&
lEntityManager.getTransaction().isActive())
lEntityManager.getTransaction().rollback();
}
}
catch (RuntimeException e)
{
slf4j.error(ExceptionUtil.describe(e), e);
throw e;
}
}
/**
* Delete an entity
* @param id
*/
@javax.ws.rs.DELETE
@javax.ws.rs.Path("/{id}")
public void delete(@javax.ws.rs.PathParam("id") long id)
{
try
{
if (slf4j.isDebugEnabled()) slf4j.debug("delete, id={}", id);
EntityManager lEntityManager = EntityManagerFinder.find();
try
{
lEntityManager.getTransaction().begin();
// example: Entity lEntity = Entity.findByPK( BigInteger.valueOf(id) );
T lT = (T)org.fest.reflect.core.Reflection.staticMethod("findByPK")
// http://docs.codehaus.org/display/FEST/Invoking+Static+Methods
.withReturnType( iEntityClass ) // why does this not work: new
TypeRef<T>(){} //
http://docs.codehaus.org/display/FEST/Overcoming+Type+Erasure
.withParameterTypes( BigInteger.class )
.in(iEntityClass)
.invoke(
BigInteger.valueOf(id) )
;
if (lT == null) throw new
IllegalArgumentException(iEntityClass.getSimpleName() + " " + id + "
does not exist");
lEntityManager.remove(lT);
lEntityManager.getTransaction().commit();
}
finally
{
// rollback if still active
if (lEntityManager != null &&
lEntityManager.getTransaction().isActive())
lEntityManager.getTransaction().rollback();
}
}
catch (RuntimeException e)
{
slf4j.error(ExceptionUtil.describe(e), e);
throw e;
}
}
//
=======================================================================
// SESSION
// Moving this code to this class result in that SOAP works, but REST
returns NULL
// // Get context for SOAP and REST
// // SOAP context:
http://cwiki.apache.org/CXF20DOC/webservicecontext.html
// @javax.annotation.Resource private javax.xml.ws.WebServiceContext
iSoapWebServiceContext;
// // REST context:
http://cwiki.apache.org/CXF20DOC/jax-rs.html#JAX-RS-Contextannotations
// @javax.ws.rs.core.Context private javax.servlet.ServletContext
iRestServletContext;
// //@javax.annotation.Resource private
org.apache.cxf.jaxrs.ext.MessageContext iRestMessageContext;
// // combining SOAP and REST:
http://cwiki.apache.org/CXF20DOC/jax-rs.html#JAX-RS-Dealingwithcontexts
//
// protected javax.servlet.ServletContext getServletContext()
// throws javax.ws.rs.WebApplicationException
// {
// if (iSoapWebServiceContext != null)
// {
// // soap invocation
// return
(javax.servlet.ServletContext)iSoapWebServiceContext.getMessageContext().get(javax.xml.ws.handler.MessageContext.SERVLET_CONTEXT);
// }
// else
// {
// // http-only jaxrs one
// return
iRestServletContext;//(javax.servlet.ServletContext)iRestMessageContext.get(MessageContext.SERVLET_CONTEXT);
// }
// }
}
/*
* Copyright: (C) Innovation Investments
* Version: $Revision: 1.4 $
* Modified: $Date: 2009/05/14 12:02:05 $
* By: $Author: toeukps $
*/
package nl.knowledgeplaza.profiler.services;
import nl.knowledgeplaza.profiler.engine.model.User;
import nl.knowledgeplaza.profiler.services.support.Users;
/**
*
* @author toeu
*
*/
@javax.jws.WebService(endpointInterface =
"nl.knowledgeplaza.profiler.services.UserService", serviceName =
"users") // the "ws" prefix is handled by the container
@javax.ws.rs.Path("/users") // the "rest" prefix is handled by the
container
@javax.ws.rs.Produces("application/xml")
public class UserServiceImpl extends AbstractServiceImpl<User, Users>
implements UserService
{
//
=======================================================================
// CONSTRUCTOR
/**
*
*/
public UserServiceImpl()
{
super(User.class, Users.class);
}
//
=======================================================================
// SERVICES
// TODO: we get an exception if this code is placed in the abstract
class, CXF is looking into it
@javax.ws.rs.POST
@Override public void add(User user)
{
super.add(user);
}
// TODO: we get an exception if this code is placed in the abstract
class, CXF is looking into it
@javax.ws.rs.PUT
@javax.ws.rs.Path("/{id}")
@Override public void update(@javax.ws.rs.PathParam("id") long id,
User user)
{
super.update(id, user);
}
}