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.api.bean;
020:
021: import java.lang.reflect.Method;
022: import java.lang.reflect.InvocationTargetException;
023:
024: import org.apache.beehive.controls.api.properties.PropertyMap;
025: import org.apache.beehive.controls.api.context.ControlBeanContext;
026: import org.apache.beehive.controls.api.ControlException;
027: import org.apache.beehive.controls.spi.bean.ControlFactory;
028: import org.apache.beehive.controls.spi.bean.JavaControlFactory;
029: import org.apache.commons.discovery.tools.DiscoverClass;
030:
031: /**
032: * Helper class for using controls. Includes static methods to help instantiate controls, and initialize
033: * declarative control clients.
034: */
035: public class Controls {
036: final private static String DEFAULT_FACTORY_CLASS = JavaControlFactory.class
037: .getName();
038:
039: /**
040: * Factory method for instantiating controls. Controls instantiated using this method will be associated with the
041: * current thread-local ControlBeanContext (possibly none), and have an auto-generated ID.
042: *
043: * @param cl the classloader used to load the ControlBean. If null, the system classloader will be used.
044: * @param beanName the fully qualified name of the ControlBean class.
045: * @param props an optional PropertyMap containing initial property values for the control. May be null.
046: * @return an instance of the specified ControlBean.
047: * @throws ClassNotFoundException
048: */
049: public static ControlBean instantiate(ClassLoader cl,
050: String beanName, PropertyMap props)
051: throws ClassNotFoundException {
052: return instantiate(cl, beanName, props, null, null);
053: }
054:
055: /**
056: * Factory method for instantiating controls.
057: *
058: * @param cl the classloader used to load the ControlBean. If null, the system classloader will be used.
059: * @param beanName the fully qualified name of the ControlBean class.
060: * @param props an optional PropertyMap containing initial property values for the control. May be null.
061: * @param cbc the ControlBeanContext that will nest the created control. If null, the thread-local context
062: * (possibly none) will be used.
063: * @param id a unique ID for the created control. If null, an ID will be auto-generated.
064: * @return an instance of the specified ControlBean.
065: * @throws ClassNotFoundException
066: */
067: public static ControlBean instantiate(ClassLoader cl,
068: String beanName, PropertyMap props, ControlBeanContext cbc,
069: String id) throws ClassNotFoundException {
070: Class beanClass = (cl == null) ? Class.forName(beanName) : cl
071: .loadClass(beanName);
072: return instantiate(beanClass, props, cbc, id);
073: }
074:
075: /**
076: * Factory method for instantiating controls.
077: *
078: * @param beanClass the ControlBean class to instantiate
079: * @param props an optional PropertyMap containing initial property values for the control.
080: * may be null.
081: * @param context the ControlBeanContext that will nest the created control. If null, the
082: * thread-local context (possibly none) will be used.
083: * @param id a unique ID for the created control. If null, an ID will be auto-generated.
084: * @return an instance of the specified ControlBean.
085: */
086: public static <T extends ControlBean> T instantiate(
087: Class<T> beanClass, PropertyMap props,
088: ControlBeanContext context, String id) {
089: try {
090: DiscoverClass discoverer = new DiscoverClass();
091: Class factoryClass = discoverer.find(ControlFactory.class,
092: DEFAULT_FACTORY_CLASS);
093: ControlFactory factory = (ControlFactory) factoryClass
094: .newInstance();
095: return factory.instantiate(beanClass, props, context, id);
096: } catch (Exception e) {
097: throw new ControlException(
098: "Exception creating ControlBean", e);
099: }
100: }
101:
102: /**
103: * Helper method for initializing instances of declarative control clients (objects that use controls via @Control
104: * and @EventHandler annotations). This method runs the client-specific generated ClientInitializer class to do
105: * its initialization work.
106: *
107: * @param cl the classloader used to load the ClientInitializer. If null, defaults to the classloader used to
108: * load the client object being initialized.
109: * @param client the client object being initialized.
110: * @param cbc the ControlBeanContext to be associated with the client object (that will nest the controls the client
111: * defines). If null, the thread-local context (possibly none) will be used.
112: * @throws ControlException
113: * @throws ClassNotFoundException
114: */
115: public static void initializeClient(ClassLoader cl, Object client,
116: ControlBeanContext cbc) throws ClassNotFoundException {
117: Class clientClass = client.getClass();
118: String clientName = clientClass.getName();
119:
120: if (cl == null)
121: cl = clientClass.getClassLoader();
122:
123: String initName = clientName + "ClientInitializer";
124: Class initClass = cl.loadClass(initName);
125:
126: try {
127: Method m = initClass.getMethod("initialize",
128: ControlBeanContext.class, clientClass);
129: m.invoke(null, cbc, client);
130: } catch (Throwable e) {
131: if (e instanceof InvocationTargetException) {
132: if (e.getCause() != null) {
133: e = e.getCause();
134: }
135: }
136:
137: throw new ControlException(
138: "Exception trying to run client initializer: "
139: + e.getClass().getName() + ", "
140: + e.getMessage(), e);
141: }
142: }
143: }
|