package corepatterns.apps.psa.ejb;

import java.util.*;
import java.rmi.RemoteException;
import javax.ejb.*;
import javax.naming.*;
import corepatterns.apps.psa.core.*;
import corepatterns.util.ServiceLocator;
import corepatterns.util.ServiceLocatorException;

// Uwaga: nie wszystkie szczegy konstrukcji try/catch zostay pokazane
// w celu zapewnienia wikszej czytelnoci.

public class ProjectResourceManagerSession
  implements SessionBean {

  private SessionContext context;

  // Zdalne refernecje do komponentw entity 
  // hermetyzowanych przez t fasad.
  private Resource resourceEntity = null;
  private Project projectEntity = null;
  ...

  // domylna metoda tworzenia
  public void ejbCreate() throws CreateException { }

  // metoda tworzenia tej fasady i ustanawiania pocze
  // do wymaganych komponentw entity przy uyciu
  // wartoci kluczy gwnych
  public void ejbCreate(String resourceId, String projectId,
    ...)
  throws CreateException, ResourceException {

    try {
      // znajdowanie i czenie si z komponentami entity
      connectToEntities(resourceId, projectId, ...);
    } catch (...) {
      // obsuga wyjtkw
    }
  }

  // metoda czenia fasady sesji z jej 
  // komponentami entity przy uyciu wartoci kluczy gwnych
  private void connectToEntities (String resourceId,
    String projectId)
  throws ResourceException {
    resourceEntity = getResourceEntity(resourceId);
    projectEntity = getProjectEntity(projectId);
    ...
  }

  // metoda ponownego czenia fasady sesji z innym zestawem
  // komponentw entity przy uyciu wartoci kluczy gwnych
  public resetEntities(String resourceId, String projectId,
     ...)
  throws PSAException {

    connectToEntities(resourceId, projectId, ...);
  }

  // metoda prywatna pobrania Home dla zasobu
  private ResourceHome getResourceHome()
  throws ServiceLocatorException {
    return ServiceLocator.getInstance().getLocalHome(
      "ResourceEntity", ResourceHome.class);
  }

  // metoda prywatna pobrania Home dla projektu
  private ProjectHome getProjectHome()
  throws ServiceLocatorException {
    return ServiceLocator.getInstance().getLocalHome(
      "ProjectEntity", ProjectHome.class);  
  }

  // metoda prywatna pobrania komponentu entity zasobw
  private Resource getResourceEntity(String resourceId)   
  throws ResourceException {
    try {
      ResourceHome home = getResourceHome();
      return (Resource) home.findByPrimaryKey(resourceId);
    } catch (...) {
      // obsuga wyjtkw
    }
  }

  // metoda prywatna pobrania komponentu entity projektu
  private Project getProjectEntity(String projectId)
  throws ProjectException {
    // podobie jak w getResourceEntity
    ...
  }

  // Metoda hermentyzacji przepywu zada zwizanych z przypisaniem
  // zasobu do projektu. Dotyczy komponentw entity projektu i zasobw
  public void assignResourceToProject(int numHours)
  throws PSAException {

    try {
      if ((projectEntity == null) ||
         (resourceEntity == null)) {
        // SessionFacade nie jest poczona z komponentami entity
        throw new PSAException(...);
      }

      // pobranie danych zasobu
      ResourceTO resourceTO = 
        resourceEntity.getResourceData();

      // pobranie danych projektu
      ProjectTO projectTO =projectEntity.getProjectData();

      // najpierw dodajemy zasb do projektu
      projectEntity.addResource(resourceTO);

      // tworzymy nowy obiekt Commitment dla projektu
      CommitmentTO commitment = new CommitmentTO(...);

      // dodajemy go do zasobu
      projectEntity.addCommitment(commitment);

    } catch (...) {
      // obsuga wyjtkw
    }
  }

  // Podobnie implementujemy inne metody biznesowe zwiazane z
  // obsug innych przypadkw uycia
  public void unassignResourceFromProject()
  throws PSAException {
    ...
  }

  // metody pracy z ResourceEntity
  public ResourceTO getResourceData()
  throws ResourceException {
    ...
  }

  // aktualizacja komponentu entity zasobw
  public void setResourceData(ResourceTO resource) 
  throws ResourceException {
    ...
  }

  // utworzenie nowego komponentu entity zasobw
  public ResourceTO createNewResource(ResourceTO resource)
  throws ResourceException {
    ...
  }

  // metody zarzdzania czasem blokowania zasobw
  public void addBlockoutTime(Collection blockoutTime) 
  throws RemoteException,BlockoutTimeException {
    ...
  }
  
  public void updateBlockoutTime(Collection blockoutTime)
  throws RemoteException, BlockoutTimeException {
    ...
  }
  
  public Collection getResourceCommitments() 
  throws RemoteException, ResourceException {
    ...
  }

  // metoda dziaajca z ProjectEntity
  public ProjectTO getProjectData()
  throws ProjectException {
    ...
  }

  // aktualizacja komponentu entity projektu
  public void setProjectData(ProjectTO project) 
  throws ProjectException {
    ...
  }

  // utworzenie nowego komponentu entity projektu
  public ProjectTO createNewProject(ProjectTO project)
  throws ProjectException {
    ...
  }

  ...

  // przykady innych metod zwizanych z fasad

  // Ten poredni wywouje wzorzec Transfer Object Assembler,
  // aby pobra zoony obiekt transferowy.
  // Patrz wzorzec Transfer Object Assembler.
  public ProjectCTO getProjectDetailsData()
  throws PSAException {
    try {
      ProjectTOAHome projectTOAHome = (ProjectTOAHome)
        ServiceLocator.getInstance().getRemoteHome(
          "ProjectTOA", ProjectTOAHome.class);

      // Komponent sesyjny Transfer Object Assembler
      ProjectTOA projectTOA =  projectTOAHome.create(...);
      return projectTOA.getData(...);
    } catch (...) {

        // Obsuga lub przekazanie wyjtkw dalej
    }
  }

  // Ta metoda wykorzystuje ValueListHandler do pobrania
  // listy projektw. Patrz wzorzec Value List Handler.
  public Collection getProjectsList(Date start, Date end)
  throws PSAException {
    try {
      ProjectListHandlerHome projectVLHHome = 
        (ProjectVLHHome)
          ServiceLocator.getInstance().getRemoteHome(
            "ProjectListHandler", ProjectVLHHome.class);

      // komponent sesyjny Value List Handler
      ProjectListHandler projectListHandler = 
        projectVLHHome.create();
      return projectListHandler.getProjects(start, end);
    } catch (...) {
        // Obsuga lub przekazanie wyjtkw dalej
    }
  }

  ...

  public void ejbActivate() {
    ...
  }

  public void ejbPassivate() {
    context = null;
  }

  public void setSessionContext(SessionContext ctx) {
       this.context = ctx;
  }

  public void ejbRemove() {
    ...
  }
}