/**
   @version 1.10 2004-08-15
   @author Cay Horstmann
*/

import java.io.*;
import java.rmi.*;
import java.util.*;
import java.rmi.server.*;
import java.util.*;
import java.util.concurrent.locks.*;

/**
   Klasa implementacji zdalnego obiektu reprezentującego dom towarowy.
*/
public class WarehouseImpl
   extends UnicastRemoteObject
   implements Warehouse
{  
   /**
      Tworzy implementację obiektu domu towarowego.
   */
   public WarehouseImpl()
      throws RemoteException
   {  
      products = new ArrayList<ProductImpl>();
      add(new ProductImpl("Core Java Book", 0, 200, Product.BOTH, "Komputery"));
   }

   /**
      Umieszcza produkt w domu towarowym. Metoda lokalna.
      @param p dodawany produkt
   */
   public void add(ProductImpl p)
   {  
      Lock wlock = rwlock.writeLock();
      wlock.lock();
      try 
      {
         products.add(p);
      }
      finally
      {
         wlock.unlock();
      }
   }

   public ArrayList<Product> find(Customer c)
      throws RemoteException
   {  
      Lock rlock = rwlock.readLock();
      rlock.lock();
      try 
      {
         ArrayList<Product> result = new ArrayList<Product>();
         // dodaje wszystkie produkty odpowiadające profilowi nabywcy
         for (ProductImpl p : products)
         {  
            if (p.match(c)) result.add(p);
         }
         // dodaje produkt odpowiedni dla każdego nabywcy
         if (!result.contains(products.get(0)))
            result.add(products.get(0));
         
         // resetuje obiekt c, by pokazać, że jest on 
         // jedynie kopią obiektu przesłanego przez klienta
 
         c.reset(); 
         return result;
      }
      finally
      {
         rlock.unlock();
      }
   }

   private ArrayList<ProductImpl> products;
   private ReadWriteLock rwlock = new ReentrantReadWriteLock();
}
