1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.commons.rng.core.source32; 18 19 import java.util.Random; 20 import java.io.IOException; 21 import java.io.ObjectOutputStream; 22 import java.io.ObjectInputStream; 23 import java.io.ByteArrayOutputStream; 24 import java.io.ByteArrayInputStream; 25 26 /** 27 * A provider that uses the {@link Random#nextInt()} method of the JDK's 28 * {@link Random} class as the source of randomness. 29 * 30 * <p> 31 * <b>Caveat:</b> All the other calls will be redirected to the methods 32 * implemented within this library. 33 * </p> 34 * 35 * <p> 36 * The state of this source of randomness is saved and restored through 37 * the serialization of the {@link Random} instance. 38 * </p> 39 * 40 * @since 1.0 41 */ 42 public class JDKRandom extends IntProvider { 43 /** Delegate. Cannot be "final" (to allow serialization). */ 44 private Random delegate; 45 /** Size of the byte representation of the state (of the delegate). */ 46 private int stateSize; 47 48 /** 49 * Creates an instance with the given seed. 50 * 51 * @param seed Initial seed. 52 */ 53 public JDKRandom(Long seed) { 54 delegate = new Random(seed); 55 } 56 57 /** 58 * {@inheritDoc} 59 * 60 * @see Random#nextInt() 61 */ 62 @Override 63 public int next() { 64 return delegate.nextInt(); 65 } 66 67 /** {@inheritDoc} */ 68 @Override 69 protected byte[] getStateInternal() { 70 try { 71 final ByteArrayOutputStream bos = new ByteArrayOutputStream(); 72 final ObjectOutputStream oos = new ObjectOutputStream(bos); 73 74 // Serialize the "delegate". 75 oos.writeObject(delegate); 76 77 final byte[] state = bos.toByteArray(); 78 stateSize = state.length; // To allow state recovery. 79 return composeStateInternal(state, 80 super.getStateInternal()); 81 } catch (IOException e) { 82 // Workaround checked exception. 83 throw new IllegalStateException(e); 84 } 85 } 86 87 /** {@inheritDoc} */ 88 @Override 89 protected void setStateInternal(byte[] s) { 90 final byte[][] c = splitStateInternal(s, stateSize); 91 92 try { 93 final ByteArrayInputStream bis = new ByteArrayInputStream(c[0]); 94 final ObjectInputStream ois = new ObjectInputStream(bis); 95 96 delegate = (Random) ois.readObject(); 97 } catch (ClassNotFoundException e) { 98 // Workaround checked exception. 99 throw new IllegalStateException(e); 100 } catch (IOException e) { 101 // Workaround checked exception. 102 throw new IllegalStateException(e); 103 } 104 105 super.setStateInternal(c[1]); 106 } 107 }