/*******************************************************************************
 * Copyright (c) 2004, 2005 Actuate Corporation.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *  Actuate Corporation  - initial API and implementation
 *******************************************************************************/

package org.eclipse.birt.data.engine.olap.data.util;

import java.io.IOException;
import java.util.Arrays;

/**
 * A List class providing the service of reading/writing objects from one file
 * when cache is not enough . It makes the reading/writing objects transparent.
 */

public class StructureDiskArray extends BaseDiskArray
{

	private IStructureCreator creator;
	private ObjectWriter[] fieldWriters;
	private ObjectReader[] fieldReaders;

	/**
	 * @throws IOException 
	 * 
	 * 
	 */
	public StructureDiskArray( IStructureCreator creator ) throws IOException
	{
		super( );
		this.creator = creator;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.birt.data.engine.cache.BasicCachedList#writeObject(java.io.DataOutputStream,
	 *      java.lang.Object)
	 */
	protected void writeObject( Object object ) throws IOException
	{
		if ( object == null )
		{
			randomAccessFile.writeShort( NULL_VALUE );
			return;
		}
		IStructure cachedObject = (IStructure) object;
		Object[] objects = cachedObject.getFieldValues( );
		randomAccessFile.writeShort( (short) objects.length );
		if ( fieldWriters == null || fieldWriters.length < objects.length )
		{
			createReadersAndWriters( objects.length );
		}
		for ( int i = 0; i < objects.length; i++ )
		{
			if( i >= fieldWriters.length )
			{
				fieldWriters[fieldWriters.length-1].write( randomAccessFile, objects[i] );
			}
			else
			{
				fieldWriters[i].write( randomAccessFile, objects[i] );
			}
		}
	}

	/**
	 * 
	 * @param size
	 */
	private void createReadersAndWriters( int size )
	{
		if ( fieldWriters == null && fieldReaders == null )
		{
			fieldWriters = new ObjectWriter[size];
			fieldReaders = new ObjectReader[size];
			for ( int i = 0; i < size; i++ )
			{
				fieldWriters[i] = new ObjectWriter( );
				fieldReaders[i] = new ObjectReader( );
			}
		}
		else
		{
			int i = fieldWriters.length;
			fieldReaders = Arrays.copyOf( fieldReaders, size );
			fieldWriters = Arrays.copyOf( fieldWriters, size );
			for ( ; i < fieldReaders.length; i++ )
			{
				fieldWriters[i] = new ObjectWriter( );
				fieldReaders[i] = new ObjectReader( );
			}
		}
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.birt.data.engine.cache.BasicCachedList#readObject(java.io.DataInputStream)
	 */
	protected Object readObject( ) throws IOException
	{
		short fieldCount = randomAccessFile.readShort( );
		if ( fieldCount == NULL_VALUE )
		{
			return null;
		}
		Object[] objects = new Object[fieldCount];
		for ( int i = 0; i < objects.length; i++ )
		{
			if ( i < fieldReaders.length && fieldReaders[i].getDataType( ) != fieldWriters[i].getDataType( ) )
				fieldReaders[i].setDataType( fieldWriters[i].getDataType( ) );
			if( i >= fieldReaders.length )
			{
				objects[i] = fieldReaders[fieldReaders.length-1].read( randomAccessFile );
			}
			else
			{
				objects[i] = fieldReaders[i].read( randomAccessFile );
			}
		}
		return creator.createInstance( objects );
	}
	
	public void clear( ) throws IOException
	{
		fieldWriters = null;
		fieldReaders = null;
		super.clear();
	}

}
@@ -628,19 +628,26 @@
 ava.
-util
+lang.reflect
 .Array
-s
 ;%0A%0A/
@@ -2420,31 +2420,24 @@
 ldReaders = 
-Arrays.
 copyOf( fiel
@@ -2476,15 +2476,8 @@
 s = 
-Arrays.
 copy
@@ -2636,24 +2636,24 @@
 er( );%0A%09%09%09%7D%0A
-
 %09%09%7D%0A%09%7D%0A%09%0A%09/*
@@ -2649,16 +2649,404 @@
 %09%7D%0A%09%7D%0A%09%0A
+%09public static %3CT, U%3E T%5B%5D copyOf( U%5B%5D original, int newLength )%0A%09%7B%0A%09%09T%5B%5D copy = ( (Object) original.getClass( ) == (Object) Object%5B%5D.class )%0A%09%09%09%09? (T%5B%5D) new Object%5BnewLength%5D%0A%09%09%09%09: (T%5B%5D) Array.newInstance( original.getClass( )%0A%09%09%09%09%09%09.getComponentType( ), newLength );%0A%09%09System.arraycopy( original,%0A%09%09%09%090,%0A%09%09%09%09copy,%0A%09%09%09%090,%0A%09%09%09%09Math.min( original.length, newLength ) );%0A%09%09return copy;%0A%09%7D%0A%09%0A
 %09/*%0A%09 * 

Remove reference to JDK6 API.