package sitris;

import javax.ejb.*;
import java.rmi.RemoteException;

import sitris.Literal;
import sitris.LiteralPK;
import sitris.LiteralHome;
import sitris.Resource;
import sitris.ResourcePK;
import sitris.ResourceHome;
import sitris.Statement;
import sitris.StatementPK;
import sitris.StatementHome;
import sitris.Model;
import sitris.ModelPK;
import sitris.ModelHome;
import sitris.RemoteNode;
import sitris.RemoteNodePK;
import java.util.Collection;

/**
 * This Entity EJB represents a RDF Statement
 @ejb:entity-cmp
 @ejb:ejb-name sitris/Statement
 @ejb:jndi-name ejb/sitris/Statement
 @ejb:finder java.util.Collection findAll()
 @ejb:finder java.util.Collection findByModel(String alias)
 @ejb:finder java.util.Collection findBySubject(java.lang.Integer subj_id)
 @ejb:finder java.util.Collection findByPredicate(java.lang.Integer pred_id)
 @ejb:finder java.util.Collection findByObject(java.lang.Integer obj_id, java.lang.Boolean type)
 @jboss:finder-query findByObject obj={0} AND is_lit={1}
 
 @ejb:finder java.util.Collection findByModelSubject(String model, java.lang.Integer subj_id)
 @jboss:finder-query findByModelSubject model={0} AND subj={1}
 @ejb:finder java.util.Collection findByModelPredicate(String model, java.lang.Integer pred_id)
 @jboss:finder-query findByModelPredicate model={0} AND pred={1}
 @ejb:finder java.util.Collection findByModelObject(String model, java.lang.Integer obj_id, java.lang.Boolean type)
 @jboss:finder-query findByModelObject model={0} AND obj={1} AND is_lit={2}
 
 @ejb:finder java.util.Collection findByPredObj(java.lang.Integer pred_id, RemoteNode obj, java.lang.Boolean type) 
 @jboss:finder-query findByPredObj pred={0} AND obj={1} AND is_lit={2}
 @ejb:finder java.util.Collection findBySubjObj(java.lang.Integer subj_id, RemoteNode obj, java.lang.Boolean type)
 @jboss:finder-query findBySubjObj subj={0} AND obj={1} AND is_lit={2}
 @ejb:finder java.util.Collection findBySubjPred(java.lang.Integer subj_id, java.lang.Integer pred_id)
 @jboss:finder-query findBySubjPred subj={0} AND pred={1} 
 
 @ejb:finder java.util.Collection findByModelPredObj(String model, java.lang.Integer pred_id, RemoteNode obj, java.lang.Boolean type) 
 @jboss:finder-query findByModelPredObj model={0} AND pred={1} AND obj={2} AND is_lit = {3}
 @ejb:finder java.util.Collection findByModelSubjObj(String model, java.lang.Integer subj_id, RemoteNode obj, java.lang.Boolean type)
 @jboss:finder-query findByModelPredObj model={0} AND subj={1} AND obj={2} AND is_lit = {3}
 @ejb:finder java.util.Collection findByModelSubjPred(String model, java.lang.Integer subj_id, java.lang.Integer pred_id)
 @jboss:finder-query findByModelPredObj model={0} AND subj={1} AND pred={2} 
 
 @ejb:ejb-ref sitris/Model
 @ejb:ejb-ref sitris/Resource
 @ejb:ejb-ref sitris/Literal
 @ejb:security-role-ref admin Administrator
 @ejb:permission Teller
 @ejb:transaction Required
 @ejb:use-soft-locking
 @ejb:data-object container false
 @ejb:remote-extends Resource
  @jboss:table-name triple
  @jboss:create-table true
  @jboss:remove-table true
  @jboss:tuned-updates true
  @jboss:read-only false
  @jboss:container-configuration Standard CMP
 
  @version 0.01
  @author <a href="mailto:volz@aifb.uni-karlsruhe.de">Raphael Volz</a>
*/
public abstract class StatementBean  {

	// Constructors
	Model model;

	Resource subj, pred;
	RemoteNode obj;

