/* * Copyright (c) 2010-2012 Thiago T. Sá * * This file is part of CloudReports. * * CloudReports is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * CloudReports is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * For more information about your rights as a user of CloudReports, * refer to the LICENSE file or see <http://www.gnu.org/licenses/>. */ package cloudreports.dao; import cloudreports.business.SettingBusiness; import cloudreports.database.Database; import cloudreports.database.HibernateUtil; import cloudreports.enums.RandomNumbersFactory; import cloudreports.models.RandomNumber; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import org.hibernate.HibernateException; import org.hibernate.Session; import qrbg.QRBG; import qrbg.ServiceDeniedException; /** * RandomNumberDAO provides basic CRUD operations related to random numbers * obtained from the QRBG service. * It consumes the random numbers pool and adds more entries on demand. * * @see <a href="http://random.irb.hr/">QRBG Service</a> * @see RandomNumbersFactory * @author Thiago T. Sá * @since 1.0 */ public class RandomNumberDAO { /** * The amount of bytes to be obtained by request when using the QRBG service. * Divide by 4 to get the number of integers returned. */ private final int NUMBER_OF_BYTES = 1440; /** * The amount of requests to be executed each time the random numbers pool * needs more entries from the QRBG service. */ private final int NUMBER_OF_REQUESTS = 10; /** * Inserts more entries in the random numbers pool. * Numbers are obtained from the QRBG service. The total amount of * integers inserted can be calculated as ({@link #NUMBER_OF_BYTES}/4 * * {@link #NUMBER_OF_REQUESTS}. * * @throws IOException If there is no Internet connectivity. * @throws ServiceDeniedException If the QRBG account is not valid. * @see <a href="http://random.irb.hr/">QRBG Service</a> * @since 1.0 */ private void insertMoreNumbersInPool() throws IOException, ServiceDeniedException { QRBG source = new QRBG(SettingBusiness.getQRBGUsername(), SettingBusiness.getQRBGPassword()); for(int request = 0; request < NUMBER_OF_REQUESTS; request++) { byte[] buffer = new byte[NUMBER_OF_BYTES]; source.getBytes(buffer, NUMBER_OF_BYTES); Session session = HibernateUtil.getSession(); try { session.beginTransaction(); for (int i = 0; i < (NUMBER_OF_BYTES - 4); i+=4) { double randomNumber = QRBG.readInt(buffer, i); if (randomNumber < 0) { randomNumber *= -1; } randomNumber /= Integer.MAX_VALUE; if(randomNumber != 0) { session.save(new RandomNumber(randomNumber)); } } session.getTransaction().commit(); } catch (HibernateException ex) { session.getTransaction().rollback(); Logger.getLogger(Database.class.getName()).log(Level.SEVERE, null, ex); } finally { HibernateUtil.closeSession(session); } } } /** * Gets the given amount of random numbers from the random numbers pool. * The effectiveness of this method depends on a proper configuration of * a valid account on the QRBG service and an active Internet connection. * Also, the QRBG service uses the port 1227. Make sure your firewall is * configured properly. * * @param amount the amount of random numbers to get. * @throws IOException If there is no Internet connectivity. * @throws ServiceDeniedException If the QRBG account is not valid. * @see <a href="http://random.irb.hr/">QRBG Service</a> * @see RandomNumber * @since 1.0 */ public List<Double> getRandomNumbers(int amount) throws IOException, ServiceDeniedException { List<RandomNumber> numbersList = getRandomNumbersFromPool(amount); if(numbersList.size() < amount) { insertMoreNumbersInPool(); numbersList = getRandomNumbersFromPool(amount); } List<Double> returnList = new ArrayList<Double>(); Session session = HibernateUtil.getSession(); try { session.beginTransaction(); for(int i = 0; i < amount; i++) { RandomNumber randomNumber = numbersList.get(i); returnList.add(randomNumber.getValue()); session.delete(randomNumber); } session.getTransaction().commit(); } catch (HibernateException ex) { session.getTransaction().rollback(); Logger.getLogger(Database.class.getName()).log(Level.SEVERE, null, ex); } finally { HibernateUtil.closeSession(session); } return returnList; } /** * Gets a list of {@link RandomNumber} registries from the random numbers * pool. * * @param amount the amount of random numbers to get from the pool. * @return a list of random numbers from the pool. * The resulting list has, at most, the number of * elements given by <code>amount</code>. * @see RandomNumber * @since 1.0 */ private List<RandomNumber> getRandomNumbersFromPool(int amount) { Session session = HibernateUtil.getSession(); List<RandomNumber> numbersList = new ArrayList<RandomNumber>(); try { numbersList = (List<RandomNumber>) session.createCriteria(RandomNumber.class).setMaxResults(amount).list(); } catch (HibernateException ex) { Logger.getLogger(Database.class.getName()).log(Level.SEVERE, null, ex); } finally { HibernateUtil.closeSession(session); } return numbersList; } }