/*
 * JBoss, the OpenSource J2EE webOS
 * 
 * Distributable under LGPL license.
 * See terms of license at gnu.org.
 */

package org.jboss.media.entity;

import java.util.Collection;
import java.util.Vector;

import javax.ejb.CreateException;
import javax.ejb.EntityBean;
import javax.ejb.EntityContext;
import javax.ejb.RemoveException;
import javax.emb.MediaEntityLocal;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import org.jboss.ejb.plugins.keygenerator.KeyGenerator;
import org.jboss.ejb.plugins.keygenerator.KeyGeneratorFactory;
import org.jboss.logging.Logger;

/**
 * Media Entity Bean implementation based on Entity Beans.
 * 
 * <p>It extends the abstract <code>MediaEntity</code> class, and only
 * declares CMP/CMR methods and implements <code>ejbCreate()</code>.
 * 
 * @version <tt>$Revision: 1.7 $</tt>
 * @author <a href="mailto:ricardoarguello@users.sourceforge.net">Ricardo Argüello</a>
 * 
 * @ejb.bean name="MediaEntity"
 *           local-jndi-name="ejb/media/MediaEntity"
 *           view-type="local"
 *           reentrant="true"
 *           type="CMP"
 *           cmp-version="2.x"
 *           primkey-field="managedIdentity"
 * 
 * @ejb.interface generate="false" local-class="javax.emb.MediaEntityLocal" * 
 * @ejb.home generate="false" local-class="javax.emb.MediaEntityLocalHome"
 * @ejb.transaction type="Required"
 * @ejb.util generate="false"
 * 
 * @ejb.finder signature="java.util.Collection findByPartialDescription(java.lang.String partialDescription)"
 *             query="SELECT DISTINCT OBJECT(mediaEntity) FROM MediaEntity AS mediaEntity WHERE LOCATE(?1, mediaEntity.managedDescription) > -1"
 * 
 * @ejb.finder signature="java.util.Collection findByPartialLocation(java.lang.String partialLocation)"
 *             query="SELECT DISTINCT OBJECT(mediaEntity) FROM MediaEntity AS mediaEntity WHERE LOCATE(?1, mediaEntity.managedLocation) > -1"
 * 
 * @ejb.persistence table-name="JBOSS_MEDIA_ENTITY_BEANS"
 * 
 * @jboss.create-table "true"
 * @jboss.remove-table "false"
 */
public abstract class MediaEntityBean extends MediaEntity implements EntityBean
{
   public static final String MEDIA_ENTITY_JNDI = "ejb/media/MediaEntity";

   private EntityContext entityContext;

   /** Logger. */
   private Logger log = Logger.getLogger(MediaEntityBean.class);

   /** KeyGenerator Factory JNDI. */
   private static final String KEY_GENERATOR_JNDI = "UUIDKeyGeneratorFactory";

   // Container Managed Persistance (CMP): ------------------------------------

   /**
    * @ejb.pk-field
    * @ejb.persistence column-name="IDENTITY"
    */
   public abstract String getManagedIdentity();
   public abstract void setManagedIdentity(String identity);

   /**
    * @ejb.persistence column-name="CONTENT"
    */
   public abstract byte[] getManagedContent();
   public abstract void setManagedContent(byte[] content);

   /**
    * @ejb.persistence column-name="LOCATION"
    */
   public abstract String getManagedLocation();
   public abstract void setManagedLocation(String location);

   /**
    * @ejb.persistence column-name="DESCRIPTION"
    */
   public abstract String getManagedDescription();
   public abstract void setManagedDescription(String description);

   /**
    * @ejb.persistence column-name="NAME"
    */
   public abstract String getManagedName();
   public abstract void setManagedName(String name);

   /**
    * @ejb.persistence column-name="MIME_TYPE"
    */
   public abstract String getManagedMimeType();
   public abstract void setManagedMimeType(String mimeType);

   /**
    * @ejb.persistence column-name="LAST_MODIFIED"
    */
   public abstract long getManagedLastModified();
   public abstract void setManagedLastModified(long lastModified);

   /**
    * @ejb.persistence column-name="LISTENERS"
    */
   public abstract Vector getManagedListeners();
   public abstract void setManagedListeners(Vector listeners);

   // Container Managed Relationships (CMR): ----------------------------------

