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

package org.jboss.media.entity;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.net.URL;

import javax.ejb.CreateException;
import javax.ejb.FinderException;
import javax.ejb.SessionBean;
import javax.emb.MediaEntityLocal;
import javax.emb.MediaEntityLocalHome;
import javax.emb.MediaException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

/**
 * Facade around the MediaEntity EJB.
 * 
 * @version <tt>$Revision: 1.3 $</tt>
 * @author <a href="mailto:ricardoarguello@users.sourceforge.net">Ricardo Argüello</a>
 * 
 * @ejb.bean name="MediaEntityManager"
 *           jndi-name="ejb/media/MediaEntityManager"
 *           local-jndi-name="ejb/media/MediaEntityManagerLocal"
 *           view-type="both"
 *           type="Stateless"
 * 
 * @ejb.transaction type="Required"
 * @ejb.transaction-type type="Container"
 * 
 * @ejb.ejb-ref ejb-name="MediaEntity" view-type="local"
 */
public abstract class MediaEntityManagerBean implements SessionBean
{
   /**
    * Creates a new MediaEntity.
    * 
    * @return the primary key of the MediaEntity created.
    * 
    * @ejb.interface-method 
    */
   public String createMediaEntity()
      throws MediaException, CreateException, NamingException
   {
      MediaEntityLocalHome mediaEntityLocalHome = getMediaEntityLocalHome();
      MediaEntityLocal mediaEntityLocal = mediaEntityLocalHome.create();
      return (String) mediaEntityLocal.getPrimaryKey();
   }

   public MediaEntityDTO getMediaEntity(String identity)
      throws MediaException, FinderException, NamingException
   {
      MediaEntityLocal mediaEntityLocal = this.findMediaEntity(identity);

      MediaEntityDTO mediaEntityDTO = new MediaEntityDTO();
      mediaEntityDTO.setContent(mediaEntityLocal.getContent());
      mediaEntityDTO.setLocation(mediaEntityLocal.getLocation());
      mediaEntityDTO.setDescription(mediaEntityLocal.getDescription());
      mediaEntityDTO.setName(mediaEntityLocal.getName());
      mediaEntityDTO.setMimeType(mediaEntityLocal.getMimeType());

      return mediaEntityDTO;
   }

   /**
    * Updates a MediaEntity given its primary key and a DTO.
    * 
    * <p>If a property is not set in the DTO, it will be set to 
    * <code>null</code> in the MediaEntity.
    * 
    * @param identity primary key.
    * @param mediaEntityDTO Data Transfer Object with the properties to update.
    * @return the primary key of the MediaEntity updated.
    * 
    * @ejb.interface-method 
    */
   public String updateMediaEntity(
      String identity,
      MediaEntityDTO mediaEntityDTO)
      throws MediaException, FinderException, NamingException
   {
      MediaEntityLocal mediaEntityLocal = this.findMediaEntity(identity);

      mediaEntityLocal.setContent(mediaEntityDTO.getContent());
      mediaEntityLocal.setLocation(mediaEntityDTO.getLocation());
      mediaEntityLocal.setDescription(mediaEntityDTO.getDescription());
      mediaEntityLocal.setName(mediaEntityDTO.getName());
      mediaEntityLocal.setMimeType(mediaEntityDTO.getMimeType());

      return (String) mediaEntityLocal.getPrimaryKey();
   }

   /**
    * Gets a MediaEntity property given its primary key and a property name.
    * 
    * <p>Posible property names and their types are:
    * 
    * <p>"content": <code>java.lang.String</code><br>
    *    "location": <code>java.net.URL</code><br>
    *    "description": <code>java.lang.String</code><br>
    *    "name": <code>java.lang.String</code><br>
    *    "mimeType": <code>java.lang.String</code>
    * 
    * @param identity primary key.
    * @param property property name.
    * @param value property value.
   
    * 
    * @param identity primary key.
    * @param property property name.
    * @return the property value.
    * 
    * @ejb.interface-method 
    */
   public Object getMediaEntityProperty(String identity, String property)
      throws MediaException, FinderException, NamingException
   {
      if (identity == null || property == null)
      {
         throw new NullPointerException();
      }

      MediaEntityLocal mediaEntityLocal = this.findMediaEntity(identity);

      if (property.equals("content"))
      {
         return mediaEntityLocal.getContent();
      }
      else if (property.equals("location"))
      {
         return mediaEntityLocal.getLocation();
      }
      else if (property.equals("description"))
      {
         return mediaEntityLocal.getDescription();
      }
      else if (property.equals("name"))
      {
         return mediaEntityLocal.getName();
      }
      else if (property.equals("mimeType"))
      {
         return mediaEntityLocal.getMimeType();
      }
      else
      {
         throw new IllegalArgumentException(
            "Invalid property name: " + property);
      }
   }

   /**
    * Sets a property for a MediaEntity given its primary key, a property name
    * and a value.
    * 
    * <p>Posible property names and their types are:
    * 
    * <p>"content": <code>java.lang.String</code><br>
    *    "location": <code>java.net.URL</code><br>
    *    "description": <code>java.lang.String</code><br>
    *    "name": <code>java.lang.String</code><br>
    *    "mimeType": <code>java.lang.String</code>
    * 
    * @param identity primary key.
    * @param property property name.
    * @param value property value.
    * 
    * @ejb.interface-method 
    */
   public void setMediaEntityProperty(
      String identity,
      String property,
      Object value)
      throws MediaException, FinderException, NamingException
   {
      if (identity == null || property == null)
      {
         throw new NullPointerException();
      }

      MediaEntityLocal mediaEntityLocal = this.findMediaEntity(identity);

      try
      {
         if (property.equals("content"))
         {
            mediaEntityLocal.setContent((byte[]) value);
         }
         else if (property.equals("location"))
         {
            mediaEntityLocal.setLocation((URL) value);
         }
         else if (property.equals("description"))
         {
            mediaEntityLocal.setDescription((String) value);
         }
         else if (property.equals("name"))
         {
            mediaEntityLocal.setName((String) value);
         }
         else if (property.equals("mimeType"))
         {
            mediaEntityLocal.setMimeType((String) value);
         }
         else
         {
            throw new IllegalArgumentException(
               "Invalid property name: " + property);
         }
      }
      catch (ClassCastException e)
      {
         throw new IllegalArgumentException(
            "Invalid value for property: " + property);
      }
   }

   /** 
    * @ejb.interface-method 
    */
   public void setMediaEntityContent(String identity, File contentFile)
      throws MediaException, FinderException, NamingException, FileNotFoundException
   {
      if (identity == null)
      {
         throw new NullPointerException();
      }

      MediaEntityLocal mediaEntityLocal = this.findMediaEntity(identity);
      InputStream contentStream = new FileInputStream(contentFile);
      mediaEntityLocal.setContent(contentStream);
   }

   //--------------------------------------------------------------------------

   private MediaEntityLocal findMediaEntity(String identity)
      throws NamingException, FinderException
   {
      MediaEntityLocalHome mediaEntityLocalHome = getMediaEntityLocalHome();
      return mediaEntityLocalHome.findByPrimaryKey(identity);
   }

   private MediaEntityLocalHome getMediaEntityLocalHome()
      throws NamingException
   {
      Context initialContext = new InitialContext();
      return (MediaEntityLocalHome) initialContext.lookup(MediaEntityBean.MEDIA_ENTITY_JNDI);
   }
}