package fr.unistra.pelican.util.data;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import fr.unistra.pelican.util.Offset;
/**
* Represents an array of instances of {@link Data}.
* These objects must not necessary be of the same class.
*
* @author Régis Witz
*/
public class DataArrayData extends Data {
/** The effective data stored in the object. */
Data[] values;
@Override
public Data clone() {
DataArrayData data = new DataArrayData();
data.setDescriptor( this.getDescriptor() );
data.setValues( this.values.clone() );
return data;
}
@Override
public double distance( Data data ) {
Data[] values2 = ( ( DataArrayData ) data ).values;
int len = this.values.length;
if ( len != values2.length ) return 1;
double distance = 0;
for ( int i = 0 ; i < this.values.length ; i++ )
distance += this.values[i].distance( values2[i] );
if ( len > 0 ) distance /= (double) len;
assert 0 <= distance && distance <= 1 :
this.getClass().getName() + " distance €[0;1] unverified : " + distance + ".";
return distance;
}
@Override
public boolean equals( Data data ) {
Data[] values2 = ( ( DataArrayData ) data).values;
if ( this.values.length != values2.length ) return false;
for ( int i = 0; i < this.values.length ; i++ )
if ( !this.values[i].equals( values2[i] ) ) return false;
return true;
}
@Override
public Object getValues() { return this.values; }
@Override
public void setValues( Object values ) { this.values = ( Data[] ) values; }
@Override
public String toString() {
String s = "<DATA="+this.getClass().getName()+">";
if ( this.getDescriptor() != null ) s += "," + this.getDescriptor().getName();
s += "," + this.values.length;
for ( int i = 0 ; i < this.values.length ; i++ ) s += "," + this.values[i].toString();
s += ",</DATA>";
return s;
}
@SuppressWarnings( "unchecked" )
public static DataArrayData getParsedInstance( String[] words, Offset c ) {
DataArrayData data = null;
Data [] values;
assert words[c.offset].startsWith(
"<DATA="+new DataArrayData().getClass().getName() ) :
"Wrong position of offset " + c.offset + ": \"" + words[c.offset] + "\".";
c.offset++; // pass <Data=...>
if ( c.offset < words.length ) {
data = new DataArrayData();
try {
Class desc = Class.forName( words[c.offset++] );
data.setDescriptor( desc );
} catch( ClassNotFoundException ex ) { ex.printStackTrace(); }
values = new Data[ new Integer( words[c.offset++] ) ];
for ( int i = 0 ; i < values.length ; i++ ) {
String dataClassName = null;
Class dataClass = null;
Method method;
int start = words[c.offset].indexOf( "<DATA=" );
int end = words[c.offset].indexOf( ">" );
dataClassName = words[c.offset].substring( start+6,end );
try { dataClass = Class.forName( dataClassName ); }
catch ( ClassNotFoundException ex ) { ex.printStackTrace(); }
try {
method = dataClass.getMethod( "getParsedInstance",
String[].class,
Offset.class );
values[i] = ( Data ) method.invoke( null,words,c );
}
catch ( IllegalAccessException ex ) { ex.printStackTrace(); }
catch ( InvocationTargetException ex ) { ex.printStackTrace(); }
catch ( NoSuchMethodException ex ) { ex.printStackTrace(); }
}
c.offset++; // pass </DATA>
data.setValues( values );
}
return data;
}
}