   /**
    * @ejb.relation name="Media-ProxyMedia"
    *               role-name="media-has-proxy-media"
    *               target-ejb="MediaEntity"
    *               target-multiple="no"
    *               target-role-name="proxy-media-has-media"
    * 
    * @jboss.relation related-pk-field="managedIdentity"
    *                 fk-column="proxy_identity_fk"
    */
   public abstract MediaEntityLocal getManagedProxy();
   public abstract void setManagedProxy(MediaEntityLocal proxy);

   /**
    * @ejb.relation name="PreviousMediaVersion-NextMediaVersion"
    *               role-name="previous-media-version-has-next-media-version"
    * 
    * @jboss.relation related-pk-field="managedIdentity"
    *                 fk-column="previous_identity_fk"
    */
   public abstract MediaEntityLocal getManagedPreviousVersion();
   public abstract void setManagedPreviousVersion(MediaEntityLocal previousVersion);

   /**
    * @ejb.relation name="PreviousMediaVersion-NextMediaVersion"
    *               role-name="next-media-version-has-previous-media-version"
    * 
    * @jboss.relation related-pk-field="managedIdentity"
    *                 fk-column="child_identity_fk"
    */
   public abstract MediaEntityLocal getManagedNextVersion();
   public abstract void setManagedNextVersion(MediaEntityLocal nextVersion);

   /**
    * @ejb.relation name="MediaParent-MediaChild"
    *               role-name="media-parent-has-media-child"
    * 
    * @jboss.relation related-pk-field="managedIdentity"
    *                 fk-column="parent_identity_fk"
    */
   public abstract Collection getManagedParents();
   public abstract void setManagedParents(Collection parents);

   /**
    * @ejb.relation name="MediaParent-MediaChild"
    *               role-name="media-child-has-media-parent"
    * 
    * @jboss.relation related-pk-field="managedIdentity"
    *                 fk-column="child_identity_fk"
    */
   public abstract Collection getManagedChildren();
   public abstract void setManagedChildren(Collection children);

   /**
    * @ejb.relation name="Media-MetaData"
    *               role-name="media-has-metadatas"
    * 
    * @jboss.relation related-pk-field="managedIdentity"
    *                 fk-column="metadata_identity_fk"
    */
   public abstract Collection getManagedMetaDatas();
   public abstract void setManagedMetaDatas(Collection metadatas);

   // javax.emb.MediaEntityLocalHome interface: -------------------------------

   /**
    * @see javax.emb.MediaEntityLocalHome#create()
    */
   public String ejbCreate() throws CreateException
   {
      String identity = generateIdentity();

      setManagedIdentity(identity);
      updateLastModified();

      return null;
   }

   /**
    * @see javax.emb.MediaEntityLocalHome#create()
    */
   public void ejbPostCreate() throws CreateException
   {
   }

   // javax.ejb.EntityBean interface: -----------------------------------------

   public void ejbActivate()
   {
   }

   public void ejbPassivate()
   {
   }

   public void ejbRemove() throws RemoveException
   {
   }

   public void ejbLoad()
   {
   }

   public void ejbStore()
   {
   }

   public void setEntityContext(EntityContext entityContext)
   {
      this.entityContext = entityContext;
   }

   public void unsetEntityContext()
   {
      entityContext = null;
   }

   // Private: ----------------------------------------------------------------

   /**
    * Create the identity (primary key) of this bean using a UUID key
    * generator.
    * 
    * @return a String containing the primary key.
    * @throws CreateException if an error accours when generating the primary
    *         key.
    */
   private String generateIdentity() throws CreateException
   {
      KeyGenerator keyGenerator = null;

      try
      {
         KeyGeneratorFactory keyGeneratorFactory =
            (KeyGeneratorFactory) new InitialContext().lookup(
               KEY_GENERATOR_JNDI);

         keyGenerator = keyGeneratorFactory.getKeyGenerator();

         String key = (String) keyGenerator.generateKey();

         if (log.isDebugEnabled())
         {
            log.debug("Generated identity: " + key);
         }

         return key;
      }
      catch (NamingException e)
      {
         throw new CreateException(
            "Error: can't find key generator factory: "
               + KEY_GENERATOR_JNDI
               + "; "
               + e.getMessage());
      }
      catch (Exception e)
      {
         throw new CreateException(
            "Error: can't create key generator instance; key generator factory: "
               + KEY_GENERATOR_JNDI
               + "; "
               + e.getMessage());
      }
   }
}