/* Software Name : AsmDex
* Version : 1.0
*
* Copyright © 2012 France Télécom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.ow2.asmdex.encodedValue;
import org.ow2.asmdex.Opcodes;
/**
* Factory for Encoded Values.
*
* @author Julien Névo
*/
public class EncodedValueFactory {
/**
* Gets the Encoded Value from an Object containing the value to encode, and the descriptor of the
* value. It can only be a primitive element.
* @param value the Value.
* @param desc descriptor of the value.
* @return the Encoded Value.
*/
public static EncodedValue getEncodedValue(Object value, String desc) {
int type = EncodedValueUtil.getTypeFromDescriptor(desc);
return getEncodedValue(value, type);
}
/**
* Returns the Encoded Value from an Object and the type of the value.
* The value is ignored for Arrays. It has to be filled element by element.
* @param value the Value.
* @param type type of the Object (see {@link org.ow2.asmdex.Opcodes#VALUE_INT}).
* @return the Encoded Value.
*/
public static EncodedValue getEncodedValue(Object value, int type) {
EncodedValue encodedValue = null;
switch (type) {
case Opcodes.VALUE_BYTE:
encodedValue = new EncodedValueByte(value);
break;
case Opcodes.VALUE_SHORT:
encodedValue = new EncodedValueShort(value);
break;
case Opcodes.VALUE_CHAR:
encodedValue = new EncodedValueCharacter(value);
break;
case Opcodes.VALUE_INT:
encodedValue = new EncodedValueInteger(value);
break;
case Opcodes.VALUE_LONG:
encodedValue = new EncodedValueLong(value);
break;
case Opcodes.VALUE_FLOAT:
encodedValue = new EncodedValueFloat(value);
break;
case Opcodes.VALUE_DOUBLE:
encodedValue = new EncodedValueDouble(value);
break;
case Opcodes.VALUE_STRING:
encodedValue = new EncodedValueString((String) value);
break;
case Opcodes.VALUE_TYPE:
encodedValue = new EncodedValueType(value);
break;
case Opcodes.VALUE_FIELD:
encodedValue = new EncodedValueField(value);
break;
case Opcodes.VALUE_METHOD:
encodedValue = new EncodedValueMethod(value);
break;
case Opcodes.VALUE_ENUM:
encodedValue = new EncodedValueEnum(value);
break;
case Opcodes.VALUE_ARRAY:
encodedValue = new EncodedValueArray();
break;
case Opcodes.VALUE_ANNOTATION:
encodedValue = new EncodedValueAnnotation(value);
break;
case Opcodes.VALUE_NULL:
encodedValue = new EncodedValueNull();
break;
case Opcodes.VALUE_BOOLEAN:
encodedValue = new EncodedValueBoolean(value);
break;
default:
try { throw new Exception("Unknown type for this value."); }
catch (Exception e) { e.printStackTrace(); }
}
return encodedValue;
}
/**
* Returns an Encoded Value, with a value to 0 (if a primitive) or Null (if a reference).
* @param desc the descriptor of the Encoded Value.
* @return an Encoded Value, with a value to 0 (if a primitive) or Null (if a reference).
*/
public static EncodedValue getEncodedEmptyValue(String desc) {
EncodedValue encodedValue = null;
if (EncodedValueUtil.isTypeAReference(desc)) {
encodedValue = new EncodedValueNull();
} else {
int type = EncodedValueUtil.getTypeFromDescriptor(desc);
encodedValue = getEncodedValue(0, type);
}
return encodedValue;
}
/**
* Returns a Null Encoded Value.
* @return a Null Encoded Value.
*/
public static EncodedValue getEncodedNullValue() {
return new EncodedValueNull();
}
/**
* Gets an Encoded Value, only from an Object. It should only be used when creating an Annotation,
* as we have the Object but not the type. Only primitives and array of primitive can be created.
* @param value the Object containing the value to encode (primitive or Object[]).
* @return the Encoded Value.
*/
public static EncodedValue getEncodedValue(Object value) {
// First, checks the primitive.
if (value instanceof Integer) {
return new EncodedValueInteger(value);
} else if (value instanceof Boolean) {
return new EncodedValueBoolean(value);
} else if (value instanceof Byte) {
return new EncodedValueByte(value);
} else if (value instanceof Character) {
return new EncodedValueCharacter(value);
} else if (value instanceof Double) {
return new EncodedValueDouble(value);
} else if (value instanceof Float) {
return new EncodedValueFloat(value);
} else if (value instanceof Long) {
return new EncodedValueLong(value);
} else if (value instanceof Short) {
return new EncodedValueShort(value);
} else if (value instanceof String) {
return new EncodedValueString((String) value);
}
// Test the Arrays.
else if (value instanceof int[]) {
EncodedValueArray encodedArray = new EncodedValueArray();
int[] array = (int[])value;
for (int v : array) {
encodedArray.addEncodedValue(new EncodedValueInteger(v));
}
return (EncodedValue)encodedArray;
} else if (value instanceof boolean[]) {
EncodedValueArray encodedArray = new EncodedValueArray();
boolean[] array = (boolean[])value;
for (boolean v : array) {
encodedArray.addEncodedValue(new EncodedValueBoolean(v));
}
return (EncodedValue)encodedArray;
} else if (value instanceof byte[]) {
EncodedValueArray encodedArray = new EncodedValueArray();
byte[] array = (byte[])value;
for (byte v : array) {
encodedArray.addEncodedValue(new EncodedValueByte(v));
}
return (EncodedValue)encodedArray;
} else if (value instanceof char[]) {
EncodedValueArray encodedArray = new EncodedValueArray();
char[] array = (char[])value;
for (char v : array) {
encodedArray.addEncodedValue(new EncodedValueCharacter(v));
}
return (EncodedValue)encodedArray;
} else if (value instanceof double[]) {
EncodedValueArray encodedArray = new EncodedValueArray();
double[] array = (double[])value;
for (double v : array) {
encodedArray.addEncodedValue(new EncodedValueDouble(v));
}
return (EncodedValue)encodedArray;
} else if (value instanceof float[]) {
EncodedValueArray encodedArray = new EncodedValueArray();
float[] array = (float[])value;
for (float v : array) {
encodedArray.addEncodedValue(new EncodedValueFloat(v));
}
return (EncodedValue)encodedArray;
} else if (value instanceof long[]) {
EncodedValueArray encodedArray = new EncodedValueArray();
long[] array = (long[])value;
for (long v : array) {
encodedArray.addEncodedValue(new EncodedValueLong(v));
}
return (EncodedValue)encodedArray;
} else if (value instanceof short[]) {
EncodedValueArray encodedArray = new EncodedValueArray();
short[] array = (short[])value;
for (short v : array) {
encodedArray.addEncodedValue(new EncodedValueShort(v));
}
return (EncodedValue)encodedArray;
} else if (value instanceof String[]) {
EncodedValueArray encodedArray = new EncodedValueArray();
String[] array = (String[])value;
for (String v : array) {
encodedArray.addEncodedValue(new EncodedValueString(v));
}
return (EncodedValue)encodedArray;
}
else {
try { throw new Exception("Unable to find the type of this Value."); }
catch (Exception e) { e.printStackTrace(); }
return null;
}
}
}