--- /dev/null
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wamblee.ioc;
+
+/**
+ * Bean factory used to obtain objects in a transparent way.
+ *
+ * @author Erik Brakkee
+ */
+public interface BeanFactory {
+ /**
+ * Finds a bean based on id.
+ *
+ * @param aId
+ * Id of the bean.
+ * @return Object (always non-null).
+ * @throws BeanFactoryException
+ * In case the object could not be found.
+ */
+ Object find(String aId);
+
+ <T> T find(Class<T> aClass);
+
+ <T> T find(String aId, Class<T> aClass);
+}
--- /dev/null
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wamblee.ioc;
+
+/**
+ * Exception thrown by the BeanFactory if an object could not be found.
+ *
+ * @author Erik Brakkee
+ */
+public class BeanFactoryException extends RuntimeException {
+ static final long serialVersionUID = -1215992188624874902L;
+
+ /**
+ * Constructs the exception.
+ *
+ * @param aMsg
+ * Message.
+ */
+ public BeanFactoryException(String aMsg) {
+ super(aMsg);
+ }
+
+ /**
+ * Constructs the exception.
+ *
+ * @param aMsg
+ * Message.
+ * @param aThrowable
+ * Cause of the exception.
+ */
+ public BeanFactoryException(String aMsg, Throwable aThrowable) {
+ super(aMsg, aThrowable);
+ }
+}
--- /dev/null
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wamblee.ioc;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.wamblee.io.ClassPathResource;
+import org.wamblee.io.InputResource;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import java.util.Properties;
+
+/**
+ * The standard means to obtain the bean factory. This works by reading a
+ * property {@value #BEAN_FACTORY_CLASS} from a property file named
+ * {@value #BEAN_KERNEL_PROP_FILE} from the class path. This property identifies
+ * the bean factory implementation to use. The configured bean factory must have
+ * a no-arg constructor.
+ */
+public final class BeanKernel {
+ private static final Log LOG = LogFactory.getLog(BeanKernel.class);
+
+ /**
+ * Bean factory kernel properties file.
+ */
+ private static final String BEAN_KERNEL_PROP_FILE = "org.wamblee.beanfactory.properties";
+
+ /**
+ * Name of the property to define the name of the bean factory class to use.
+ * THis class must have a public default constructor.
+ */
+ private static final String BEAN_FACTORY_CLASS = "org.wamblee.beanfactory.class";
+
+ /**
+ * Cached bean factory.
+ */
+ private static BeanFactory BEAN_FACTORY;
+
+ /**
+ * Disabled constructor.
+ *
+ */
+ private BeanKernel() {
+ // Empty
+ }
+
+ /**
+ * Overrides the default mechanism for looking up the bean factory by
+ * specifying it yourself.
+ *
+ * @param aOverride
+ * Override bean factory.
+ */
+ public static void overrideBeanFactory(BeanFactory aOverride) {
+ BEAN_FACTORY = aOverride;
+ }
+
+ /**
+ * Gets the bean factory.
+ *
+ * @return Bean factory.
+ */
+ public static BeanFactory getBeanFactory() {
+ synchronized (BeanFactory.class) {
+ if (BEAN_FACTORY == null) {
+ BEAN_FACTORY = lookupBeanFactory(BEAN_KERNEL_PROP_FILE);
+ }
+ }
+
+ return BEAN_FACTORY;
+ }
+
+ /**
+ * Lookup the bean factory based on the properties file.
+ *
+ *
+ * @return Bean factory.
+ *
+ */
+ static BeanFactory lookupBeanFactory(String aPropertyFilename) {
+ InputResource resource = new ClassPathResource(aPropertyFilename);
+ InputStream is;
+
+ try {
+ is = resource.getInputStream();
+ } catch (IOException e) {
+ throw new BeanFactoryException("Cannot open resource " + resource,
+ e);
+ }
+
+ try {
+ Properties props = new Properties();
+ props.load(is);
+
+ String className = props.getProperty(BEAN_FACTORY_CLASS);
+ Class beanFactory = Class.forName(className);
+
+ return (BeanFactory) beanFactory.newInstance();
+ } catch (Exception e) {
+ throw new BeanFactoryException("Cannot read from resource " +
+ resource, e);
+ } finally {
+ try {
+ is.close();
+ } catch (IOException e) {
+ // last resort cannot do much now.
+ LOG.error("Error closing resource " + resource);
+ }
+ }
+ }
+}