/*******************************************************************************
* Copyright 2011 André Rouél
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package net.sf.jacclog.persistence.jpa.internal;
import java.net.Inet4Address;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.TemporalType;
import net.sf.jacclog.persistence.jpa.entity.Country;
import net.sf.jacclog.util.net.IpAddressTranslator;
import org.joda.time.Interval;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The country repository gives you all CRUD operations for country entities and isolates the service layer from data
* access specifics.
*
* @author André Rouél
*/
public class CountryRepository {
private static final Logger LOG = LoggerFactory.getLogger(CountryRepository.class);
/**
* The name of the persistence unit as defined in the persistence.xml file.
*/
private static final String PERSISTENCE_UNIT_NAME = "jacclogPU";
private final EntityManagerFactory entityManagerFactory;
public CountryRepository() {
entityManagerFactory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
}
public CountryRepository(final Map<String, String> properties) {
if (properties == null) {
throw new IllegalArgumentException("Argument 'properties' can not be null.");
}
entityManagerFactory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME, properties);
}
/**
* Count all countries within a start and end date.
*
* @param period
* @return
*/
public long count(final Date start, final Date end) {
if (start == null) {
throw new IllegalArgumentException("Argument 'start' can not be null.");
}
if (end == null) {
throw new IllegalArgumentException("Argument 'end' can not be null.");
}
final EntityManager entityManager = entityManagerFactory.createEntityManager();
final Long count = entityManager
.createQuery("SELECT count(o) FROM Country o WHERE o.requestTime BETWEEN :start AND :end",
Long.class).setParameter("start", start, TemporalType.DATE)
.setParameter("end", end, TemporalType.DATE).getSingleResult();
entityManager.close();
return count;
}
/**
* Counts all countries within an interval.
*
* @param interval
* A time interval
* @return The number of countries between the interval
*/
public long count(final Interval interval) {
if (interval == null) {
throw new IllegalArgumentException("Argument 'interval' can not be null.");
}
return count(interval.getStart().toDate(), interval.getEnd().toDate());
}
/**
* Counts all countries in the repository.
*
* @return The total number of countries in the repository
*/
public long countAll() {
final EntityManager entityManager = entityManagerFactory.createEntityManager();
final Long count = entityManager.createQuery("SELECT count(o) FROM Country o", Long.class).getSingleResult();
entityManager.close();
return count;
}
/**
* Finds a country by an IP address. It is checked whether the given address lies between a defined IP address range
* of a record.
*
* @param ipAddress
* IP address (IPv4)
* @return A country
* @throws IllegalArgumentException
* If the given argument is null
*/
public Country find(final Inet4Address ipAddress) {
if (ipAddress == null) {
throw new IllegalArgumentException("Argument 'ipAddress' can not be null.");
}
final long ipnum = IpAddressTranslator.toLong(ipAddress);
final EntityManager entityManager = entityManagerFactory.createEntityManager();
final Country country = entityManager
.createQuery(
"SELECT o FROM Country o WHERE o.beginIpAddressAsNumber < :address AND o.endIpAddressAsNumber > :address",
Country.class).setParameter("address", ipnum).getSingleResult();
return country;
}
/**
* Finds all countries in a specific range by specifying a starting position and a maximum number of results.
*
* @param startPosition
* Position of the first result, numbered from 0
* @param maxResults
* Maximum number of results to retrieve
* @return A list of countries
*/
public List<Country> find(final int startPosition, final int maxResults) {
final EntityManager entityManager = entityManagerFactory.createEntityManager();
final List<Country> countries = entityManager.createQuery("SELECT o FROM Country o", Country.class)
.setFirstResult(startPosition).setMaxResults(maxResults).getResultList();
entityManager.close();
return countries;
}
/**
* Finds a country by ID.
*
* @param id
* ID of a country
* @return A country
*/
public Country find(final Long id) {
if (id == null) {
throw new IllegalArgumentException("Argument 'id' can not be null.");
}
final EntityManager entityManager = entityManagerFactory.createEntityManager();
final Country country = entityManager.find(Country.class, id);
entityManager.close();
return country;
}
/**
* Finds all countries in the repository.
*
* @return A list of all countries in the repository
*/
public List<Country> findAll() {
final EntityManager entityManager = entityManagerFactory.createEntityManager();
final List<Country> countries = entityManager.createQuery("SELECT o FROM Country o", Country.class)
.getResultList();
entityManager.close();
return countries;
}
/**
* Updates (or synchronize) a country with the stored content in the repository.
*
* @param country
* An already persisted country
* @return An updated country entity
*/
public Country merge(final Country country) {
if (country == null) {
throw new IllegalArgumentException("Argument 'country' must be set.");
}
Country merged = null;
final EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
try {
merged = entityManager.merge(country);
entityManager.getTransaction().commit();
} catch (final RuntimeException e1) {
if (entityManager.getTransaction().isActive()) {
try {
entityManager.getTransaction().rollback();
} catch (final RuntimeException e2) {
// Log rollback failure or something
throw e2;
}
}
throw e1;
} finally {
if (entityManager != null) {
entityManager.clear();
entityManager.close();
}
}
return merged;
}
/**
* Stores a country in the repository.
*
* @param country
* An unsaved country
*/
public void persist(final Country country) {
if (country == null) {
throw new IllegalArgumentException("Argument 'country' must be set.");
}
final EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
try {
entityManager.persist(country);
entityManager.getTransaction().commit();
} catch (final RuntimeException e1) {
if (entityManager.getTransaction().isActive()) {
try {
entityManager.getTransaction().rollback();
} catch (final RuntimeException e2) {
// Log rollback failure or something
throw e2;
}
}
throw e1;
} finally {
if (entityManager != null) {
entityManager.clear();
entityManager.close();
}
}
}
/**
* Stores a list of unsaved countries in the repository.
*
* @param country
* An unsaved country
*/
public void persist(final List<Country> countries) {
if (countries == null) {
throw new IllegalArgumentException("Argument 'countries' can not be null.");
}
final EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
try {
for (final Country country : countries) {
entityManager.persist(country);
}
entityManager.getTransaction().commit();
} catch (final RuntimeException e1) {
if (entityManager.getTransaction().isActive()) {
try {
entityManager.getTransaction().rollback();
} catch (final RuntimeException e2) {
// Log rollback failure or something
throw e2;
}
}
throw e1;
} finally {
if (entityManager != null) {
entityManager.clear();
entityManager.close();
}
}
}
/**
* Removes an already stored country in the repository.
*
* @param country
* An already stored country
*/
public void remove(final Country country) {
if (country == null) {
throw new IllegalArgumentException("Argument 'country' can not be null.");
}
if (country.getId() == null) {
throw new IllegalArgumentException("The ID for an log country can not be null.");
}
final EntityManager entityManager = entityManagerFactory.createEntityManager();
final Country attached = entityManager.find(Country.class, country.getId());
entityManager.getTransaction().begin();
try {
entityManager.remove(attached);
entityManager.getTransaction().commit();
} catch (final RuntimeException e1) {
if (entityManager.getTransaction().isActive()) {
try {
entityManager.getTransaction().rollback();
} catch (final RuntimeException e2) {
// Log rollback failure or something
throw e2;
}
}
throw e1;
} finally {
if (entityManager != null) {
entityManager.clear();
entityManager.close();
}
}
}
/**
* Removes a list of already stored countries in the repository.
*
* @param country
* An already stored country
*/
public void remove(final List<Country> countries) {
if (countries == null || countries.isEmpty()) {
throw new IllegalArgumentException("Argument 'countries' can not be null or empty.");
}
final EntityManager entityManager = entityManagerFactory.createEntityManager();
final List<Country> attached = new ArrayList<Country>(countries.size());
for (final Country country : countries) {
attached.add(entityManager.find(Country.class, country.getId()));
}
entityManager.getTransaction().begin();
try {
for (final Country country : attached) {
entityManager.remove(country);
}
entityManager.getTransaction().commit();
} catch (final RuntimeException e1) {
if (entityManager.getTransaction().isActive()) {
try {
entityManager.getTransaction().rollback();
} catch (final RuntimeException e2) {
// Log rollback failure or something
throw e2;
}
}
throw e1;
} finally {
if (entityManager != null) {
entityManager.clear();
entityManager.close();
}
}
}
public void start() {
LOG.debug("Starting country repository...");
}
public void stop() {
LOG.debug("Stopping country repository...");
if (entityManagerFactory != null) {
entityManagerFactory.close();
}
}
}