/****************************************************************************** | |
* 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.reflect; | |
import java.util.Collection; | |
import java.util.List; | |
import java.util.Set; | |
import org.eclipse.gemini.blueprint.blueprint.reflect.internal.support.OrderedManagedProperties; | |
import org.osgi.service.blueprint.reflect.CollectionMetadata; | |
import org.osgi.service.blueprint.reflect.ComponentMetadata; | |
import org.osgi.service.blueprint.reflect.IdRefMetadata; | |
import org.osgi.service.blueprint.reflect.MapEntry; | |
import org.osgi.service.blueprint.reflect.MapMetadata; | |
import org.osgi.service.blueprint.reflect.Metadata; | |
import org.osgi.service.blueprint.reflect.NullMetadata; | |
import org.osgi.service.blueprint.reflect.PropsMetadata; | |
import org.osgi.service.blueprint.reflect.RefMetadata; | |
import org.osgi.service.blueprint.reflect.ValueMetadata; | |
import org.springframework.beans.BeanMetadataElement; | |
import org.springframework.beans.factory.annotation.Value; | |
import org.springframework.beans.factory.config.RuntimeBeanNameReference; | |
import org.springframework.beans.factory.config.RuntimeBeanReference; | |
import org.springframework.beans.factory.support.ManagedArray; | |
import org.springframework.beans.factory.support.ManagedList; | |
import org.springframework.beans.factory.support.ManagedMap; | |
import org.springframework.beans.factory.support.ManagedProperties; | |
import org.springframework.beans.factory.support.ManagedSet; | |
/** | |
* Adapter between OSGi's Blueprint {@link Value} and Spring {@link BeanMetadataElement}. | |
* | |
* @see ValueFactory | |
* @author Costin Leau | |
*/ | |
class BeanMetadataElementFactory { | |
static BeanMetadataElement buildBeanMetadata(Metadata metadata) { | |
return buildBeanMetadata(metadata, null); | |
} | |
/** | |
* Creates the equivalent Spring metadata for the given value. | |
* | |
* @param value | |
* @param defaultTypeName | |
* @return | |
*/ | |
static BeanMetadataElement buildBeanMetadata(Metadata value, String defaultTypeName) { | |
if (value instanceof ValueMetadata) { | |
ValueMetadata typedString = (ValueMetadata) value; | |
String specifiedType = typedString.getType(); | |
if (specifiedType == null) { | |
specifiedType = defaultTypeName; | |
} | |
return new org.springframework.beans.factory.config.TypedStringValue(typedString.getStringValue(), | |
specifiedType); | |
} | |
if (value instanceof ComponentMetadata) { | |
ComponentMetadata component = (ComponentMetadata) value; | |
return MetadataFactory.buildBeanDefinitionFor(component); | |
} | |
// null vs non-null check | |
if (value instanceof NullMetadata) { | |
return new org.springframework.beans.factory.config.TypedStringValue(null); | |
} | |
if (value instanceof RefMetadata) { | |
RefMetadata reference = (RefMetadata) value; | |
return new RuntimeBeanReference(reference.getComponentId()); | |
} | |
if (value instanceof IdRefMetadata) { | |
IdRefMetadata reference = (IdRefMetadata) value; | |
return new RuntimeBeanNameReference(reference.getComponentId()); | |
} | |
if (value instanceof CollectionMetadata) { | |
CollectionMetadata collection = (CollectionMetadata) value; | |
Class<?> type = collection.getCollectionClass(); | |
List<Metadata> values = collection.getValues(); | |
Collection coll; | |
if (List.class.isAssignableFrom(type)) { | |
ManagedList<BeanMetadataElement> list = new ManagedList<BeanMetadataElement>(values.size()); | |
list.setElementTypeName(collection.getValueType()); | |
coll = list; | |
} else if (Set.class.isAssignableFrom(type)) { | |
ManagedSet<BeanMetadataElement> set = new ManagedSet<BeanMetadataElement>(values.size()); | |
set.setElementTypeName(collection.getValueType()); | |
coll = set; | |
} else if (Object[].class.isAssignableFrom(type)) { | |
ManagedArray array = new ManagedArray(collection.getValueType(), values.size()); | |
coll = array; | |
} else { | |
throw new IllegalArgumentException("Cannot create collection for type " + type); | |
} | |
for (Metadata val : values) { | |
coll.add(BeanMetadataElementFactory.buildBeanMetadata(val, collection.getValueType())); | |
} | |
return (BeanMetadataElement) coll; | |
} | |
if (value instanceof MapMetadata) { | |
MapMetadata mapValue = (MapMetadata) value; | |
List<MapEntry> entries = mapValue.getEntries(); | |
String defaultKeyType = mapValue.getKeyType(); | |
String defaultValueType = mapValue.getValueType(); | |
ManagedMap<BeanMetadataElement, BeanMetadataElement> managedMap = | |
new ManagedMap<BeanMetadataElement, BeanMetadataElement>(entries.size()); | |
managedMap.setKeyTypeName(defaultKeyType); | |
managedMap.setValueTypeName(defaultValueType); | |
for (MapEntry mapEntry : entries) { | |
managedMap.put(BeanMetadataElementFactory.buildBeanMetadata(mapEntry.getKey(), defaultKeyType), | |
BeanMetadataElementFactory.buildBeanMetadata(mapEntry.getValue(), defaultValueType)); | |
} | |
return managedMap; | |
} | |
if (value instanceof PropsMetadata) { | |
PropsMetadata propertiesValue = (PropsMetadata) value; | |
List<MapEntry> entries = propertiesValue.getEntries(); | |
ManagedProperties managedProperties = new OrderedManagedProperties(); | |
for (MapEntry mapEntry : entries) { | |
managedProperties.put(BeanMetadataElementFactory.buildBeanMetadata(mapEntry.getKey()), | |
BeanMetadataElementFactory.buildBeanMetadata(mapEntry.getValue())); | |
} | |
} | |
throw new IllegalArgumentException("Unknown value type " + value.getClass()); | |
} | |
} |