/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
package com.sun.star.uno;
/** This class provides static methods which aim at exploring the contents of an
* Any and extracting its value. All public methods take an Object argument that
* either is the immediate object, such as Boolean, Type, interface implementation,
* or an Any that contains an object.
The methods which extract the value do a
* widening conversion. See the method comments for the respective conversions.
*/
public class AnyConverter
{
/** Determines the type of an any object.
@param object any object
@return type object
*/
static public Type getType( Object object )
{
Type t;
if (null == object)
{
t = m_XInterface_type;
}
else if (object instanceof Any)
{
t = ((Any)object).getType();
// nested any
if (TypeClass.ANY_value == t.getTypeClass().getValue())
return getType( ((Any)object).getObject() );
}
else
{
t = new Type( object.getClass() );
}
return t;
}
/** checks if the any contains the idl type void
.
@param object the object to check
@return true when the any is void, false otherwise
*/
static public boolean isVoid(Object object){
return containsType(TypeClass.VOID, object);
}
/** checks if the any contains a value of the idl type char
.
@param object the object to check
@return true when the any contains a char, false otherwise.
*/
static public boolean isChar(Object object){
return containsType(TypeClass.CHAR, object);
}
/** checks if the any contains a value of the idl type boolean
.
@param object the object to check
@return true when the any contains a boolean, false otherwise.
*/
static public boolean isBoolean(Object object){
return containsType(TypeClass.BOOLEAN, object);
}
/** checks if the any contains a value of the idl type byte
.
@param object the object to check
@return true when the any contains a byte, false otherwise.
*/
static public boolean isByte(Object object){
return containsType(TypeClass.BYTE, object);
}
/** checks if the any contains a value of the idl type short
.
@param object the object to check
@return true when the any contains a short, false otherwise.
*/
static public boolean isShort(Object object){
return containsType(TypeClass.SHORT, object);
}
/** checks if the any contains a value of the idl type long
(which maps to a java-int).
@param object the object to check
@return true when the any contains a int, false otherwise.
*/
static public boolean isInt(Object object){
return containsType(TypeClass.LONG, object);
}
/** checks if the any contains a value of the idl type hyper
(which maps to a java-long).
@param object the object to check
@return true when the any contains a long, false otherwise.
*/
static public boolean isLong(Object object){
return containsType(TypeClass.HYPER, object);
}
/** checks if the any contains a value of the idl type float
.
@param object the object to check
@return true when the any contains a float, false otherwise.
*/
static public boolean isFloat(Object object){
return containsType(TypeClass.FLOAT, object);
}
/** checks if the any contains a value of the idl type double
.
@param object the object to check
@return true when the any contains a double, false otherwise.
*/
static public boolean isDouble(Object object){
return containsType(TypeClass.DOUBLE, object);
}
/** checks if the any contains a value of the idl type string
.
@param object the object to check
@return true when the any contains a string, false otherwise.
*/
static public boolean isString(Object object){
return containsType(TypeClass.STRING, object);
}
/** checks if the any contains a value of the idl type enum
.
@param object the object to check
@return true if the any contains an enum, false otherwise
*/
static public boolean isEnum(Object object)
{
return containsType(TypeClass.ENUM, object);
}
/** checks if the any contains a value of the idl type type
.
@param object the object to check
@return true when the any contains a type, false otherwise.
*/
static public boolean isType(Object object){
return containsType(TypeClass.TYPE, object);
}
/** checks if the any contains an interface, struct, exception, sequence or enum.
If object is an any with an interface type, then true is also returned if
the any contains a null reference. This is because interfaces are allowed to have
a null value contrary to other UNO types.
@param object the object to check
@return true if the any contains an object
*/
static public boolean isObject(Object object)
{
int tc = getType(object).getTypeClass().getValue();
return (TypeClass.INTERFACE_value == tc ||
TypeClass.STRUCT_value == tc ||
TypeClass.EXCEPTION_value == tc ||
TypeClass.SEQUENCE_value == tc ||
TypeClass.ENUM_value == tc);
}
/** checks if the any contains UNO idl sequence value (meaning a java array
containing elements which are values of UNO idl types).
@param object the object to check
@return true when the any contains an object which implements interfaces, false otherwise.
*/
static public boolean isArray(Object object){
return containsType(TypeClass.SEQUENCE, object);
}
/** converts an Char object or an Any object containing a Char object into a simple char.
@param object the object to convert
@return the char contained within the object
@throws com.sun.star.lang.IllegalArgumentException in case no char is contained within object
@see #isChar
*/
static public char toChar(Object object) throws com.sun.star.lang.IllegalArgumentException{
Character ret= (Character)convertSimple(TypeClass.CHAR, null, object);
return ret.charValue();
}
/** converts an Boolean object or an Any object containing a Boolean object into a simple boolean.
@param object the object to convert
@return the boolean contained within the object
@throws com.sun.star.lang.IllegalArgumentException in case no boolean is contained within object
@see #isBoolean
*/
static public boolean toBoolean(Object object) throws com.sun.star.lang.IllegalArgumentException{
Boolean ret= (Boolean)convertSimple(TypeClass.BOOLEAN, null, object);
return ret.booleanValue();
}
/** converts an Byte object or an Any object containing a Byte object into a simple byte.
@param object the object to convert
@return the boolean contained within the object
@throws com.sun.star.lang.IllegalArgumentException in case no byte is contained within object
@see #isBoolean
*/
static public byte toByte(Object object) throws com.sun.star.lang.IllegalArgumentException{
Byte ret= (Byte)convertSimple(TypeClass.BYTE, null, object);
return ret.byteValue();
}
/** converts a number object into a simple short and allows widening conversions.
Allowed argument types are Byte, Short or Any containing these types.
@param object the object to convert
@throws com.sun.star.lang.IllegalArgumentException in case no short or byte is contained within object
@return the short contained within the object
*/
static public short toShort(Object object) throws com.sun.star.lang.IllegalArgumentException{
Short ret= (Short)convertSimple(TypeClass.SHORT, null, object);
return ret.shortValue();
}
/** converts a number object into an idl unsigned short and allows widening conversions.
Allowed argument types are Anies containing idl unsigned short values.
@param object the object to convert
@throws com.sun.star.lang.IllegalArgumentException
in case no idl unsigned short is contained within Any
@return an (unsigned) short
*/
static public short toUnsignedShort(Object object)
throws com.sun.star.lang.IllegalArgumentException
{
Short ret= (Short)convertSimple(TypeClass.UNSIGNED_SHORT, null, object);
return ret.shortValue();
}
/** converts a number object into a simple int and allows widening conversions.
Allowed argument types are Byte, Short, Integer or Any containing these types.
@param object the object to convert
@throws com.sun.star.lang.IllegalArgumentException in case no short, byte or int is contained within object.
@return the int contained within the object
*/
static public int toInt(Object object) throws com.sun.star.lang.IllegalArgumentException{
Integer ret= (Integer) convertSimple( TypeClass.LONG, null, object);
return ret.intValue();
}
/** converts a number object into an idl unsigned long and allows widening conversions.
Allowed argument types are Anies containing idl unsigned short or unsigned long values.
@param object the object to convert
@throws com.sun.star.lang.IllegalArgumentException
in case no idl unsigned short nor unsigned long is contained within Any
@return an (unsigned) int
*/
static public int toUnsignedInt(Object object)
throws com.sun.star.lang.IllegalArgumentException
{
Integer ret = (Integer)convertSimple(TypeClass.UNSIGNED_LONG, null, object);
return ret.intValue();
}
/** converts a number object into a simple long and allows widening conversions.
Allowed argument types are Byte, Short, Integer, Long or Any containing these types.
@param object the object to convert
@throws com.sun.star.lang.IllegalArgumentException in case no short, byte, int or long
is contained within object.
@return the long contained within the object
*/
static public long toLong(Object object) throws com.sun.star.lang.IllegalArgumentException{
Long ret= (Long) convertSimple( TypeClass.HYPER, null, object);
return ret.longValue();
}
/** converts a number object into an idl unsigned hyper and allows widening conversions.
Allowed argument types are Anies containing idl unsigned short, unsigned long or
unsigned hyper values.
@param object the object to convert
@throws com.sun.star.lang.IllegalArgumentException
in case no idl unsigned short, nor unsigned long nor unsigned hyper
is contained within object.
@return an (unsigned) long
*/
static public long toUnsignedLong(Object object)
throws com.sun.star.lang.IllegalArgumentException
{
Long ret = (Long)convertSimple(TypeClass.UNSIGNED_HYPER, null, object);
return ret.longValue();
}
/** converts a number object into a simple float and allows widening conversions.
Allowed argument types are Byte, Short, Float or Any containing these types.
@param object the object to convert
@throws com.sun.star.lang.IllegalArgumentException in case no byte, short or float
is contained within object.
@return the float contained within the object
*/
static public float toFloat(Object object) throws com.sun.star.lang.IllegalArgumentException{
Float ret= (Float) convertSimple( TypeClass.FLOAT,null, object);
return ret.floatValue();
}
/** converts a number object into a simple double and allows widening conversions.
Allowed argument types are Byte, Short, Int, Float, Double or Any containing these types.
@param object the object to convert
@throws com.sun.star.lang.IllegalArgumentException in case no byte, short, int, float
or double is contained within object.
@return the double contained within the object
*/
static public double toDouble(Object object) throws com.sun.star.lang.IllegalArgumentException {
Double ret= (Double) convertSimple( TypeClass.DOUBLE, null, object);
return ret.doubleValue();
}
/** converts a string or an any containing a string into a string.
@param object the object to convert
@throws com.sun.star.lang.IllegalArgumentException in case no string is contained within object.
@return the string contained within the object
*/
static public String toString(Object object) throws com.sun.star.lang.IllegalArgumentException {
return (String) convertSimple( TypeClass.STRING, null, object);
}
/** converts a Type or an any containing a Type into a Type.
@param object the object to convert
@throws com.sun.star.lang.IllegalArgumentException in case no type is contained within object.
@return the type contained within the object
*/
static public Type toType(Object object) throws com.sun.star.lang.IllegalArgumentException {
return (Type) convertSimple( TypeClass.TYPE, null, object);
}
/** converts a UNO object (struct, exception, sequence, enum or interface) or an Any containing
* these types into an UNO object of a specified destination type.
* For interfaces, the argument object is queried for the interface specified
* by the type argument. That query (UnoRuntime.queryInterface) might return null,
* if the interface is not implemented or a null-ref or a VOID any is given.
*
* @param type type of the returned value
* @param object the object that is to be converted
* @return destination object
* @throws com.sun.star.lang.IllegalArgumentException
* in case conversion is not possible
*/
static public Object toObject(Type type, Object object)
throws com.sun.star.lang.IllegalArgumentException
{
return convertSimple( type.getTypeClass(), type, object );
}
/** converts a UNO object (struct, exception, sequence, enum or interface) or an Any containing
* these types into an UNO object of a specified destination type.
* For interfaces, the argument object is queried for the interface specified
* by the type argument. That query (UnoRuntime.queryInterface) might return null,
* if the interface is not implemented or a null-ref or a VOID any is given.
*
* @param clazz class of the returned value
* @param object the object that is to be converted
* @return destination object
* @throws com.sun.star.lang.IllegalArgumentException
* in case conversion is not possible
*/
static public Object toObject(Class clazz, Object object)
throws com.sun.star.lang.IllegalArgumentException
{
return toObject( new Type( clazz ), object );
}
/** converts an array or an any containing an array into an array.
@param object the object to convert
@throws com.sun.star.lang.IllegalArgumentException in case no array is contained within object.
@return the array contained within the object
*/
static public Object toArray( Object object) throws com.sun.star.lang.IllegalArgumentException {
return convertSimple( TypeClass.SEQUENCE, null, object);
}
/**
Examines the argument object if is correspond to the type in argument what.
object is either matched directly against the type or if it is an any then the
contained object is matched against the type.
*/
static private boolean containsType( TypeClass what, Object object){
return (getType(object).getTypeClass().getValue() == what.getValue());
}
static private final Type m_XInterface_type = new Type( XInterface.class );
static private Object convertSimple( TypeClass destTClass, Type destType, Object object_ )
throws com.sun.star.lang.IllegalArgumentException
{
Object object;
Type type;
if (object_ instanceof Any)
{
// unbox
Any a = (Any)object_;
object = a.getObject();
type = a.getType();
// nested any
if (TypeClass.ANY_value == type.getTypeClass().getValue())
return convertSimple( destTClass, destType, object );
}
else
{
object = object_;
type = (null == object ? m_XInterface_type : new Type( object.getClass() ));
}
int tc = type.getTypeClass().getValue();
int dest_tc = destTClass.getValue();
if (null == object)
{
// special for interfaces
if (TypeClass.INTERFACE_value == tc && dest_tc == tc)
return null;
}
else
{
switch (dest_tc)
{
case TypeClass.CHAR_value:
if (tc == TypeClass.CHAR_value)
return object;
break;
case TypeClass.BOOLEAN_value:
if (tc == TypeClass.BOOLEAN_value)
return object;
break;
case TypeClass.BYTE_value:
if (tc == TypeClass.BYTE_value)
return object;
break;
case TypeClass.SHORT_value:
switch (tc)
{
case TypeClass.BYTE_value:
return new Short( ((Byte)object).byteValue() );
case TypeClass.SHORT_value:
return object;
}
break;
case TypeClass.UNSIGNED_SHORT_value:
switch (tc)
{
case TypeClass.UNSIGNED_SHORT_value:
return object;
}
break;
case TypeClass.LONG_value:
switch (tc)
{
case TypeClass.BYTE_value:
return new Integer( ((Byte)object).byteValue() );
case TypeClass.SHORT_value:
case TypeClass.UNSIGNED_SHORT_value:
return new Integer( ((Short)object).shortValue() );
case TypeClass.LONG_value:
return object;
}
break;
case TypeClass.UNSIGNED_LONG_value:
switch (tc)
{
case TypeClass.UNSIGNED_SHORT_value:
return new Integer( ((Short)object).shortValue() );
case TypeClass.UNSIGNED_LONG_value:
return object;
}
break;
case TypeClass.HYPER_value:
switch (tc)
{
case TypeClass.BYTE_value:
return new Long( ((Byte)object).byteValue() );
case TypeClass.SHORT_value:
case TypeClass.UNSIGNED_SHORT_value:
return new Long( ((Short)object).shortValue() );
case TypeClass.LONG_value:
case TypeClass.UNSIGNED_LONG_value:
return new Long( ((Integer)object).intValue() );
case TypeClass.HYPER_value:
return object;
}
break;
case TypeClass.UNSIGNED_HYPER_value:
switch (tc)
{
case TypeClass.UNSIGNED_SHORT_value:
return new Long( ((Short)object).shortValue() );
case TypeClass.UNSIGNED_LONG_value:
return new Long( ((Integer)object).intValue() );
case TypeClass.UNSIGNED_HYPER_value:
return object;
}
break;
case TypeClass.FLOAT_value:
switch (tc)
{
case TypeClass.BYTE_value:
return new Float( ((Byte)object).byteValue() );
case TypeClass.SHORT_value:
return new Float( ((Short)object).shortValue() );
case TypeClass.FLOAT_value:
return object;
}
break;
case TypeClass.DOUBLE_value:
switch (tc)
{
case TypeClass.BYTE_value:
return new Double( ((Byte)object).byteValue() );
case TypeClass.SHORT_value:
return new Double( ((Short)object).shortValue() );
case TypeClass.LONG_value:
return new Double( ((Integer)object).intValue() );
case TypeClass.FLOAT_value:
return new Double( ((Float)object).floatValue() );
case TypeClass.DOUBLE_value:
return object;
}
break;
case TypeClass.ENUM_value:
if (tc == TypeClass.ENUM_value &&
(null == destTClass || destType.equals( type ) /* optional destType */))
{
return object;
}
break;
case TypeClass.STRING_value:
if (tc == TypeClass.STRING_value)
return object;
break;
case TypeClass.TYPE_value:
if (tc == TypeClass.TYPE_value)
return object;
break;
case TypeClass.INTERFACE_value:
// Because object is a class, not an interface, it is
// controversial what kind of Type "new Type(object.class)"
// above should return (UNKNOWN or INTERFACE), so that we should
// not check here for "tc == TypeClass.INTERFACE_value".
// Instead, we check whether object (indirectly) derives from
// XInterface:
if (object instanceof XInterface)
return UnoRuntime.queryInterface( destType, object );
break;
case TypeClass.STRUCT_value:
case TypeClass.EXCEPTION_value:
if (destType.isSupertypeOf(type)) {
return object;
}
break;
case TypeClass.SEQUENCE_value:
if (tc == TypeClass.SEQUENCE_value &&
(null == destType || destType.equals( type ) /* optional destType */))
{
return object;
}
break;
}
}
throw new com.sun.star.lang.IllegalArgumentException(
"The Argument did not hold the proper type");
}
}