All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.axis2.jaxws.utility.ConvertUtils Maven / Gradle / Ivy

There is a newer version: 1.8.2
Show newest version
/*
 * 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 org.apache.axis2.jaxws.utility;

import org.apache.axis2.jaxws.ExceptionFactory;
import org.apache.axis2.jaxws.i18n.Messages;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.activation.DataHandler;
import javax.imageio.ImageIO;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import javax.xml.ws.WebServiceException;
import java.awt.*;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

/**
 * Provides utilities to convert an object into a different kind of Object. For example, convert a
 * String[] into a List
 */
public class ConvertUtils {

    private static final Log log = LogFactory.getLog(ConvertUtils.class);

    /**
     * This method should return true if the convert method will succeed.
     * 

* Note that any changes to isConvertable() must also be accompanied by similar changes to * convert() * * @param obj source object or class * @param dest destination class * @return boolean true if convert(..) can convert obj to the destination class */ public static boolean isConvertable(Object obj, Class dest) { Class src = null; if (obj != null) { if (obj instanceof Class) { src = (Class)obj; } else { src = obj.getClass(); } } if (dest == null) { return false; } if (src == null) { return true; } // If we're directly assignable, we're good. if (dest.isAssignableFrom(src)) { return true; } // If it's a wrapping conversion, we're good. if (JavaUtils.getWrapperClass(src) == dest) { return true; } if (JavaUtils.getWrapperClass(dest) == src) { return true; } // If it's List -> Array or vice versa, we're good. if ((Collection.class.isAssignableFrom(src) || src.isArray()) && (Collection.class.isAssignableFrom(dest) || dest.isArray())) { // TODO this should consider the component types instead of returning true. return true; } // Allow mapping of HashMaps to Hashtables if (src == HashMap.class && dest == Hashtable.class) return true; // Allow mapping of Calendar to Date if (Calendar.class.isAssignableFrom(src) && dest == Date.class) { return true; } if (src.isPrimitive()) { return isConvertable(JavaUtils.getWrapperClass(src), dest); } if (InputStream.class.isAssignableFrom(src) && dest == byte[].class) { return true; } if (Source.class.isAssignableFrom(src) && dest == byte[].class) { return true; } if (DataHandler.class.isAssignableFrom(src) && isConvertable(byte[].class, dest)) { return true; } if (DataHandler.class.isAssignableFrom(src) && dest == Image.class) { return true; } if (DataHandler.class.isAssignableFrom(src) && dest == Source.class) { return true; } if (byte[].class.isAssignableFrom(src) && dest == String.class) { return true; } // If it's a MIME type mapping and we want a DataHandler, // then we're good. // REVIEW Do we want to support this /* if (dest.getName().equals("javax.activation.DataHandler")) { String name = src.getName(); if (src == String.class || src == java.awt.Image.class || name.equals("javax.mail.internet.MimeMultipart") || name.equals("javax.xml.transform.Source")) return true; } */ return false; } /** * Utility function to convert an Object to some desired Class. *

* Normally this is used for T[] to List processing. Other conversions are also done (i.e. * HashMap <->Hashtable, etc.) *

* Use the isConvertable() method to determine if conversion is possible. Note that any changes * to convert() must also be accompanied by similar changes to isConvertable() * * @param arg the array to convert * @param destClass the actual class we want * @return object of destClass if conversion possible, otherwise returns arg */ public static Object convert(Object arg, Class destClass) throws WebServiceException { if (destClass == null) { return arg; } if (arg != null && destClass.isAssignableFrom(arg.getClass())) { return arg; } if (log.isDebugEnabled()) { String clsName = "null"; if (arg != null) clsName = arg.getClass().getName(); log.debug("Converting an object of type " + clsName + " to an object of type " + destClass.getName()); } // Convert between Calendar and Date if (arg instanceof Calendar && destClass == Date.class) { return ((Calendar)arg).getTime(); } // Convert between HashMap and Hashtable if (arg instanceof HashMap && destClass == Hashtable.class) { return new Hashtable((HashMap)arg); } if (arg instanceof InputStream && destClass == byte[].class) { try { InputStream is = (InputStream) arg; return getBytesFromStream(is); } catch (IOException e) { throw ExceptionFactory.makeWebServiceException(e); } } if (arg instanceof Source && destClass == byte[].class) { try { if (arg instanceof StreamSource) { InputStream is = ((StreamSource) arg).getInputStream(); if (is != null) { return getBytesFromStream(is); } } ByteArrayOutputStream out = new ByteArrayOutputStream(); Result result = new StreamResult(out); Transformer transformer = TransformerFactory.newInstance().newTransformer(); transformer.transform((Source) arg, result); byte[] bytes = out.toByteArray(); return bytes; } catch (Exception e) { throw ExceptionFactory.makeWebServiceException(e); } } if (arg instanceof DataHandler) { try { InputStream is = ((DataHandler) arg).getInputStream(); if (destClass == Image.class) { return ImageIO.read(is); } else if (destClass == Source.class) { return new StreamSource(is); } byte[] bytes = getBytesFromStream(is); return convert(bytes, destClass); } catch (Exception e) { throw ExceptionFactory.makeWebServiceException(e); } } if (arg instanceof byte[] && destClass == String.class) { return new String((byte[]) arg); } // If the destination is an array and the source // is a suitable component, return an array with // the single item. /* REVIEW do we need to support atomic to array conversion ? if (arg != null && destClass.isArray() && !destClass.getComponentType().equals(Object.class) && destClass.getComponentType().isAssignableFrom(arg.getClass())) { Object array = Array.newInstance(destClass.getComponentType(), 1); Array.set(array, 0, arg); return array; } */ // Return if no conversion is available if (!(arg instanceof Collection || (arg != null && arg.getClass().isArray()))) { return arg; } if (arg == null) { return null; } // The arg may be an array or List Object destValue = null; int length = 0; if (arg.getClass().isArray()) { length = Array.getLength(arg); } else { length = ((Collection)arg).size(); } try { if (destClass.isArray()) { if (destClass.getComponentType().isPrimitive()) { Object array = Array.newInstance(destClass.getComponentType(), length); // Assign array elements if (arg.getClass().isArray()) { for (int i = 0; i < length; i++) { Array.set(array, i, Array.get(arg, i)); } } else { int idx = 0; for (Iterator i = ((Collection)arg).iterator(); i.hasNext();) { Array.set(array, idx++, i.next()); } } destValue = array; } else { Object [] array; try { array = (Object [])Array.newInstance(destClass.getComponentType(), length); } catch (Exception e) { return arg; } // Use convert to assign array elements. if (arg.getClass().isArray()) { for (int i = 0; i < length; i++) { array[i] = convert(Array.get(arg, i), destClass.getComponentType()); } } else { int idx = 0; for (Iterator i = ((Collection)arg).iterator(); i.hasNext();) { array[idx++] = convert(i.next(), destClass.getComponentType()); } } destValue = array; } } else if (Collection.class.isAssignableFrom(destClass)) { Collection newList = null; try { // if we are trying to create an interface, build something // that implements the interface if (destClass == Collection.class || destClass == List.class) { newList = new ArrayList(); } else if (destClass == Set.class) { newList = new HashSet(); } else { newList = (Collection)destClass.newInstance(); } } catch (Exception e) { // No FFDC code needed // Couldn't build one for some reason... so forget it. return arg; } if (arg.getClass().isArray()) { for (int j = 0; j < length; j++) { newList.add(Array.get(arg, j)); } } else { for (Iterator j = ((Collection)arg).iterator(); j.hasNext();) { newList.add(j.next()); } } destValue = newList; } else { destValue = arg; } } catch (Throwable t) { throw ExceptionFactory. makeWebServiceException( Messages.getMessage("convertUtils", arg.getClass().toString(), destClass.toString()), t); } return destValue; } private static byte[] getBytesFromStream(InputStream is) throws IOException { // TODO This code assumes that available is the length of the stream. byte[] bytes = new byte[is.available()]; is.read(bytes); return bytes; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy