You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by ma...@apache.org on 2010/02/17 12:16:57 UTC

svn commit: r910918 - in /incubator/aries/trunk/jpa/jpa-container-context/src: main/java/org/apache/aries/jpa/container/context/namespace/NSHandler.java test/java/org/apache/aries/jpa/container/context/namespace/NSHandlerTest.java

Author: mahrwald
Date: Wed Feb 17 11:16:57 2010
New Revision: 910918

URL: http://svn.apache.org/viewvc?rev=910918&view=rev
Log:
ARIES-88 Support field injection from JPA container

Modified:
    incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/namespace/NSHandler.java
    incubator/aries/trunk/jpa/jpa-container-context/src/test/java/org/apache/aries/jpa/container/context/namespace/NSHandlerTest.java

Modified: incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/namespace/NSHandler.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/namespace/NSHandler.java?rev=910918&r1=910917&r2=910918&view=diff
==============================================================================
--- incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/namespace/NSHandler.java (original)
+++ incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/namespace/NSHandler.java Wed Feb 17 11:16:57 2010
@@ -28,9 +28,11 @@
 
 import javax.persistence.EntityManager;
 import javax.persistence.EntityManagerFactory;
+import javax.persistence.PersistenceContext;
 import javax.persistence.PersistenceContextType;
 import javax.persistence.PersistenceUnit;
 
+import org.apache.aries.blueprint.ExtendedBeanMetadata;
 import org.apache.aries.blueprint.NamespaceHandler;
 import org.apache.aries.blueprint.ParserContext;
 import org.apache.aries.blueprint.PassThroughMetadata;
@@ -42,7 +44,6 @@
 import org.apache.aries.jpa.container.context.PersistenceManager;
 import org.apache.aries.jpa.container.context.impl.PersistenceContextManager;
 import org.osgi.framework.Bundle;
