001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: * $Header:$
018: */
019: package org.apache.beehive.controls.spi.bean;
020:
021: import java.io.InputStream;
022: import java.io.IOException;
023: import java.lang.reflect.Constructor;
024: import java.lang.reflect.InvocationTargetException;
025: import java.util.Properties;
026: import java.util.concurrent.ConcurrentHashMap;
027:
028: import org.apache.beehive.controls.api.properties.PropertyMap;
029: import org.apache.beehive.controls.api.properties.BeanPropertyMap;
030: import org.apache.beehive.controls.api.properties.PropertyKey;
031: import org.apache.beehive.controls.api.bean.ControlBean;
032: import org.apache.beehive.controls.api.context.ControlBeanContext;
033: import org.apache.beehive.controls.api.ControlException;
034:
035: /**
036: * The SimpleControlFactory class is a default implementation of the
037: * <code>org.apache.beehive.controls.api.bean.ControlFactory</code> interface. It
038: * uses Java reflection to create new control instances.
039: *
040: * @see org.apache.beehive.controls.api.bean.Controls#instantiate
041: * @see org.apache.beehive.controls.spi.bean.ControlFactory
042: */
043: public class JavaControlFactory implements ControlFactory {
044: private static ConcurrentHashMap<Class, Constructor> _constructors = new ConcurrentHashMap<Class, Constructor>();
045:
046: private static final Properties _extImplBindings = new Properties();
047:
048: private static final String EXT_IMPL_BINDING_CONFIG = "controlbindings.properties";
049: private static final String KEY_CONTROL_IMPLEMENTATION = "controlImplementation";
050:
051: static {
052: InputStream is = JavaControlFactory.class.getClassLoader()
053: .getResourceAsStream(EXT_IMPL_BINDING_CONFIG);
054:
055: if (is != null) {
056: try {
057: _extImplBindings.load(is);
058: } catch (IOException ignore) {
059: // ignore...
060: } finally {
061: try {
062: is.close();
063: } catch (IOException ignore) {
064: // ignore...
065: }
066: }
067: }
068: }
069:
070: /**
071: * Instantiates a new ControlBean of the requested class, using mechanisms provided
072: * by a provider-specific JavaBeans framework.
073: *
074: * @param beanClass the ControlBean class to instantiate
075: * @param props an initial set of client-specified properties to associate with the
076: * bean instance. May be null.
077: * @param context the containing ControlBeanContext for the bean, if nested inside of
078: * a container or other control. May be null to use the current active
079: * execution context.
080: * @param id the bean control ID. Must be unique within the containing context. If
081: * null, a unique identifier will be auto-generated.
082: * @return a new ControlBean instance of the requested class.
083: */
084: public <T extends ControlBean> T instantiate(Class<T> beanClass,
085: PropertyMap props, ControlBeanContext context, String id) {
086: String beanClassName = beanClass.getName();
087:
088: String extImplBinding = _extImplBindings
089: .getProperty(beanClassName + "_" + id);
090: if (extImplBinding == null)
091: extImplBinding = _extImplBindings
092: .getProperty(beanClassName);
093:
094: if (extImplBinding != null) {
095: BeanPropertyMap bpm = props == null ? new BeanPropertyMap(
096: beanClass) : new BeanPropertyMap(props);
097: PropertyKey propKey = new PropertyKey(
098: org.apache.beehive.controls.api.properties.BaseProperties.class,
099: KEY_CONTROL_IMPLEMENTATION);
100:
101: bpm.setProperty(propKey, extImplBinding);
102: props = bpm;
103: }
104:
105: T ret = null;
106: try {
107: Constructor<T> ctor = _constructors.get(beanClass);
108: if (ctor == null) {
109: ctor = beanClass.getConstructor(
110: ControlBeanContext.class, String.class,
111: PropertyMap.class);
112:
113: _constructors.put(beanClass, ctor);
114: }
115: ret = ctor.newInstance(context, id, props);
116: } catch (InvocationTargetException ite) {
117: Throwable t = ite.getCause();
118: throw new ControlException(
119: "ControlBean constructor exception", t);
120: } catch (Exception e) {
121: throw new ControlException(
122: "Exception creating ControlBean", e);
123: }
124:
125: return ret;
126: }
127: }
|