Author: sergeyb
Date: Wed May 23 14:54:39 2012
New Revision: 1341886
URL: http://svn.apache.org/viewvc?rev=1341886&view=rev
Log:
[ARIES-855] Initial support for loading nested classes
Added:
aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/BeanLoadingTest.java
(with props)
aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/pojos/SimpleBean.java
(with props)
aries/trunk/blueprint/blueprint-core/src/test/resources/test-bean-classes.xml
(with props)
Modified:
aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/di/AbstractRecipe.java
Modified:
aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/di/AbstractRecipe.java
URL:
http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/di/AbstractRecipe.java?rev=1341886&r1=1341885&r2=1341886&view=diff
==============================================================================
---
aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/di/AbstractRecipe.java
(original)
+++
aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/di/AbstractRecipe.java
Wed May 23 14:54:39 2012
@@ -26,16 +26,21 @@ import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import org.apache.aries.blueprint.container.GenericType;
-import org.osgi.service.blueprint.container.ReifiedType;
import org.osgi.service.blueprint.container.ComponentDefinitionException;
+import org.osgi.service.blueprint.container.ReifiedType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public abstract class AbstractRecipe implements Recipe {
+ private static final Logger LOGGER = LoggerFactory
+ .getLogger(AbstractRecipe.class);
protected final String name;
protected boolean prototype = true;
protected AbstractRecipe(String name) {
- if (name == null) throw new NullPointerException("name is null");
+ if (name == null)
+ throw new NullPointerException("name is null");
this.name = name;
}
@@ -55,7 +60,8 @@ public abstract class AbstractRecipe imp
// Ensure a container has been set
ExecutionContext context = ExecutionContext.Holder.getContext();
- // if this recipe has already been executed in this context, return
the currently registered value
+ // if this recipe has already been executed in this context, return the
+ // currently registered value
Object result = context.getPartialObject(name);
if (result != null) {
return result;
@@ -66,12 +72,15 @@ public abstract class AbstractRecipe imp
boolean didCreate = false;
try {
if (!prototype) {
- FutureTask<Object> objectCreation = new FutureTask<Object>(new
Callable<Object>() {
- public Object call() throws ComponentDefinitionException {
- return internalCreate();
- }
- });
- Future<Object> resultFuture = context.addFullObject(name,
objectCreation);
+ FutureTask<Object> objectCreation = new FutureTask<Object>(
+ new Callable<Object>() {
+ public Object call()
+ throws ComponentDefinitionException {
+ return internalCreate();
+ }
+ });
+ Future<Object> resultFuture = context.addFullObject(name,
+ objectCreation);
// are we the first to try to create it
if (resultFuture == null) {
@@ -79,8 +88,7 @@ public abstract class AbstractRecipe imp
objectCreation.run();
resultFuture = objectCreation;
}
-
-
+
try {
result = resultFuture.get();
} catch (InterruptedException ie) {
@@ -90,45 +98,51 @@ public abstract class AbstractRecipe imp
throw (ComponentDefinitionException) ee.getCause();
else if (ee.getCause() instanceof RuntimeException)
throw (RuntimeException) ee.getCause();
- else
+ else
throw (Error) ee.getCause();
}
-
+
} else {
result = internalCreate();
}
} finally {
- if (didCreate) context.removePartialObject(name);
-
+ if (didCreate)
+ context.removePartialObject(name);
+
Recipe popped = context.pop();
if (popped != this) {
- //noinspection ThrowFromFinallyBlock
- throw new IllegalStateException("Internal Error: recipe stack
is corrupt:" +
- " Expected " + this + " to be popped of the stack but
was " + popped);
+ // noinspection ThrowFromFinallyBlock
+ throw new IllegalStateException(
+ "Internal Error: recipe stack is corrupt:"
+ + " Expected " + this
+ + " to be popped of the stack but was "
+ + popped);
}
}
-
+
return result;
}
- protected abstract Object internalCreate() throws
ComponentDefinitionException;
-
+ protected abstract Object internalCreate()
+ throws ComponentDefinitionException;
+
protected void addPartialObject(Object obj) {
- if (!prototype) {
+ if (!prototype) {
ExecutionContext.Holder.getContext().addPartialObject(name, obj);
}
}
-
+
protected boolean canConvert(Object obj, ReifiedType type) {
- return ExecutionContext.Holder.getContext().canConvert(obj, type);
+ return ExecutionContext.Holder.getContext().canConvert(obj, type);
}
-
+
protected Object convert(Object obj, ReifiedType type) throws Exception {
return ExecutionContext.Holder.getContext().convert(obj, type);
}
protected Object convert(Object obj, Type type) throws Exception {
- return ExecutionContext.Holder.getContext().convert(obj, new
GenericType(type));
+ return ExecutionContext.Holder.getContext().convert(obj,
+ new GenericType(type));
}
protected Class loadClass(String className) {
@@ -144,10 +158,41 @@ public abstract class AbstractRecipe imp
if (typeName == null) {
return null;
}
+ return doLoadType(typeName, fromClassLoader, true, false);
+ }
+
+ private ReifiedType doLoadType(String typeName,
+ ClassLoader fromClassLoader, boolean checkNestedIfFailed,
+ boolean retry) {
try {
- return GenericType.parse(typeName, fromClassLoader != null ?
fromClassLoader : ExecutionContext.Holder.getContext());
+ return GenericType.parse(typeName,
+ fromClassLoader != null ? fromClassLoader
+ : ExecutionContext.Holder.getContext());
} catch (ClassNotFoundException e) {
- throw new ComponentDefinitionException("Unable to load class " +
typeName + " from recipe " + this, e);
+ String errorMessage = "Unable to load class " + typeName
+ + " from recipe " + this;
+ if (checkNestedIfFailed) {
+ int lastDot = typeName.lastIndexOf('.');
+ if (lastDot > 0 && lastDot < typeName.length()) {
+ String nestedTypeName = typeName.substring(0, lastDot)
+ + "$" + typeName.substring(lastDot + 1);
+ LOGGER.debug(errorMessage
+ + ", trying to load a nested class "
+ + nestedTypeName);
+ try {
+ return doLoadType(nestedTypeName, fromClassLoader,
+ false, true);
+ } catch (ComponentDefinitionException e2) {
+ // ignore, the recursive call will throw this
exception,
+ // but ultimately the exception referencing the
original
+ // typeName has to be thrown
+ }
+ }
+ }
+ if (!retry) {
+ LOGGER.error(errorMessage);
+ }
+ throw new ComponentDefinitionException(errorMessage, e);
}
}
@@ -157,11 +202,9 @@ public abstract class AbstractRecipe imp
public List<Recipe> getConstructorDependencies() {
return Collections.emptyList();
}
-
+
public String toString() {
- return getClass().getSimpleName() + "[" +
- "name='" + name + '\'' +
- ']';
+ return getClass().getSimpleName() + "[" + "name='" + name + '\'' + ']';
}
Added:
aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/BeanLoadingTest.java
URL:
http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/BeanLoadingTest.java?rev=1341886&view=auto
==============================================================================
---
aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/BeanLoadingTest.java
(added)
+++
aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/BeanLoadingTest.java
Wed May 23 14:54:39 2012
@@ -0,0 +1,46 @@
+/*
+ * 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;
+
+import org.apache.aries.blueprint.di.Repository;
+import org.apache.aries.blueprint.parser.ComponentDefinitionRegistryImpl;
+import org.apache.aries.blueprint.pojos.SimpleBean;
+
+public class BeanLoadingTest extends AbstractBlueprintTest {
+
+ public void testLoadSimpleBean() throws Exception {
+ ComponentDefinitionRegistryImpl registry =
parse("/test-bean-classes.xml");
+ Repository repository = new TestBlueprintContainer(registry)
+ .getRepository();
+
+ Object obj = repository.create("simpleBean");
+ assertNotNull(obj);
+ assertTrue(obj instanceof SimpleBean);
+ }
+
+ public void testLoadSimpleBeanNested() throws Exception {
+ ComponentDefinitionRegistryImpl registry =
parse("/test-bean-classes.xml");
+ Repository repository = new TestBlueprintContainer(registry)
+ .getRepository();
+
+ Object obj = repository.create("simpleBeanNested");
+ assertNotNull(obj);
+ assertTrue(obj instanceof SimpleBean.Nested);
+ }
+}
Propchange:
aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/BeanLoadingTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/BeanLoadingTest.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added:
aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/pojos/SimpleBean.java
URL:
http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/pojos/SimpleBean.java?rev=1341886&view=auto
==============================================================================
---
aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/pojos/SimpleBean.java
(added)
+++
aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/pojos/SimpleBean.java
Wed May 23 14:54:39 2012
@@ -0,0 +1,25 @@
+/*
+ * 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.pojos;
+
+public class SimpleBean {
+ public static class Nested {
+
+ }
+}
Propchange:
aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/pojos/SimpleBean.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/pojos/SimpleBean.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added:
aries/trunk/blueprint/blueprint-core/src/test/resources/test-bean-classes.xml
URL:
http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/src/test/resources/test-bean-classes.xml?rev=1341886&view=auto
==============================================================================
---
aries/trunk/blueprint/blueprint-core/src/test/resources/test-bean-classes.xml
(added)
+++
aries/trunk/blueprint/blueprint-core/src/test/resources/test-bean-classes.xml
Wed May 23 14:54:39 2012
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+ default-availability="mandatory" >
+
+ <bean id="simpleBean" class="org.apache.aries.blueprint.pojos.SimpleBean"/>
+ <bean id="simpleBeanNested"
class="org.apache.aries.blueprint.pojos.SimpleBean.Nested"/>
+
+
+</blueprint>
Propchange:
aries/trunk/blueprint/blueprint-core/src/test/resources/test-bean-classes.xml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
aries/trunk/blueprint/blueprint-core/src/test/resources/test-bean-classes.xml
------------------------------------------------------------------------------
svn:keywords = Rev Date
Propchange:
aries/trunk/blueprint/blueprint-core/src/test/resources/test-bean-classes.xml
------------------------------------------------------------------------------
svn:mime-type = text/xml