-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.ComponentMetadata;
@@ -61,317 +62,421 @@
 
 /**
  * This class handles the JPA namespace in blueprint xml files, it configures
- * injection for managed persistence units and managed persistence contexts.
- * The namespace handler also registers clients of managed persistence contexts
- * with the {@link GlobalPersistenceManager}.
+ * injection for managed persistence units and managed persistence contexts. The
+ * namespace handler also registers clients of managed persistence contexts with
+ * the {@link GlobalPersistenceManager}.
  */
 public class NSHandler implements NamespaceHandler {
-  /** Logger */
-  private static final Logger _logger = LoggerFactory.getLogger("org.apache.aries.jpa.container.context");
-  
-  /** The JPA namespace */
-  public static final String NS_URI = "http://aries.apache.org/xmlns/jpa/v1.0.0";
-  /** The standard blueprint namespace */
-  private static final String BLUEPRINT_NS = "http://www.osgi.org/xmlns/blueprint/v1.0.0";
-  
-  /** The element name for an injected persistence unit (see {@link PersistenceUnit}) */
-  private static final String TAG_UNIT = "unit";
-  /** The element name for an injected persistence context (see {@link PersistenceContext}) */
-  private static final String TAG_CONTEXT = "context";
-  /** The element name for a blueprint map */
-  private static final String TAG_MAP = "map";
-  
-  /** The jpa attribute for property injection, provides the injection site */
-  private static final String ATTR_PROPERTY = "property";
-  /** The {@link PersistenceContextType} of a persistence context */
-  private static final String ATTR_TYPE = "type";
-  /** The name of the persistence unit */
-  private static final String ATTR_UNIT_NAME = "unitname";
-  /** The default name to use if no unit name is specified */
-  private static final String DEFAULT_UNIT_NAME = "";
-  
-  /** A filter to find persistence units that specify an empty name */
-  public static final String EMPTY_UNIT_NAME_FILTER = 
-    "(" + PersistenceUnitConstants.EMPTY_PERSISTENCE_UNIT_NAME + "=true)";
-  
-  /** The service property indicating that a registered EMF is used to create managed persistence contexts */
-  public static final String PROXY_FACTORY_EMF_ATTRIBUTE = "org.apache.aries.jpa.proxy.factory";
-
-  /** The blueprint attribute value to make a bean eager */
-  private static final String ACTIVATION_EAGER = "EAGER";
-  /** The {@link PersistenceManager} to register contexts with */
-  private PersistenceManager manager;
-  
-  public void setManager(PersistenceManager manager) {
-    this.manager = manager;
-  }
-
-  /**
-   * Called by blueprint when we meet a JPA namespace element
-   */
-  public ComponentMetadata decorate(Node node, ComponentMetadata component, ParserContext context) {
-    //The node should always be an element
-    if (node.getNodeType() != Node.ELEMENT_NODE) {
-      _logger.error("The JPA namespace handler does not understand the DOM node {}.", new Object[] {node});
-      throw new IllegalArgumentException();    
+    /** Logger */
+    private static final Logger _logger = LoggerFactory
+            .getLogger("org.apache.aries.jpa.container.context");
+
+    /** The JPA namespace */
+    public static final String NS_URI = "http://aries.apache.org/xmlns/jpa/v1.0.0";
+    /** The standard blueprint namespace */
+    private static final String BLUEPRINT_NS = "http://www.osgi.org/xmlns/blueprint/v1.0.0";
+
+    /**
+     * The element name for an injected persistence unit (see
+     * {@link PersistenceUnit})
+     */
+    private static final String TAG_UNIT = "unit";
+    /**
+     * The element name for an injected persistence context (see
+     * {@link PersistenceContext})
+     */
+    private static final String TAG_CONTEXT = "context";
+    /** The element name for a blueprint map */
+    private static final String TAG_MAP = "map";
+
+    /** The jpa attribute for property injection, provides the injection site */
+    private static final String ATTR_PROPERTY = "property";
+    /** The {@link PersistenceContextType} of a persistence context */
+    private static final String ATTR_TYPE = "type";
+    /** The name of the persistence unit */
+    private static final String ATTR_UNIT_NAME = "unitname";
+    /** The default name to use if no unit name is specified */
+    private static final String DEFAULT_UNIT_NAME = "";
+
+    /** A filter to find persistence units that specify an empty name */
+    public static final String EMPTY_UNIT_NAME_FILTER = "("
+            + PersistenceUnitConstants.EMPTY_PERSISTENCE_UNIT_NAME + "=true)";
+
+    /**
+     * The service property indicating that a registered EMF is used to create
+     * managed persistence contexts
+     */
+    public static final String PROXY_FACTORY_EMF_ATTRIBUTE = "org.apache.aries.jpa.proxy.factory";
+
+    /** The blueprint attribute value to make a bean eager */
+    private static final String ACTIVATION_EAGER = "EAGER";
+    /** The {@link PersistenceManager} to register contexts with */
+    private PersistenceManager manager;
+
+    public void setManager(PersistenceManager manager) {
+        this.manager = manager;
     }
-    
-    Element element = (Element) node;
-    //The surrounding component should always be a bean
-    if (!(component instanceof BeanMetadata)) {
-      _logger.error("The JPA namespace should only be used to inject properties into a bean. The surrounding component was {}.", new Object[] {component});
-      throw new IllegalArgumentException();
+
+    /**
+     * Called by blueprint when we meet a JPA namespace element
+     */
+    public ComponentMetadata decorate(Node node, ComponentMetadata component,
+            ParserContext context) {
+        // The node should always be an element
+        if (node.getNodeType() != Node.ELEMENT_NODE) {
+            _logger
+                    .error(
+                            "The JPA namespace handler does not understand the DOM node {}.",
+                            new Object[] { node });
+            throw new IllegalArgumentException();
+        }
+
+        Element element = (Element) node;
+        // The surrounding component should always be a bean
+        if (!(component instanceof BeanMetadata)) {
+            _logger
+                    .error(
+                            "The JPA namespace should only be used to inject properties into a bean. The surrounding component was {}.",
+                            new Object[] { component });
+            throw new IllegalArgumentException();
+        }
+
+        final BeanMetadata bean = (BeanMetadata) component;
+
+        if (!NS_URI.equals(element.getNamespaceURI())) {
+            _logger
+                    .error(
+                            "The JPA namespace handler should not be called for the namespace {}.",
+                            new Object[] { element.getNamespaceURI() });
+            throw new IllegalArgumentException();
+        }
+
+        if (!TAG_UNIT.equals(element.getLocalName())
+                && !TAG_CONTEXT.equals(element.getLocalName())) {
+            _logger
+                    .error(
+                            "The JPA namespace handler did not recognize the element named {}.",
+                            new Object[] { element.getLocalName() });
+            throw new IllegalArgumentException();
+        }
+
+        // Create an injection point for the JPA resource (a blueprint property)
+        final BeanProperty beanProperty = createInjectMetadata(element,
+                TAG_UNIT.equals(element.getLocalName()), context);
+
+        // If this is a persistence context then register it with the manager
+        if (TAG_CONTEXT.equals(element.getLocalName())) {
+            Bundle client = getBlueprintBundle(context);
+            String unitName = parseUnitName(element);
+
+            HashMap<String, Object> properties = new HashMap<String, Object>();
+            // Remember to add the PersistenceContextType so that we can create
+            // the correct type of
+            // EntityManager
+            properties.put(PersistenceContextManager.PERSISTENCE_CONTEXT_TYPE,
+                    parseType(element));
+            properties.putAll(parseJPAProperties(element, context));
+
+            manager.registerContext(unitName, client, properties);
+        }
+
+        // Create a new Bean to replace the one passed in
+        if (bean instanceof ExtendedBeanMetadata) {
+            return new ExtendedBeanMetadataProxy((ExtendedBeanMetadata) bean) {
+                @Override
+                public List getProperties() {
+                    // Remember to add the jpa injection property
+                    ArrayList<BeanProperty> result = new ArrayList<BeanProperty>(
+                            bean.getProperties());
+                    result.add(beanProperty);
+                    return result;
+                }
+            };            
+        } else {
+            return new BeanMetadataProxy(bean) {
+                @Override
+                public List getProperties() {
+                    // Remember to add the jpa injection property
+                    ArrayList<BeanProperty> result = new ArrayList<BeanProperty>(
+                            bean.getProperties());
+                    result.add(beanProperty);
+                    return result;
+                }
+            };
+        }
     }
-    
-    final BeanMetadata bean = (BeanMetadata) component;
-    
-    if (!NS_URI.equals(element.getNamespaceURI())) {
-      _logger.error("The JPA namespace handler should not be called for the namespace {}.", new Object[] {element.getNamespaceURI()});
-      throw new IllegalArgumentException();
+
+    @SuppressWarnings("unchecked")
+    public Set<Class> getManagedClasses() {
+        // This is a no-op
+        return null;
     }
-        
-    if (!TAG_UNIT.equals(element.getLocalName()) && !TAG_CONTEXT.equals(element.getLocalName())) {
-      _logger.error("The JPA namespace handler did not recognize the element named {}.", new Object[] {element.getLocalName()});
-      throw new IllegalArgumentException();
+
+    public URL getSchemaLocation(String namespace) {
+        return getClass().getResource("jpa.xsd");
     }
-    
-    //Create an injection point for the JPA resource (a blueprint property)
-    final BeanProperty beanProperty = createInjectMetadata(element, 
-        TAG_UNIT.equals(element.getLocalName()),
-        context);
-    
-    //If this is a persistence context then register it with the manager
-    if (TAG_CONTEXT.equals(element.getLocalName())) {
-      Bundle client = getBlueprintBundle(context);
-      String unitName = parseUnitName(element);
-
-      HashMap<String,Object> properties = new HashMap<String, Object>();
-      //Remember to add the PersistenceContextType so that we can create the correct type of
-      //EntityManager
-      properties.put(PersistenceContextManager.PERSISTENCE_CONTEXT_TYPE, parseType(element));
-      properties.putAll(parseJPAProperties(element, context));
 
-      manager.registerContext(unitName, client, properties);      
+    public Metadata parse(Element element, ParserContext context) {
+        /*
+         * The namespace does not define any top-level elements, so we should
+         * never get here. In case we do -> explode.
+         */
+        _logger
+                .error("The JPA namespace handler was called to parse a top level element.");
+        throw new UnsupportedOperationException();
     }
-    
-    // Create a new Bean to replace the one passed in
-    return new BeanMetadata() {
-      
-      public String getId() {
-        return bean.getId();
-      }
-      
-      @SuppressWarnings("unchecked")
-      public List<String> getDependsOn() {
-        return bean.getDependsOn();
-      }
-      
-      public int getActivation() {
-        return bean.getActivation();
-      }
-      
-      public String getScope() {
-        return bean.getScope();
-      }
-      
-      @SuppressWarnings("unchecked")
-      public List<BeanProperty> getProperties() {
-        //Remember to add the jpa injection property
-        ArrayList<BeanProperty> result = new ArrayList<BeanProperty>(bean.getProperties());
-        result.add(beanProperty);
+
+    /**
+     * Create a BeanProperty that will inject a JPA resource into a bean
+     * 
+     * @param element
+     *            The element being parsed
+     * @param isPersistenceUnit
+     *            true if this is a persistence unit
+     * @param ctx
+     *            The current parser context
+     * @return
+     */
+    private BeanProperty createInjectMetadata(Element element,
+            boolean isPersistenceUnit, ParserContext ctx) {
+        String unitName = parseUnitName(element);
+        final String property = element.getAttribute(ATTR_PROPERTY);
+
+        if (_logger.isDebugEnabled()) {
+            if (isPersistenceUnit)
+                _logger
+                        .debug(
+                                "Creating blueprint injection metadata to inject the unit {} into bean property {}",
+                                new Object[] { unitName, property });
+            else
+                _logger
+                        .debug(
+                                "Creating blueprint injection metadata to inject the context {} into bean property {}",
+                                new Object[] { unitName, property });
+        }
+
+        // Create a service reference for the EMF (it is an EMF for persistence
+        // contexts and units)
+        final MutableReferenceMetadata refMetadata = (MutableReferenceMetadata) ctx
+                .createMetadata(ReferenceMetadata.class);
+        refMetadata.setActivation(ACTIVATION_EAGER.equalsIgnoreCase(ctx
+                .getDefaultActivation()) ? ReferenceMetadata.ACTIVATION_EAGER
+                : ReferenceMetadata.ACTIVATION_LAZY);
+        refMetadata.setAvailability(ReferenceMetadata.AVAILABILITY_MANDATORY);
+        refMetadata.setInterface(EntityManagerFactory.class.getName());
+
+        // Pick the right EMF by looking for the presence, or absence, of the
+        // PROXY_FACTORY service property
+        StringBuilder filter = new StringBuilder("(&");
+        // Persistence units do not have the property, persistence contexts do
+        if (isPersistenceUnit)
+            filter.append("(!(").append(PROXY_FACTORY_EMF_ATTRIBUTE).append(
+                    "=*))");
+        else
+            filter.append("(").append(PROXY_FACTORY_EMF_ATTRIBUTE)
+                    .append("=*)");
+
+        // Add the empty name filter if necessary
+        if (!"".equals(unitName))
+            filter.append("(" + PersistenceUnitConstants.OSGI_UNIT_NAME + "="
+                    + unitName + ")");
+        else
+            filter.append(EMPTY_UNIT_NAME_FILTER);
+
+        filter.append(")");
+
+        refMetadata.setFilter(filter.toString());
+        refMetadata.setTimeout(Integer.parseInt(ctx.getDefaultTimeout()));
+        refMetadata.setDependsOn((List<String>) Collections.EMPTY_LIST);
+        refMetadata.setId(ctx.generateId());
+
+        // Finally, if this is a persistence context we need to create the
+        // entity manager as the Target
+        final Metadata target = isPersistenceUnit ? refMetadata
+                : createInjectionBeanMetedata(ctx, refMetadata);
+
+        return new BeanProperty() {
+            public Metadata getValue() {
+                return target;
+            }
+
+            public String getName() {
+                return property;
+            }
+        };
+    }
+
+    /**
+     * This method turns a persistence context factory into an
+     * {@link EntityManager} using blueprint factories
+     * 
+     * @param ctx
+     *            the {@link ParserContext}
+     * @param factory
+     *            the reference bean for the persistence context factory
+     * @return
+     */
+    private Metadata createInjectionBeanMetedata(ParserContext ctx,
+            ReferenceMetadata factory) {
+
+        if (_logger.isDebugEnabled())
+            _logger
+                    .debug("Creating a managed persistence context definition for injection");
+
+        // Register the factory bean, and then create an entitymanager from it
+        ctx.getComponentDefinitionRegistry().registerComponentDefinition(
+                factory);
+
+        MutableBeanMetadata meta = (MutableBeanMetadata) ctx
+                .createMetadata(BeanMetadata.class);
+        MutableRefMetadata ref = (MutableRefMetadata) ctx
+                .createMetadata(RefMetadata.class);
+        ref.setComponentId(factory.getId());
+        meta.setFactoryComponent(ref);
+        meta.setActivation(factory.getActivation());
+        meta.setFactoryMethod("createEntityManager");
+        meta.setScope(BeanMetadata.SCOPE_PROTOTYPE);
+        meta.setDestroyMethod("internalClose");
+
+        return meta;
+    }
+
+    /**
+     * Get hold of the blueprint bundle using the built in components
+     * 
+     * @param context
+     * @return
+     */
+    private Bundle getBlueprintBundle(ParserContext context) {
+        PassThroughMetadata metadata = (PassThroughMetadata) context
+                .getComponentDefinitionRegistry().getComponentDefinition(
+                        "blueprintBundle");
+
+        Bundle result = null;
+        if (metadata != null) {
+            result = (Bundle) metadata.getObject();
+        }
+
         return result;
-      }
-      
-      public String getInitMethod() {
-        return bean.getInitMethod();
-      }
-      
-      public String getFactoryMethod() {
-        return bean.getFactoryMethod();
-      }
-      
-      public Target getFactoryComponent() {
-        return bean.getFactoryComponent();
-      }
-      
-      public String getDestroyMethod() {
-        return bean.getDestroyMethod();
-      }
-      
-      public String getClassName() {
-        return bean.getClassName();
-      }
-      
-      @SuppressWarnings("unchecked")
-      public List<BeanArgument> getArguments() {
-        return bean.getArguments();
-      }
-    };
-  }
-
-  @SuppressWarnings("unchecked")
-  public Set<Class> getManagedClasses() {
-    //This is a no-op
-    return null;
-  }
-
-  public URL getSchemaLocation(String namespace) {
-    return getClass().getResource("jpa.xsd");
-  }
-
-  public Metadata parse(Element element, ParserContext context) {
-    /*
-     * The namespace does not define any top-level elements, so we should never get here.
-     * In case we do -> explode.
+    }
+
+    private PersistenceContextType parseType(Element element) {
+        if (element.hasAttribute(ATTR_TYPE))
+            return PersistenceContextType.valueOf(element
+                    .getAttribute(ATTR_TYPE));
+        else
+            return PersistenceContextType.TRANSACTION;
+    }
+
+    private String parseUnitName(Element element) {
+        return element.hasAttribute(ATTR_UNIT_NAME) ? element
+                .getAttribute(ATTR_UNIT_NAME) : DEFAULT_UNIT_NAME;
+    }
+
+    /**
+     * Parse any properties for creating the persistence context
+     * 
+     * @param element
+     * @param context
+     * @return
      */
-    _logger.error("The JPA namespace handler was called to parse a top level element.");
-    throw new UnsupportedOperationException();
-  }
-  
-  /**
-   * Create a BeanProperty that will inject a JPA resource into a bean
-   * @param element  The element being parsed
-   * @param isPersistenceUnit  true if this is a persistence unit
-   * @param ctx  The current parser context
-   * @return
-   */
-  private BeanProperty createInjectMetadata(Element element, boolean isPersistenceUnit, ParserContext ctx) {
-    String unitName = parseUnitName(element);
-    final String property = element.getAttribute(ATTR_PROPERTY);
-
-    if(_logger.isDebugEnabled()) {
-      if(isPersistenceUnit)
-      _logger.debug("Creating blueprint injection metadata to inject the unit {} into bean property {}",
-          new Object[] {unitName, property});
-      else
-        _logger.debug("Creating blueprint injection metadata to inject the context {} into bean property {}",
-            new Object[] {unitName, property});
+    private Map<String, Object> parseJPAProperties(Element element,
+            ParserContext context) {
+        Map<String, Object> result = new HashMap<String, Object>();
+        NodeList ns = element.getElementsByTagNameNS(BLUEPRINT_NS, TAG_MAP);
+        // Use the parser context to parse the map for us
+        for (int i = 0; i < ns.getLength(); i++) {
+            MapMetadata metadata = context.parseElement(MapMetadata.class,
+                    null, (Element) ns.item(i));
+            for (MapEntry entry : (List<MapEntry>) metadata.getEntries()) {
+                if (entry.getKey() instanceof ValueMetadata
+                        && entry.getValue() instanceof ValueMetadata) {
+                    ValueMetadata key = (ValueMetadata) entry.getKey();
+                    ValueMetadata value = (ValueMetadata) entry.getValue();
+
+                    result.put(key.getStringValue(), value.getStringValue());
+                } else {
+                    _logger
+                            .error("There was a problem parsing a map of JPA properties");
+                    throw new UnsupportedOperationException();
+                }
+            }
+        }
+
+        return result;
     }
-    
-    //Create a service reference for the EMF (it is an EMF for persistence contexts and units)
-    final MutableReferenceMetadata refMetadata = (MutableReferenceMetadata) ctx.createMetadata(ReferenceMetadata.class);
-    refMetadata.setActivation(ACTIVATION_EAGER.equalsIgnoreCase(ctx.getDefaultActivation()) ?
-        ReferenceMetadata.ACTIVATION_EAGER : ReferenceMetadata.ACTIVATION_LAZY);
-    refMetadata.setAvailability(ReferenceMetadata.AVAILABILITY_MANDATORY);
-    refMetadata.setInterface(EntityManagerFactory.class.getName());    
-    
-    //Pick the right EMF by looking for the presence, or absence, of the PROXY_FACTORY service property 
-    StringBuilder filter = new StringBuilder("(&");
-    //Persistence units do not have the property, persistence contexts do
-    if (isPersistenceUnit)
-      filter.append("(!(").append(PROXY_FACTORY_EMF_ATTRIBUTE).append("=*))");
-    else
-      filter.append("(").append(PROXY_FACTORY_EMF_ATTRIBUTE).append("=*)");      
-    
-    //Add the empty name filter if necessary
-    if (!"".equals(unitName))
-      filter.append("(" + PersistenceUnitConstants.OSGI_UNIT_NAME + "=" + unitName + ")");
-    else
-      filter.append(EMPTY_UNIT_NAME_FILTER);
-    
-    filter.append(")");
-    
-    refMetadata.setFilter(filter.toString());
-    refMetadata.setTimeout(Integer.parseInt(ctx.getDefaultTimeout()));
-    refMetadata.setDependsOn((List<String>) Collections.EMPTY_LIST);
-    refMetadata.setId(ctx.generateId());
-    
-    //Finally, if this is a persistence context we need to create the entity manager as the Target
-    final Metadata target = isPersistenceUnit ? refMetadata 
-        : createInjectionBeanMetedata(ctx, refMetadata);
-    
-    return new BeanProperty() {      
-      public Metadata getValue() {
-        return target;
-      }
-      
-      public String getName() {
-        return property;
-      }
-    };
-  }
-  
-  /**
-   * This method turns a persistence context factory into an {@link EntityManager} using blueprint
-   * factories 
-   * @param ctx  the {@link ParserContext}
-   * @param factory  the reference bean for the persistence context factory
-   * @return
-   */
-  private Metadata createInjectionBeanMetedata(ParserContext ctx, ReferenceMetadata factory) {
-    
-    if(_logger.isDebugEnabled())
-      _logger.debug("Creating a managed persistence context definition for injection");
-    
-    //Register the factory bean, and then create an entitymanager from it
-    ctx.getComponentDefinitionRegistry().registerComponentDefinition(factory);
-    
-    MutableBeanMetadata meta = (MutableBeanMetadata) ctx.createMetadata(BeanMetadata.class);
-    MutableRefMetadata ref = (MutableRefMetadata) ctx.createMetadata(RefMetadata.class);
-    ref.setComponentId(factory.getId());
-    meta.setFactoryComponent(ref);
-    meta.setActivation(factory.getActivation());
-    meta.setFactoryMethod("createEntityManager");
-    meta.setScope(BeanMetadata.SCOPE_PROTOTYPE);
-    meta.setDestroyMethod("internalClose");
-    
-    return meta;
-  }
-  
-  /**
-   * Get hold of the blueprint bundle using the built in components
-   * @param context
-   * @return
-   */
-  private Bundle getBlueprintBundle(ParserContext context) {
-    PassThroughMetadata metadata = (PassThroughMetadata) context.getComponentDefinitionRegistry()
-      .getComponentDefinition("blueprintBundle");
-    
-    Bundle result = null;
-    if (metadata != null) {
-      result = (Bundle) metadata.getObject();
+
+    private static class BeanMetadataProxy implements BeanMetadata {
+        private final BeanMetadata delegate;
+
+        public BeanMetadataProxy(BeanMetadata delegate) {
+            this.delegate = delegate;
+        }
+
+        public List getArguments() {
+            return delegate.getArguments();
+        }
+
+        public String getClassName() {
+            return delegate.getClassName();
+        }
+
+        public String getDestroyMethod() {
+            return delegate.getDestroyMethod();
+        }
+
+        public Target getFactoryComponent() {
+            return delegate.getFactoryComponent();
+        }
+
+        public String getFactoryMethod() {
+            return delegate.getFactoryMethod();
+        }
+
+        public String getInitMethod() {
+            return delegate.getInitMethod();
+        }
+
+        public List getProperties() {
+            return delegate.getProperties();
+        }
+
+        public String getScope() {
+            return delegate.getScope();
+        }
+
+        public int getActivation() {
+            return delegate.getActivation();
+        }
+
+        public List getDependsOn() {
+            return delegate.getDependsOn();
+        }
+
+        public String getId() {
+            return delegate.getId();
+        }
     }
     
-    return result;
-  }
+    private static class ExtendedBeanMetadataProxy extends BeanMetadataProxy implements ExtendedBeanMetadata {
+        private final ExtendedBeanMetadata delegate;
+        
+        public ExtendedBeanMetadataProxy(ExtendedBeanMetadata delegate) {
+            super(delegate);
+            this.delegate = delegate;
+        }
+        
+        public boolean getFieldInjection() {
+            return delegate.getFieldInjection();
+        }
 
+        public Class<?> getRuntimeClass() {
+            return delegate.getRuntimeClass();
+        }
 
-  private PersistenceContextType parseType(Element element) {
-    if(element.hasAttribute(ATTR_TYPE))
-      return PersistenceContextType.valueOf(element.getAttribute(ATTR_TYPE));
-    else return PersistenceContextType.TRANSACTION;
-  }
-  
-  private String parseUnitName(Element element) {
-    return element.hasAttribute(ATTR_UNIT_NAME) ? 
-        element.getAttribute(ATTR_UNIT_NAME) : DEFAULT_UNIT_NAME;
-  }
-  
-  /**
-   * Parse any properties for creating the persistence context
-   * @param element
-   * @param context
-   * @return
-   */
-  private Map<String, Object> parseJPAProperties(Element element, ParserContext context) {
-    Map<String, Object> result = new HashMap<String, Object>();
-    NodeList ns = element.getElementsByTagNameNS(BLUEPRINT_NS, TAG_MAP);
-    //Use the parser context to parse the map for us
-    for (int i=0; i<ns.getLength(); i++) {
-      MapMetadata metadata = context.parseElement(MapMetadata.class, null, (Element) ns.item(i));
-      for (MapEntry entry : (List<MapEntry>) metadata.getEntries()) {
-        if (entry.getKey() instanceof ValueMetadata && entry.getValue() instanceof ValueMetadata) {
-          ValueMetadata key = (ValueMetadata) entry.getKey();
-          ValueMetadata value = (ValueMetadata) entry.getValue();
-          
-          result.put(key.getStringValue(), value.getStringValue());
-        } else {
-          _logger.error("There was a problem parsing a map of JPA properties");
-          throw new UnsupportedOperationException();
+        public boolean isProcessor() {
+            return delegate.isProcessor();
         }
-      }
+        
     }
-    
-    return result;
-  }
 }

Modified: incubator/aries/trunk/jpa/jpa-container-context/src/test/java/org/apache/aries/jpa/container/context/namespace/NSHandlerTest.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jpa/jpa-container-context/src/test/java/org/apache/aries/jpa/container/context/namespace/NSHandlerTest.java?rev=910918&r1=910917&r2=910918&view=diff
==============================================================================
--- incubator/aries/trunk/jpa/jpa-container-context/src/test/java/org/apache/aries/jpa/container/context/namespace/NSHandlerTest.java (original)
+++ incubator/aries/trunk/jpa/jpa-container-context/src/test/java/org/apache/aries/jpa/container/context/namespace/NSHandlerTest.java Wed Feb 17 11:16:57 2010
@@ -33,6 +33,7 @@
 import javax.xml.parsers.DocumentBuilderFactory;
 
 import org.apache.aries.blueprint.ComponentDefinitionRegistry;
+import org.apache.aries.blueprint.ExtendedBeanMetadata;
 import org.apache.aries.blueprint.ParserContext;
 import org.apache.aries.blueprint.PassThroughMetadata;
 import org.apache.aries.blueprint.container.Parser;
@@ -229,6 +230,13 @@
         new MethodCall(PersistenceManager.class, "registerContext", "", clientBundle, props));    
   }
   
+  @Test
+  public void testExtendedMetadataProxying() {
+      Element e = getTestElement("contextWithProps");
+      Object res = sut.decorate(e, Skeleton.newMock(ExtendedBeanMetadata.class), parserCtx);
+      assertTrue(res instanceof ExtendedBeanMetadata);
+  }
+  
   private Element getTestElement(String beanName) {
     NodeList ns = root.getElementsByTagName("bean");