/tags/menta-container-1.0.2/src/test/java/org/mentacontainer/impl/GenericFactoryTest.java |
---|
New file |
0,0 → 1,45 |
package org.mentacontainer.impl; |
import junit.framework.Assert; |
import org.junit.Test; |
import org.mentacontainer.Factory; |
import org.mentacontainer.Container; |
import org.mentacontainer.impl.GenericFactory; |
import org.mentacontainer.impl.MentaContainer; |
public class GenericFactoryTest { |
public static class SomeFactory { |
public String giveMeSomething() { |
return String.valueOf(System.nanoTime()); |
} |
} |
@Test |
public void testGenericFactory() throws Exception { |
// in real life this will be a SessionFactory, a ConnectionPool or any factory... |
SomeFactory factory = new SomeFactory(); |
Container c = new MentaContainer(); |
// giveMeSomething => method that will be called to return object |
Factory generic = new GenericFactory(factory, "giveMeSomething"); |
c.ioc("myFactory", generic); |
String s1 = c.get("myFactory"); |
Thread.sleep(5); // so strings are different... my cpu is fast! :-) |
String s2 = c.get("myFactory"); |
Assert.assertNotNull(s1); |
Assert.assertNotNull(s2); |
Assert.assertTrue(s1 != s2); |
Assert.assertTrue(!s1.equals(s2)); |
} |
} |
/tags/menta-container-1.0.2/src/test/java/org/mentacontainer/impl/MentaContainerTest.java |
---|
New file |
0,0 → 1,535 |
package org.mentacontainer.impl; |
import junit.framework.Assert; |
import org.junit.Test; |
import org.mentacontainer.Interceptor; |
import org.mentacontainer.Factory; |
import org.mentacontainer.Container; |
import org.mentacontainer.Scope; |
public class MentaContainerTest { |
@Test |
public void testSimpleGet() { |
Container c = new MentaContainer(); |
c.ioc("myStr", String.class); |
Assert.assertEquals("", c.get("myStr")); |
String s1 = c.get("myStr"); |
String s2 = c.get("myStr"); |
Assert.assertTrue(s1 != s2); |
Assert.assertTrue(s1.equals(s2)); |
} |
@Test |
public void testConstructorInit() { |
Container c = new MentaContainer(); |
c.ioc("myStr", String.class).addInitValue("hello"); |
Assert.assertEquals("hello", c.get("myStr")); |
String s1 = c.get("myStr"); |
String s2 = c.get("myStr"); |
Assert.assertTrue(s1 != s2); |
Assert.assertTrue(s1.equals(s2)); |
c.ioc("anotherStr", String.class).addInitValue("hi"); |
String s3 = c.get("anotherStr"); |
Assert.assertTrue(s1 != s3); |
Assert.assertFalse(s1.equals(s3)); |
} |
@Test |
public void testSingleton() { |
Container c = new MentaContainer(); |
c.ioc("myStr", String.class, Scope.SINGLETON).addInitValue("hello"); |
Assert.assertEquals("hello", c.get("myStr")); |
String s1 = c.get("myStr"); |
String s2 = c.get("myStr"); |
Assert.assertTrue(s1 == s2); |
Assert.assertTrue(s1.equals(s2)); |
} |
@Test |
public void testCheckAndClear() { |
Container c = new MentaContainer(); |
c.ioc("myStr", String.class, Scope.SINGLETON).addInitValue("hello"); |
Assert.assertEquals(false, c.check("myStr")); |
String s1 = c.get("myStr"); |
Assert.assertEquals(true, c.check("myStr")); |
String s2 = c.get("myStr"); |
Assert.assertTrue(s1 == s2); |
c.clear(Scope.SINGLETON); |
Assert.assertEquals(false, c.check("myStr")); |
String s3 = c.get("myStr"); |
Assert.assertTrue(s3 != s2); |
} |
private static class MyThread extends Thread { |
private final Container c; |
private final String key; |
private String value = null; |
public MyThread(Container c, String key) { |
super(); |
this.c = c; |
this.key = key; |
} |
@Override |
public void run() { |
for(int i = 0; i < 50; i++) { |
String v = c.get(key); |
if (this.value != null) { |
Assert.assertTrue(this.value == v); |
} |
this.value = v; |
} |
} |
public String getValue() { return value; } |
} |
@Test |
public void testScopes() { |
Container c = new MentaContainer(); |
// if you don't provide a scope the Scope is NONE |
// meaning a new instance is created on every |
// request for the bean |
c.ioc("myString", String.class).addInitValue("saoj"); |
String s1 = c.get("myString"); |
String s2 = c.get("myString"); |
Assert.assertTrue(s1 != s2); |
// then you can use SINGLETON |
// always get the same instance no matter what |
c.ioc("myString", String.class, Scope.SINGLETON).addInitValue("saoj"); |
s1 = c.get("myString"); |
s2 = c.get("myString"); |
Assert.assertTrue(s1 == s2); |
// then you can use THREAD |
// each thread will get a different instance |
c.ioc("myString", String.class, Scope.THREAD).addInitValue("saoj"); |
s1 = c.get("myString"); |
s2 = c.get("myString"); |
Assert.assertTrue(s1 == s2); // same thread |
} |
@Test |
public void testThreadLocal() throws Exception { |
final Container c = new MentaContainer(); |
c.ioc("myStr", String.class, Scope.THREAD).addInitValue("saoj"); |
String s1 = c.get("myStr"); |
MyThread t1 = new MyThread(c, "myStr"); |
MyThread t2 = new MyThread(c, "myStr"); |
t1.start(); |
t2.start(); |
t1.join(); |
t2.join(); |
String s2 = t1.getValue(); |
String s3 = t2.getValue(); |
Assert.assertTrue(s1 != s2); |
Assert.assertTrue(s2 != s3); |
} |
public static interface MyDAO { |
public Object getSomething(); |
} |
public static class SomeDependency { |
private String name; |
public SomeDependency() { } |
public void setName(String name) { |
this.name = name; |
} |
public String getName() { |
return name; |
} |
} |
public static class Connection { |
private final String name; |
private SomeDependency dep; |
public Connection(String name) { |
this.name = name; |
} |
@Override |
public String toString() { |
return getClass().getName() + ": " + name; |
} |
public String getName() { return name; } |
public void setMyDep(SomeDependency dep) { this.dep = dep; } |
public SomeDependency getMyDep() { return dep; } |
} |
public static class JdbcMyDAO implements MyDAO { |
private Connection conn; |
public void setConnection(Connection conn) { this.conn = conn; } |
public Connection getConnection() { return conn; } |
@Override |
public Object getSomething() { |
// use the connection to do something... |
Assert.assertNotNull(conn); // it cannot be null! |
// also test if the connection also received the myDep dependency... |
Assert.assertNotNull(conn.getMyDep()); |
return conn.toString(); |
} |
} |
private Container getConfiguredContainer() { |
Container c = new MentaContainer(); |
c.ioc("myDAO", JdbcMyDAO.class); |
c.ioc("aDependency", SomeDependency.class, Scope.SINGLETON).addPropertyValue("name", "A super dependency!"); |
c.ioc("connection", Connection.class).addInitValue("A super JDBC connection!"); |
c.autowire("connection"); |
c.autowire("aDependency", "myDep"); |
return c; |
} |
@Test |
public void testAutoWiring() { |
Container c = getConfiguredContainer(); |
MyDAO myDAO = c.get("myDAO"); |
// check implementation... |
Assert.assertEquals(JdbcMyDAO.class, myDAO.getClass()); |
// check dependency... |
Connection conn = ((JdbcMyDAO) myDAO).getConnection(); |
Assert.assertNotNull(conn); |
Assert.assertEquals("A super JDBC connection!", conn.getName()); |
// check dependency of dependency... |
Assert.assertEquals(c.get("aDependency"), conn.getMyDep()); |
Assert.assertTrue(c.get("aDependency") == conn.getMyDep()); // singleton! |
// check DAO can do its job... |
Assert.assertNotNull(myDAO.getSomething()); |
} |
public static class MyObject1 { |
} |
public static class MyObject2 { |
} |
public static class MyObject3 { |
public MyObject3(MyObject2 o2, MyObject1 o1) { |
} |
} |
private Container getConfiguredContainer2() { |
Container c = new MentaContainer(); |
c.ioc("myObj1", MyObject1.class); |
c.ioc("myObj2", MyObject2.class); |
c.ioc("myObj3", MyObject3.class); |
c.autowire("myObj1"); |
c.autowire("myObj2"); |
return c; |
} |
@Test |
public void testAutoWiringWithTwoConstructors() { |
Container c = getConfiguredContainer2(); |
MyObject3 obj3 = c.get("myObj3"); |
Assert.assertNotNull(obj3); |
} |
public static class SomeAction { |
private MyDAO myDAO = null; |
public void setMyDAO(MyDAO myDAO) { |
this.myDAO = myDAO; |
} |
public MyDAO getMyDAO() { return myDAO; } |
} |
@Test |
public void testPopulate() { |
Container c = getConfiguredContainer(); |
SomeAction a = new SomeAction(); |
c.inject(a); // great... properties of SomeAction were populated by container... |
// let's check if myDAO was injected... |
Assert.assertNotNull(a.getMyDAO()); |
// also check if myDAO was corrected wired... |
Connection conn = ((JdbcMyDAO) a.getMyDAO()).getConnection(); |
Assert.assertNotNull(conn); |
// check if conn was also wired... |
Assert.assertNotNull(conn.getMyDep()); |
} |
public static class SomeAction2 { |
private final MyDAO myDAO; |
public SomeAction2(MyDAO myDAO) { |
this.myDAO = myDAO; |
} |
public MyDAO getMyDAO() { return myDAO; } |
} |
@Test |
public void testConstructorDependency() { |
Container c = new MentaContainer(); |
c.ioc("myDAO", JdbcMyDAO.class); |
c.ioc("aDependency", SomeDependency.class, Scope.SINGLETON).addPropertyValue("name", "A super dependency!"); |
c.ioc("connection", Connection.class).addInitValue("A super JDBC connection!"); |
c.autowire("connection"); |
c.autowire("aDependency", "myDep"); |
c.ioc("someAction2", SomeAction2.class).addConstructorDependency("myDAO"); |
SomeAction2 action = c.get("someAction2"); |
Assert.assertNotNull(action.getMyDAO()); |
} |
@Test |
public void testConstruct() { |
Container c = getConfiguredContainer(); |
SomeAction2 a = c.construct(SomeAction2.class); |
// let's check if myDAO was injected... |
Assert.assertNotNull(a.getMyDAO()); |
// also check if myDAO was corrected wired... |
Connection conn = ((JdbcMyDAO) a.getMyDAO()).getConnection(); |
Assert.assertNotNull(conn); |
// check if conn was also wired... |
Assert.assertNotNull(conn.getMyDep()); |
} |
private static class SomeObject { |
private boolean destroyed = false; |
private boolean created = false; |
public void destroyed() { this.destroyed = true; } |
public boolean isDestroyed() { return destroyed; } |
public void created() { this.created = true; } |
public boolean isCreated() { return created; } |
} |
private static class SomeFactory implements Factory, Interceptor<SomeObject> { |
@Override |
public <T> T getInstance() { |
return (T) new SomeObject(); |
} |
@Override |
public Class<?> getType() { |
return SomeObject.class; |
} |
@Override |
public void onCleared(SomeObject obj) { |
obj.destroyed(); |
} |
@Override |
public void onCreated(SomeObject obj) { |
obj.created(); |
} |
} |
@Test |
public void testInterceptor() { |
Container c = new MentaContainer(); |
c.ioc("o", new SomeFactory(), Scope.SINGLETON); |
SomeObject o = c.get("o"); |
Assert.assertTrue(o.isCreated()); |
c.clear(Scope.SINGLETON); |
Assert.assertEquals(true, o.isDestroyed()); |
c.ioc("o", new SomeFactory(), Scope.THREAD); |
o = c.get("o"); |
Assert.assertTrue(o.isCreated()); |
c.clear(Scope.SINGLETON); |
Assert.assertEquals(false, o.isDestroyed()); |
c.clear(Scope.THREAD); |
Assert.assertEquals(true, o.isDestroyed()); |
c.ioc("o", new SomeFactory(), Scope.NONE); |
o = c.get("o"); |
Assert.assertTrue(o.isCreated()); |
o = c.clear("o"); |
Assert.assertNull(o); |
c.ioc("o", new SomeFactory(), Scope.THREAD); |
o = c.clear("o"); |
Assert.assertNull(o); |
o = c.get("o"); |
Assert.assertTrue(o.isCreated()); |
o = c.clear("o"); |
Assert.assertEquals(true, o.isDestroyed()); |
} |
} |
/tags/menta-container-1.0.2/src/test/java/org/mentacontainer/impl/WrapperFactoryTest.java |
---|
New file |
0,0 → 1,31 |
package org.mentacontainer.impl; |
import junit.framework.Assert; |
import org.junit.Test; |
import org.mentacontainer.Factory; |
import org.mentacontainer.Container; |
public class WrapperFactoryTest { |
@Test |
public void testInstanceFactory() throws Exception { |
String s = new String("saoj"); |
Factory ic = new SingletonFactory(s); |
Container c = new MentaContainer(); |
c.ioc("myString", ic); |
String s1 = c.get("myString"); |
String s2 = c.get("myString"); |
Assert.assertNotNull(s1); |
Assert.assertNotNull(s2); |
Assert.assertTrue(s == s1); |
Assert.assertTrue(s1 == s2); |
} |
} |
/tags/menta-container-1.0.2/src/test/java/org/mentacontainer/impl/ClassFactoryTest.java |
---|
New file |
0,0 → 1,290 |
package org.mentacontainer.impl; |
import junit.framework.Assert; |
import org.junit.Test; |
import org.mentacontainer.Factory; |
public class ClassFactoryTest { |
private static class User { |
private String username; |
public User() { } |
public User(String username) { |
this.username = username; |
} |
public String getUsername() { |
return username; |
} |
public void setUsername(String username) { |
this.username = username; |
} |
} |
@Test |
public void testFactory() { |
MentaContainer container = new MentaContainer(); |
Factory c1 = new ClassFactory(container, User.class).addInitValue("saoj"); |
Factory c2 = new ClassFactory(container, User.class).addPropertyValue("username", "soliveira"); |
User u1 = c1.getInstance(); |
User u2 = c2.getInstance(); |
Assert.assertTrue(u1 != u2); |
Assert.assertTrue(!u1.getUsername().equals(u2.getUsername())); |
} |
private static class TestObj1 { |
String s; |
int i; |
long l; |
User u; |
public TestObj1(String s, int i, long l, User u) { |
this.s = s; |
this.i = i; |
this.l = l; |
this.u = u; |
} |
} |
@Test |
public void testDependable1() { |
MentaContainer c = new MentaContainer(); |
c.ioc("myString", String.class).addInitValue("hello"); |
Factory c1 = new ClassFactory(c, TestObj1.class).addConstructorDependency("myString").addInitValue(20).addInitValue(30000L) |
.addInitValue(new User("saoj")); |
TestObj1 o = c1.getInstance(); |
Assert.assertEquals("hello", o.s); |
Assert.assertEquals(20, o.i); |
Assert.assertEquals(30000L, o.l); |
Assert.assertEquals("saoj", o.u.getUsername()); |
} |
private static class TestObj1_1 { |
String s; |
int i; |
public TestObj1_1() { } |
public void setS(String s) { this.s = s; } |
public void setI(int i) { this.i = i; } |
} |
@Test |
public void testDependable2() { |
MentaContainer c = new MentaContainer(); |
c.ioc("myString", String.class).addInitValue("hello"); |
Factory c1 = new ClassFactory(c, TestObj1_1.class).addPropertyDependency("s", "myString").addPropertyValue("i", 30); |
TestObj1_1 o = c1.getInstance(); |
Assert.assertEquals("hello", o.s); |
Assert.assertEquals(30, o.i); |
} |
private static class TestObj2 { |
int x; |
public TestObj2() { } |
public void setInteger(int x) { |
this.x = x; |
} |
} |
@Test |
public void testPrimitivePropertyValue1() { |
MentaContainer container = new MentaContainer(); |
Factory f = new ClassFactory(container, TestObj2.class).addPropertyValue("integer", 20); |
TestObj2 o = f.getInstance(); |
Assert.assertEquals(20, o.x); |
} |
@Test |
public void testPrimitivePropertyValue2() { |
MentaContainer container = new MentaContainer(); |
Factory f = new ClassFactory(container, TestObj2.class).addPropertyValue("integer", new Integer(20)); |
TestObj2 o = f.getInstance(); |
Assert.assertEquals(20, o.x); |
} |
private static class TestObj2_1 { |
int x; |
public TestObj2_1() { } |
public void setInteger(Integer x) { |
this.x = x; |
} |
} |
@Test |
public void testPrimitivePropertyValue3() { |
MentaContainer container = new MentaContainer(); |
Factory f = new ClassFactory(container, TestObj2_1.class).addPropertyValue("integer", 20); |
TestObj2_1 o = f.getInstance(); |
Assert.assertEquals(20, o.x); |
} |
@Test |
public void testPrimitivePropertyValue4() { |
MentaContainer container = new MentaContainer(); |
Factory f = new ClassFactory(container, TestObj2_1.class).addPropertyValue("integer", new Integer(20)); |
TestObj2_1 o = f.getInstance(); |
Assert.assertEquals(20, o.x); |
} |
private static class TestObj3 { |
int x; |
public TestObj3(int x) { |
this.x = x; |
} |
} |
@Test |
public void testPrimitiveInitValue1() { |
MentaContainer container = new MentaContainer(); |
Factory f = new ClassFactory(container, TestObj3.class).addInitValue(20); |
TestObj3 o = f.getInstance(); |
Assert.assertEquals(20, o.x); |
} |
private static class TestObj3_1 { |
int x; |
public TestObj3_1(Integer x) { |
this.x = x; |
} |
} |
@Test |
public void testPrimitiveInitValue2() { |
MentaContainer container = new MentaContainer(); |
Factory f = new ClassFactory(container, TestObj3_1.class).addInitValue(20); |
TestObj3_1 o = f.getInstance(); |
Assert.assertEquals(20, o.x); |
} |
private static class TestObj3_2 { |
int x; |
long l; |
public TestObj3_2(Integer x, long l) { |
this.x = x; |
this.l = l; |
} |
} |
@Test |
public void testPrimitiveInitValue3() { |
MentaContainer container = new MentaContainer(); |
Factory f = new ClassFactory(container, TestObj3_2.class).addInitValue(20).addInitPrimitive(30L); |
TestObj3_2 o = f.getInstance(); |
Assert.assertEquals(20, o.x); |
Assert.assertEquals(30L, o.l); |
} |
private static class TestObj4 { |
int x; |
String s; |
Long l1; |
long l2; |
public TestObj4(int x, String s, Long l1, long l2) { |
this.x = x; |
this.s = s; |
this.l1 = l1; |
this.l2 = l2; |
} |
} |
@Test |
public void testMixInitValues() { |
MentaContainer container = new MentaContainer(); |
Factory f = new ClassFactory(container, TestObj4.class).addInitPrimitive(20).addInitValue("hello").addInitValue(20L).addInitPrimitive(20L); |
TestObj4 o = f.getInstance(); |
Assert.assertEquals(20, o.x); |
Assert.assertEquals("hello", o.s); |
Assert.assertEquals(new Long(20), o.l1); |
Assert.assertEquals(20, o.l2); |
} |
private static class TestObj22 { |
public TestObj22() { } |
} |
@Test |
public void testOnlyOneZeroArgConstructor() { |
MentaContainer container = new MentaContainer(); |
Factory f = new ClassFactory(container, TestObj22.class); |
TestObj22 o = f.getInstance(); |
Assert.assertNotNull(o); |
} |
} |
/tags/menta-container-1.0.2/src/test/java/org/mentacontainer/example/CoreExamplesTest.java |
---|
New file |
0,0 → 1,198 |
package org.mentacontainer.example; |
import java.util.Calendar; |
import java.util.Date; |
import junit.framework.Assert; |
import org.junit.Test; |
import org.mentacontainer.Container; |
import org.mentacontainer.impl.MentaContainer; |
public class CoreExamplesTest { |
@Test |
public void testBeanInitialization() { |
Container c = new MentaContainer(); |
c.ioc("myString1", String.class); |
String myString1 = c.get("myString1"); |
Assert.assertEquals("", myString1); // default constructor... |
c.ioc("myString2", String.class).addInitValue("saoj"); |
String myString2 = c.get("myString2"); // using constructor.... |
Assert.assertEquals("saoj", myString2); |
Assert.assertNotSame(c.get("myString1"), c.get("myString1")); // most be different instances... |
// test setters... |
c.ioc("myDate1", Date.class).addPropertyValue("hours", 15) // setHours(15) |
.addPropertyValue("minutes", 10) // setMinutes(10) |
.addPropertyValue("seconds", 45); // setSeconds(45) |
Date myDate1 = c.get("myDate1"); |
Assert.assertTrue(myDate1.toString().indexOf("15:10:45") > 0); |
// test setter together with constructor... |
Calendar cal = Calendar.getInstance(); |
cal.set(Calendar.YEAR, 1976); |
c.ioc("myDate2", Date.class).addInitValue(cal.getTimeInMillis()).addPropertyValue("seconds", 59); |
Date myDate2 = c.get("myDate2"); |
Assert.assertTrue(myDate2.toString().indexOf(":59") > 0); |
Assert.assertTrue(myDate2.toString().indexOf("1976") > 0); |
} |
@Test |
public void testDependencies() { |
// constructor dependency... |
Container c = new MentaContainer(); |
c.ioc("username", String.class).addInitValue("saoj"); |
c.ioc("myString", String.class).addConstructorDependency("username"); |
String myString = c.get("myString"); |
Assert.assertEquals("saoj", myString); |
// setter dependency... |
c.ioc("myBirthdayYear", Integer.class).addInitValue(76); |
c.ioc("myBirthday", Date.class).addPropertyDependency("year", "myBirthdayYear").addPropertyValue("month", 0).addPropertyValue("date", 20); |
Date myBirthday = c.get("myBirthday"); |
Assert.assertTrue(myBirthday.toString().indexOf("Jan 20") > 0); |
Assert.assertTrue(myBirthday.toString().indexOf("1976") > 0); |
// both... |
Calendar cal = Calendar.getInstance(); |
cal.set(Calendar.YEAR, 1976); |
c.ioc("timeInMillis", Long.class).addInitValue(cal.getTimeInMillis()); |
c.ioc("myBirthdayMonth", Integer.class).addInitValue(0); |
c.ioc("myBirthday", Date.class).addConstructorDependency("timeInMillis").addPropertyDependency("month", "myBirthdayMonth").addPropertyValue("date", 20); |
myBirthday = c.get("myBirthday"); |
Assert.assertTrue(myBirthday.toString().indexOf("Jan 20") > 0); |
Assert.assertTrue(myBirthday.toString().indexOf("1976") > 0); |
} |
@Test |
public void testAutoWiring() { |
// constructor dependency... |
Container c = new MentaContainer(); |
c.ioc("username", String.class).addInitValue("saoj"); |
c.ioc("myString", String.class); |
c.autowire("username"); |
String myString = c.get("myString"); |
Assert.assertEquals("saoj", myString); |
// setter dependency... |
c = new MentaContainer(); |
c.ioc("myBirthdayYear", Integer.class).addInitValue(76); |
c.ioc("myBirthday", Date.class).addPropertyValue("month", 0).addPropertyValue("date", 20); |
c.autowire("myBirthdayYear", "year"); |
Date myBirthday = c.get("myBirthday"); |
Assert.assertTrue(myBirthday.toString().indexOf("Jan 20") > 0); |
Assert.assertTrue(myBirthday.toString().indexOf("1976") > 0); |
// both... |
c = new MentaContainer(); |
Calendar cal = Calendar.getInstance(); |
cal.set(Calendar.YEAR, 1976); |
c.ioc("timeInMillis", Long.class).addInitValue(cal.getTimeInMillis()); |
c.ioc("myBirthdayMonth", Integer.class).addInitValue(0); |
c.ioc("myBirthday", Date.class).addPropertyValue("date", 20); |
c.autowire("timeInMillis"); |
c.autowire("myBirthdayMonth", "month"); |
myBirthday = c.get("myBirthday"); |
Assert.assertTrue(myBirthday.toString().indexOf("Jan 20") > 0); |
Assert.assertTrue(myBirthday.toString().indexOf("1976") > 0); |
// bypass autowireByConstructor by specifying... |
c = new MentaContainer(); |
cal = Calendar.getInstance(); |
cal.set(Calendar.YEAR, 1976); |
Calendar cal2 = Calendar.getInstance(); |
cal2.set(Calendar.YEAR, 1977); |
c.ioc("timeInMillis", Long.class).addInitValue(cal.getTimeInMillis()); |
c.ioc("timeInMillis2", Long.class).addInitValue(cal2.getTimeInMillis()); |
c.ioc("myBirthdayMonth", Integer.class).addInitValue(0); |
c.ioc("myBirthday", Date.class).addPropertyValue("date", 20).addConstructorDependency("timeInMillis2"); |
c.autowire("timeInMillis"); |
c.autowire("myBirthdayMonth", "month"); |
myBirthday = c.get("myBirthday"); |
Assert.assertTrue(myBirthday.toString().indexOf("Jan 20") > 0); |
Assert.assertTrue(myBirthday.toString().indexOf("1977") > 0); |
// bypass autowireBySetter by specifying... |
// not supported yet... |
// force zero arguments constructor... |
c = new MentaContainer(); |
cal = Calendar.getInstance(); |
cal.set(Calendar.YEAR, 1976); |
c.ioc("timeInMillis", Long.class).addInitValue(cal.getTimeInMillis()); |
c.ioc("myBirthdayMonth", Integer.class).addInitValue(0); |
c.ioc("myBirthday", Date.class).addPropertyValue("date", 20).useZeroArgumentConstructor(); |
c.autowire("timeInMillis"); |
c.autowire("myBirthdayMonth", "month"); |
myBirthday = c.get("myBirthday"); |
Assert.assertTrue(myBirthday.toString().indexOf("Jan 20") > 0); |
Assert.assertTrue(myBirthday.toString().indexOf("1976") == -1); |
} |
} |
/tags/menta-container-1.0.2/src/main/java/org/mentacontainer/impl/ConstructorDependency.java |
---|
New file |
0,0 → 1,54 |
package org.mentacontainer.impl; |
/** |
* A simple implementation of the Dependency interface. |
* |
* @author sergio.oliveira.jr@gmail.com |
*/ |
class ConstructorDependency { |
private final String sourceFromContainer; |
private final Class<?> sourceType; |
public ConstructorDependency(String sourceFromContainer, Class<?> sourceType) { |
this.sourceFromContainer = sourceFromContainer; |
this.sourceType = sourceType; |
} |
public String getSource() { |
return sourceFromContainer; |
} |
public Class<?> getSourceType() { |
return sourceType; |
} |
@Override |
public int hashCode() { |
return sourceFromContainer.hashCode(); |
} |
@Override |
public boolean equals(Object obj) { |
if (!(obj instanceof ConstructorDependency)) return false; |
ConstructorDependency d = (ConstructorDependency) obj; |
if (!d.sourceFromContainer.equals(this.sourceFromContainer)) return false; |
return true; |
} |
@Override |
public String toString() { |
return "[ConstructorDependency: sourceFromContainer=" + sourceFromContainer + "]"; |
} |
} |
/tags/menta-container-1.0.2/src/main/java/org/mentacontainer/impl/GenericFactory.java |
---|
New file |
0,0 → 1,74 |
package org.mentacontainer.impl; |
import java.lang.reflect.Method; |
import org.mentacontainer.Factory; |
import org.mentacontainer.Interceptor; |
import org.mentacontainer.util.FindMethod; |
public class GenericFactory<E> implements Factory, Interceptor<E> { |
private final Object factory; |
private final Method method; |
private final Class<?> type; |
private Interceptor<E> interceptor = null; |
public GenericFactory(Object factory, String methodName) { |
this.factory = factory; |
try { |
this.method = FindMethod.getMethod(factory.getClass(), methodName, new Class[] { }); |
this.method.setAccessible(true); |
this.type = method.getReturnType(); |
} catch(Exception e) { |
throw new RuntimeException(e); |
} |
} |
public void setInterceptor(Interceptor<E> interceptor) { |
this.interceptor = interceptor; |
} |
@Override |
public void onCreated(E createdObject) { |
if (interceptor != null) { |
interceptor.onCreated(createdObject); |
} |
} |
@Override |
public void onCleared(E clearedObject) { |
if (interceptor != null) { |
interceptor.onCleared(clearedObject); |
} |
} |
@Override |
public <T> T getInstance() { |
try { |
return (T) method.invoke(factory, (Object[]) null); |
} catch(Exception e) { |
throw new RuntimeException("Cannot invoke method: " + method, e); |
} |
} |
@Override |
public Class<?> getType() { |
return type; |
} |
} |
/tags/menta-container-1.0.2/src/main/java/org/mentacontainer/impl/SetterDependency.java |
---|
New file |
0,0 → 1,141 |
package org.mentacontainer.impl; |
import java.lang.reflect.Method; |
import java.util.HashMap; |
import java.util.Map; |
import org.mentacontainer.util.InjectionUtils; |
/** |
* A simple implementation of the Dependency interface. |
* |
* @author sergio.oliveira.jr@gmail.com |
*/ |
class SetterDependency { |
private final String targetProperty; |
private final String sourceFromContainer; |
private final Class<?> sourceType; |
private Map<String, Method> cache = new HashMap<String, Method>(); |
public SetterDependency(String targetProperty, String sourceFromContainer, Class<?> sourceType) { |
this.targetProperty = targetProperty; |
this.sourceFromContainer = sourceFromContainer; |
this.sourceType = sourceType; |
} |
public String getTarget() { |
return targetProperty; |
} |
public String getSource() { |
return sourceFromContainer; |
} |
@Override |
public int hashCode() { |
return targetProperty.hashCode() * 31 + sourceFromContainer.hashCode(); |
} |
@Override |
public boolean equals(Object obj) { |
if (!(obj instanceof SetterDependency)) return false; |
SetterDependency d = (SetterDependency) obj; |
if (!d.targetProperty.equals(this.targetProperty)) return false; |
if (!d.sourceFromContainer.equals(this.sourceFromContainer)) return false; |
return true; |
} |
public Method check(Class<?> targetClass) { |
String className = targetClass.getName(); |
// first check cache... |
Method m = null; |
synchronized(cache) { |
m = cache.get(className); |
} |
if (m == null && cache.containsKey(className)) return null; // it is null... |
if (m != null) return m; |
m = InjectionUtils.findMethodToInject(targetClass, targetProperty, sourceType); |
/* |
try { |
Method[] methods = targetClass.getMethods(); |
StringBuilder sb = new StringBuilder(128); |
sb.append("set"); |
sb.append(targetProperty.substring(0, 1).toUpperCase()); |
if (targetProperty.length() > 1) sb.append(targetProperty.substring(1)); |
String methodName = sb.toString(); |
for(Method theMethod : methods) { |
if (theMethod.getName().equals(methodName)) { |
// check type... |
Class<?>[] params = theMethod.getParameterTypes(); |
if (params == null || params.length != 1) continue; |
if (params[0].isAssignableFrom(sourceType)) { |
m = theMethod; |
break; |
} |
} |
} |
} catch(Exception e) { |
e.printStackTrace(); |
} |
*/ |
if (m != null) { |
synchronized(cache) { |
cache.put(className, m); |
} |
return m; |
} |
synchronized(cache) { |
// save null to indicate there is no method here... (so you don't do again to find null !!! |
cache.put(className, null); |
} |
return null; |
} |
} |
/tags/menta-container-1.0.2/src/main/java/org/mentacontainer/impl/MentaContainer.java |
---|
New file |
0,0 → 1,556 |
package org.mentacontainer.impl; |
import java.lang.reflect.Method; |
import java.util.Collections; |
import java.util.HashSet; |
import java.util.Hashtable; |
import java.util.LinkedList; |
import java.util.List; |
import java.util.Map; |
import java.util.Set; |
import org.mentacontainer.ConfigurableFactory; |
import org.mentacontainer.Container; |
import org.mentacontainer.Factory; |
import org.mentacontainer.Interceptor; |
import org.mentacontainer.Scope; |
import org.mentacontainer.util.InjectionUtils; |
import org.mentacontainer.util.InjectionUtils.Provider; |
/** |
* The implementation of the IoC container. |
* |
* @author sergio.oliveira.jr@gmail.com |
*/ |
public class MentaContainer implements Container { |
private Map<String, Factory> factoriesByName = new Hashtable<String, Factory>(); |
private Map<String, Scope> scopes = new Hashtable<String, Scope>(); |
private Map<String, Object> singletonsCache = new Hashtable<String, Object>(); |
private Map<String, ThreadLocal<Object>> threadLocalsCache = new Hashtable<String, ThreadLocal<Object>>(); |
private Set<SetterDependency> setterDependencies = Collections.synchronizedSet(new HashSet<SetterDependency>()); |
private Set<ConstructorDependency> constructorDependencies = Collections.synchronizedSet(new HashSet<ConstructorDependency>()); |
private Set<ConstructorDependency> forConstructMethod = Collections.synchronizedSet(new HashSet<ConstructorDependency>()); |
@Override |
public Class<?> getType(Object key) { |
String k = InjectionUtils.getKeyName(key); |
Factory factory = factoriesByName.get(k); |
if (factory == null) return null; |
return factory.getType(); |
} |
@Override |
public void clear(Scope scope) { |
if (scope == Scope.SINGLETON) { |
List<ClearableHolder> listToClear = new LinkedList<ClearableHolder>(); |
synchronized(this) { |
for(String key : singletonsCache.keySet()) { |
Factory factory = factoriesByName.get(key); |
if (factory instanceof Interceptor) { |
Interceptor c = (Interceptor) factory; |
Object value = singletonsCache.get(key); |
listToClear.add(new ClearableHolder(c, value)); |
} |
} |
singletonsCache.clear(); |
} |
// clear everything inside a non-synchronized block... |
for(ClearableHolder cp : listToClear) cp.clear(); |
} else if (scope == Scope.THREAD) { |
List<ClearableHolder> listToClear = new LinkedList<ClearableHolder>(); |
synchronized(this) { |
for(String key : threadLocalsCache.keySet()) { |
Factory factory = factoriesByName.get(key); |
if (factory instanceof Interceptor) { |
Interceptor c = (Interceptor) factory; |
ThreadLocal<Object> t = threadLocalsCache.get(key); |
Object value = t.get(); |
// we are ONLY clearing if this thread has something in the threadlocal, in other words, |
// if the thread has previously requested this key... |
if (value != null) listToClear.add(new ClearableHolder(c, value)); |
} |
} |
// and now we clear all thread locals belonging to this thread... |
// this will only clear the instances related to this thread... |
for(ThreadLocal<Object> t : threadLocalsCache.values()) { |
t.remove(); |
} |
} |
// clear everything inside a non-synchronized block... |
for(ClearableHolder cp : listToClear) cp.clear(); |
} |
} |
@Override |
public <T> T clear(Object key) { |
String keyString = InjectionUtils.getKeyName(key); |
if (!factoriesByName.containsKey(keyString)) return null; |
Scope scope = scopes.get(keyString); |
if (scope == Scope.SINGLETON) { |
ClearableHolder cp = null; |
Object value = null; |
synchronized(this) { |
value = singletonsCache.remove(keyString); |
if (value != null) { |
Factory factory = factoriesByName.get(keyString); |
if (factory instanceof Interceptor) { |
Interceptor c = (Interceptor) factory; |
cp = new ClearableHolder(c, value); |
} |
} |
} |
if (cp != null) cp.clear(); |
return (T) value; |
} else if (scope == Scope.THREAD) { |
ClearableHolder cp = null; |
Object retVal = null; |
synchronized(this) { |
ThreadLocal<Object> t = threadLocalsCache.get(keyString); |
if (t != null) { |
Object o = t.get(); |
if (o != null) { |
Factory factory = factoriesByName.get(keyString); |
if (factory instanceof Interceptor) { |
Interceptor c = (Interceptor) factory; |
cp = new ClearableHolder(c, o); |
} |
t.remove(); |
retVal = o; |
} |
} |
} |
if (cp != null) cp.clear(); |
return (T) retVal; |
} else if (scope == Scope.NONE) { |
return null; // always... |
} else { |
throw new UnsupportedOperationException("Scope not supported: " + scope); |
} |
} |
@Override |
public <T> T get(Object key) { |
String keyString = InjectionUtils.getKeyName(key); |
if (!factoriesByName.containsKey(keyString)) return null; |
Factory c = factoriesByName.get(keyString); |
Scope scope = scopes.get(keyString); |
Object target = null; |
try { |
if (scope == Scope.SINGLETON) { |
boolean needsToCreate = false; |
synchronized(this) { |
if (singletonsCache.containsKey(keyString)) { |
target = singletonsCache.get(keyString); |
return (T) target; // no need to wire again... |
} else { |
needsToCreate = true; |
} |
} |
if (needsToCreate) { |
// getInstance needs to be in a non-synchronized block |
target = c.getInstance(); |
checkInterceptable(c, target); |
synchronized(this) { |
singletonsCache.put(keyString, target); |
} |
} |
} else if (scope == Scope.THREAD) { |
boolean needsToCreate = false; |
boolean needsToAddToCache = false; |
ThreadLocal<Object> t = null; |
synchronized(this) { |
if (threadLocalsCache.containsKey(keyString)) { |
t = threadLocalsCache.get(keyString); |
target = t.get(); |
if (target == null) { // different thread... |
needsToCreate = true; |
// don't return... let it be wired... |
} else { |
return (T) target; // no need to wire again... |
} |
} else { |
t = new ThreadLocal<Object>(); |
needsToCreate = true; |
needsToAddToCache = true; |
// let it be wired... |
} |
} |
if (needsToCreate) { |
// getInstance needs to be in a non-synchronized block |
target = c.getInstance(); |
checkInterceptable(c, target); |
t.set(target); |
} |
if (needsToAddToCache) { |
synchronized(this) { |
threadLocalsCache.put(keyString, t); |
} |
} |
} else if (scope == Scope.NONE) { |
target = c.getInstance(); |
checkInterceptable(c, target); |
} else { |
throw new UnsupportedOperationException("Don't know how to handle scope: " + scope); |
} |
if (target != null) { |
for (SetterDependency d : setterDependencies) { |
// has dependency ? |
Method m = d.check(target.getClass()); |
if (m != null) { |
String sourceKey = d.getSource(); |
if (sourceKey.equals(keyString)) { |
// cannot depend on itself... also avoid recursive StackOverflow... |
continue; |
} |
Object source = get(sourceKey); |
try { |
// inject |
m.invoke(target, source); |
} catch (Exception e) { |
throw new RuntimeException("Cannot inject dependency: method = " + (m != null ? m.getName() : "NULL") + " / source = " |
+ (source != null ? source : "NULL") + " / target = " + target, e); |
} |
} |
} |
} |
return (T) target; // return target nicely with all the dependencies |
} catch (Exception e) { |
throw new RuntimeException(e); |
} |
} |
private final void checkInterceptable(Factory f, Object value) { |
if (f instanceof Interceptor) { |
Interceptor i = (Interceptor) f; |
((Interceptor) f).onCreated(value); |
} |
} |
@Override |
public Factory ioc(Object key, Factory factory, Scope scope) { |
String keyString = InjectionUtils.getKeyName(key); |
factoriesByName.put(keyString, factory); |
singletonsCache.remove(keyString); // just in case we are overriding a previous singleton bean... |
ThreadLocal<Object> threadLocal = threadLocalsCache.remove(keyString); // just in case we are overriding a previous thread local... |
if (threadLocal != null) { |
threadLocal.remove(); |
} |
scopes.put(keyString, scope); |
forConstructMethod.add(new ConstructorDependency(keyString, factory.getType())); |
return factory; |
} |
@Override |
public Factory ioc(Object key, Factory factory) { |
return ioc(key, factory, Scope.NONE); |
} |
@Override |
public ConfigurableFactory ioc(Object key, Class<?> klass) { |
ConfigurableFactory cc = new ClassFactory(this, klass); |
ioc(key, cc); |
return cc; |
} |
@Override |
public ConfigurableFactory ioc(Object key, Class<?> klass, Scope scope) { |
ConfigurableFactory cc = new ClassFactory(this, klass); |
ioc(key, cc, scope); |
return cc; |
} |
@Override |
public void autowire(Object sourceFromContainer) { |
// autowire by constructor and setter... |
String s = InjectionUtils.getKeyName(sourceFromContainer); |
autowireBySetter(s); |
autowireByConstructor(s); |
} |
@Override |
public void autowire(Object sourceFromContainer, String beanProperty) { |
// autowire by constructor and setter... |
String s = InjectionUtils.getKeyName(sourceFromContainer); |
autowireBySetter(beanProperty, s); |
autowireByConstructor(s); |
} |
private void autowireBySetter(String targetProperty, String sourceFromContainer) { |
Class<?> sourceType = getType(sourceFromContainer); |
SetterDependency d = new SetterDependency(targetProperty, sourceFromContainer, sourceType); |
setterDependencies.add(d); |
} |
private void autowireBySetter(String targetProperty) { |
autowireBySetter(targetProperty, targetProperty); |
} |
private void autowireByConstructor(String sourceFromContainer) { |
Class<?> sourceType = getType(sourceFromContainer); |
ConstructorDependency d = new ConstructorDependency(sourceFromContainer, sourceType); |
constructorDependencies.add(d); |
} |
Set<ConstructorDependency> getConstructorDependencies() { |
return constructorDependencies; |
} |
@Override |
public <T> T construct(Class<?> klass) { |
ClassFactory f = new ClassFactory(this, klass, forConstructMethod); |
return (T) f.getInstance(); |
} |
@Override |
public void inject(Object bean) { |
Provider p = new Provider() { |
@Override |
public Object get(String key) { |
return MentaContainer.this.get(key); |
} |
@Override |
public boolean hasValue(String key) { |
return MentaContainer.this.check(key); |
} |
}; |
try { |
InjectionUtils.getObject(bean, p, false, null, true, false, true); |
} catch(Exception e) { |
throw new RuntimeException("Error populating bean: " + bean, e); |
} |
} |
@Override |
public synchronized boolean check(Object obj) { |
String key = InjectionUtils.getKeyName(obj); |
if (!factoriesByName.containsKey(key)) return false; |
Scope scope = scopes.get(key); |
if (scope == Scope.NONE) { |
return false; // always... |
} else if (scope == Scope.SINGLETON) { |
return singletonsCache.containsKey(key); |
} else if (scope == Scope.THREAD) { |
ThreadLocal<Object> t = threadLocalsCache.get(key); |
if (t != null) return t.get() != null; |
return false; |
} else { |
throw new UnsupportedOperationException("This scope is not supported: " + scope); |
} |
} |
private static class ClearableHolder { |
private Interceptor c; |
private Object value; |
public ClearableHolder(Interceptor c, Object value) { |
this.c = c; |
this.value = value; |
} |
public void clear() { |
c.onCleared(value); |
} |
} |
} |
/tags/menta-container-1.0.2/src/main/java/org/mentacontainer/impl/SingletonFactory.java |
---|
New file |
0,0 → 1,30 |
package org.mentacontainer.impl; |
import org.mentacontainer.Factory; |
public class SingletonFactory implements Factory { |
private final Object instance; |
private final Class<?> type; |
public SingletonFactory(Object instance) { |
this.instance = instance; |
this.type = instance.getClass(); |
} |
@Override |
public <T> T getInstance() { |
return (T) instance; |
} |
@Override |
public Class<?> getType() { |
return type; |
} |
} |
/tags/menta-container-1.0.2/src/main/java/org/mentacontainer/impl/ClassFactory.java |
---|
New file |
0,0 → 1,505 |
package org.mentacontainer.impl; |
import java.lang.reflect.Constructor; |
import java.lang.reflect.Method; |
import java.util.HashMap; |
import java.util.HashSet; |
import java.util.Iterator; |
import java.util.LinkedList; |
import java.util.List; |
import java.util.Map; |
import java.util.Set; |
import org.mentacontainer.ConfigurableFactory; |
import org.mentacontainer.util.FindConstructor; |
import org.mentacontainer.util.FindMethod; |
import org.mentacontainer.util.InjectionUtils; |
/** |
* The implementation of the Configurable Factory. |
* |
* @author sergio.oliveira.jr@gmail.com |
*/ |
class ClassFactory implements ConfigurableFactory { |
private final MentaContainer container; |
private final Class<?> klass; |
private Map<String, Object> props = null; |
private List<Object> initValues = null; |
private List<Class<?>> initTypes = null; |
private Constructor<?> constructor = null; |
private Map<String, Method> cache = null; |
private boolean useZeroArgumentsConstructor = false; |
private final Set<ConstructorDependency> constructorDependencies; |
public ClassFactory(MentaContainer container, Class<?> klass) { |
this(container, klass, null); |
} |
ClassFactory(MentaContainer container, Class<?> klass, Set<ConstructorDependency> constructorDependencies) { |
this.container = container; |
this.klass = klass; |
this.constructorDependencies = constructorDependencies; |
} |
@Override |
public ConfigurableFactory addPropertyValue(String name, Object value) { |
if (props == null) { |
props = new HashMap<String, Object>(); |
cache = new HashMap<String, Method>(); |
} |
props.put(name, value); |
return this; |
} |
@Override |
public ConfigurableFactory useZeroArgumentConstructor() { |
this.useZeroArgumentsConstructor = true; |
return this; |
} |
@Override |
public ConfigurableFactory addPropertyDependency(String property, Object key) { |
String k = InjectionUtils.getKeyName(key); |
return addPropertyValue(property, new DependencyKey(k)); |
} |
@Override |
public ConfigurableFactory addPropertyDependency(String property) { |
return addPropertyDependency(property, property); |
} |
@Override |
public ConfigurableFactory addConstructorDependency(Object key) { |
String k = InjectionUtils.getKeyName(key); |
return addInitValue(new DependencyKey(k), container.getType(k)); |
} |
private ConfigurableFactory addInitValue(Object value, Class<?> type) { |
if (initValues == null) { |
initValues = new LinkedList<Object>(); |
initTypes = new LinkedList<Class<?>>(); |
} |
initValues.add(value); |
initTypes.add(type); |
return this; |
} |
@Override |
public ConfigurableFactory addInitValue(Object value) { |
return addInitValue(value, value.getClass()); |
} |
@Override |
public ConfigurableFactory addInitPrimitive(Object value) { |
Class<?> primitive = getPrimitiveFrom(value); |
if (primitive == null) throw new IllegalArgumentException("Value is not a primitive: " + value); |
return addInitValue(value, primitive); |
} |
private List<Class<?>> convertToPrimitives(List<Class<?>> list) { |
if (list == null) return null; |
Iterator<Class<?>> iter = list.iterator(); |
List<Class<?>> results = new LinkedList<Class<?>>(); |
while(iter.hasNext()) { |
Class<?> klass = iter.next(); |
Class<?> primitive = getPrimitiveFrom(klass); |
if (primitive != null) { |
results.add(primitive); |
} else { |
results.add(klass); |
} |
} |
return results; |
} |
private Class<?>[] getClasses(List<Class<?>> values) { |
if (values == null) return new Class[0]; |
Class<?>[] types = (Class<?>[]) new Class[values.size()]; |
return values.toArray(types); |
} |
private Object [] getValues(List<Object> values) throws InstantiationException { |
if (values == null) return null; |
Object [] array = new Object[values.size()]; |
int index = 0; |
Iterator<Object> iter = values.iterator(); |
while(iter.hasNext()) { |
Object obj = iter.next(); |
if (obj instanceof DependencyKey) { |
DependencyKey dk = (DependencyKey) obj; |
array[index++] = container.get(dk.getKey()); |
} else { |
array[index++] = obj; |
} |
} |
return array; |
} |
/* |
* Use reflection to set a property in the bean |
*/ |
private void setValue(Object bean, String name, Object value) { |
try { |
StringBuffer sb = new StringBuffer(30); |
sb.append("set"); |
sb.append(name.substring(0,1).toUpperCase()); |
if (name.length() > 1) sb.append(name.substring(1)); |
String methodName = sb.toString(); |
if (!cache.containsKey(name)) { |
Method m = null; |
try { |
m = FindMethod.getMethod(klass, methodName, new Class[] { value.getClass() }); |
} catch(Exception e) { |
// try primitive... |
Class<?> primitive = getPrimitiveFrom(value); |
if (primitive != null) { |
try { |
m = klass.getMethod(methodName, new Class[] { primitive }); |
} catch(Exception ex) { |
// not found! |
} |
} |
if (m == null) { |
throw new InstantiationException("Cannot find method for property: " + name); |
} |
} |
if (m != null) { |
cache.put(name, m); |
m.setAccessible(true); |
} |
} |
Method m = cache.get(name); |
if (m != null) { |
m.invoke(bean, new Object[] { value }); |
} |
} catch(Exception e) { |
throw new RuntimeException("Error trying to set a property with reflection: " + name, e); |
} |
} |
private static Class<?> getPrimitiveFrom(Object w) { |
if (w instanceof Boolean) { return Boolean.TYPE; } |
else if (w instanceof Byte) { return Byte.TYPE; } |
else if (w instanceof Short) { return Short.TYPE; } |
else if (w instanceof Character) { return Character.TYPE; } |
else if (w instanceof Integer) { return Integer.TYPE; } |
else if (w instanceof Long) { return Long.TYPE; } |
else if (w instanceof Float) { return Float.TYPE; } |
else if (w instanceof Double) { return Double.TYPE; } |
return null; |
} |
private static Class<?> getPrimitiveFrom(Class<?> klass) { |
if (klass.equals(Boolean.class)) { return Boolean.TYPE; } |
else if (klass.equals(Byte.class)) { return Byte.TYPE; } |
else if (klass.equals(Short.class)) { return Short.TYPE; } |
else if (klass.equals(Character.class)) { return Character.TYPE; } |
else if (klass.equals(Integer.class)) { return Integer.TYPE; } |
else if (klass.equals(Long.class)) { return Long.TYPE; } |
else if (klass.equals(Float.class)) { return Float.TYPE; } |
else if (klass.equals(Double.class)) { return Double.TYPE; } |
return null; |
} |
@Override |
public <T> T getInstance() { |
Object obj = null; |
Object[] values = null; |
synchronized(this) { |
if (constructor == null) { |
if (!useZeroArgumentsConstructor) { |
checkConstructorDependencies(); |
} else { |
if (initTypes != null) initTypes = null; // just in case client did something stupid... |
if (initValues != null) initValues = null; // just in case client did something stupid... |
} |
try { |
//constructor = klass.getConstructor(getClasses(initTypes)); |
constructor = FindConstructor.getConstructor(klass, getClasses(initTypes)); |
} catch(Exception e) { |
// try primitives... |
try { |
//constructor = klass.getConstructor(getClasses(convertToPrimitives(initTypes))); |
constructor = FindConstructor.getConstructor(klass, getClasses(convertToPrimitives(initTypes))); |
} catch(Exception ee) { |
throw new RuntimeException("Cannot find a constructor for class: " + klass); |
} |
} |
} |
try { |
values = getValues(initValues); |
} catch(Exception e) { |
new RuntimeException("Cannot instantiate values for constructor!", e); |
} |
} |
try { |
obj = constructor.newInstance(values); |
} catch(Exception e) { |
throw new RuntimeException("Cannot create instance from constructor: " + constructor, e); |
} |
if (props != null && props.size() > 0) { |
Iterator<String> iter = props.keySet().iterator(); |
while(iter.hasNext()) { |
String name = iter.next(); |
Object value = props.get(name); |
if (value instanceof DependencyKey) { |
DependencyKey dk = (DependencyKey) value; |
value = container.get(dk.getKey()); |
} |
setValue(obj, name, value); |
} |
} |
return (T) obj; |
} |
private static boolean betterIsAssignableFrom(Class<?> klass1, Class<?> klass2) { |
// with autoboxing both ways... |
if (klass1.isAssignableFrom(klass2)) return true; |
Class<?> k1 = klass1.isPrimitive() ? klass1 : getPrimitiveFrom(klass1); |
Class<?> k2 = klass2.isPrimitive() ? klass2 : getPrimitiveFrom(klass2); |
if (k1 == null || k2 == null) return false; |
return k1.isAssignableFrom(k2); |
} |
private void checkConstructorDependencies() { |
Constructor<?>[] constructors = klass.getConstructors(); |
for(Constructor<?> c : constructors) { |
LinkedList<Class<?>> providedInitTypes = null; |
if (initTypes != null) { |
providedInitTypes = new LinkedList<Class<?>>(initTypes); |
} else { |
providedInitTypes = new LinkedList<Class<?>>(); |
} |
LinkedList<Object> providedInitValues = null; |
if (initValues != null) { |
providedInitValues = new LinkedList<Object>(initValues); |
} else { |
providedInitValues = new LinkedList<Object>(); |
} |
LinkedList<Class<?>> newInitTypes = new LinkedList<Class<?>>(); |
LinkedList<Object> newInitValues = new LinkedList<Object>(); |
Set<ConstructorDependency> constructorDependencies = this.constructorDependencies != null ? this.constructorDependencies : container.getConstructorDependencies(); |
Set<ConstructorDependency> dependencies = new HashSet<ConstructorDependency>(constructorDependencies); |
Class<?>[] constructorParams = c.getParameterTypes(); |
if (constructorParams == null || constructorParams.length == 0) continue; // skip default constructor for now... |
for(Class<?> constructorParam : constructorParams) { |
// first see if it was provided... |
Class<?> provided = providedInitTypes.isEmpty() ? null : providedInitTypes.get(0); |
if (provided != null && constructorParam.isAssignableFrom(provided)) { |
newInitTypes.add(providedInitTypes.removeFirst()); // we matched this one, so remove... |
newInitValues.add(providedInitValues.removeFirst()); |
continue; |
} else { |
// check auto-wiring... |
Iterator<ConstructorDependency> iter = dependencies.iterator(); |
boolean foundMatch = false; |
while(iter.hasNext()) { |
ConstructorDependency d = iter.next(); |
if (betterIsAssignableFrom(constructorParam, d.getSourceType())) { |
iter.remove(); |
newInitTypes.add(d.getSourceType()); |
newInitValues.add(new DependencyKey(d.getSource())); |
foundMatch = true; |
break; |
} |
} |
if (foundMatch) { |
continue; // next constructor param... |
} |
} |
break; // no param... next constructor... |
} |
// done, check if found... |
if (constructorParams.length == newInitTypes.size() && providedInitTypes.isEmpty()) { |
this.initTypes = newInitTypes; |
this.initValues = newInitValues; |
} |
} |
} |
private static class DependencyKey { |
private String key; |
public DependencyKey(String key) { this.key = key; } |
private String getKey() { return key; } |
} |
@Override |
public Class<?> getType() { |
return klass; |
} |
} |
/tags/menta-container-1.0.2/src/main/java/org/mentacontainer/Container.java |
---|
New file |
0,0 → 1,156 |
package org.mentacontainer; |
/** |
* A IoC container that provides: |
* <ul> |
* <li>Programmatic Configuration</li> |
* <li>Bean Instantiation through constructors</li> |
* <li>Bean Initialization through setters</li> |
* <li>Dependency Injection through constructors</li> |
* <li>Dependency Injection through setters</li> |
* <li>Auto-wiring through constructors and setters (very simple!)</li> |
* <li>Injection through setters so you can populate any external object with objects from the container</li> |
* <li>Instantiation through constructors so you can instantiate any external class with objects from the container</li> |
* <li>Support for SINGLETON and THREAD scopes, plus you can easily create REQUEST and SESSION scopes for web projects</li> |
* <li>Generic Factories so you can easily turn anything into a object factory</li> |
* <li>Interceptors for factories: onCreated, onCleared, useful for object pooling</li> |
* </ul> |
* |
* @author sergio.oliveira.jr@gmail.com |
* |
*/ |
public interface Container { |
/** |
* Get an instance from the container by using the associated factory. |
* |
* The instance will be fully initialized (through constructor and/or setters) and fully wired (all dependencies will be resolved). |
* |
* @param key The key representing the factory to use. The name of the bean in the container. |
* @return The fully initialized and wired bean. |
*/ |
public <T> T get(Object key); |
/** |
* Get the type of the instances returned by the associated factory. |
* |
* @param key The factory |
* @return The type returned by this factory |
*/ |
public Class<?> getType(Object key); |
/** |
* Configure a bean to be returned with the given implementation when {@link #get(String)} is called. |
* An internal factory will be used. |
* |
* @param key The key representing the bean to return. The name of the bean in the container. |
* @param klass The class used to instantiate the bean, in other words, its implementation. |
* @param scope The scope of the factory. |
* @return The factory created as a ConfigurableFactory. (Fluent API) |
* @see Scope |
*/ |
public ConfigurableFactory ioc(Object key, Class<?> klass, Scope scope); |
/** |
* Same as {@link #ioc(String, Class, Scope)} except that it assumes |
* there is no scope (Scope.NONE). |
* |
* @param key |
* @param klass |
* @return The factory created as a ConfigurableFactory. (Fluent API) |
* @see Scope |
*/ |
public ConfigurableFactory ioc(Object key, Class<?extends Object> klass); |
/** |
* Set up a factory for the given key. The scope assumed is NONE. |
* |
* @param key The key representing the bean to return. The name of the bean in the container. |
* @param factory The factory for the IoC. |
* @return The factory passed as a parameter. (Fluent API) |
* @see Factory |
*/ |
public Factory ioc(Object key, Factory factory); |
/** |
* Set up a factory for the given key in the given scope. |
* |
* @param key The key representing the bean to return. The name of the bean in the container. |
* @param factory The factory for the IoC. |
* @param scope The scope used by the factory. |
* @return The factory passed as a parameter (Fluent API). |
* @see Factory |
* @see Scope |
*/ |
public Factory ioc(Object key, Factory factory, Scope scope); |
/** |
* Configure a bean dependency to be auto-wired by the container. |
* It wires by constructor and by setter. By constructor is uses the type of sourceFromContainer. By setter it assumes the property is also named sourceFromContainer. |
* |
* @param sourceFromContainer The bean inside the container that will be wired automatically inside any other bean the depends on it. |
*/ |
public void autowire(Object sourceFromContainer); |
/** |
* Configure a bean dependency to be auto-wired by the container. |
* It wires by constructor and by setter. By constructor is uses the type of sourceFromContainer. By setter it looks for a property with the given name and try to inject. |
* |
* @param sourceFromContainer The bean inside the container that will be wired automatically inside any other bean the depends on it. |
* @param property The name of the property to inject, whey trying auto-wiring by setter. |
*/ |
public void autowire(Object sourceFromContainer, String property); |
/** |
* Take a given bean and populate its properties with other beans coming from this container. |
* You basically checking properties of the given bean and looking for values inside the container. |
* And injecting in the given bean, in other words, populating it. |
* |
* @param bean The bean to be populated with other beans from the container. |
*/ |
public void inject(Object bean); |
/** |
* Construct an instance using beans from the container. A constructor will be chosen that has arguments that can be found |
* inside the container. |
* |
* @param klass The class that should be instantiated. |
* @return An instantiated bean. |
*/ |
public <T> T construct(Class<?> klass); |
/** |
* Check whether the container currently has a value for this key. For example, |
* if it is a singleton AND someone has requested it, the container will have it cached. |
* The method is useful to check for an instance without forcing her creation. |
* |
* @param key The key representing the bean inside the container. |
* @return true if the container has an instance cached in the scope for this key |
*/ |
public boolean check(Object key); |
/** |
* Clear all cached instances for that scope. If you have a thread-pool for example you will |
* want to clear the THREAD scope when your thread is returned to the pool. Because you have a thread |
* pool you will have the SAME thread handling different requests and each request will need its own instances |
* from the container. Therefore, each time you are done with a thread and it is returned to your thread-pool |
* you can call clear to release the instances allocated and cached by the container. A web container and/or framework |
* can use this feature to implement a REQUEST scope which is nothing more than the THREAD scope with clear. If the web |
* container was not using a thread-pool, the THREAD scope would be equal to the REQUEST scope as each request would |
* always be handled by a different thread. |
* |
* It does not make sense to clear a NONE scope (the method returns doing nothing). You can clear a SINGLETON scope if necessary. |
* |
* @param scope The scope to be cleared. |
*/ |
public void clear(Scope scope); |
/** |
* Clear a single key from cache and return the instance that was cached. |
* |
* @param key The key representing the bean inside the container. |
* @return The value that was cached and it is not anymore (was cleared) or null if nothing was cleared |
*/ |
public <T> T clear(Object key); |
} |
/tags/menta-container-1.0.2/src/main/java/org/mentacontainer/Factory.java |
---|
New file |
0,0 → 1,24 |
package org.mentacontainer; |
/** |
* An IoC factory that knows how to create instances. |
* |
* @author sergio.oliveira.jr@gmail.com |
*/ |
public interface Factory { |
/** |
* Returns an instance. Creates one if necessary. |
* |
* @return an instance |
*/ |
public <T> T getInstance(); |
/** |
* Return the type of objects that this factory disposes. |
* |
* @return the type of objects returned by this factory. |
*/ |
public Class<?> getType(); |
} |
/tags/menta-container-1.0.2/src/main/java/org/mentacontainer/ConfigurableFactory.java |
---|
New file |
0,0 → 1,89 |
package org.mentacontainer; |
/** |
* An IoC factory that knows how to create instances and |
* can be configured by accepting values for its constructor |
* and properties (setters). It can also be intercepted right |
* after it creates an instance and right before it releases an instance |
* through the Interceptor interface. |
* |
* It also supports constructor and property values that are dependencies, in other words, they come from the container itself. |
* |
* @author sergio.oliveira.jr@gmail.com |
* @see Interceptor |
*/ |
public interface ConfigurableFactory extends Factory { |
/** |
* Add a constructor parameter to be used when the bean is instantiated. It can be called more than once to |
* use constructors with more than one argument. |
* |
* @param value A parameter value to be used by a constructor. |
* @return The factory itself. (Fluent API) |
*/ |
public ConfigurableFactory addInitValue(Object value); |
/** |
* Add a constructor parameter that is a primitive to be used when the bean is instantiated. It can be called more than once to |
* use constructors with more than one argument.<br/> |
* <br/> |
* Note: This method is seldom necessary and should be used if and only if you have a constructor that mixes Wrappers and primitives, like below:<br/> |
* <br/><pre> |
* public AObject(int x, Integer i, Boolean b, boolean f) { ... } |
* </pre> |
* |
* @param value A parameter value to be used by a constructor. Must be a primitive that will be autoboxed. |
* @return The factory itself. (Fluent API) |
*/ |
public ConfigurableFactory addInitPrimitive(Object value); |
/** |
* Add a constructor parameter that is a dependency, in other words, it gets its value from the container. |
* When the object is created the dependency will be obtained from the container. |
* |
* @param key The key used to get an instance from the container |
* @return The factory itself. (Fluent API) |
*/ |
public ConfigurableFactory addConstructorDependency(Object key); |
/** |
* In case you want to force the use of a zero argument constructor and avoid any ambiguity when choosing the constructor to use. |
* |
* This method is seldom necessary and should be used in the rare cases that the container cannot correctly determine the constructor you |
* want to use due to auto-wiring. |
* |
* @return The factory itself. (Fluent API) |
*/ |
public ConfigurableFactory useZeroArgumentConstructor(); |
/** |
* Add a property to be injected through a setter when the factory instantiates an object. |
* |
* @param name The property name. |
* @param value The property value. |
* @return The factory itself. (Fluent API) |
*/ |
public ConfigurableFactory addPropertyValue(String name, Object value); |
/** |
* Add a setter property that is a dependency, in other words, its value will be obtained from the container. |
* |
* The property name and the dependency name are the same. If they are different you can use the other version of addPropertyDependency that accepts both values. |
* |
* @param property The dependency name which is equal to the property name. |
* @return The factory itself. (Fluent API) |
*/ |
public ConfigurableFactory addPropertyDependency(String property); |
/** |
* Add a setter property that is a dependency, in other words, its value will be obtained from the container. |
* |
* The property name and the dependency name are different. |
* |
* @param property The property that will be injected by the container. |
* @param key The dependency name, in other words, the key used to get a bean from the container. |
* @return The factory itself. (Fluent API) |
*/ |
public ConfigurableFactory addPropertyDependency(String property, Object key); |
} |
/tags/menta-container-1.0.2/src/main/java/org/mentacontainer/Scope.java |
---|
New file |
0,0 → 1,19 |
package org.mentacontainer; |
public enum Scope { |
/** |
* The container calls factory.getInstance on every request for the bean, returning always new instances. |
*/ |
NONE, |
/** |
* The container calls factory.getInstance only once and caches the value, returning always the same instance. |
*/ |
SINGLETON, |
/** |
* The container calls factory.getInstance and caches the value on a thread local, so the same thread will always get the same instance, at least until the scope is cleared by the client. |
*/ |
THREAD |
} |
/tags/menta-container-1.0.2/src/main/java/org/mentacontainer/example/BasicOperations.java |
---|
New file |
0,0 → 1,274 |
package org.mentacontainer.example; |
import java.util.Date; |
import org.mentacontainer.Container; |
import org.mentacontainer.Scope; |
import org.mentacontainer.impl.MentaContainer; |
public class BasicOperations { |
public static void main(String[] args) { |
case1(); |
case2(); |
case3(); |
case4(); |
case5(); |
case6(); |
case7(); |
case8(); |
case9(); |
case10(); |
} |
public static class Connection { |
} |
public static interface UserDAO { |
public String getUsername(int id); |
} |
public static class JdbcUserDAO implements UserDAO { |
private Connection conn; |
public void setConnection(Connection conn) { |
this.conn = conn; |
} |
@Override |
public String getUsername(int id) { |
// connection will be injected by the container... |
if (conn == null) throw new IllegalStateException("conn is null!"); |
// use the connection to get the username... |
return "saoj"; |
} |
} |
public static interface AccountDAO { |
public double getBalance(int id); |
} |
public static class JdbcAccountDAO implements AccountDAO { |
private final Connection conn; |
public JdbcAccountDAO(Connection conn) { |
this.conn = conn; |
} |
@Override |
public double getBalance(int id) { |
assert conn != null; |
// use the connection to get the balance... |
return 1000000D; |
} |
} |
private static void case9() { |
Container c = new MentaContainer(); |
c.ioc("connection", Connection.class); // in real life this will be a connection pool factory... |
c.ioc("accountDAO", JdbcAccountDAO.class); |
c.ioc("userDAO", JdbcUserDAO.class); |
c.autowire("connection"); // all beans that need a connection in the constructor or setter will receive one... |
AccountDAO accountDAO = c.get("accountDAO"); |
UserDAO userDAO = c.get("userDAO"); |
System.out.println(accountDAO.getBalance(25)); // => 1000000 |
System.out.println(userDAO.getUsername(45)); // => "saoj" |
} |
private static void case1() { |
Container c = new MentaContainer(); |
c.ioc("myString1", String.class); |
String myString1 = c.get("myString1"); |
System.out.println(myString1); // ==> "" ==> default constructor new String() was used |
c.ioc("myString2", String.class).addInitValue("saoj"); |
String myString2 = c.get("myString2"); |
System.out.println(myString2); // ==> "saoj" ==> constructor new String("saoj") was used |
c.ioc("myDate1", Date.class).addPropertyValue("hours", 15) // setHours(15) |
.addPropertyValue("minutes", 10) // setMinutes(10) |
.addPropertyValue("seconds", 45); // setSeconds(45) |
Date myDate1 = c.get("myDate1"); |
System.out.println(myDate1); // ==> a date with time 15:10:45 |
} |
private static void case5() { |
Container c = new MentaContainer(); |
c.ioc("connection", Connection.class); // in real life this will be a connection pool factory... |
c.ioc("accountDAO", JdbcAccountDAO.class).addConstructorDependency("connection"); |
AccountDAO accountDAO = c.get("accountDAO"); |
System.out.println(accountDAO.getBalance(25)); // => 1000000 |
} |
private static void case7() { |
Container c = new MentaContainer(); |
c.ioc("connection", Connection.class); // in real life this will be a connection pool factory... |
c.ioc("accountDAO", JdbcAccountDAO.class); |
c.autowire("connection"); // all beans that need a connection in the constructor will get one... |
AccountDAO accountDAO = c.get("accountDAO"); |
System.out.println(accountDAO.getBalance(25)); // => 1000000 |
} |
private static void case6() { |
Container c = new MentaContainer(); |
c.ioc("connection", Connection.class); // in real life this will be a connection pool factory... |
c.ioc("userDAO", JdbcUserDAO.class).addPropertyDependency("connection"); |
UserDAO userDAO = c.get("userDAO"); |
System.out.println(userDAO.getUsername(54)); // => "saoj" |
} |
private static void case8() { |
Container c = new MentaContainer(); |
c.ioc("connection", Connection.class); // in real life this will be a connection pool factory... |
c.ioc("userDAO", JdbcUserDAO.class); |
c.autowire("connection"); |
UserDAO userDAO = c.get("userDAO"); |
System.out.println(userDAO.getUsername(54)); // => "saoj" |
} |
private static void case2() { |
Container c = new MentaContainer(); |
c.ioc("myString", String.class, Scope.SINGLETON).addInitValue("saoj"); |
String s1 = c.get("myString"); |
String s2 = c.get("myString"); |
System.out.println(s1 == s2); // ==> true ==> same instance |
System.out.println(s1.equals(s2)); // ==> true => of course |
} |
private static void case3() { |
Container c = new MentaContainer(); |
c.ioc("userDAO", JdbcUserDAO.class); |
c.ioc("connection", Connection.class); // in real life this would be a connection pool |
// or the hibernate SessionFactory |
// "conn" = the name of the property |
// Connection.class = the type of the property |
// "connection" = the source from where the dependency will come from |
c.autowire("connection"); |
UserDAO userDAO = c.get("userDAO"); |
// the container detects that userDAO has a dependency: name = "conn" and type = "Connection.class" |
// where does it go to get the dependency to insert? |
// In itself: it does a Container.get("connection") => "connection" => the source |
System.out.println(userDAO.getUsername(11)); // ==> "saoj" ==> connection is not null as expected... |
} |
public static class SomeService { |
private UserDAO userDAO; |
public void setUserDAO(UserDAO userDAO) { |
this.userDAO = userDAO; |
} |
public void doSomething() { |
System.out.println(userDAO.getUsername(11)); |
} |
} |
private static void case4() { |
Container c = new MentaContainer(); |
c.ioc("userDAO", JdbcUserDAO.class); |
c.ioc("connection", Connection.class); |
c.autowire("connection"); |
SomeService service = new SomeService(); |
c.inject(service); // populate (inject) all properties of SomeService with |
// beans from the container |
service.doSomething(); // ==> "saoj" |
} |
public static class SomeService2 { |
private final UserDAO userDAO; |
public SomeService2(UserDAO userDAO) { |
this.userDAO = userDAO; |
} |
public void doSomething() { |
System.out.println(userDAO.getUsername(11)); |
} |
} |
private static void case10() { |
Container c = new MentaContainer(); |
c.ioc("userDAO", JdbcUserDAO.class); |
c.ioc("connection", Connection.class); |
c.autowire("connection"); |
SomeService2 service = c.construct(SomeService2.class); |
service.doSomething(); // ==> "saoj" |
} |
} |
/tags/menta-container-1.0.2/src/main/java/org/mentacontainer/util/FindMethod.java |
---|
New file |
0,0 → 1,144 |
package org.mentacontainer.util; |
import java.lang.reflect.Method; |
import java.util.LinkedList; |
import java.util.List; |
/** |
* Find method with polymorphism! |
* Class.getMethod only finds an exact match. |
* |
* @author Jon Skeet (http://groups.google.com/group/comp.lang.java.programmer/browse_thread/thread/921ab91865c8cc2e/9e141d3d62e7cb3f) |
*/ |
public class FindMethod { |
/** |
* Finds the most specific applicable method |
* |
* @param source Class to find method in |
* @param name Name of method to find |
* @param parameterTypes Parameter types to search for |
*/ |
public static Method getMethod(Class<?> source, |
String name, |
Class<?>[] parameterTypes) |
throws NoSuchMethodException { |
return internalFind(source.getMethods(), |
name, |
parameterTypes); |
} |
/** |
* Finds the most specific applicable declared method |
* |
* @param source Class to find method in |
* @param name Name of method to find |
* @param parameterTypes Parameter types to search for |
*/ |
public static Method getDeclaredMethod(Class<?> source, |
String name, |
Class<?>[] parameterTypes) |
throws NoSuchMethodException { |
return internalFind(source.getDeclaredMethods(), |
name, |
parameterTypes); |
} |
/** |
* Internal method to find the most specific applicable method |
*/ |
private static Method internalFind(Method[] toTest, |
String name, |
Class<?>[] parameterTypes) |
throws NoSuchMethodException { |
int l = parameterTypes.length; |
// First find the applicable methods |
List<Method> applicableMethods = new LinkedList<Method>(); |
for (int i = 0; i < toTest.length; i++) { |
// Check the name matches |
if (!toTest[i].getName().equals(name)) |
continue; |
// Check the parameters match |
Class<?>[] params = toTest[i].getParameterTypes(); |
if (params.length != l) |
continue; |
int j; |
for (j = 0; j < l; j++) |
if (!params[j].isAssignableFrom(parameterTypes[j])) |
break; |
// If so, add it to the list |
if (j == l) |
applicableMethods.add(toTest[i]); |
} |
/* |
* If we've got one or zero methods, we can finish |
* the job now. |
*/ |
int size = applicableMethods.size(); |
if (size == 0) |
throw new NoSuchMethodException ("No such method: " + name); |
if (size == 1) |
return applicableMethods.get(0); |
/* |
* Now find the most specific method. Do this in a very primitive |
* way - check whether each method is maximally specific. If more |
* than one method is maximally specific, we'll throw an exception. |
* For a definition of maximally specific, see JLS section 15.11.2.2. |
* |
* I'm sure there are much quicker ways - and I could probably |
* set the second loop to be from i+1 to size. I'd rather not though, |
* until I'm sure... |
*/ |
int maximallySpecific = -1; // Index of maximally specific method |
for (int i = 0; i < size; i++) { |
int j; |
// In terms of the JLS, current is T |
Method current = applicableMethods.get(i); |
Class<?>[] currentParams = current.getParameterTypes(); |
Class<?> currentDeclarer = current.getDeclaringClass(); |
for (j = 0; j < size; j++) { |
if (i == j) |
continue; |
// In terms of the JLS, test is U |
Method test = applicableMethods.get(j); |
Class<?>[] testParams = test.getParameterTypes(); |
Class<?> testDeclarer = test.getDeclaringClass(); |
// Check if T is a subclass of U, breaking if not |
if (!testDeclarer.isAssignableFrom(currentDeclarer)) |
break; |
// Check if each parameter in T is a subclass of the |
// equivalent parameter in U |
int k; |
for (k = 0; k < l; k++) |
if (!testParams[k].isAssignableFrom(currentParams[k])) |
break; |
if (k != l) |
break; |
} |
// Maximally specific! |
if (j == size) { |
if (maximallySpecific != -1) |
throw new NoSuchMethodException |
("Ambiguous method search - more " + |
"than one maximally specific method"); |
maximallySpecific = i; |
} |
} |
if (maximallySpecific == -1) |
throw new NoSuchMethodException ("No maximally specific method."); |
return applicableMethods.get(maximallySpecific); |
} |
} |
/tags/menta-container-1.0.2/src/main/java/org/mentacontainer/util/InjectionUtils.java |
---|
New file |
0,0 → 1,820 |
package org.mentacontainer.util; |
import java.lang.reflect.Field; |
import java.lang.reflect.InvocationTargetException; |
import java.lang.reflect.Method; |
import java.util.ArrayList; |
import java.util.HashMap; |
import java.util.Iterator; |
import java.util.List; |
import java.util.Map; |
public class InjectionUtils { |
/** |
* The character used to separate the prefix from the value name when you are using the getObject method with a prefix. You can change the value of this prefix if you want to |
* by changing this static variable. |
* |
* Ex: getObject(User.class, "user") will get all values that begin with "user.". |
*/ |
public static char PREFIX_SEPARATOR = '.'; |
private static Map<Class<?>, Map<String, Object>> settersMaps = new HashMap<Class<?>, Map<String, Object>>(); |
private static Map<Class<?>, Map<String, Object>> fieldsMaps = new HashMap<Class<?>, Map<String, Object>>(); |
public static void prepareForInjection(Class<?> klass, Map<String, Object> setters, Map<String, Object> fields) { |
StringBuffer sb = new StringBuffer(32); |
Method[] methods = klass.getMethods(); |
for (int i = 0; i < methods.length; i++) { |
Method m = methods[i]; |
String name = m.getName(); |
Class<?>[] types = m.getParameterTypes(); |
if (name.startsWith("set") && name.length() > 3 && types.length == 1) { |
String var = name.substring(3); |
if (var.length() > 1) { |
sb.delete(0, sb.length()); |
sb.append(var.substring(0, 1).toLowerCase()); |
sb.append(var.substring(1)); |
var = sb.toString(); |
} else { |
var = var.toLowerCase(); |
} |
m.setAccessible(true); |
if (setters.containsKey(var)) { |
Object obj = setters.get(var); |
if (obj instanceof List) { |
List<Method> list = (List<Method>) obj; |
list.add(m); |
} else if (obj instanceof Method) { |
List<Method> list = new ArrayList<Method>(); |
list.add((Method) obj); |
list.add(m); |
setters.put(var, list); |
} |
} else { |
setters.put(var, m); |
} |
} |
} |
if (fields == null) return; |
Field[] f = klass.getDeclaredFields(); |
for (int i = 0; i < f.length; i++) { |
Field field = f[i]; |
field.setAccessible(true); |
String name = field.getName(); |
if (setters.containsKey(name)) { |
Object obj = setters.get(name); |
if (obj instanceof Method) { |
Method m = (Method) obj; |
Class<?>[] types = m.getParameterTypes(); |
Class<?> type = field.getType(); |
if (type.isAssignableFrom(types[0])) continue; |
} else if (obj instanceof List) { |
List<Method> list = (List<Method>) obj; |
Iterator<Method> iter = list.iterator(); |
boolean found = false; |
while (iter.hasNext()) { |
Method m = iter.next(); |
Class<?>[] types = m.getParameterTypes(); |
Class<?> type = field.getType(); |
if (type.isAssignableFrom(types[0])) { |
found = true; |
break; |
} |
} |
if (found) continue; |
} |
} |
fields.put(name, field); |
} |
} |
public static boolean checkPrimitives(Class<?> target, Class<?> source) { |
if (target.equals(int.class) && source.equals(Integer.class)) return true; |
if (target.equals(boolean.class) && source.equals(Boolean.class)) return true; |
if (target.equals(byte.class) && source.equals(Byte.class)) return true; |
if (target.equals(short.class) && source.equals(Short.class)) return true; |
if (target.equals(char.class) && source.equals(Character.class)) return true; |
if (target.equals(long.class) && source.equals(Long.class)) return true; |
if (target.equals(float.class) && source.equals(Float.class)) return true; |
if (target.equals(double.class) && source.equals(Double.class)) return true; |
return false; |
} |
public static Object tryToConvert(Object source, Class<?> targetType) { |
return tryToConvert(source, targetType, false); |
} |
public static Object tryToConvert(Object source, Class<?> targetType, boolean tryNumber) { |
String value = null; |
if (source instanceof String) { |
value = (String) source; |
} else if (tryNumber && source instanceof Number) { |
value = source.toString(); |
} else { |
return null; |
} |
Object newValue = null; |
String className = targetType.getName(); |
if (className.equals("int") || className.equals("java.lang.Integer")) { |
int x = -1; |
try { |
x = Integer.parseInt(value); |
} catch (Exception e) { |
return null; |
} |
newValue = new Integer(x); |
} else if (className.equals("short") || className.equals("java.lang.Short")) { |
short x = -1; |
try { |
x = Short.parseShort(value); |
} catch (Exception e) { |
return null; |
} |
newValue = new Short(x); |
} else if (className.equals("char") || className.equals("java.lang.Character")) { |
if (value.length() != 1) { |
return null; |
} |
newValue = new Character(value.charAt(0)); |
} else if (className.equals("long") || className.equals("java.lang.Long")) { |
long x = -1; |
try { |
x = Long.parseLong(value); |
} catch (Exception e) { |
return null; |
} |
newValue = new Long(x); |
} else if (className.equals("float") || className.equals("java.lang.Float")) { |
float x = -1; |
try { |
x = Float.parseFloat(value); |
} catch (Exception e) { |
return null; |
} |
newValue = new Float(x); |
} else if (className.equals("double") || className.equals("java.lang.Double")) { |
double x = -1; |
try { |
x = Double.parseDouble(value); |
} catch (Exception e) { |
return null; |
} |
newValue = new Double(x); |
} else if (className.equals("boolean") || className.equals("java.lang.Boolean")) { |
try { |
int x = Integer.parseInt(value); |
if (x == 1) { |
newValue = Boolean.TRUE; |
} else if (x == 0) { |
newValue = Boolean.FALSE; |
} else { |
return null; |
} |
} catch (Exception e) { |
if (value.equalsIgnoreCase("true") || value.equals("on")) { |
newValue = Boolean.TRUE; |
} else if (value.equalsIgnoreCase("false")) { |
newValue = Boolean.FALSE; |
} else { |
return null; |
} |
} |
} else if (targetType.isEnum()) { |
try { |
Class k = (Class) targetType; // not sure how to avoid this raw type! |
newValue = Enum.valueOf(k, value); |
} catch (Exception e) { |
return null; |
} |
} |
return newValue; |
} |
public static Object shouldConvertToNull(Object value, Class<?> targetType) { |
if (targetType.equals(String.class)) { |
return value; |
} else if (targetType.isPrimitive()) { |
return value; |
} |
return null; |
} |
public static Class<?> getPrimitiveFrom(Object w) { |
if (w instanceof Boolean) { |
return Boolean.TYPE; |
} else if (w instanceof Byte) { |
return Byte.TYPE; |
} else if (w instanceof Short) { |
return Short.TYPE; |
} else if (w instanceof Character) { |
return Character.TYPE; |
} else if (w instanceof Integer) { |
return Integer.TYPE; |
} else if (w instanceof Long) { |
return Long.TYPE; |
} else if (w instanceof Float) { |
return Float.TYPE; |
} else if (w instanceof Double) { |
return Double.TYPE; |
} |
return null; |
} |
public static Class<?> getPrimitiveFrom(Class<?> klass) { |
String s = klass.getName(); |
if (s.equals("java.lang.Boolean")) { |
return Boolean.TYPE; |
} else if (s.equals("java.lang.Byte")) { |
return Byte.TYPE; |
} else if (s.equals("java.lang.Short")) { |
return Short.TYPE; |
} else if (s.equals("java.lang.Character")) { |
return Character.TYPE; |
} else if (s.equals("java.lang.Integer")) { |
return Integer.TYPE; |
} else if (s.equals("java.lang.Long")) { |
return Long.TYPE; |
} else if (s.equals("java.lang.Float")) { |
return Float.TYPE; |
} else if (s.equals("java.lang.Double")) { |
return Double.TYPE; |
} |
return null; |
} |
public static Field getField(Object target, String name) { |
return getField(target.getClass(), name); |
} |
public static Field getField(Class<?> target, String name) { |
Field fields[] = target.getDeclaredFields(); |
for (int i = 0; i < fields.length; i++) { |
if (name.equals(fields[i].getName())) { |
return fields[i]; |
} |
} |
return null; |
} |
public static String getKeyName(Object obj) { |
if (obj instanceof Class<?>) { |
Class<?> k = (Class<?>) obj; |
String s = k.getSimpleName(); |
StringBuilder sb = new StringBuilder(s.length()); |
sb.append(s.substring(0, 1).toLowerCase()); |
if (s.length() > 1) { |
sb.append(s.substring(1)); |
} |
return sb.toString(); |
} |
return obj.toString(); |
} |
public static Method findMethodToGet(Class<?> target, String name) { |
StringBuffer sb = new StringBuffer(128); |
sb.append("get").append(name.substring(0, 1).toUpperCase()); |
if (name.length() > 1) sb.append(name.substring(1)); |
try { |
return target.getMethod(sb.toString(), (Class[]) null); |
} catch (Exception e) { |
} |
sb.setLength(0); |
sb.append("is").append(name.substring(0, 1).toUpperCase()); |
if (name.length() > 1) { |
sb.append(name.substring(1)); |
} |
try { |
return target.getMethod(sb.toString(), (Class[]) null); |
} catch (Exception e) { |
} |
return null; |
} |
public static Method findMethodToInject(Class<?> target, String name, Class<?> source) { |
StringBuffer sb = new StringBuffer(128); |
sb.append("set").append(name.substring(0, 1).toUpperCase()); |
if (name.length() > 1) sb.append(name.substring(1)); |
String methodName = sb.toString(); |
Method m = null; |
try { |
m = FindMethod.getMethod(target, methodName, new Class[] { source }); |
} catch (Exception e) { |
} |
if (m == null) { |
Class<?> primitive = getPrimitiveFrom(source); |
if (primitive != null) { |
try { |
m = target.getMethod(methodName, new Class[] { primitive }); |
} catch (Exception e) { |
} |
} |
} |
if (m != null) { |
m.setAccessible(true); |
} |
return m; |
} |
public static Field findFieldToInject(Class<?> target, String name, Class<?> source) { |
Field f = getField(target, name); |
if (f != null) { |
Class<?> type = f.getType(); |
if (type.isAssignableFrom(source) || checkPrimitives(type, source)) { |
f.setAccessible(true); |
return f; |
} |
} |
return null; |
} |
private static final boolean isBlank(Object value) { |
if (value != null && value instanceof String) { |
String s = ((String) value).trim(); |
if (s.length() == 0) return true; |
} |
return false; |
} |
public static boolean inject(Method m, Object target, Object value, boolean tryToConvert, boolean tryingToConvertBoolean) throws Exception { |
Class<?> type = m.getParameterTypes()[0]; |
if (tryingToConvertBoolean) { |
if (value == null && (type.equals(Boolean.class) || type.equals(boolean.class))) { |
value = Boolean.FALSE; |
} else { |
// if trying to convert boolean, convert or don't do anything... |
return false; |
} |
} |
if (value == null |
|| (type.isAssignableFrom(value.getClass()) || checkPrimitives(type, value.getClass()) || (tryToConvert && ((isBlank(value) && (value = shouldConvertToNull(value, |
type)) == null) || (value = tryToConvert(value, type)) != null)))) { |
try { |
m.invoke(target, new Object[] { value }); |
return true; |
} catch (Exception e) { |
System.err.println("Error injecting by method: " + value + " in " + target + " thru " + m); |
e.printStackTrace(); |
throw e; |
} |
} |
return false; |
} |
public static boolean hasDefaultConstructor(Class<?> klass) { |
try { |
return klass.getConstructor((Class[]) null) != null; |
} catch (Exception e) { |
return false; |
} |
} |
/** |
* Extract the value of a property of a bean! |
* |
* @param bean |
* the target bean |
* @param nameProperty |
* the property name |
* @return they value as String. The method toString is always called to every property! |
* @throws Exception |
*/ |
public static String getProperty(Object bean, String nameProperty) throws Exception { |
if (nameProperty == null || nameProperty.equals("")) return null; |
String methodName = getter(nameProperty); |
Class<?> clazz = bean.getClass(); |
Method[] methods = clazz.getMethods(); |
for (Method method : methods) { |
if (method.getName().equals(methodName) && method.getParameterTypes().length == 0) { |
Object value = method.invoke(bean, (Object[]) null); |
if (value == null) return null; |
return value.toString(); |
} |
} |
Field[] fields = clazz.getDeclaredFields(); |
for (Field field : fields) { |
field.setAccessible(true); |
if (field.getName().equals(nameProperty)) { |
Object value = field.get(bean); |
if (value == null) return null; |
return value.toString(); |
} |
} |
return null; |
} |
private static String getter(String name) { |
StringBuilder sb = new StringBuilder(name.length() + 3); |
sb.append("get").append(name.substring(0, 1).toUpperCase()); |
if (name.length() > 1) sb.append(name.substring(1)); |
return sb.toString(); |
} |
public static void beanToMap(Object bean, Map<String, String> map) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { |
if (bean != null) { |
for (Method method : bean.getClass().getMethods()) { |
String name = method.getName(); |
if (name.length() > 3 && name.startsWith("get") && !name.equals("getClass") && method.getParameterTypes().length == 0) { |
method.setAccessible(true); |
Object value = method.invoke(bean, new Object[0]); |
map.put(name, value.toString()); |
} |
} |
} |
} |
public static interface Provider { |
public Object get(String key); |
public boolean hasValue(String key); |
} |
public static void getObject(Object target, Provider provider, boolean tryField, String prefix, boolean tryToConvert, boolean convertBoolean, boolean allowRecursion) |
throws Exception { |
Class<?> targetClass = target.getClass(); |
Map<String, Object> setters, fields; |
// see if we have these in cache... |
synchronized (settersMaps) { |
setters = settersMaps.get(targetClass); |
fields = fieldsMaps.get(targetClass); |
} |
// if not in cache, prepare maps for injection... |
if (setters == null) { |
setters = new HashMap<String, Object>(); |
fields = null; |
if (tryField) { |
fields = new HashMap<String, Object>(); |
} |
prepareForInjection(targetClass, setters, fields); |
synchronized (settersMaps) { |
settersMaps.put(targetClass, setters); |
fieldsMaps.put(targetClass, fields); |
} |
} |
Iterator<String> iter = setters.keySet().iterator(); |
while (iter.hasNext()) { |
String var = iter.next(); |
boolean hasValue = provider.hasValue(var); |
Object value = provider.get(var); |
boolean tryingToConvertBoolean = false; |
if (value == null && !hasValue) { |
if (!convertBoolean) { |
continue; |
} else { |
tryingToConvertBoolean = true; |
} |
} |
// if (value == null) continue; |
Object obj = setters.get(var); |
// we may have a list of overloaded methods... |
List<Method> list = null; |
Method m = null; |
if (obj instanceof List) { |
list = (List<Method>) obj; |
} else { |
m = (Method) setters.get(var); |
} |
if (m != null) { |
if (!inject(m, target, value, tryToConvert, tryingToConvertBoolean) && allowRecursion) { |
// i did not inject... how about a VO object for this |
// setter? |
Class<?> type = m.getParameterTypes()[0]; |
if (!type.getName().startsWith("java.") && !type.isPrimitive() && hasDefaultConstructor(type)) { |
Object param = type.newInstance(); |
InjectionUtils.getObject(param, provider, true, prefix, true, true, false); // no |
// recursion... |
inject(m, target, param, false, false); |
} |
} |
} else { |
Iterator<Method> it = list.iterator(); |
boolean injected = false; |
while (it.hasNext()) { |
m = it.next(); |
if (inject(m, target, value, tryToConvert, tryingToConvertBoolean)) { |
injected = true; |
break; |
} |
} |
if (!injected && allowRecursion) { |
// i could not inject anything... how about a VO object for |
// this setter... |
it = list.iterator(); |
while (it.hasNext()) { |
m = (Method) it.next(); |
Class<?> type = m.getParameterTypes()[0]; |
if (!type.getName().startsWith("java.") && !type.isPrimitive() && hasDefaultConstructor(type)) { |
Object param = type.newInstance(); |
InjectionUtils.getObject(param, provider, true, prefix, true, true, false); // no |
// recursion... |
if (inject(m, target, param, false, false)) { |
break; // done... |
} |
} |
} |
} |
} |
} |
if (fields != null) { |
iter = fields.keySet().iterator(); |
while (iter.hasNext()) { |
String var = iter.next(); |
boolean hasValue = provider.hasValue(var); |
Object value = provider.get(var); |
Field f = (Field) fields.get(var); |
Class<?> type = f.getType(); |
// If there is no value in the action input, assume false for |
// booleans... |
// (checkboxes and radio buttons are not send when not |
// marked...) |
if (convertBoolean && value == null && !hasValue) { |
if (type.equals(Boolean.class) || type.equals(boolean.class)) { |
value = Boolean.FALSE; |
} |
} |
if (value == null && !hasValue) continue; |
// if (value == null) continue; |
if (value == null |
|| (type.isAssignableFrom(value.getClass()) || checkPrimitives(type, value.getClass()) || (tryToConvert && ((isBlank(value) && (value = shouldConvertToNull( |
value, type)) == null) || (value = tryToConvert(value, type)) != null)))) { |
try { |
f.set(target, value); |
} catch (Exception e) { |
System.err.println("Error injecting by field: " + value + " in " + target); |
e.printStackTrace(); |
throw e; |
} |
} |
} |
} |
} |
} |
/tags/menta-container-1.0.2/src/main/java/org/mentacontainer/util/FindConstructor.java |
---|
New file |
0,0 → 1,135 |
package org.mentacontainer.util; |
import java.lang.reflect.Constructor; |
import java.util.LinkedList; |
import java.util.List; |
/** |
* Find constructor with polymorphism! |
* Class.getConstructor only finds an exact match. |
* |
* @author Jon Skeet (http://groups.google.com/group/comp.lang.java.programmer/browse_thread/thread/921ab91865c8cc2e/9e141d3d62e7cb3f) |
*/ |
public class FindConstructor { |
/** |
* Finds the most specific applicable constructor |
* |
* @param source Class to find a constructor for |
* @param parameterTypes Parameter types to search for |
*/ |
public static Constructor<?> getConstructor(Class<?> source, |
Class<?>[] parameterTypes) |
throws NoSuchMethodException { |
return internalFind(source.getConstructors(), |
parameterTypes); |
} |
/** |
* Finds the most specific applicable declared constructor |
* |
* @param source Class to find method in |
* @param parameterTypes Parameter types to search for |
*/ |
public static Constructor<?> getDeclaredConstructor(Class<?> source, |
Class<?>[] parameterTypes) |
throws NoSuchMethodException { |
return internalFind(source.getDeclaredConstructors(), |
parameterTypes); |
} |
/** |
* Internal method to find the most specific applicable method |
*/ |
private static Constructor<?> internalFind(Constructor<?>[] toTest, |
Class<?>[] parameterTypes) |
throws NoSuchMethodException { |
int l = parameterTypes.length; |
// First find the applicable methods |
List<Constructor<?>> applicableMethods = new LinkedList<Constructor<?>>(); |
for (int i = 0; i < toTest.length; i++) { |
// Check the parameters match |
Class<?>[] params = toTest[i].getParameterTypes(); |
if (params.length != l) |
continue; |
int j; |
for (j = 0; j < l; j++) |
if (!params[j].isAssignableFrom(parameterTypes[j])) |
break; |
// If so, add it to the list |
if (j == l) |
applicableMethods.add(toTest[i]); |
} |
/* |
* If we've got one or zero methods, we can finish |
* the job now. |
*/ |
int size = applicableMethods.size(); |
if (size == 0) |
throw new NoSuchMethodException ("No such constructor!"); |
if (size == 1) |
return applicableMethods.get(0); |
/* |
* Now find the most specific method. Do this in a very primitive |
* way - check whether each method is maximally specific. If more |
* than one method is maximally specific, we'll throw an exception. |
* For a definition of maximally specific, see JLS section 15.11.2.2. |
* |
* I'm sure there are much quicker ways - and I could probably |
* set the second loop to be from i+1 to size. I'd rather not though, |
* until I'm sure... |
*/ |
int maximallySpecific = -1; // Index of maximally specific method |
for (int i = 0; i < size; i++) { |
int j; |
// In terms of the JLS, current is T |
Constructor<?> current = applicableMethods.get(i); |
Class<?>[] currentParams = current.getParameterTypes(); |
Class<?> currentDeclarer = current.getDeclaringClass(); |
for (j = 0; j < size; j++) { |
if (i == j) |
continue; |
// In terms of the JLS, test is U |
Constructor<?> test = applicableMethods.get(j); |
Class<?>[] testParams = test.getParameterTypes(); |
Class<?> testDeclarer = test.getDeclaringClass(); |
// Check if T is a subclass of U, breaking if not |
if (!testDeclarer.isAssignableFrom(currentDeclarer)) |
break; |
// Check if each parameter in T is a subclass of the |
// equivalent parameter in U |
int k; |
for (k = 0; k < l; k++) |
if (!testParams[k].isAssignableFrom(currentParams[k])) |
break; |
if (k != l) |
break; |
} |
// Maximally specific! |
if (j == size) { |
if (maximallySpecific != -1) |
throw new NoSuchMethodException |
("Ambiguous method search - more " + |
"than one maximally specific method"); |
maximallySpecific = i; |
} |
} |
if (maximallySpecific == -1) |
throw new NoSuchMethodException ("No maximally specific method."); |
return applicableMethods.get(maximallySpecific); |
} |
} |
/tags/menta-container-1.0.2/src/main/java/org/mentacontainer/Interceptor.java |
---|
New file |
0,0 → 1,36 |
package org.mentacontainer; |
/** |
* Some factories can also implement this interface to perform some cleanup |
* when the instance is created or cleared. For example, a connection pool will want |
* to know when the connection instance is cleared so it can return it to |
* the pool. |
* |
* It makes more sense to use this interface for factories that will be placed |
* in the THREAD scope, but you can also use it with other scopes as well. |
* |
* This is particular useful for the THREAD scope for dealing with thread pools, so |
* when the thread is returned to the thread pool you will want to clear the THREAD |
* scope. That's pretty much how web containers work: one thread per request coming from |
* a thread pool. |
* |
* @author sergio.oliveira.jr@gmail.com |
* |
* @param <E> |
*/ |
public interface Interceptor<E> { |
/** |
* This method will be called right after the getInstance() method returns a new instance from the factory. |
* |
* @param createdObject The object that was just returned by the factory. |
*/ |
public void onCreated(E createdObject); |
/** |
* This method will be called right after the object is cleared from the scope. |
* |
* @param clearedObject The object that was cleared. |
*/ |
public void onCleared(E clearedObject); |
} |
/tags/menta-container-1.0.2/pom.xml |
---|
New file |
0,0 → 1,420 |
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
<modelVersion>4.0.0</modelVersion> |
<parent> |
<artifactId>oss-parent</artifactId> |
<groupId>org.sonatype.oss</groupId> |
<version>3</version> |
</parent> |
<groupId>me.soliveirajr</groupId> |
<artifactId>menta-container</artifactId> |
<version>1.0.2</version> |
<name>MentaContainer</name> |
<description>A IOC container as simple and pragmatic as it can get with programmatic configuration through a Fluent API.</description> |
<url>http://maven.apache.org</url> |
<licenses> |
<license> |
<name>GNU Lesser General Public License (LGPL), Version 2.1</name> |
<url>http://www.fsf.org/licensing/licenses/lgpl.txt</url> |
<distribution>repo</distribution> |
</license> |
</licenses> |
<scm> |
<connection>scm:svn:svn://soliveirajr.com/mentacontainer/tags/menta-container-1.0.2</connection> |
<developerConnection>scm:svn:svn://soliveirajr.com/mentacontainer/tags/menta-container-1.0.2</developerConnection> |
<url>svn://soliveirajr.com/mentacontainer/tags/menta-container-1.0.2</url> |
</scm> |
<distributionManagement> |
<repository> |
<id>sonatype-nexus-staging</id> |
<name>Nexus Release Repository</name> |
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url> |
</repository> |
<snapshotRepository> |
<id>sonatype-nexus-snapshots</id> |
<name>Sonatype Nexus Snapshots</name> |
<url>https://oss.sonatype.org/content/repositories/snapshots</url> |
</snapshotRepository> |
</distributionManagement> |
<properties> |
<build.final.name>mentacontainer</build.final.name> |
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
<svn.tags>svn://soliveirajr.com/mentacontainer/tags</svn.tags> |
<svn.url>svn://soliveirajr.com/mentacontainer/trunk</svn.url> |
</properties> |
<dependencies> |
<dependency> |
<groupId>junit</groupId> |
<artifactId>junit</artifactId> |
<version>4.8.1</version> |
<scope>test</scope> |
</dependency> |
</dependencies> |
<repositories> |
<repository> |
<releases> |
<enabled>false</enabled> |
</releases> |
<snapshots> |
<enabled>true</enabled> |
</snapshots> |
<id>sonatype-nexus-snapshots</id> |
<name>Sonatype Nexus Snapshots</name> |
<url>http://oss.sonatype.org/content/repositories/snapshots</url> |
</repository> |
<repository> |
<snapshots> |
<enabled>false</enabled> |
</snapshots> |
<id>central</id> |
<name>Maven Repository Switchboard</name> |
<url>http://repo1.maven.org/maven2</url> |
</repository> |
</repositories> |
<pluginRepositories> |
<pluginRepository> |
<releases> |
<updatePolicy>never</updatePolicy> |
</releases> |
<snapshots> |
<enabled>false</enabled> |
</snapshots> |
<id>central</id> |
<name>Maven Plugin Repository</name> |
<url>http://repo1.maven.org/maven2</url> |
</pluginRepository> |
</pluginRepositories> |
<build> |
<finalName>mentacontainer</finalName> |
<pluginManagement> |
<plugins> |
<plugin> |
<artifactId>maven-antrun-plugin</artifactId> |
<version>1.3</version> |
</plugin> |
<plugin> |
<artifactId>maven-assembly-plugin</artifactId> |
<version>2.2-beta-5</version> |
</plugin> |
<plugin> |
<artifactId>maven-dependency-plugin</artifactId> |
<version>2.1</version> |
</plugin> |
<plugin> |
<artifactId>maven-release-plugin</artifactId> |
<version>2.0</version> |
<configuration> |
<mavenExecutorId>forked-path</mavenExecutorId> |
</configuration> |
</plugin> |
</plugins> |
</pluginManagement> |
<plugins> |
<plugin> |
<groupId>org.apache.maven.plugins</groupId> |
<artifactId>maven-shade-plugin</artifactId> |
<version>1.7</version> |
<executions> |
<execution> |
<phase>package</phase> |
<goals> |
<goal>shade</goal> |
</goals> |
<configuration> |
<finalName>mentacontainer-all</finalName> |
<shadedArtifactAttached>true</shadedArtifactAttached> |
<shadedClassifierName>all</shadedClassifierName> |
</configuration> |
</execution> |
</executions> |
</plugin> |
<plugin> |
<artifactId>maven-source-plugin</artifactId> |
<version>2.1.2</version> |
<executions> |
<execution> |
<id>attach-sources</id> |
<goals> |
<goal>jar</goal> |
</goals> |
</execution> |
</executions> |
</plugin> |
<plugin> |
<artifactId>maven-compiler-plugin</artifactId> |
<version>2.0.2</version> |
<executions> |
<execution> |
<id>default-testCompile</id> |
<phase>test-compile</phase> |
<goals> |
<goal>testCompile</goal> |
</goals> |
<configuration> |
<source>1.6</source> |
<target>1.6</target> |
</configuration> |
</execution> |
<execution> |
<id>default-compile</id> |
<phase>compile</phase> |
<goals> |
<goal>compile</goal> |
</goals> |
<configuration> |
<source>1.6</source> |
<target>1.6</target> |
</configuration> |
</execution> |
</executions> |
<configuration> |
<source>1.6</source> |
<target>1.6</target> |
</configuration> |
</plugin> |
<plugin> |
<artifactId>maven-javadoc-plugin</artifactId> |
<version>2.8</version> |
<executions> |
<execution> |
<id>attach-javadocs</id> |
<goals> |
<goal>jar</goal> |
</goals> |
</execution> |
</executions> |
</plugin> |
<plugin> |
<artifactId>maven-release-plugin</artifactId> |
<version>2.0</version> |
<configuration> |
<tagBase>svn://soliveirajr.com/mentacontainer/tags</tagBase> |
<connectionUrl>scm:svn:svn://soliveirajr.com/mentacontainer/trunk</connectionUrl> |
<mavenExecutorId>forked-path</mavenExecutorId> |
</configuration> |
</plugin> |
<plugin> |
<artifactId>maven-clean-plugin</artifactId> |
<version>2.4.1</version> |
<executions> |
<execution> |
<id>default-clean</id> |
<phase>clean</phase> |
<goals> |
<goal>clean</goal> |
</goals> |
</execution> |
</executions> |
</plugin> |
<plugin> |
<artifactId>maven-install-plugin</artifactId> |
<version>2.3.1</version> |
<executions> |
<execution> |
<id>default-install</id> |
<phase>install</phase> |
<goals> |
<goal>install</goal> |
</goals> |
</execution> |
</executions> |
</plugin> |
<plugin> |
<artifactId>maven-resources-plugin</artifactId> |
<version>2.4.3</version> |
<executions> |
<execution> |
<id>default-resources</id> |
<phase>process-resources</phase> |
<goals> |
<goal>resources</goal> |
</goals> |
</execution> |
<execution> |
<id>default-testResources</id> |
<phase>process-test-resources</phase> |
<goals> |
<goal>testResources</goal> |
</goals> |
</execution> |
</executions> |
</plugin> |
<plugin> |
<artifactId>maven-surefire-plugin</artifactId> |
<version>2.7.2</version> |
<executions> |
<execution> |
<id>default-test</id> |
<phase>test</phase> |
<goals> |
<goal>test</goal> |
</goals> |
</execution> |
</executions> |
</plugin> |
<plugin> |
<artifactId>maven-jar-plugin</artifactId> |
<version>2.3.1</version> |
<executions> |
<execution> |
<id>default-jar</id> |
<phase>package</phase> |
<goals> |
<goal>jar</goal> |
</goals> |
</execution> |
</executions> |
</plugin> |
<plugin> |
<artifactId>maven-deploy-plugin</artifactId> |
<version>2.5</version> |
<executions> |
<execution> |
<id>default-deploy</id> |
<phase>deploy</phase> |
<goals> |
<goal>deploy</goal> |
</goals> |
</execution> |
</executions> |
</plugin> |
<plugin> |
<artifactId>maven-site-plugin</artifactId> |
<version>2.0.1</version> |
<executions> |
<execution> |
<id>default-site</id> |
<phase>site</phase> |
<goals> |
<goal>site</goal> |
</goals> |
<configuration> |
<reportPlugins> |
<reportPlugin> |
<groupId>org.apache.maven.plugins</groupId> |
<artifactId>maven-surefire-plugin</artifactId> |
<version>2.5</version> |
</reportPlugin> |
<reportPlugin> |
<groupId>org.apache.maven.plugins</groupId> |
<artifactId>maven-surefire-report-plugin</artifactId> |
<version>2.5</version> |
</reportPlugin> |
<reportPlugin> |
<groupId>org.apache.maven.plugins</groupId> |
<artifactId>maven-javadoc-plugin</artifactId> |
<version>2.8</version> |
<configuration>...</configuration> |
</reportPlugin> |
<reportPlugin> |
<groupId>org.apache.maven.plugins</groupId> |
<artifactId>maven-project-info-reports-plugin</artifactId> |
</reportPlugin> |
</reportPlugins> |
</configuration> |
</execution> |
<execution> |
<id>default-deploy</id> |
<phase>site-deploy</phase> |
<goals> |
<goal>deploy</goal> |
</goals> |
<configuration> |
<reportPlugins> |
<reportPlugin> |
<groupId>org.apache.maven.plugins</groupId> |
<artifactId>maven-surefire-plugin</artifactId> |
<version>2.5</version> |
</reportPlugin> |
<reportPlugin> |
<groupId>org.apache.maven.plugins</groupId> |
<artifactId>maven-surefire-report-plugin</artifactId> |
<version>2.5</version> |
</reportPlugin> |
<reportPlugin> |
<groupId>org.apache.maven.plugins</groupId> |
<artifactId>maven-javadoc-plugin</artifactId> |
<version>2.8</version> |
<configuration>...</configuration> |
</reportPlugin> |
<reportPlugin> |
<groupId>org.apache.maven.plugins</groupId> |
<artifactId>maven-project-info-reports-plugin</artifactId> |
</reportPlugin> |
</reportPlugins> |
</configuration> |
</execution> |
</executions> |
<configuration> |
<reportPlugins> |
<reportPlugin> |
<groupId>org.apache.maven.plugins</groupId> |
<artifactId>maven-surefire-plugin</artifactId> |
<version>2.5</version> |
</reportPlugin> |
<reportPlugin> |
<groupId>org.apache.maven.plugins</groupId> |
<artifactId>maven-surefire-report-plugin</artifactId> |
<version>2.5</version> |
</reportPlugin> |
<reportPlugin> |
<groupId>org.apache.maven.plugins</groupId> |
<artifactId>maven-javadoc-plugin</artifactId> |
<version>2.8</version> |
<configuration>...</configuration> |
</reportPlugin> |
<reportPlugin> |
<groupId>org.apache.maven.plugins</groupId> |
<artifactId>maven-project-info-reports-plugin</artifactId> |
</reportPlugin> |
</reportPlugins> |
</configuration> |
</plugin> |
</plugins> |
</build> |
<reporting> |
<plugins> |
<plugin> |
<artifactId>maven-surefire-plugin</artifactId> |
<version>2.5</version> |
</plugin> |
<plugin> |
<artifactId>maven-surefire-report-plugin</artifactId> |
<version>2.5</version> |
</plugin> |
<plugin> |
<artifactId>maven-javadoc-plugin</artifactId> |
<version>2.8</version> |
</plugin> |
</plugins> |
</reporting> |
<profiles> |
<profile> |
<id>release-sign-artifacts</id> |
<activation> |
<property> |
<name>performRelease</name> |
<value>true</value> |
</property> |
</activation> |
<build> |
<plugins> |
<plugin> |
<artifactId>maven-gpg-plugin</artifactId> |
<executions> |
<execution> |
<id>sign-artifacts</id> |
<phase>verify</phase> |
<goals> |
<goal>sign</goal> |
</goals> |
</execution> |
</executions> |
</plugin> |
</plugins> |
</build> |
</profile> |
</profiles> |
</project> |
/tags/menta-container-1.0.2/readme.txt |
---|
New file |
0,0 → 1,2 |
MentaContainer 2010-2012 |
/menta-container-1.0.2 |
---|
Property changes: |
Added: svn:ignore |
+ target |
.classpath |
.project |
.settings |
site |