001: // Copyright 2004, 2005 The Apache Software Foundation
002: //
003: // Licensed under the Apache License, Version 2.0 (the "License");
004: // you may not use this file except in compliance with the License.
005: // You may obtain a copy of the License at
006: //
007: // http://www.apache.org/licenses/LICENSE-2.0
008: //
009: // Unless required by applicable law or agreed to in writing, software
010: // distributed under the License is distributed on an "AS IS" BASIS,
011: // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: // See the License for the specific language governing permissions and
013: // limitations under the License.
014:
015: package org.apache.hivemind.lib.factory;
016:
017: import java.lang.reflect.Constructor;
018: import java.util.HashMap;
019: import java.util.Iterator;
020: import java.util.List;
021: import java.util.Map;
022:
023: import org.apache.hivemind.ApplicationRuntimeException;
024: import org.apache.hivemind.ErrorLog;
025: import org.apache.hivemind.HiveMind;
026: import org.apache.hivemind.impl.BaseLocatable;
027: import org.apache.hivemind.lib.BeanFactory;
028:
029: /**
030: * Implementation of {@link org.apache.hivemind.lib.BeanFactory}.
031: *
032: * @author Howard Lewis Ship
033: */
034: public class BeanFactoryImpl extends BaseLocatable implements
035: BeanFactory {
036: private ErrorLog _errorLog;
037:
038: private Class _vendType;
039:
040: private Map _contributions = new HashMap();
041:
042: private Map _cache = new HashMap();
043:
044: private boolean _defaultCacheable;
045:
046: public BeanFactoryImpl(ErrorLog errorLog, Class vendType,
047: List contributions, boolean defaultCacheable) {
048: _errorLog = errorLog;
049: _vendType = vendType;
050: _defaultCacheable = defaultCacheable;
051:
052: processContributions(contributions);
053: }
054:
055: public boolean contains(String locator) {
056: int commax = locator.indexOf(',');
057:
058: String name = commax < 0 ? locator.trim() : locator.substring(
059: 0, commax);
060:
061: return _contributions.containsKey(name);
062: }
063:
064: private void processContributions(List list) {
065: Iterator i = list.iterator();
066:
067: while (i.hasNext()) {
068: BeanFactoryContribution c = (BeanFactoryContribution) i
069: .next();
070:
071: Class beanClass = c.getBeanClass();
072:
073: if (beanClass.isInterface() || beanClass.isArray()
074: || beanClass.isPrimitive()) {
075: _errorLog.error(FactoryMessages
076: .invalidContributionClass(c), c.getLocation(),
077: null);
078: continue;
079: }
080:
081: if (!_vendType.isAssignableFrom(beanClass)) {
082: _errorLog.error(FactoryMessages.wrongContributionType(
083: c, _vendType), c.getLocation(), null);
084: continue;
085: }
086:
087: _contributions.put(c.getName(), c);
088: }
089: }
090:
091: public synchronized Object get(String locator) {
092: Object result = _cache.get(locator);
093:
094: if (result == null)
095: result = create(locator);
096:
097: return result;
098: }
099:
100: // Implicitly synchronized by get()
101:
102: private Object create(String locator) {
103: int commax = locator.indexOf(',');
104:
105: String name = commax < 0 ? locator.trim() : locator.substring(
106: 0, commax);
107: String initializer = commax < 0 ? null : locator.substring(
108: commax + 1).trim();
109:
110: BeanFactoryContribution c = (BeanFactoryContribution) _contributions
111: .get(name);
112:
113: if (c == null)
114: throw new ApplicationRuntimeException(FactoryMessages
115: .unknownContribution(name));
116:
117: Object result = construct(c, initializer);
118:
119: if (c.getStoreResultInCache(_defaultCacheable))
120: _cache.put(locator, result);
121:
122: return result;
123: }
124:
125: private Object construct(BeanFactoryContribution contribution,
126: String initializer) {
127: Class beanClass = contribution.getBeanClass();
128:
129: try {
130: if (HiveMind.isBlank(initializer))
131: return beanClass.newInstance();
132:
133: Constructor c = beanClass
134: .getConstructor(new Class[] { String.class });
135:
136: return c.newInstance(new Object[] { initializer });
137: } catch (Exception ex) {
138: throw new ApplicationRuntimeException(FactoryMessages
139: .unableToInstantiate(beanClass, ex), contribution
140: .getLocation(), ex);
141:
142: }
143: }
144:
145: }
|