	public StatementPK ejbCreate(Model m, Resource subj, Resource pred, RemoteNode obj)
	throws CreateException {
		// Model setzen
		setModelKey(((ModelPK) m.getPrimaryKey()).alias);
		model = m;

		// Subject setzen
		setSubjKey(((ResourcePK) subj.getPrimaryKey()).hash);
		this.subj = subj;
		// Predicate setzen
		setPredKey(((ResourcePK) subj.getPrimaryKey()).hash);
		this.pred = pred;
		// Object setzen 
		setLiteral(obj instanceof Literal);
		setObjKey(((RemoteNodePK) obj.getPrimaryKey()).getHash());
		this.obj = obj;
		return null;
	}

	public void ejbPostCreate(Model m, Resource subj, Resource pred, RemoteNode obj) throws CreateException {}

	// COLUMN DECLARATION ------------------------------------------------------
	/**
	@ejb:remote-method
	@ejb:persistent-field
	@ejb:pk-field
	@jboss:column-name model
	*/
	public abstract String getModelKey();
	public abstract void setModelKey(String value);

	/**
	@ejb:persistent-field
	@ejb:pk-field
	@jboss:column-name subj
	@jboss:sql-type INTEGER
	*/
	public abstract int getSubjKey();
	public abstract void setSubjKey(int value);

	/**
	@ejb:persistent-field
	@ejb:pk-field
	@jboss:column-name pred
	@jboss:sql-type INTEGER
	*/
	public abstract int getPredKey();
	public abstract void setPredKey(int value);

	/**
	@ejb:persistent-field
	@ejb:pk-field
	@jboss:column-name obj
	@jboss:sql-type INTEGER
	*/
	public abstract int getObjKey();
	public abstract void setObjKey(int value);

	/**
	@ejb:persistent-field
	@ejb:remote-method
	@jboss:column-name is_lit
	*/
	public abstract boolean isLiteral();
	public abstract boolean setLiteral(boolean lit);


	// HELPER Methods -------------------------------------------------------------

	protected transient EntityContext ctx;

	public void setEntityContext(javax.ejb.EntityContext ctx)
	{
		this.ctx = ctx;
	}

	protected EntityContext getEntityContext() {
		return ctx;
	}

	/**
		Is implemented by the Doclet generated Class
	*/
	public abstract boolean isModified();

	protected EJBHome findHome(String homeName) {
		Context initCtx = new InitialContext(ctx.getEnvironment());
		return home = initCtx.lookup(homeName);
	}

	protected ResourceHome getResourceHome() {
		return (ResourceHome) findHome(ResourceHome.JNDI_NAME);
	}

	protected ModelHome getModelHome() {
		return (ModelHome) findHome(ModelHome.JNDI_NAME);
	}

	protected LiteralHome getLiteralHome() {
		return (LiteralHome) findHome(LiteralHome.JNDI_NAME);
	}


	// PUBLIC Methods  ------------------------------------------------------------



	/** @return the subject of this statement
	@ejb:remote-method
	@ejb:transaction Supports
	* @return subject of the triple
	*/
	public Resource getSubject() throws FinderException {
		if(isModified() || (subj == null))  {
			ResourceHome home = getResourceHome();
			subj = home.findByPrimaryKey(new ResourcePK(getSubjKey()));
		}
		return subj;
	}

	/**
	 * @return predicate of this statement
	@ejb:remote-method
	@ejb:transaction Supports
	 */
	public Resource getPredicate() throws FinderException {
		if(isModified() || (pred == null))  {
			ResourceHome home = getResourceHome();
			pred = home.findByPrimaryKey(new ResourcePK(getPredKey()));
		}
		return pred;
	}

	/**
	 * @return object of this statement
		@ejb:remote-method
		@ejb:transaction Supports
	 */
	public RemoteNode getObject() throws FinderException {
		return isLiteral() ? getObjLit() : getObjRes();
	}

	protected Resource getObjRes() throws FinderException {
		if(isModified() || (obj == null))  {
			ResourceHome home = getResourceHome();
			obj = home.findByPrimaryKey(new ResourcePK(getObjKey()));
		}
		return obj;
	}

	protected Literal getObjLit() throws FinderException {
		if(isModified() || (obj == null))  {
			LiteralHome home = getLiteralHome();
			obj = home.findByPrimaryKey(new LiteralPK(getObjKey()));
		}
		return obj;
	}

	/**
	 * @return the model that contains this statement
	@ejb:remote-method
	@ejb:transaction Supports
	*/
	public Model getModel() {
		if(isModified() || (model == null))  {
			ModelHome home = getModelHome();
			model = home.findByPrimaryKey(new ModelPK(getModelKey()));
		}
		return model;
	}

	
}
