| /** |
| * 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.aries.blueprint.ext; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.regex.Matcher; |
| import java.util.regex.Pattern; |
| |
| import org.apache.aries.blueprint.ComponentDefinitionRegistry; |
| import org.apache.aries.blueprint.ComponentDefinitionRegistryProcessor; |
| import org.apache.aries.blueprint.mutable.MutableBeanArgument; |
| import org.apache.aries.blueprint.mutable.MutableBeanMetadata; |
| import org.apache.aries.blueprint.mutable.MutableBeanProperty; |
| import org.apache.aries.blueprint.mutable.MutableCollectionMetadata; |
| import org.apache.aries.blueprint.mutable.MutableMapEntry; |
| import org.apache.aries.blueprint.mutable.MutableMapMetadata; |
| import org.apache.aries.blueprint.mutable.MutablePropsMetadata; |
| import org.apache.aries.blueprint.mutable.MutableReferenceListener; |
| import org.apache.aries.blueprint.mutable.MutableRegistrationListener; |
| import org.apache.aries.blueprint.mutable.MutableServiceMetadata; |
| import org.osgi.service.blueprint.container.ComponentDefinitionException; |
| import org.osgi.service.blueprint.reflect.BeanArgument; |
| import org.osgi.service.blueprint.reflect.BeanMetadata; |
| import org.osgi.service.blueprint.reflect.BeanProperty; |
| import org.osgi.service.blueprint.reflect.CollectionMetadata; |
| 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.NonNullMetadata; |
| import org.osgi.service.blueprint.reflect.PropsMetadata; |
| import org.osgi.service.blueprint.reflect.ReferenceListMetadata; |
| import org.osgi.service.blueprint.reflect.ReferenceListener; |
| import org.osgi.service.blueprint.reflect.ReferenceMetadata; |
| import org.osgi.service.blueprint.reflect.RegistrationListener; |
| import org.osgi.service.blueprint.reflect.ServiceMetadata; |
| import org.osgi.service.blueprint.reflect.Target; |
| import org.osgi.service.blueprint.reflect.ValueMetadata; |
| |
| /** |
| * Abstract class for property placeholders. |
| * |
| * @version $Rev: 916935 $, $Date: 2010-02-27 10:05:06 +0000 (Sat, 27 Feb 2010) $ |
| */ |
| public abstract class AbstractPropertyPlaceholder implements ComponentDefinitionRegistryProcessor { |
| |
| private String placeholderPrefix = "${"; |
| private String placeholderSuffix = "}"; |
| private Pattern pattern; |
| |
| public String getPlaceholderPrefix() { |
| return placeholderPrefix; |
| } |
| |
| public void setPlaceholderPrefix(String placeholderPrefix) { |
| this.placeholderPrefix = placeholderPrefix; |
| } |
| |
| public String getPlaceholderSuffix() { |
| return placeholderSuffix; |
| } |
| |
| public void setPlaceholderSuffix(String placeholderSuffix) { |
| this.placeholderSuffix = placeholderSuffix; |
| } |
| |
| public void process(ComponentDefinitionRegistry registry) throws ComponentDefinitionException { |
| for (String name : registry.getComponentDefinitionNames()) { |
| processMetadata(registry.getComponentDefinition(name)); |
| } |
| } |
| |
| protected Metadata processMetadata(Metadata metadata) { |
| if (metadata instanceof BeanMetadata) { |
| return processBeanMetadata((BeanMetadata) metadata); |
| } else if (metadata instanceof ReferenceListMetadata) { |
| return processRefCollectionMetadata((ReferenceListMetadata) metadata); |
| } else if (metadata instanceof ReferenceMetadata) { |
| return processReferenceMetadata((ReferenceMetadata) metadata); |
| } else if (metadata instanceof ServiceMetadata) { |
| return processServiceMetadata((ServiceMetadata) metadata); |
| } else if (metadata instanceof CollectionMetadata) { |
| return processCollectionMetadata((CollectionMetadata) metadata); |
| } else if (metadata instanceof MapMetadata) { |
| return processMapMetadata((MapMetadata) metadata); |
| } else if (metadata instanceof PropsMetadata) { |
| return processPropsMetadata((PropsMetadata) metadata); |
| } else if (metadata instanceof ValueMetadata) { |
| return processValueMetadata((ValueMetadata) metadata); |
| } else { |
| return metadata; |
| } |
| } |
| |
| protected Metadata processBeanMetadata(BeanMetadata component) { |
| for (BeanArgument arg : component.getArguments()) { |
| ((MutableBeanArgument) arg).setValue(processMetadata(arg.getValue())); |
| } |
| for (BeanProperty prop : component.getProperties()) { |
| ((MutableBeanProperty) prop).setValue(processMetadata(prop.getValue())); |
| } |
| ((MutableBeanMetadata) component).setFactoryComponent((Target) processMetadata(component.getFactoryComponent())); |
| return component; |
| } |
| |
| protected Metadata processServiceMetadata(ServiceMetadata component) { |
| ((MutableServiceMetadata) component).setServiceComponent((Target) processMetadata(component.getServiceComponent())); |
| List<MapEntry> entries = new ArrayList<MapEntry>(component.getServiceProperties()); |
| for (MapEntry entry : entries) { |
| ((MutableServiceMetadata) component).removeServiceProperty(entry); |
| } |
| for (MapEntry entry : processMapEntries(entries)) { |
| ((MutableServiceMetadata) component).addServiceProperty(entry); |
| } |
| for (RegistrationListener listener : component.getRegistrationListeners()) { |
| ((MutableRegistrationListener) listener).setListenerComponent((Target) processMetadata(listener.getListenerComponent())); |
| } |
| return component; |
| } |
| |
| protected Metadata processReferenceMetadata(ReferenceMetadata component) { |
| for (ReferenceListener listener : component.getReferenceListeners()) { |
| ((MutableReferenceListener) listener).setListenerComponent((Target) processMetadata(listener.getListenerComponent())); |
| } |
| return component; |
| } |
| |
| protected Metadata processRefCollectionMetadata(ReferenceListMetadata component) { |
| for (ReferenceListener listener : component.getReferenceListeners()) { |
| ((MutableReferenceListener) listener).setListenerComponent((Target) processMetadata(listener.getListenerComponent())); |
| } |
| return component; |
| } |
| |
| protected Metadata processPropsMetadata(PropsMetadata metadata) { |
| List<MapEntry> entries = new ArrayList<MapEntry>(metadata.getEntries()); |
| for (MapEntry entry : entries) { |
| ((MutablePropsMetadata) metadata).removeEntry(entry); |
| } |
| for (MapEntry entry : processMapEntries(entries)) { |
| ((MutablePropsMetadata) metadata).addEntry(entry); |
| } |
| return metadata; |
| } |
| |
| protected Metadata processMapMetadata(MapMetadata metadata) { |
| List<MapEntry> entries = new ArrayList<MapEntry>(metadata.getEntries()); |
| for (MapEntry entry : entries) { |
| ((MutableMapMetadata) metadata).removeEntry(entry); |
| } |
| for (MapEntry entry : processMapEntries(entries)) { |
| ((MutableMapMetadata) metadata).addEntry(entry); |
| } |
| return metadata; |
| } |
| |
| protected List<MapEntry> processMapEntries(List<MapEntry> entries) { |
| for (MapEntry entry : entries) { |
| ((MutableMapEntry) entry).setKey((NonNullMetadata) processMetadata(entry.getKey())); |
| ((MutableMapEntry) entry).setValue(processMetadata(entry.getValue())); |
| } |
| return entries; |
| } |
| |
| protected Metadata processCollectionMetadata(CollectionMetadata metadata) { |
| List<Metadata> values = new ArrayList<Metadata>(metadata.getValues()); |
| for (Metadata value : values) { |
| ((MutableCollectionMetadata) metadata).removeValue(value); |
| } |
| for (Metadata value : values) { |
| ((MutableCollectionMetadata) metadata).addValue(processMetadata(value)); |
| } |
| return metadata; |
| } |
| |
| protected Metadata processValueMetadata(ValueMetadata metadata) { |
| return new LateBindingValueMetadata(metadata); |
| } |
| |
| protected String processString(String str) { |
| // TODO: we need to handle escapes on the prefix / suffix |
| Matcher matcher = getPattern().matcher(str); |
| while (matcher.find()) { |
| String rep = getProperty(matcher.group(1)); |
| if (rep != null) { |
| str = str.replace(matcher.group(0), rep); |
| matcher.reset(str); |
| } |
| } |
| return str; |
| } |
| |
| protected String getProperty(String val) { |
| return null; |
| } |
| |
| protected Pattern getPattern() { |
| if (pattern == null) { |
| pattern = Pattern.compile("\\Q" + placeholderPrefix + "\\E(.+?)\\Q" + placeholderSuffix + "\\E"); |
| } |
| return pattern; |
| } |
| |
| public class LateBindingValueMetadata implements ValueMetadata { |
| |
| private final ValueMetadata metadata; |
| private boolean retrieved; |
| private String retrievedValue; |
| |
| public LateBindingValueMetadata(ValueMetadata metadata) { |
| this.metadata = metadata; |
| } |
| |
| public String getStringValue() { |
| if (!retrieved) { |
| retrieved = true; |
| retrievedValue = processString(metadata.getStringValue()); |
| } |
| return retrievedValue; |
| } |
| |
| public String getType() { |
| return metadata.getType(); |
| } |
| |
| } |
| |
| } |