/******************************************************************************
* Copyright (c) 2006, 2010 VMware Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Apache License v2.0 which accompanies this distribution.
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html and the Apache License v2.0
* is available at http://www.opensource.org/licenses/apache2.0.php.
* You may elect to redistribute this code under either of these licenses.
*
* Contributors:
* VMware Inc.
*****************************************************************************/
package org.eclipse.gemini.blueprint.blueprint.container;
import java.awt.Point;
import java.util.LinkedList;
import java.util.List;
import java.util.TreeMap;
import org.osgi.service.blueprint.container.Converter;
import org.osgi.service.blueprint.container.ReifiedType;
/**
* @author Costin Leau
*/
public class GenericConverter implements Converter {
public Object convert(Object s, ReifiedType type) throws Exception {
switch (type.size()) {
// we should only be getting called for things we've already vetted,
// so we can take some short cuts.
case 1: {
Class<?> targetType = type.getRawClass();
// we only handle LinkedList<Point>, and only from an array of ints.
if (targetType == LinkedList.class) {
LinkedList result = new LinkedList();
int[] source = (int[]) s;
int counter = 0;
while (counter < source.length) {
Point p = new Point(source[counter], source[counter + 1]);
result.add(p);
counter += 2;
}
return result;
} else if (targetType == GenericHolder.class) {
Class<?> listType = type.getActualTypeArgument(0).getRawClass();
GenericHolder source = (GenericHolder) s;
// this just validates the type
if (listType.isInstance(source.getTarget())) {
return source;
}
}
}
case 2: {
TreeMap result = new TreeMap();
List source = (List) s;
int counter = 0;
while (counter < source.size()) {
String index = (String) source.get(counter);
int x = Integer.parseInt((String) source.get(counter + 1));
int y = Integer.parseInt((String) source.get(counter + 2));
Point p = new Point(x, y);
result.put(index, p);
counter += 3;
}
return result;
}
}
// we're supposed to throw an exception if we can't convert
throw new Exception("Unconvertable object type");
}
public boolean canConvert(Object source, ReifiedType type) {
switch (type.size()) {
case 0:
return false;
// probably a collection type with a target. We only handle some
// very specific conversions here.
case 1: {
Class<?> targetType = type.getRawClass();
// we only handle LinkedList<Point>, and only from an array of ints.
if (targetType == LinkedList.class) {
Class<?> listType = type.getActualTypeArgument(0).getRawClass();
if (!(listType == Point.class)) {
return false;
}
// the only source we handle is an array of ints with even size
if (source instanceof int[] && (((int[]) source).length % 2) == 0) {
return true;
}
return false;
}
// this is our generic type class. Check for convertability also
else if (targetType == GenericHolder.class) {
// all we do is handle the held value
return source instanceof GenericHolder;
}
return false;
}
case 2: {
Class<?> targetType = type.getRawClass();
// we only handle TreeMap<String, Point>, and only from a List of triplet values
if (targetType != TreeMap.class) {
return false;
}
Class<?> indexType = type.getActualTypeArgument(0).getRawClass();
if (indexType != String.class) {
return false;
}
Class<?> itemType = type.getActualTypeArgument(1).getRawClass();
if (itemType != Point.class) {
return false;
}
// the only source we handle is a list of values with a size that's
// a multiple of 3.
if (source instanceof List && (((List) source).size() % 3) == 0) {
return true;
}
return false;
}
default:
// don't understand this
return false;
}
}
}