/*
* Copyright (C) 2009 eXo Platform SAS.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.exoplatform.services.jcr.impl.tools.tree.generator;
import org.exoplatform.services.jcr.util.IdGenerator;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Calendar;
import java.util.Random;
import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
import javax.jcr.Value;
import javax.jcr.ValueFactory;
/**
* @author <a href="mailto:Sergey.Kabashnyuk@gmail.com">Sergey Kabashnyuk</a>
* @version $Id: RandomValueNodeGenerator.java 11907 2008-03-13 15:36:21Z ksm $
*/
public class RandomValueNodeGenerator extends WeightNodeGenerator
{
private static final Random random = new Random();
protected static Log log = ExoLogger.getLogger("exo.jcr.component.core.RandomValueNodeGenerator");
private final int maxBinarySize;
private final int maxPropertiesCount;
private final int maxValuesCount;
private final boolean isAddMultivalued;
private final ValueFactory valueFactory;
public RandomValueNodeGenerator(ValueFactory valueFactory, int maxDepth, int maxWidth, int maxPropertiesCount,
int maxValuesCount, int maxBinarySize)
{
super(maxDepth, maxWidth);
this.valueFactory = valueFactory;
this.maxPropertiesCount = maxPropertiesCount;
this.maxValuesCount = maxValuesCount;
this.maxBinarySize = maxBinarySize;
this.isAddMultivalued = maxValuesCount > 1;
}
private Value getNewValue(int propType) throws FileNotFoundException, IOException, IllegalStateException,
RepositoryException
{
Value val = null;
byte[] buffer;
switch (propType)
{
case PropertyType.STRING :
val = valueFactory.createValue(IdGenerator.generate(), propType);
break;
case PropertyType.BINARY :
int size = random.nextInt(maxBinarySize);
InputStream inputStream = null;
File file = null;
if (size < 1024 * 200)
{// 200K
buffer = new byte[random.nextInt(maxBinarySize)];
random.nextBytes(buffer);
inputStream = new ByteArrayInputStream(buffer);
}
else
{
file = createBLOBTempFile(size);
inputStream = new BufferedInputStream(new FileInputStream(file));
}
val = valueFactory.createValue(inputStream);
val.getStream();// to spool data;
inputStream.close();
if (file != null)
file.delete();
break;
case PropertyType.BOOLEAN :
val = valueFactory.createValue(random.nextBoolean());
break;
case PropertyType.DATE :
val = valueFactory.createValue(Calendar.getInstance());
break;
case PropertyType.DOUBLE :
val = valueFactory.createValue(random.nextDouble());
break;
case PropertyType.LONG :
val = valueFactory.createValue(random.nextLong());
break;
case PropertyType.NAME :
val = valueFactory.createValue(IdGenerator.generate(), propType);
break;
case PropertyType.PATH :
val = valueFactory.createValue(currentNode.getPath(), propType);
break;
default :
break;
}
return val;
}
@Override
protected void addProperties() throws RepositoryException
{
int propCount = random.nextInt(maxPropertiesCount);
log.info("add " + propCount + " properties to the node " + currentNode.getPath());
for (int i = 0; i < propCount; i++)
{
log.info("add property number " + i);
int valueType = random.nextInt(8) + 1;
try
{
if (this.isAddMultivalued && random.nextBoolean())
{
int valueCount = random.nextInt(maxValuesCount) + 1;
Value[] values = new Value[valueCount];
for (int j = 0; j < valueCount; j++)
{
values[j] = getNewValue(valueType);
}
log.info("add " + valueCount + " values " + " type " + valueType);
currentNode.setProperty(IdGenerator.generate(), values);
}
else
{
log.info("add " + " type " + valueType);
currentNode.setProperty(IdGenerator.generate(), getNewValue(valueType));
}
}
catch (FileNotFoundException e)
{
throw new RepositoryException(e);
}
catch (IllegalStateException e)
{
throw new RepositoryException(e);
}
catch (IOException e)
{
throw new RepositoryException(e);
}
}
}
public static File createBLOBTempFile(int sizeInb) throws IOException
{
// create test file
byte[] data = new byte[1024]; // 1Kb
File testFile = File.createTempFile("randomsizefile", ".tmp");
FileOutputStream tempOut = new FileOutputStream(testFile);
for (int i = 0; i < sizeInb; i += 1024)
{
if (i + 1024 > sizeInb)
{
byte[] rest = new byte[sizeInb - i];
random.nextBytes(rest);
tempOut.write(rest);
continue;
}
random.nextBytes(data);
tempOut.write(data);
}
tempOut.close();
testFile.deleteOnExit(); // delete on test exit
log.info("Temp file created: " + testFile.getAbsolutePath() + " size: " + testFile.length());
return testFile;
}
}