/* * Copyright 2012 The Solmix Project * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.gnu.org/licenses/ * or see the FSF site: http://www.fsf.org. */ package org.solmix.runtime.support.blueprint; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.osgi.service.blueprint.container.BlueprintContainer; import org.osgi.service.blueprint.container.NoSuchComponentException; import org.osgi.service.blueprint.reflect.BeanMetadata; import org.osgi.service.blueprint.reflect.ComponentMetadata; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.solmix.commons.util.Reflection; import org.solmix.runtime.bean.BeanConfigurer; import org.solmix.runtime.bean.Configurable; /** * * @author solmix.f@gmail.com * @version $Id$ 2013-11-5 */ public class BlueprintConfigurer implements BeanConfigurer { private static final Logger LOG = LoggerFactory.getLogger(BlueprintConfigurer.class); private final BlueprintContainer blueprintContainer; private final Map<String, List<MatcherHolder>> wildCardBeanDefinitions = new HashMap<String, List<MatcherHolder>>(); static class MatcherHolder { Matcher matcher; String wildCardId; public MatcherHolder(String orig, Matcher matcher) { wildCardId = orig; this.matcher = matcher; } } public BlueprintConfigurer(BlueprintContainer container) { this.blueprintContainer = container; initializeWildcardMap(); } private void initializeWildcardMap() { for (String s : blueprintContainer.getComponentIds()) { if (isWildcardBeanName(s)) { ComponentMetadata cmd = blueprintContainer.getComponentMetadata(s); Class<?> cls = BlueprintBeanProvider.getClassForMetaData(blueprintContainer, cmd); if (cls != null) { String orig = s; if (s.charAt(0) == '*') { // old wildcard s = "." + s.replaceAll("\\.", "\\."); } Matcher matcher = Pattern.compile(s).matcher(""); List<MatcherHolder> m = wildCardBeanDefinitions.get(cls.getName()); if (m == null) { m = new ArrayList<MatcherHolder>(); wildCardBeanDefinitions.put(cls.getName(), m); } MatcherHolder holder = new MatcherHolder(orig, matcher); m.add(holder); } } } } private boolean isWildcardBeanName(String bn) { return bn.indexOf('*') != -1 || bn.indexOf('?') != -1 || (bn.indexOf('(') != -1 && bn.indexOf(')') != -1); } /** * {@inheritDoc} * * @see org.solmix.api.bean.BeanConfigurer#configureBean(java.lang.Object) */ @Override public void configureBean(Object beanInstance) { configureBean(null, beanInstance, true); } /** * @param object * @param beanInstance * @param b */ public synchronized void configureBean(String bname, Object bean, boolean checkWildcards) { if(bean==null){ bname=getBeanName(bean); } if(bname==null){ return; } if (checkWildcards) { configureWithWildCard(bname, bean); } Method m = Reflection.findMethod(blueprintContainer.getClass(), "injectBeanInstance", BeanMetadata.class, Object.class); try { if(m!=null){ ComponentMetadata cm = null; try { cm = blueprintContainer.getComponentMetadata(bname); } catch (NoSuchComponentException nsce) { cm = null; } if (cm instanceof BeanMetadata) { m.invoke(blueprintContainer, cm, bean); } } } catch (InvocationTargetException e) { Throwable t = e.getCause(); if (t instanceof RuntimeException) { throw (RuntimeException)t; } else { throw new RuntimeException(t); } }catch(Exception e){ LOG.warn("Can't configured object {}",bname); } } private void configureWithWildCard(String bn, Object beanInstance) { if (!wildCardBeanDefinitions.isEmpty()) { Class<?> clazz = beanInstance.getClass(); while (!Object.class.equals(clazz)) { String className = clazz.getName(); List<MatcherHolder> matchers = wildCardBeanDefinitions.get(className); if (matchers != null) { for (MatcherHolder m : matchers) { synchronized (m.matcher) { m.matcher.reset(bn); if (m.matcher.matches()) { configureBean(m.wildCardId, beanInstance, false); return; } } } } clazz = clazz.getSuperclass(); } } } protected String getBeanName(Object beanInstance) { if (beanInstance instanceof Configurable) { return ((Configurable)beanInstance).getConfigueName(); }else{ return null; } /*String beanName = null; Method m = null; try { m = beanInstance.getClass().getDeclaredMethod("getConfigureName", (Class[])null); } catch (NoSuchMethodException ex) { try { m = beanInstance.getClass().getMethod("getConfigureName", (Class[])null); } catch (NoSuchMethodException e) { //ignore } } if (m != null) { try { beanName = (String)(m.invoke(beanInstance)); } catch (Exception ex) { LOG.warn("Error determining bean name",ex); } } if (null == beanName) { LOG.warn("Could not determining bean name {}",beanInstance.getClass().getName()); } return beanName;*/ } /** * {@inheritDoc} * * @see org.solmix.api.bean.BeanConfigurer#configureBean(java.lang.String, java.lang.Object) */ @Override public void configureBean(String name, Object beanInstance) { configureBean(name, beanInstance, true); } }