how to invoke PageJpaController.create from a Facade?

206 Views Asked by At

What is the correct way to invoke PageFacade, or how can PageFacade be modified, so that it invokes PageJpaController.create()? I'm not quite sure how to use the generic AbstractFacade class for this purpose. While I know that the following classes are related, I'm not exactly sure how to organize and invoke methods.

The database operations are in a library:

AggregatorJpaLibrary/src/net/bounceme/dur/selenium/jpa/
├── AbstractFacade.java
├── exceptions
│   ├── IllegalOrphanException.java
│   └── NonexistentEntityException.java
├── Feed.java
├── FeedJpaController.java
├── LinkFacade.java
├── Link.java
├── LinkJpaController.java
├── PageFacade.java
├── Page.java
└── PageJpaController.java

The client iterates URL's from the database:

package net.bounceme.dur.aggregator.client;

import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
import net.bounceme.dur.selenium.jpa.Link;
import net.bounceme.dur.selenium.jpa.LinkFacade;
import net.bounceme.dur.selenium.jpa.Page;
import net.bounceme.dur.selenium.jpa.PageFacade;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;

public class SeleniumWebPageIterator {

    private final static Logger log = Logger.getLogger(SeleniumWebPageIterator.class.getName());
    private final PageFacade pageFacade = new PageFacade();
    private final LinkFacade linkFacade = new LinkFacade();

    public SeleniumWebPageIterator() {
    }

    public void processLinks() {
        List<Link> links = linkFacade.findAll();
        for (Link l : links) {
            processLink(l);
        }
    }

    private void processLink(Link l) {
        log.fine(l.toString());
        WebDriver driver = new FirefoxDriver();
        driver.get(l.getLink());
        driver.manage().timeouts().implicitlyWait(9, TimeUnit.SECONDS);
        String s = driver.getPageSource();
        createPage(l, s);
        driver.close();
    }

    private void createPage(Link l, String s) {
        Page p = new Page();
        p.setCreated(new Date());
        p.setLinkId(l.getId());
        p.setPage(s);
        pageFacade.create(p);
    }
}

There are links (URL's) in the database, and the webpages are visited by Selenium. The source HTML for the page isn't persisted, however.

The PageFacade is simple:

package net.bounceme.dur.selenium.jpa;

import java.util.logging.Logger;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class PageFacade extends AbstractFacade {

    private final static Logger log = Logger.getLogger(PageFacade.class.getName());
    private final EntityManagerFactory emf = Persistence.createEntityManagerFactory("SeleniumIteratorPU");
//    @PersistenceContext(unitName = "SeleniumReaderPU")

    public PageFacade() {
        super(Page.class);
    }

    @Override
    protected EntityManager getEntityManager() {
        return emf.createEntityManager();
    }
}

and extends, of course, AbstractFacade:

package net.bounceme.dur.selenium.jpa;

import java.util.List;
import java.util.logging.Logger;
import javax.persistence.EntityManager;

public abstract class AbstractFacade<T> {

    private final static Logger log = Logger.getLogger(AbstractFacade.class.getName());
    private Class<T> entityClass;

    public AbstractFacade(Class<T> entityClass) {
        this.entityClass = entityClass;
    }

    protected abstract EntityManager getEntityManager();

    //how to invoke the JpaController create method?
    public void create(T entity) {
        getEntityManager().persist(entity);
        log.info("..persisted!");
    }

    public void edit(T entity) {
        getEntityManager().merge(entity);
    }

    public void remove(T entity) {
        getEntityManager().remove(getEntityManager().merge(entity));
    }

    public T find(Object id) {
        return getEntityManager().find(entityClass, id);
    }

    public List<T> findAll() {
        javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
        cq.select(cq.from(entityClass));
        return getEntityManager().createQuery(cq).getResultList();
    }

    public List<T> findRange(int[] range) {
        javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
        cq.select(cq.from(entityClass));
        javax.persistence.Query q = getEntityManager().createQuery(cq);
        q.setMaxResults(range[1] - range[0] + 1);
        q.setFirstResult(range[0]);
        return q.getResultList();
    }

    public int count() {
        javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
        javax.persistence.criteria.Root<T> rt = cq.from(entityClass);
        cq.select(getEntityManager().getCriteriaBuilder().count(rt));
        javax.persistence.Query q = getEntityManager().createQuery(cq);
        return ((Long) q.getSingleResult()).intValue();
    }

}

which uses, or should use, PageJpaController to actually persist to the database:

package net.bounceme.dur.selenium.jpa;

import java.io.Serializable;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import net.bounceme.dur.selenium.jpa.exceptions.NonexistentEntityException;

public class PageJpaController implements Serializable {

    public PageJpaController(EntityManagerFactory emf) {
        this.emf = emf;
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Page page) {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            em.persist(page);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Page page) throws NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            page = em.merge(page);
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = page.getId();
                if (findPage(id) == null) {
                    throw new NonexistentEntityException("The page with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Integer id) throws NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Page page;
            try {
                page = em.getReference(Page.class, id);
                page.getId();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The page with id " + id + " no longer exists.", enfe);
            }
            em.remove(page);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Page> findPageEntities() {
        return findPageEntities(true, -1, -1);
    }

    public List<Page> findPageEntities(int maxResults, int firstResult) {
        return findPageEntities(false, maxResults, firstResult);
    }

    private List<Page> findPageEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Page.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Page findPage(Integer id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Page.class, id);
        } finally {
            em.close();
        }
    }

    public int getPageCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Page> rt = cq.from(Page.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }

}

How can I ensure that PageJpaController is actually being used?

1

There are 1 best solutions below

0
On

It seems from the design provided that the subclasses of AbstractFacade, as PageFacade will use by default the raw jpa persistence methods of the EntityManager. To call the jpa controller implementation the methods of the AbstractFacade can be overriden.

For example something like,

....
public class PageFacade extends AbstractFacade<Page> {

private final static Logger log = Logger.getLogger(PageFacade.class.getName());
private final EntityManagerFactory emf = Persistence.createEntityManagerFactory("SeleniumIteratorPU");
private PageJpaController controller;

public PageFacade() {
    super(Page.class);
    controller = new PageJpaController(emf);
}

@Override
protected EntityManager getEntityManager() {
    return emf.createEntityManager();
}

@Override
public void create(Page entity) {
    controller.create(entity);
    log.info("..persisted!");
}

@Override
public void edit(Page entity) {
   controller.edit(entity);
}
....