Fork from beehive

This commit is contained in:
Travis Burtrum 2017-05-28 00:29:58 -04:00
parent d8f7e6df4a
commit 59cf4ff2cd
1091 changed files with 13 additions and 174702 deletions

View File

@ -1,177 +0,0 @@
Welcome to Beehive
==================
To build Beehive, you will first need to check the source out from
Apache SVN and then install / configure required external software and
your shell environment.
Checkout Beehive from SVN
=========================
To do this, run the command:
svn checkout https://svn.apache.org/repos/asf/beehive/trunk
After running this command, you should have a directory "trunk/" which
contains the current Beehive source. If you ran this command in:
d:\java\beehive
you should have the directory:
d:\java\beehive\trunk
In the following steps, we'll refer to this as ${beehive.home}.
Install / configure external software and setup your shell
==========================================================
1) Java 5
Download: http://java.sun.com/j2se/1.5.0/download.jsp
Install Java 5 and set the JAVA_HOME environment variable to
refernce the JDK install directory. Ensure that $JAVA_HOME/bin is
available in your $PATH.
2) Ant 1.6.2+
Download: http://ant.apache.org/bindownload.cgi
Ant 1.6.2 is the minimum version required to build Beehive. Install
Ant 1.6.2 and set the ANT_HOME environment variable to reference the
Ant install directory. Ensure that $ANT_HOME/bin is available in your
$PATH. Copy junit.jar (in external/junit/) to $ANT_HOME/lib. This step is
required in order for the Ant <junit> tasks to work correctly.
3) Tomcat 5.0.x
Download: http://jakarta.apache.org/site/binindex.cgi#tomcat
Tomcat is used as the default test environment for Beehive. Install
Tomcat and set the CATALINA_HOME environment variable to reference the
Tomcat install directory. If you're installing Tomcat on Linux,
be sure to set the execute bit on the shell scripts in $CATALINA_HOME/bin.
If you installed these into d:\java, your environment variables
might look something like:
JAVA_HOME=d:\java\jdk1.5.0
CATALINA_HOME=d:\java\jakarta-tomcat-5.0.25
ANT_HOME=d:\java\apache-ant-1.6.2
Configure installed products
In order to run the Beehive tests, ensure that Tomcat has the the
"manager" role is defined in ${CATALINA_HOME}/conf/tomcat-users.xml
with a "manager" role and manager username/password of manager/manager.
This step is required in order to use the Tomcat Ant tasks to deploy
applications to Tomcat. An example of this file is available here:
${beehive.home}/test/conf/tomcat-users.xml
In the following examples, '$>' is your propmpt at $BEEHIVE_HOME, so if
you see '$>ant', type 'ant' (without the quotes) and press [enter].
In addition to the external software installed above, Beehive requires
one additional JAR to provide JSR 173 support for StAX, which is
required by XMLBeans. This JAR is downloaded from the network when
running Beehive's "bootstrap" target, so be sure to have a network
connection for your first build. A network connection is not required
for any subsequent builds. To install the JSR 173 API, run:
$>ant bootstrap
To check your Beehive build setup, run:
$>ant check.setup
This should end with "BUILD SUCCESSFUL" if you see any failures, be
sure to re-check your setup steps above.
To build Beehive, run:
$>ant clean deploy
To run the Beehive tests, run:
$>ant drt
Using Proxies With a Beehive Build
====================================
If you need to use proxies you can setup additional environment variables
so that the Ant "bootstrap" target is successful in downloading the
JSR 173 API JAR file.
PROXYHOST=<name of proxy host>
PROXYPORT=<port used for proxying>
PROXYUSER=<username for proxy authentication>
PROXYPASSWORD=<password for proxy authentication>
NONPROXYHOSTS=<hosts that should not be proxied>
SOCKSPROXYHOST=<socks proxy host name>
SOCKSPROXYPORT=<socks proxy port>
At a minimum, you will need to set PROXYHOST and PROXYPORT if your
network environment requires a proxy connection. To set these
environment variables in your shell, run:
set PROXYHOST=<name of proxy host>
in a Windows shell and
export PROXYHOST=<name of proxy host>
in a UNIX shell.
For information on proxy support using the <setproxy> task, please
visit http://ant.apache.org/manual/OptionalTasks/setproxy.html
Building Beehive documentation
=============================
The following documentation-related targets in
beehive/trunk/build.xml require that you have
Apache Forrest installed locally:
$>ant docs
$>ant build.dist
Before running these targets, complete the following steps.
1) Download and install Forrest 0.7 on your machine.
A list of available download locations is available at:
http://forrest.apache.org/mirrors.cgi
2) Copy the JAR file
apache-forrest-0.7/lib/core/xml-commons-resolver-1.1.jar
into
$ANT_HOME/lib
(This allows the Ant targets to call Forrest tasks.)
3) Ensure that FORREST_HOME is set to the following path.
On Windows machines:
set FORREST_HOME=C:\MyApacheStuff\apache-forrest-0.7
On Unix machines:
export FORREST_HOME=/MyApacheStuff/apache-forrest-0.7
4) Set the PATH as follows:
On Windows machines:
set PATH=%FORREST_HOME%\bin;%PATH%
On Unix machines:
export PATH=$FORREST_HOME/bin:$PATH
You are now ready to run these targets:
$>ant docs
$>ant build.dist

View File

@ -1,83 +0,0 @@
Developing in Beehive
=====================
Hey; we're glad you're here! If you're interested in developing Beehive, the
information below is for you. First, make sure you've read the introduction
for Beehive contributors here:
http://wiki.apache.org/beehive/For_Beehive_Developers
This should help you get started setting up Beehive in your IDE and navigating
what code is where.
You'll also need to configure your Subversion client to handle end-of-line styles
correctly. To do this, follow the directions below.
Configuring your Subversion client
==================================
Every text file must have the svn:eol-style property set to 'native'. This
causes ends-of-line to be translated to the correct format for the local
operating system when files are checked out (e.g., LF on linux, CR/LF on
Windows). You can do this on a per-file basis using the 'svn propset' command:
svn propset svn:eol-style native <file path>
An easier way to ensure that all added files have the right properties set is
to use the "auto-props" feature in the SVN client configuration file. The
location of this file varies depending on the operating system (see
http://svnbook.red-bean.com/svnbook/book.html#svn-ch-7-sect-1).
On Linux/UNIX it is located:
~/.subversion/config
On Windows, it is typically located in a hidden directory:
%SYSROOT%\Documents and Settings\<user name>\Application Data\Subversion
If you have problems locating this, make sure you can view hidden directory
contents.
Confirm the "header" named [miscellany] is uncommented.
Then, add (uncomment) the following line under the "[miscellany]" section:
enable-auto-props = yes
Then, add (uncomment) an "[auto-props]" section (include the [auto-props]
header as well) with a list of file extensions that will automatically
trigger the svn:eol-style=native property:
[auto-props]
*.txt = svn:eol-style=native
*.java = svn:eol-style=native
*.jj = svn:eol-style=native
*.xml = svn:eol-style=native
*.xsd = svn:eol-style=native
*.xsdconfig = svn:eol-style=native
*.dtd = svn:eol-style=native
*.properties = svn:eol-style=native
*.jcs = svn:eol-style=native
*.jcx = svn:eol-style=native
*.jpf = svn:eol-style=native
*.jpfs = svn:eol-style=native
Global.app = svn:eol-style=native
*.jsp* = svn:eol-style=native
*.jspx = svn:eol-style=native
*.jspf = svn:eol-style=native
*.jsf = svn:eol-style=native
*.jsfb = svn:eol-style=native
*.faces = svn:eol-style=native
*.tld = svn:eol-style=native
*.tldx = svn:eol-style=native
*.tag = svn:eol-style=native
*.tagf = svn:eol-style=native
*.html = svn:eol-style=native
*.css = svn:eol-style=native
*.js = svn:eol-style=native
*.inc = svn:eol-style=native
*.sh = svn:eol-style=native;svn:executable
*.cmd = svn:eol-style=native
*.pl = svn:eol-style=native
*.py = svn:eol-style=native
*.beaninfo = svn:eol-style=native

View File

@ -200,53 +200,3 @@
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
============================================
Licenses for Included Dependencies
============================================
The exceptions are as follows:
============================================
org/apache/beehive/netui/util/internal/concurrent/**
============================================
"Sun hereby grants you a non-exclusive, worldwide, non-transferrable
license to use and distribute the Java Software technologies as part
of a larger work in source and binary forms, with or without
modification, provided that the following conditions are met:
-Neither the name of or trademarks of Sun may be used to endorse or
promote products derived from the Java Software technology without
specific prior written permission.
-Redistributions of source or binary code must be accompanied by the
following notice and disclaimers:
Portions copyright Sun Microsystems, Inc. Used with kind permission.
This software is provided AS IS, without a warranty of any kind. ALL
EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PUPOSE OR
NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
MICROSYSTEMS, INC. AND ITS LICENSORS SHALL NOT BE LIABLE
FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
USING, MODIFYING OR DISTRIBUTING THE SOFTWARE OR ITS
DERIVATIVES. IN NO EVENT WILL SUN MICROSYSTEMS, INC. OR
ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR
DATA, OR FOR DIRECT, INDIRECT,CONSQUENTIAL, INCIDENTAL
OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF
THE THEORY OR LIABILITY, ARISING OUT OF THE USE OF OR
INABILITY TO USE SOFTWARE, EVEN IF SUN MICROSYSTEMS, INC.
HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
You acknowledge that Software is not designed, licensed or intended for
use in the design, construction, operation or maintenance of any nuclear
facility."
============================================
Spring Framework 1.1.5
============================================
Licensed under terms of the Apache Software License (ASL) 2.0, provided above.

View File

@ -1,34 +0,0 @@
=========================================================================
== NOTICE file corresponding to section 4(d) of the Apache License, ==
== Version 2.0, in this case for the Apache Beehive distribution. ==
=========================================================================
This product includes software developed by
The Apache Software Foundation (http://www.apache.org/).
Portions of this software were originally based on the following:
* software copyright (c) 2000-2003, BEA Systems, <http://www.bea.com/>.
and are licensed to the Apache Software Foundation under the
"Software Grant and Corporate Contribution License Agreement"
Aside from contributions to the Apache Beehive project, this
software also includes:
* One or more JARs from the Jakarta Commons, Jakarta ORO, Log4J,
Struts, and Velocity Apache projects, Copyright (c) 1999-2006
Apache Software Foundation
* One or more JARs from the Spring Framework Project
See the LICENSE.txt file for information on all licenses associated with
this software.
COPYRIGHT NOTICES:
* Apache Beehive is bundled with source and binaries from the JSR-166
implementation licensed under the relevant license in LICENSE.txt.
The source code and license are avaialble at:
http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/main/readme
* Apache Beehive is bundled with binaries from The Spring Framework Project

View File

@ -1,21 +0,0 @@
Welcome to Beehive!
If you've come here to learn more about Beehive, here are a few
starting points:
BUILDING.txt: How to build Beehive on your machine.
DEVELOPING.txt Technical notes on contributing/committing files.
LICENSE.txt: The Apache License and any other relevant licenses for this software.
NOTICE.txt: Attribution notices required by various contributions.
The Apache Beehive website is located at:
http://beehive.apache.org
And, the Beehive wiki is located at:
http://wiki.apache.org/beehive
Both of these contain additionl resources for getting started
with developing or using Beehive.

View File

@ -1,98 +0,0 @@
This directory contains the Beehive Controls source and test files. This
README provides an overview of the basic directory structure, and describes
some of the useful ant targets for building, generating javadoc, and running
tests for the Controls runtime.
SOURCE DIRECTORY STRUCTURE:
./src:
Contains all of the source files for the Beehive Controls runtime. When the
runtime is built, all of the generated classes end up in
build/jars/controls.jar.
./src/api:
Contains all of the source files for Controls public APIs used by Control
authors or clients. All annotation type, interfaces, and classes in the public
API set live within the org.apache.beehive.controls.api.* package space.
./src/spi:
Contains a small set of service provider interfaces used to adapt or
extend the Controls runtime for a specific environment. The audience for
the SPI set is primary system developers who want to integrate the runtime
into a specific container or application server environment, implement a
specific type of interceptor or instantiation factory, etc. All of the
classes in the SPI set live within the org.apache.beehive.controls.spi.*
package space.
./src/runtime:
Contains the Control runtime implementation classes. There are several
base classes used for code-generated ControlBeans as well as supporting
runtime classes for properties, contextual services, container integration,
etc. Control authors or clients should never reference any of these
runtime classes directly. All of the runtime classes live within the
org.apache.beehive.controls.runtime.* package space.
SOURCE DEPENDENCIES:
The dependencies across the various types of Control sources are:
api -> spi : API public factory classes depend upon some SPI interfaces
spi -> api : the SPI classes often consume public classes
runtime -> api, spi : the runtime classes reference both API and SPI types
Note: there are *no* dependencies from public interfaces to runtime classes.
This relationship is enforced by actually having them compile separately
(api + spi first, then runtime).
SOURCE ANT TARGETS
This section describes some of the available ant targets from the Controls
root directory.
ant build:
Compiles all annotation type, interface, and class files in the API, SPI, and
runtime directory and creates build/jars/controls.jar to contain them.
ant docs:
Generates javadoc documention for all API, SPI, and runtime classes and puts
them in build/docs. After running this target, you can browse to
file:build/docs/apidocs/classref_controls/index.html to view them.
ant clean:
Removes all generated output files from any of the build targets in the top
level or test directories.
TEST INFRASTRUCTURE:
The Controls runtime test infrastructure lives under the test subdirectory. It
includes a variety of test for Controls running in different context, from
vanilla Junit/java tests to running Controls inside of the various containers
that are part of the Beehive programming model: JWS, JPF, and nesting inside
of other controls. More details about the Controls runtime test tools
can be found at http://wiki.apache.org/beehive/Controls/TestingControls.
CONTROLS TEST TARGETS:
There are two main test targets for running Controls tests. These should be run
from within the controls/test directory:
ant checkin.tests:
These are a set of checkin tests that do shallow testing of a broad range of
functionality. These should be run and pass 100% before a committer submits
any Controls runtime changes.
ant detailed.tests:
This runs all control tests. Since some of them are test cases that are the
basis of open JIRA issues, THESE TESTS ARE NOT EXPECTED TO PASS 100%. Currently,
there is no good filter for running the detailed tests that are expected to
pass, but it has been suggested that this would be a good thing (to enable
deeper testing of larger changes).

View File

@ -1,71 +0,0 @@
<?xml version="1.0"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You 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.
$Header:$
-->
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.moparisthebest.beehive</groupId>
<artifactId>beehive</artifactId>
<version>1.0.5-SNAPSHOT</version>
</parent>
<artifactId>beehive-controls</artifactId>
<name>beehive-controls</name>
<dependencies>
<dependency>
<groupId>velocity</groupId>
<artifactId>velocity-dep</artifactId>
</dependency>
<dependency>
<groupId>commons-discovery</groupId>
<artifactId>commons-discovery</artifactId>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
</dependency>
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant-launcher</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</dependency>
<dependency>
<groupId>com.moparisthebest.aptIn16</groupId>
<artifactId>apt-mirror-api</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -1,63 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api;
/**
* The ControlException class declares an unchecked exception that is thrown by the Controls
* runtime under certain failure conditions.
*/
public class ControlException extends RuntimeException
{
/**
* Default constructor.
*/
public ControlException() {
super();
}
/**
* Constructs a ControlException object with the specified String as a message.
*
* @param message The message to use.
*/
public ControlException(String message)
{
super(message);
}
/**
* Constructs a ControlException with the specified cause.
* @param t the cause
*/
public ControlException(Throwable t) {
super(t);
}
/**
* Constructs a ControlException object using the specified String as a message, and the
* specified Throwable as a nested exception.
*
* @param message The message to use.
* @param t The exception to nest within this exception.
*/
public ControlException(String message, Throwable t)
{
super(message + "[" + t + "]", t);
}
}

View File

@ -1,45 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.assembly;
/**
* Control implementations may need to do build-time work on or impacted by
* their control client(s), such as side-effecting their client's deployment
* descriptors, or generating additional files that are implementation-
* specific.
*
* The build phase where this work is done is called assembly, and occurs
* at the granularity level of the J2EE module.
* The control author participates in this phase by authoring classes that
* implement the ControlAssembler interface, and associating such classes
* with control implementations. Instances of ControlAssembler are then
* called at assembly-time by build tools.
*/
public interface ControlAssembler
{
/**
* A ControlAssembler implementation's assemble method is called once
* per control assembler per module per assembly-time pass. The call
* passes a ControlAssemblyContext, from which information such as the
* list of client classes in the module that use the control can be
* obtained.
*/
void assemble(ControlAssemblyContext cac) throws ControlAssemblyException;
}

View File

@ -1,171 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.assembly;
import java.io.File;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Set;
import com.sun.mirror.apt.Messager;
/**
* Control assemblers are passed a ControlAssemblyContext at the time they are
* invoked; the context allows the assemblers to interact with their external
* environment (checking files, side-effecting deployment descriptors, emitting
* code parameterized by the specifics of the control extension, etc).
*
* Beehive provides ControlAssemblyContext implementations that expose the
* standard environments of J2EE applications and modules. Vendor-specific
* implementations may provide access to their specific environment information,
* such as vendor-specific descriptors, via definition and implementation
* of additional interfaces. ControlAssemblers should use reflection to
* determine if the ControlAssemblyContext implementation they are passed
* supports a particular set of environment features.
*/
public interface ControlAssemblyContext
{
/**
* Providers of ControlAssemblyContext implementations MUST implement
* Factory and newInstance to return their implementation.
*/
interface Factory
{
/**
* Creates a new instance of a ControlAssemblyContext implementation.
*
* @param controlIntfOrExt public interface/extension of the control
* type being assembled
* @param bindings map of control implementation bindings, null
* means use defaults.
* @param clients set of clients that use this control type.
* @param moduleRoot file root of the J2EE module containing the
* control clients to be assembled
* @param moduleName name of the J2EE module containing the
* control clients to be assembled
* @param srcOutputRoot file root of a location where assemblers
* should output any sources they create that
* may need further processing before use.
* @return a new instance of a ControlAssemblyContext implementation
*/
ControlAssemblyContext newInstance( Class controlIntfOrExt,
Map<String,String> bindings,
Set<String> clients,
File moduleRoot,
String moduleName,
File srcOutputRoot )
throws ControlAssemblyException;
}
/**
* Providers of ControlAssemblyContext implementations may implement
* EJBModule to provide access to an EJB module environment.
*/
interface EJBModule
{
// TODO: Provide more abstract helpers for common tasks.
// E.g. addResourceRef().
File getEjbJarXml();
}
/**
* Providers of ControlAssemblyContext implementations may implement
* WebAppModule to provide access to a webapp module environment.
*/
interface WebAppModule
{
File getWebXml();
}
/**
* Providers of ControlAssemblyContext implementations may implement
* EntAppModule to provide access to an enterprise application module
* environment.
*/
interface EntAppModule
{
File getApplicationXml();
}
/**
* @return the interface type of the control being assembled (annotated
* w/ ControlExtension or ControlInterface)
*/
Class getControlType();
/**
* @return the most derived interface of the control being assembled that
* is annotated with ControlInterface (may return the same as
* getControlType() if the control type is non-extended)
*/
Class getMostDerivedControlInterface();
/**
* @return an annotation on the interface returned by
* getControlType()
*/
<T extends Annotation> T
getControlAnnotation(Class<T> annotationClass);
/**
* @return an annotation on a method on the interface
* returned by getControlType()
*/
<T extends Annotation> T
getControlMethodAnnotation(Class<T> annotationClass, Method m)
throws NoSuchMethodException;
/**
* @return the defaultBinding member of the ControlInterface
*/
String getDefaultImplClassName();
/**
* @return the output directory into which "compilable" source should be output.
*/
File getSrcOutputDir();
/**
* @return the root of the module for which assembly is taking place.
*/
File getModuleDir();
/**
* @return the name of the module for which assembly is taking place.
*/
String getModuleName();
/**
* @return the set of clients (by class name) which use the control type
*/
Set<String> getClients();
/**
* @return a Messager implementation that can be used to emit diagnostics during the
* assembly process.
*/
Messager getMessager();
/**
* @return true if the assembly process reported errors via the Messager
*/
boolean hasErrors();
}

View File

@ -1,37 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.assembly;
/**
* Checked exceptions thrown during the assembly process. ControlAssembler
* implementations may throw this exception in their assemble() method, which
* will halt the assembly process.
*/
public class ControlAssemblyException extends Exception
{
public ControlAssemblyException(String msg)
{
super(msg);
}
public ControlAssemblyException(String msg, Throwable cause)
{
super(msg, cause);
}
}

View File

@ -1,28 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.assembly;
/**
* The default or "empty" control assembler that's assigned to an @ControlImplementation's
* assembler attribute if none is provided.
*/
public final class DefaultControlAssembler implements ControlAssembler
{
public void assemble(ControlAssemblyContext cac) throws ControlAssemblyException { };
}

View File

@ -1,90 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.bean;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Retention;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
/**
* AnnotationConstraints defines meta-annotations that allow
* specification of additional constraints that aren't
* expressible using J2SE 5.0 meta-annotations.
*
* Actual enforcement of these semantics is implementation dependent.
* An <code>apt</code>-based reference implementation is provided by
* {@link org.apache.beehive.controls.runtime.bean.AnnotationConstraintValidator}.
*
* @see org.apache.beehive.controls.runtime.bean.AnnotationConstraintValidator
*/
public interface AnnotationConstraints
{
/**
* Defines a number of simple constraints on the way annotation members
* can be used together.
*
* @see MembershipRule
*/
public enum MembershipRuleValues
{
AT_LEAST_ONE,
AT_MOST_ONE,
EXACTLY_ONE,
ALL_IF_ANY
}
/**
* Provides a mechanism for enforcing constraints between members of
* an annotation (such a mechanism is absent from J2SE 5.0; for example,
* given an annotation with members 'a' and 'b' there is no way to say
* that they are mutually exclusive).
*
* @see MembershipRuleValues
*/
@Target({ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MembershipRule
{
/** Required, the membership rule.*/
MembershipRuleValues value();
/** Optional list of member names to apply rule against. Empty array implies all members. */
String[] memberNames() default {};
}
/**
* Defines whether the annotation decorated by this
* annotation can overriden externally (a marker interface).
*/
@Target({ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface AllowExternalOverride
{
}
/**
* Specifies the version of the control runtime required by this annotation.
*/
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequiredRuntimeVersion
{
String value(); // no default
}
}

View File

@ -1,214 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.bean;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* <p>AnnotationMemberTypes defines a set of annotations meant to used on
* annotation members to specify additional syntatic and semantic behaviour
* or constraints.</p>
*
* <p>J2SE 5 annotation members provide a very weak level of syntactic and
* semantic enforcement. Annotation members may only be a certain type
* (mostly primitives, arrays, plus java.lang.String and a few other classes);
* it is often useful to be more specific than those types permit.</p>
*
* <p>Consider the following example:</p>
*
* <pre>
* public &#064;interface LastChanged
* {
* &#064;AnnotationMemberTypes.Date()
* public String date();
* }
* </pre>
*
* <p>The use of <code>&#064;AnnotationMemberTypes.Date</code> means that the
* value of the <code>date</code> string must be a date in some standard
* form.</p>
*
* <p>AnnotationMemberTypes defines a set of annotations and their semantics,
* but actual enforcement of those semantics is implementation dependent.
* An <code>apt</code>-based reference implementation is provided by
* {@link org.apache.beehive.controls.runtime.bean.AnnotationConstraintValidator}.</p>
*
* @see org.apache.beehive.controls.runtime.bean.AnnotationConstraintValidator
*/
public interface AnnotationMemberTypes
{
public final static String OPTIONAL_STRING = "";
public final static double OPTIONAL_DOUBLE = Double.MIN_VALUE;
public final static float OPTIONAL_FLOAT = Float.MIN_VALUE;
public final static int OPTIONAL_INT = Integer.MIN_VALUE;
public final static long OPTIONAL_LONG = Long.MIN_VALUE;
public final static short OPTIONAL_SHORT = Short.MIN_VALUE;
public final static char OPTIONAL_CHAR = Character.MIN_VALUE;
public final static byte OPTIONAL_BYTE = Byte.MIN_VALUE;
public final static int UNLIMITED_PLACES = -1;
/**
* Marks a member as optional. Member must have
* a default value.
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Optional
{
}
/**
* Member must be a String value.
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Text
{
boolean isLong() default false;
int maxLength() default Integer.MAX_VALUE;
}
/**
* Member is a Decimal Value.
* Can be applied to a member that returns float, double or String.
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Decimal
{
int places() default UNLIMITED_PLACES;
double minValue() default Double.MIN_VALUE;
double maxValue() default Double.MAX_VALUE;
}
/**
* Member is an Integer value.
* Can be applied to a member that returns String or int.
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Int
{
int minValue() default Integer.MIN_VALUE;
int maxValue() default Integer.MAX_VALUE;
}
/**
* Member is a Date in the format specified (default is YYYY/MM/DD)
* Only valid on a member that returns String
* @see java.text.SimpleDateFormat when selecting another date format.
* Note: JSR175 does not allow java.util.Date as
* a member type.
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Date
{
String format() default "yyyy/MM/dd";
String minValue() default "";
String maxValue() default "";
}
/**
* Member is a URI
* Only valid on a member that returns String
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface URI
{
}
/**
* Member is a URN
* Only valid on a member that returns String
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface URN
{
}
/**
* Member is a URL
* Only valid on a member that returns String
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface URL
{
}
/**
* Member is a QName
* Only valid on a member that returns String
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface QName
{
}
/**
* Member contains well formed XML
* Only valid on a member that returns String
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface XML
{
}
/**
* Member is a File Path
* Compiler MUST validate that value points
* to a <code>readable</code> file.
* Only valid on a member that returns String.
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface FilePath
{
}
/**
* Member is a JNDI name.
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface JndiName
{
/**
* Defines the type of JNDI resource reference by a member.
*/
public enum ResourceType
{
DATASOURCE,
EJB,
JMS_TOPIC,
JMS_QUEUE ,
OTHER
}
ResourceType resourceType();
}
}

View File

@ -1,44 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.bean;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* The Control annotation type is used to annotate a field within a control
* client source file that is a control reference. It is the declarative
* mechanism for instantiating controls in Java clients. Java Controls
* runtime implementations will automatically initialize such annotated field
* references to an appropriate Java Control Bean of the requested type,
* and perform event listener hookup etc.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface Control
{
/**
* Optional member used to specify the control interface class.
* Typically only necessary to resolve ambiguities when multiple
* control interfaces with same name but different packages are present.
*/
Class<?> interfaceHint() default Object.class;
}

View File

@ -1,76 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.bean;
import java.beans.beancontext.BeanContext;
import java.beans.beancontext.BeanContextProxy;
import org.apache.beehive.controls.api.context.ControlBeanContext;
/**
* The ControlBean interface defines a base set of methods that are implemented by all
* <code>JavaBeans</code> that host Java Controls.
* <p>
* A ControlBean will implement the <code>java.beans.beancontext.BeanContextProxy</code>
* interface to provide a way to get the <code>BeanContext</code> directly associated
* with the Java Control. The <code>getBeanContext()</code> API on the interface will
* return the parent (containing) context.
*
* @see java.beans.beancontext.BeanContextProxy
*/
public interface ControlBean extends BeanContextProxy, java.io.Serializable
{
/**
* The IDSeparator character is used to separated individual control IDs in nesting
* scenarios whether the identifier is actually a composite path that represents
* a nesting relationship.
*/
public static final char IDSeparator = '/';
/**
* Returns the <code>java.beans.beancontext.BeanContext</code> that provides the parent
* context for the Java Control.
* @return the containing <code>BeanContext</code> for the Java ControlBean.
*
* @see java.beans.beancontext.BeanContext
*/
BeanContext getBeanContext();
/**
* Returns the <code>org.apache.beehive.controls.api.context.ControlBeanContext</code> instance
* that provides the local context for this control bean. <b>This is not the parent
* context for the control.</b> It is the context that would be the parent context for
* any nested controls hosted by this control.
*/
ControlBeanContext getControlBeanContext();
/**
* Returns the unique control ID associated with the Java ControlBean. This control ID
* is guaranteed to be unique within the containing <code>BeanContext</code>
* @return the control ID
*/
String getControlID();
/**
* Returns the Java Control public interface for the ControlBean. This interface defines
* the operations and events exposed by the Java Control to its clients.
* @return the control public interface
*/
Class getControlInterface();
}

View File

@ -1,44 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.bean;
import com.sun.mirror.apt.AnnotationProcessorEnvironment;
import com.sun.mirror.declaration.Declaration;
/**
* The ControlChecker interface is implemented by control authors wishing to
* enforce rich semantic validation on extension and field instance declarations of
* their controls. By supplying a ControlChecker implementation (a "checker")
* and associating it with your control's public interface, when an extension (.jcx)
* of your control is processed at build-time, the checker will be invoked and
* can do rich validation of the jcx type and field instances via introspection and
* analysis of the jcx's type structure, signatures and annotations.
* <p>
* Checkers are instantiated by, and required to implement, a no-arg constructor.
* They are provided with type information and context via the Sun mirror API.
*/
public interface ControlChecker
{
/**
* Invoked by the control build-time infrastructure to process a declaration of
* a control extension (ie, an interface annotated with @ControlExtension), or
* a field instance of a control type.
*/
public void check(Declaration decl, AnnotationProcessorEnvironment env);
}

View File

@ -1,34 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.bean;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* The ControlExtension annotation type is used to annotate a control extension interface.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface ControlExtension
{
// Members parameterizing the control extension will be added here
}

View File

@ -1,56 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.bean;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.apache.beehive.controls.api.assembly.ControlAssembler;
import org.apache.beehive.controls.api.assembly.DefaultControlAssembler;
/**
* The ControlImplementation annotation type is used to annotate the implementation class for a
* Java Control. It marks the class as a control implementation and (in the future) parameterizes
* it.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface ControlImplementation
{
/** class name for the Class (which implements
* com.bea.control.assembly.ControlAssembler) whose assemble()
* method is called at assembly time - if left Void then no
* special assembly is needed
*/
Class assemblyHelperClass() default java.lang.Void.class; // DEPRECATED
/**
* Class that implements ControlAssembler, which gets called at assembly time.
* Default implementation does nothing.
*/
Class<? extends ControlAssembler> assembler() default DefaultControlAssembler.class;
/**
* Specifies whether the control implementation class contains state that should be
* serialized as part of the containing Control/JavaBean or is fully stateless/transient.
*/
boolean isTransient() default false; // default to assuming stateful
}

View File

@ -1,61 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.bean;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* The ControlInterface annotation type is used to annotate a control public interface.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface ControlInterface
{
/**
* Placeholder string used in defaultBinding attr. Tools and runtime should replace
* instances of INTERFACE_NAME found in values of defaultBinding with the fully
* qualified name of the interface annotated with @ControlInterface.
*/
static final String INTERFACE_NAME = "<InterfaceName>";
/**
* Specify the fully qualified name of the control implementation for this control interface.
* If no value is specified the implementation will be the name of the interface with 'Impl' appended.
* */
String defaultBinding() default INTERFACE_NAME + "Impl";
/**
* @deprecated Replaced by checker() element.
*/
Class<? extends ControlChecker> checkerClass() default DefaultControlChecker.class;
/**
* Used by control authors wishing to enforce rich semantic validation on extension and field
* instance declarations of their controls. By supplying a ControlChecker implementation
* (a "checker") and associating it with your control's public interface, when an
* extension of your control is processed at build-time, the checker will be invoked and
* can do rich validation of the extension type and field instances via introspection and
* analysis of the control extension's type structure, signatures and annotations.
* @see org.apache.beehive.controls.api.bean.ControlChecker
*/
Class<? extends ControlChecker> checker() default DefaultControlChecker.class;
}

View File

@ -1,38 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.bean;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* The ControlReferences annotation type is used to annotate a control client
* type, listing any control types that the client uses purely programmatically
* (and not declaratively). Tools will treat the union of the set of types
* annotated w/ @Control and the types listed in @ControlReferences as the
* complete set of controls used by a client.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface ControlReferences
{
Class[] value() default {};
}

View File

@ -1,153 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.bean;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
import org.apache.beehive.controls.api.properties.PropertyMap;
import org.apache.beehive.controls.api.context.ControlBeanContext;
import org.apache.beehive.controls.api.ControlException;
import org.apache.beehive.controls.spi.bean.ControlFactory;
import org.apache.beehive.controls.spi.bean.JavaControlFactory;
import org.apache.commons.discovery.tools.DiscoverClass;
/**
* Helper class for using controls. Includes static methods to help instantiate controls, and initialize
* declarative control clients.
*/
public class Controls
{
final private static String DEFAULT_FACTORY_CLASS = JavaControlFactory.class.getName();
/**
* Factory method for instantiating controls. Controls instantiated using this method will be associated with the
* current thread-local ControlBeanContext (possibly none), and have an auto-generated ID.
*
* @param cl the classloader used to load the ControlBean. If null, the system classloader will be used.
* @param beanName the fully qualified name of the ControlBean class.
* @param props an optional PropertyMap containing initial property values for the control. May be null.
* @return an instance of the specified ControlBean.
* @throws ClassNotFoundException
*/
public static ControlBean instantiate( ClassLoader cl,
String beanName,
PropertyMap props )
throws ClassNotFoundException
{
return instantiate( cl, beanName, props, null, null );
}
/**
* Factory method for instantiating controls.
*
* @param cl the classloader used to load the ControlBean. If null, the system classloader will be used.
* @param beanName the fully qualified name of the ControlBean class.
* @param props an optional PropertyMap containing initial property values for the control. May be null.
* @param cbc the ControlBeanContext that will nest the created control. If null, the thread-local context
* (possibly none) will be used.
* @param id a unique ID for the created control. If null, an ID will be auto-generated.
* @return an instance of the specified ControlBean.
* @throws ClassNotFoundException
*/
public static ControlBean instantiate( ClassLoader cl,
String beanName,
PropertyMap props,
ControlBeanContext cbc,
String id )
throws ClassNotFoundException
{
Class beanClass = ( cl == null ) ? Class.forName( beanName ) : cl.loadClass( beanName );
return instantiate(beanClass, props, cbc, id);
}
/**
* Factory method for instantiating controls.
*
* @param beanClass the ControlBean class to instantiate
* @param props an optional PropertyMap containing initial property values for the control.
* may be null.
* @param context the ControlBeanContext that will nest the created control. If null, the
* thread-local context (possibly none) will be used.
* @param id a unique ID for the created control. If null, an ID will be auto-generated.
* @return an instance of the specified ControlBean.
*/
public static <T extends ControlBean> T instantiate( Class<T> beanClass,
PropertyMap props,
ControlBeanContext context,
String id )
{
try
{
DiscoverClass discoverer = new DiscoverClass();
Class factoryClass = discoverer.find( ControlFactory.class, DEFAULT_FACTORY_CLASS );
ControlFactory factory = (ControlFactory)factoryClass.newInstance();
return factory.instantiate( beanClass, props, context, id );
}
catch ( Exception e )
{
throw new ControlException( "Exception creating ControlBean", e );
}
}
/**
* Helper method for initializing instances of declarative control clients (objects that use controls via @Control
* and @EventHandler annotations). This method runs the client-specific generated ClientInitializer class to do
* its initialization work.
*
* @param cl the classloader used to load the ClientInitializer. If null, defaults to the classloader used to
* load the client object being initialized.
* @param client the client object being initialized.
* @param cbc the ControlBeanContext to be associated with the client object (that will nest the controls the client
* defines). If null, the thread-local context (possibly none) will be used.
* @throws ControlException
* @throws ClassNotFoundException
*/
public static void initializeClient( ClassLoader cl, Object client, ControlBeanContext cbc )
throws ClassNotFoundException
{
Class clientClass = client.getClass();
String clientName = clientClass.getName();
if ( cl == null )
cl = clientClass.getClassLoader();
String initName = clientName + "ClientInitializer";
Class initClass = cl.loadClass( initName );
try
{
Method m = initClass.getMethod( "initialize", ControlBeanContext.class, clientClass );
m.invoke(null, cbc, client );
}
catch ( Throwable e )
{
if ( e instanceof InvocationTargetException )
{
if ( e.getCause() != null )
{
e = e.getCause();
}
}
throw new ControlException( "Exception trying to run client initializer: " + e.getClass().getName() + ", " +
e.getMessage(), e );
}
}
}

View File

@ -1,31 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.bean;
import com.sun.mirror.apt.AnnotationProcessorEnvironment;
import com.sun.mirror.declaration.Declaration;
/**
* The default or "empty" control checker that assigned to an @ControlInterface's
* controlChecker attribute if none is provided.
*/
public final class DefaultControlChecker implements ControlChecker
{
public void check(Declaration decl, AnnotationProcessorEnvironment env) { };
}

View File

@ -1,45 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.bean;
import java.lang.reflect.Method;
/**
* The Extensible interface is implemented by a Java Control implementation class if the
* control defines an extensibility model that allows extended operations to be declared
* using a JCX interface.
* <p>
* The interface provides the <code>invoke</code> method, that is called whenever an
* extended operation is called by the client at run time.
*/
public interface Extensible
{
/**
* Called by the Controls runtime to handle calls to methods of an
* extensible control.
* <p>
* @param method The extended operation that was called.
* @param args Parameters of the operation.
* @return The value that should be returned by the operation.
* @throws java.lang.Throwable any exception declared on the extended operation may be
* thrown. If a checked exception is thrown from the implementation that is not declared
* on the original interface, it will be wrapped in a ControlException.
*/
public Object invoke(Method method, Object[] args) throws Throwable;
}

View File

@ -1,36 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.bean;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Used on control interfaces to specify any external property sets that
* the control uses. External property sets are property sets that are
* their own top-level interfaces, i.e. not nested.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface ExternalPropertySets
{
Class[] value();
}

View File

@ -1,36 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.bean;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Used to specify the desired threading policy to apply to a control
* implementation type. See {@link ThreadingPolicy}. Only permitted
* on classes that are also annotated with {@link ControlImplementation}.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface Threading
{
ThreadingPolicy value() default ThreadingPolicy.SINGLE_THREADED;
}

View File

@ -1,48 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.bean;
/**
* Specifies threading policy for control implementations. The constants
* of this enumerated type describe the threading policies that apply
* during execution of controls. They are used in conjunction with the
* {@link Threading} annotation type to specify the responsibilities of
* the runtime infrastructure and control implementation with respect to
* threading.
*/
public enum ThreadingPolicy
{
/**
* When a control implementation is declared as SINGLE_THREADED, the
* controls infrastructure ensures that only a single thread will be
* executing in a particular instance of that control at any time.
* This is the default policy if no {@link Threading} annotation is
* specified.
*/
SINGLE_THREADED,
/**
* When a control implementation is declared as MULTI_THREADED, the
* controls infrastructure permits multiple threads to concurrently
* execute in instances of that control. It is then the responsibility
* of the implementation to ensure internal thread-safety using
* standard Java concurrency mechanisms. This policy may yield higher
* performance, at the cost of additional work on the implementor's part.
*/
MULTI_THREADED
}

View File

@ -1,50 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.context;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* The Context annotation type is used to annotate a field within a control implementation
* class that refers to a contextual service. The Java Controls runtime will automatically
* initialize the field value to an appropriate provider of the requested service, or will
* throw a construction or deserialization error if no such provider is available.
*
* The following is a simple example:
*
* <code><pre>
* <sp>@ControlImplementation
* public class MyControlImpl
* {
* <sp>@Context
* ControlContext myContext;
* }
* </pre></code>
* This example declares a field named <code>myContext</code> that will automatically be
* initialized by the Java Controls runtime to refer to a provider of the
* <code>ControlContext</code> contextual service.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface Context
{
}

View File

@ -1,238 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.context;
import java.beans.beancontext.BeanContextServices;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyVetoException;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Method;
import org.apache.beehive.controls.api.bean.ControlBean;
import org.apache.beehive.controls.api.events.EventSet;
import org.apache.beehive.controls.api.properties.PropertyMap;
/**
* The ControlBeanContext interface defines the basic set of contextual services and lifecycle
* events for Java ControlBean implementations.
* <p>
* ControlBeanContext also extends the <code>java.beans.beancontext.BeanContextServices</code>
* interface, so it also provide core Java Beans services for managing contained controls,
* looking up contextual services, and locating the parent {@link java.beans.beancontext.BeanContext} context.
* <p>
* A Control implementation class can obtain access to the ControlBeanContext associated
* with it by declaring an instance field of this type and annotating it with the
* <code>org.apache.beehive.controls.api.context.Context</code> annotation, as in the following
* example:
*
* <code><pre>
* import org.apache.beehive.controls.api.context.Context;
* import org.apache.beehive.controls.api.context.ControlBeanContext;
*
* <sp>@ControlImplementation
* public class MyControlImpl
* {
* <sp>@Context
* ControlBeanContext myContext;
* }
* </pre></code>
* The Java Control runtime will automatically initialize this field to a reference to the
* ControlBeanContext associated with the implementation instance.
*/
public interface ControlBeanContext extends BeanContextServices
{
/**
* Returns the public or extension interface associated with the context
*/
public Class getControlInterface();
/**
* Returns the current value of PropertySet for the associated control, or
* null if the property set has not been bound. Actual bindings for property
* values may be the result of annotations on the control field or class,
* property setting via factory arguments or setter APIs, or external
* configuration.
*
* @param propertySet the PropertySet to return
* @return the requested PropertySet instance, or null if not bound
*
* @see org.apache.beehive.controls.api.properties.PropertySet
*/
public <T extends Annotation> T getControlPropertySet(Class<T> propertySet);
/**
* Returns the current value of PropertySet for the provided method, or null
* if the property set has not been bound for this method.
*
* @param m the Method to check for properties.
* @param propertySet the PropertySet to return
* @return the requested PropertySet instance, or null if not bound
*
* @see org.apache.beehive.controls.api.properties.PropertySet
*/
public <T extends Annotation> T getMethodPropertySet(Method m, Class<T> propertySet)
throws IllegalArgumentException;
/**
* Returns the current value of PropertySet for the selected (by index) method parameter,
* or null if the property set has not been bound for this method.
*
* @param m the Method to check for properties
* @param i the index of the method parameter to check for the request PropertySet
* @param propertySet the PropertySet to return
* @return the request PropertySet instance, or null if not bound
*/
public <T extends Annotation> T getParameterPropertySet(Method m, int i, Class<T> propertySet)
throws IllegalArgumentException, IndexOutOfBoundsException;
/**
* Returns an array containing the parameter names for the specified method
*
* @param m the Method whose parameter names should be returned.
* @return the array of parameter names (or an empty array if no parameters)
*/
public String [] getParameterNames(Method m)
throws IllegalArgumentException;
/**
* Returns the value of a named method parameter from the input parameter array.
*
* @param m the Method associated with the input parameter list
* @param parameterName the name of the requested parameter
* @param parameters the array of method parameters
* @return the element in the input parameter array that corresponds to the requested
* parameter
*/
public Object getParameterValue(Method m, String parameterName, Object [] parameters)
throws IllegalArgumentException;
/**
* Returns the current set of properties (in PropertyMap format) for the control
* associated with the context. The return map will contain the values for all bound
* properties for the control.
* @return the PropertyMap containing properties of the control. This map is read-only;
* any changes to it will not effect the local bean instance.
*
* @see org.apache.beehive.controls.api.properties.PropertyMap
*/
public PropertyMap getControlPropertyMap();
/**
* Returns an instance of a contextual service based upon the local context. If
* no provider for this service is available, then null will be returned.
*
* @param serviceClass the class of the requested service
* @param selector the service dependent parameter
* @return an instance of the request service, or null if unavailable
*
* @see java.beans.beancontext.BeanContextServices#getService
*/
public <T> T getService(Class<T> serviceClass, Object selector);
/**
* Returns a ControlHandle instance that enables operations and events to be dispatched
* to the target control, if it is running inside of a container that supports external
* event dispatch. If the runtime container for the control does not support this
* functionality, a value of null will be returned.
*
* @return a ControlHandle instance for the control, or null.
*
* @see org.apache.beehive.controls.api.context.ControlHandle
*/
public ControlHandle getControlHandle();
/**
* Returns the PropertyMap containing default properties for an AnnotatedElement
* in the current context.
*/
public PropertyMap getAnnotationMap(AnnotatedElement annotElem);
/**
* Returns the ClassLoader used to load the ControlBean class associated with the control
* implementation instance. This is useful for loading other classes or resources that may
* have been packaged with the public interfaces of the Control type (since they may not
* necessarily have been packaged directly with the implementation class).
*/
public java.lang.ClassLoader getClassLoader();
/**
* Returns true if this container guarantees single-threaded behaviour.
*/
public boolean isSingleThreadedContainer();
/**
* Returns the peer ControlBean associated with this ControlBeanContext. If the context
* represents a top-level container (i.e. not a Control containing other controls), null
* will be returned.
*/
public ControlBean getControlBean();
/**
* Returns any child ControlBean that is nested in the ControlBeanContext, or null
* if no matching child is found. The <code>id</code> parameter is relative to
* the current nesting context, not an absolute control id.
*/
public ControlBean getBean(String id);
/**
* The Lifecycle event interface defines a set of lifecycle events exposed by the
* ControlBeanContext to any registered listener.
*/
@EventSet
public interface LifeCycle
{
/**
* The onCreate event is delivered when the control implementation instance for
* the associated bean has been instantiated and fully initialized.
*/
public void onCreate();
/**
* The onPropertyChange event is delivered when a property setter method is
* called for a bound property on the Java Control.
*
* @see org.apache.beehive.controls.api.packaging.PropertyInfo
*/
public void onPropertyChange(PropertyChangeEvent pce);
/**
* The onVetoableChange event is delivered when a property setter method is
* called for a constrained property on the Java Control. A PropertyVetoException
* may be thrown to veto the change made by the client.
*
* @see org.apache.beehive.controls.api.packaging.PropertyInfo
*/
public void onVetoableChange(PropertyChangeEvent pce) throws PropertyVetoException;
}
/**
* Registers a new listener for LifeCycle events on the context.
*
* @see org.apache.beehive.controls.api.context.ControlBeanContext.LifeCycle
*/
public void addLifeCycleListener(LifeCycle listener);
/**
* Removes a currently registered LifeCycle event listener on the context.
*
* @see org.apache.beehive.controls.api.context.ControlBeanContext.LifeCycle
*/
public void removeLifeCycleListener(LifeCycle listener);
}

View File

@ -1,48 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.context;
import org.apache.beehive.controls.api.bean.ControlBean;
import org.apache.beehive.controls.api.events.EventDispatcher;
/**
* The ControlContainerContext interface defines the basic contract between an external container
* of controls and the Controls runtime.
*/
public interface ControlContainerContext extends EventDispatcher, ControlBeanContext
{
/**
* Makes the ControlContainerContext instance the current active context. This is
* called at the beginning of the execution scope for the control container.
*/
public void beginContext();
/**
* Ends the active context associated with the ControlContainerContext. This is called
* at the end of the execution scope for the control container.
*/
public void endContext();
/**
* Returns a ControlHandle to the component containing the control. This handle can be
* used to dispatch events and operations to a control instance. This method will return
* null if the containing component does not support direct dispatch.
*/
public ControlHandle getControlHandle(ControlBean bean);
}

View File

@ -1,46 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.context;
import org.apache.beehive.controls.api.events.EventRef;
import java.lang.reflect.InvocationTargetException;
/**
* The ControlHandle interface defines a reference object to a control instance that enables
* control events to be fired on the control. Control container implementations will provide
* implementation of this interface that use container-specific dispatch mechanisms to locate
* the appropriate control container instance when events are fired.
*
* Classes implementing the ControlHandle interface should also implement the <code>
* java.io.Serializable</code> interface. This will enable handles to be serialized /
* deserialized as part of event queueing or routing.
*/
public interface ControlHandle
{
/**
* Returns the controlID of the target control referenced by this handle
*/
public String getControlID();
/**
* Delivers the specified event to the target control referenced by this handle.
*/
public Object sendEvent(EventRef event, Object [] args)
throws IllegalAccessException,IllegalArgumentException,InvocationTargetException;
}

View File

@ -1,82 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.context;
import java.util.Stack;
/**
* The ControlThreadContext class manages the association between ControlContainerContexts
* and threads of execution. For a given thread of execution, the beginning and ending of
* contexts will always be nested (never interleaved), so each thread will maintain its own
* stack of currently executing contexts. This can be used to reassociate with the current
* active context.
*/
public class ControlThreadContext
{
/**
* This thread local maintains a per-thread stack of ControlContainerContext instances.
*/
private static ThreadLocal<Stack<ControlContainerContext>> _threadContexts =
new ThreadLocal<Stack<ControlContainerContext>>();
/**
* Returns the active ControlContainerContext for the current thread, or null if no
* context is currently active.
* @return the current active ControlContainerContext
*/
public static ControlContainerContext getContext()
{
Stack<ControlContainerContext> contextStack = _threadContexts.get();
if (contextStack == null || contextStack.size() == 0)
return null;
return contextStack.peek();
}
/**
* Defines the beginning of a new control container execution context.
*/
public static void beginContext(ControlContainerContext context)
{
Stack<ControlContainerContext> contextStack = _threadContexts.get();
if (contextStack == null)
{
contextStack = new Stack<ControlContainerContext>();
_threadContexts.set(contextStack);
}
contextStack.push(context);
}
/**
* Ends the current control container execution context
* @throws IllegalStateException if there is not current active context or it is not
* the requested context.
*/
public static void endContext(ControlContainerContext context)
{
Stack<ControlContainerContext> contextStack = _threadContexts.get();
if (contextStack == null || contextStack.size() == 0)
throw new IllegalStateException("No context started for current thread");
if (contextStack.peek() != context)
throw new IllegalStateException("Context is not the current active context");
contextStack.pop();
}
}

View File

@ -1,167 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.context;
import org.apache.beehive.controls.api.events.EventSet;
/**
* The ResourceContext interface defines a basic contextual service for coordinating the
* resource utilization of a control implementation within a resource scope defined external
* to the control. This contextual service that provides assistance to a Control in managing
* any external resources (connections, sesssions, etc) that may be relatively expensive to
* obtain and/or can only be held for a relatively short duration.
* <p>
* A ResourceContext implementation may be provided by an external container of Controls, such
* as a servlet engine or EJB container, that coordinates the resource lifecycle of controls with
* the activities of the external container. For example, the resource scope for a
* ResourceContext provider associated with the web tier might enable control resources to be
* used for the duration of a single http request; for the EJB tier it might mean for the
* lifetime of the current EJB invocation or active transaction.
* <p>
* A control implementation participates in this resource management contract by declaring a
* ResourceContext instance annotated with the
* <sp>@Context annotation, the standard service provider model of the Control runtime will
* associate the control instance with a ResourceControl provider implementation that is
* associated with the current execution context. This is demonstrated by the following
* code excerpt from a ControlImplementation class:
* <p>
* <pre><code>
* <sp>@org.apache.beehive.controls.api.bean.ControlImplementation
* public class MyControlImpl
* {
* ...
* // Declare need for resource mgmt support via the ResourceContext service
* <sp>@org.apache.beehive.controls.api.context.Context
* ResourceContext resourceContext;
* ...
* </code></pre>
* <p>
* Once the control has been associated with a ResourceContext provider, the provider will
* deliver events to the Control Implementation instance according to the following basic
* contract:
* <p>
* <ul>
* <li>the ResourceContext provider notifies a control implementation when it should acquire its
* resources using the onAcquire event.
* <li>the ResourceContext provider notifies a control implementation when it should release its
* resources using the onRelease event.
* </ul>
* <p>
* The following code fragment shows how to receive resource events from within a Control
* implementation:
* <p>
* <pre><code>
* import org.apache.beehive.controls.api.events.EventHandler;
*
* ...
*
* <sp>@EventHandler(field="resourceContext",
* eventSet=ResourceContext.ResourceEvents.class,
* eventName="onAcquire")
* public void onAcquire()
* {
* // code to obtain connections/sessions/...
* }
*
* <sp>@EventHandler(field="resourceContext",
* eventSet=ResourceContext.ResourceEvents.class,
* eventName="onRelease")
* public void onRelease()
* {
* // code to release connections/sessions/...
* }
* </code></pre>
* <p>
* The onAcquire resource event is guaranteed to be delivered once before any operation declared
* on a public or extension interface associated with the control. This event will be delivered
* once, and only once, within a particular resource scope associated with the ResourceContext.
*
* If a control needs to utilize its resources in another context (such as in response to a
* PropertyChange notification), the ResourceContext also provides support for manually
* acquiring and releasing resources.
*
* @see org.apache.beehive.controls.api.context.ResourceContext.ResourceEvents
* @see org.apache.beehive.controls.api.context.Context
* @see org.apache.beehive.controls.api.events.EventHandler
*/
public interface ResourceContext
{
/**
* The acquire method allows a Control implementation to manually request acquisition.
* This is useful in contexts where the control needs access to associated resources
* from outside the scope of an operation. If invoked when the control has not currently
* acquired resources, the onAcquire event will be delivered to the control and it will
* be registered in the current resource scope as holding resources. If the control has
* previously acquired resources in the current resource scope, then calling acquire()
* will have no effect.
*/
public void acquire();
/**
* The release method allows a Control implement to manually release resources immediately,
* instead of waiting until the end of the current resource scope. If invoked when the
* control has currently acquired resources, the onRelease event will be delivered immediately
* and the control will no longer be in the list of controls holding resources in the current
* resource scope. If the control has not previously acquired resources, then calling
* release() will have no effect.
*/
public void release();
/**
* The hasResources method returns true if the control has currently acquired resources,
* false otherwise.
*/
public boolean hasResources();
/**
* The ResourceEvents interface defines the resource events delivered by a ResourceContext
* provider.
*/
@EventSet
public interface ResourceEvents
{
/**
* The onAcquire event will be delivered by a ResourceContext provider to the
* Control implementation <b>before</b> any operation on the control is invoked within
* the resource scope associated with the provider and its associated container. This
* provides the opportunity for the implementation instance to obtain any resource it
* uses to provide its services.
*/
public void onAcquire();
/**
* The onRelease event will be delivered by a ResourceContext provider to the
* Control implementation <b>immediately before</b> before the end of the resource
* scope associated with the provider and its associated container. This provides
* the opportunity for the implementation instance to relinquish any resources it
* obtained during <i>onAcquire</i> event handling.
*/
public void onRelease();
}
/**
* Registers a listener that implements the ResourceEvents interface for the ResourceContext.
*/
public void addResourceEventsListener(ResourceEvents resourceListener);
/**
* Unregisters a listener that implements the ResourceEvents interface for the ResourceContext.
*/
public void removeResourceEventsListener(ResourceEvents resourceListener);
}

View File

@ -1,34 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.events;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* The Client annotation type is used to mark fields in a Control implementation class
* that define client event proxies.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface Client
{
}

View File

@ -1,50 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.events;
import java.lang.reflect.InvocationTargetException;
import org.apache.beehive.controls.api.context.ControlContainerContext;
import org.apache.beehive.controls.api.context.ControlHandle;
import org.apache.beehive.controls.api.context.ControlThreadContext;
/**
* The EventDispatchHelper class is a simple implementation of the EventDispatcher interface
* that is suitable for use <b>inside</b> the execution context of a control container. It
* assumes that you are already running inside the target container instance, and all that is
* required is the correct routing of the event to the correct control.
*/
public class EventDispatchHelper implements EventDispatcher
{
public Object dispatchEvent(ControlHandle target, EventRef event, Object [] args)
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException
{
//
// Obtain the current active control container context
//
ControlContainerContext context = ControlThreadContext.getContext();
if (context == null)
throw new IllegalStateException("No active control container context");
//
// Dispatch the event using it.
//
return context.dispatchEvent(target, event, args);
}
}

View File

@ -1,47 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.events;
import java.lang.reflect.InvocationTargetException;
import org.apache.beehive.controls.api.context.ControlHandle;
/**
* The EventDispatcher interface defines the method signature that a container supporting
* the external dispatch of Control events would implement.
*/
public interface EventDispatcher
{
/**
* Dispatches a Control event to a target control.
* @param target the target control
* @param event the event to deliver to the control
* @param args the parameters to the control event
* @throws IllegalAccessException the underlying event method is not accessible due to
* access control.
* @throws IllegalArgumentException the target is not valid, the event is not a valid event
* type for the requested target, or the argument types do not match the event
* signature.
* @throws InvocationTargetException wraps any exception thrown by the underlying event
* handler.
*/
public Object dispatchEvent(ControlHandle target, EventRef event, Object [] args)
throws IllegalAccessException, IllegalArgumentException,
InvocationTargetException;
}

View File

@ -1,42 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.events;
import java.rmi.RemoteException;
import org.apache.beehive.controls.api.context.ControlHandle;
/**
* The EventDispatcherRemote interface defines the event dispatch signature when event
* dispatching is happening via RMI.
*
* @see org.apache.beehive.controls.api.events.EventDispatcher
*/
public interface EventDispatcherRemote
{
/**
* Dispatches a Control event to a target control.
* @param target the target control
* @param event the event to deliver to the control
* @param args the parameters to the control event
* @throws RemoteException wraps any exception thrown during event dispatch
*/
public Object dispatchEvent(ControlHandle target, EventRef event, Object [] args)
throws RemoteException;
}

View File

@ -1,53 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.events;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* The EventHandler annotation type is used to mark a method that provides the event handler
* implementation for a Control event.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface EventHandler
{
/**
* The field name of the Java control event source. This must be an @Control field declared
* on the class defining the event handler method (or on a superclass if the field is not
* declared to be private).
*/
String field();
/**
* The EventSet interface that declares the event. This must be a valid EventSet interface
* associated with the control type of the <code>field</code> member.
*/
Class eventSet();
/**
* The name of the handled event. This must be the name of a method declared on the EventSet
* interface referenced by the <code>eventSet</code> member. The annotated method must have
* an event signature that <b>exactly</b> matches one of the event methods with this name.
*/
String eventName();
}

View File

@ -1,255 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.events;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.WeakHashMap;
/**
* The EventRef class represents a reference to a specific Control event. EventRefs can
* be used to fire external events into a Control, in contexts where the event source may
* not share the associated EventSet class instance with the event target, or even have
* access to the EventSet class itself.
* <p>
* It is roughly equivalent to the java.lang.reflect.Method object that refers to a method
* on an EventSet interface, but has several additional properties:
* <ul>
* <li>It is serializable, so can be persisted/restored or passed across the wire</li>
* <li>It supports materializing the EventRef back to a Method reference in a way that allows
* EventRefs to be passed across class loaders</li>
* <li>It can be constructed in contexts where a reference to the actual EventSet class might
* not be available (using a String event descriptor format to describe events)</li>
* </ul>
*/
public class EventRef implements java.io.Serializable
{
//
// Static helper map to go from a primitive type to the type descriptor string
//
static private HashMap<Class,String> _primToType = new HashMap<Class,String>();
static
{
_primToType.put(Integer.TYPE, "I");
_primToType.put(Boolean.TYPE, "Z");
_primToType.put(Byte.TYPE, "B");
_primToType.put(Character.TYPE, "C");
_primToType.put(Short.TYPE, "S");
_primToType.put(Long.TYPE, "J");
_primToType.put(Float.TYPE, "F");
_primToType.put(Double.TYPE, "D");
_primToType.put(Void.TYPE, "V");
}
/**
* Constructs a new EventRef based upon a Method reference. The input method must be one
* that is declared within a Control EventSet interface.
* @param eventMethod the Method associated with the event
*/
public EventRef(Method eventMethod)
{
_method = eventMethod;
_descriptor = computeEventDescriptor(eventMethod);
}
/**
* Constructs a new EventRef using an event descriptor string. The format of this string
* is:
* <pre>
* <eventSet>.<eventName><eventDescriptor>
* </pre>
* where <i>eventSet</i> refers to the fully qualified name of the EventSet class,
* <i>eventName</i> refers to the name of the event Method, and <i>eventDescriptor</i>
* describes the event argument and return types using the method descriptor format
* defined in the Java Language Specification.
* <p>
* For example, given the following EventSet interface:
* <pre>
* <sp>@ControlInterface
* public interface MyControl
* {
* <sp>@EventSet
* public interface MyEvents
* {
* public String myEvent(int arg0, Object arg2);
* }
* }
* </pre>
* the eventDescriptor for myEvent would be:
* <pre>
* MyControl.MyEvents.myEvent(ILjava/lang/Object;)Ljava/lang/String;
* </pre>
* @param eventDescriptor the event descriptor string associated with the event
*/
public EventRef(String eventDescriptor)
{
_descriptor = eventDescriptor;
}
/**
* Returns the event descriptor string associated with the EventRef.
* @param controlInterface the ControlInterface
*/
public String getEventDescriptor(Class controlInterface)
{
//
// NOTE: The input controlInterface is currently unused, but included to
// enable downstream optimization of serialization representation. See the
// OPTIMIZE comment below for more details. If implemented, the interface
// is needed to reverse the transformation from a hash back to a method or
// descriptor.
//
if (_descriptor == null)
_descriptor = computeEventDescriptor(_method);
return _descriptor;
}
/**
* Helper method that computes the event descriptor sting for a method
*/
private String computeEventDescriptor(Method method)
{
StringBuilder sb = new StringBuilder();
// Add event class and method name
sb.append(method.getDeclaringClass().getName());
sb.append(".");
sb.append(method.getName());
// Add event arguments
Class [] parms = method.getParameterTypes();
sb.append("(");
for (int i = 0; i < parms.length; i++)
appendTypeDescriptor(sb, parms[i]);
sb.append(")");
// Add event return type
appendTypeDescriptor(sb, method.getReturnType());
return sb.toString();
}
/**
* Helper method that appends a type descriptor to a StringBuilder. Used
* while accumulating an event descriptor string.
*/
private void appendTypeDescriptor(StringBuilder sb, Class clazz)
{
if (clazz.isPrimitive())
sb.append(_primToType.get(clazz));
else if (clazz.isArray())
sb.append(clazz.getName().replace('.','/'));
else
{
sb.append("L");
sb.append(clazz.getName().replace('.','/'));
sb.append(";");
}
}
/**
* Returns the event Method associated with this EventRef.
*/
public Method getEventMethod(Class controlInterface)
{
//
// If we already hold a method reference and its loader matches up with the input
// interface, then just return it.
//
if (_method != null &&
_method.getDeclaringClass().getClassLoader().equals(controlInterface.getClassLoader()))
return _method;
//
// Otherwise, obtain the mapping from descriptors to methods, and use it to
// convert back to a method.
//
String eventDescriptor = getEventDescriptor(controlInterface);
HashMap<String,Method> descriptorMap = getDescriptorMap(controlInterface);
if (!descriptorMap.containsKey(eventDescriptor))
{
throw new IllegalArgumentException("Control interface " + controlInterface +
" does not contain an event method that " +
" corresponds to " + eventDescriptor);
}
return descriptorMap.get(eventDescriptor);
}
/**
* A WeakHashMap used to cache the event descriptor-to-Method mapping for control
* interfaces.
*/
static private WeakHashMap<Class, HashMap<String,Method>> _descriptorMaps =
new WeakHashMap<Class, HashMap<String,Method>>();
private HashMap<String,Method> getDescriptorMap(Class controlInterface)
{
//
// If the local cache has the mapping, then return it.
//
HashMap<String,Method> descMap = _descriptorMaps.get(controlInterface);
if (descMap == null)
{
//
// Compute the mapping from event descriptors to event methods, using reflection
//
descMap = new HashMap<String, Method>();
Class [] innerClasses = controlInterface.getClasses();
for (int i = 0; i < innerClasses.length; i++)
{
if (!innerClasses[i].isInterface() ||
!innerClasses[i].isAnnotationPresent(EventSet.class))
continue;
Method [] eventMethods = innerClasses[i].getMethods();
for (int j = 0; j < eventMethods.length; j++)
descMap.put(computeEventDescriptor(eventMethods[j]), eventMethods[j]);
}
_descriptorMaps.put(controlInterface, descMap);
}
return descMap;
}
/**
* Two EventRefs are equal if the method descriptor string associated with them is equal
*/
public boolean equals(Object obj)
{
if (obj == null || !(obj instanceof EventRef))
return false;
return _descriptor.equals(((EventRef)obj)._descriptor);
}
public String toString()
{
return "EventRef: " + _descriptor;
}
//
// OPTIMIZE: A more efficient internal representation for serialization/wire purposes
// would be to compute a hash of the descriptor string (ala RMI opnums), that could be
// reconstituted on the other end, given a candidate ControlInterface. The public APIs
// are structured to support this downstream optimization.
//
private String _descriptor;
transient private Method _method;
}

View File

@ -1,80 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.events;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* The EventSet annotation type is used to mark an interface that defines a group of events
* associated with a Java Control. By convention, event interfaces are defined as inner
* classes on the Java Control public interface. Each method defined within a
* event interface indicates an event that can be delivered by the control.
* <p>
* Here is a simple example:
* <code><pre>
* public interface MyControl extends org.apache.beehive.controls.api.Control
* {
* <sp>@EventSet
* public interface MyEvents
* {
* public void anEvent();
* }
*
* ...
* }
* </pre></code>
* This will declare an event interface named <code>MyEvents</code> that declares a single
* event: <code>anEvent</code>
*
* The declaration of an EventSet for a control also means that the associated Control
* JavaBean will have listener registration/deregistration APIs. The name of these
* APIs will be <i>add/remove<EventSetName>Listener</i>, and the argument will be an
* listener instance that implements the EventSet interface.
* <p>
* The above example would result in the following APIs on <code>MyControlBean</code>
*
* <code><pre>
* public class MyControlBean implements MyControl
* {
* ...
* public void addMyEventsListener(MyEvents listener) { ... }
* public void removeMyEventsListener(MyEvents listener) { ... }
* </pre></code>
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface EventSet
{
/**
* Defines whether the events defined by the interface are unicast events. A unicast
* event set may have only a single listener registered to receive events for any
* given bean instance. Any attempt to register additional listeners will result in
* a <code>java.util.TooManyListenersException</code> being thrown by the event
* listener registration method.
* <p>
* If an event set provides multicast support (the default), then it may only declare
* event methods that have a <code>void</code> return type. Unicast event sets may
* support event return values, that will be provided by the (single) registered
* listener.
*/
public boolean unicast() default false;
}

View File

@ -1,46 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.events;
import java.rmi.RemoteException;
import org.apache.beehive.controls.api.context.ControlHandle;
/**
* The RemoteEventDispatcher interface defines the method signature that a container supporting
* the external dispatch of Control events would implement if events can be dispatched using RMI.
*/
public interface RemoteEventDispatcher
{
/**
* Dispatches a Control event to a target control.
* @param target the target control
* @param event the event to deliver to the control
* @param args the parameters to the control event
* @throws IllegalAccessException the underlying event method is not accessible due to
* access control.
* @throws IllegalArgumentException the target is not valid, the event is not a valid event
* type for the requested target, or the argument types do not match the event
* signature.
* @throws InvocationTargetException wraps any exception thrown by the underlying event
* handler.
*/
public Object dispatchEvent(ControlHandle target, EventRef event, Object [] args)
throws RemoteException;
}

View File

@ -1,44 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.packaging;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
/**
* The FeatureInfo annotation type defines a JSR-175 syntax for annotating a Control to
* provide BeanInfo FeatureDescriptor information for the bean, its properties, methods,
* or events.
* <p>
* The elements of FeatureInfo correspond 1-to-1 with the information exposed by the
* <code>java.beans.FeatureDescriptor</code> class.
*
* @see java.beans.FeatureDescriptor
*/
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface BeanInfo
{
/**
* The NoCustomizer class can be used as the value of the customizerClass attribute to
* indicate that the bean has no customizer.
*/
static public class NoCustomizer {}
public Class customizerClass() default NoCustomizer.class;
}

View File

@ -1,39 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.packaging;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
/**
* The EventSetInfo annotation type defines a JSR-175 syntax for annotating a Control
* property declaration to provide java.beans.EventSetDescriptor information. Generic
* feature information is defined using the <code>FeatureInfo</code> annotation type
* <p>
* The elements of EventStInfo correspond 1-to-1 with the information exposed by the
* <code>java.beans.EventSetDescriptor</code> class.
*
* @see java.beans.EventSetDescriptor
*/
@Target({ElementType.TYPE}) // appears on EventSet interface declaration
public @interface EventSetInfo
{
public boolean isUnicast() default false; // single listener model
public boolean isDefault() default true; // is the default event set
}

View File

@ -1,37 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.packaging;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
/**
* The FeatureAttribute annotation type defines a JSR-175 syntax for specifying JavaBean
* FeatureDescriptor attributes associated with a Control.
*
* @see org.apache.beehive.controls.api.packaging.FeatureInfo
*/
public @interface FeatureAttribute
{
/* Specifies the feature attribute name */
public String name();
/* Specifies the feature attribute value */
public String value();
}

View File

@ -1,44 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.packaging;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
/**
* The FeatureInfo annotation type defines a JSR-175 syntax for annotating a Control to
* provide BeanInfo FeatureDescriptor information for the bean, its properties, methods,
* or events.
* <p>
* The elements of FeatureInfo correspond 1-to-1 with the information exposed by the
* <code>java.beans.FeatureDescriptor</code> class.
*
* @see java.beans.FeatureDescriptor
*/
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface FeatureInfo
{
public String displayName() default ""; // default: use reflection name
public String name() default ""; // default: use reflection name
public String shortDescription() default "";
public boolean isExpert() default false;
public boolean isHidden() default false;
public boolean isPreferred() default false;
public FeatureAttribute [] attributes() default {};
}

View File

@ -1,38 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.packaging;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
/**
* The ManifestAttribute annotation type defines a JSR-175 syntax for specifying JAR
* manifest attributes associated with a control type. The Beehive Controls packaging
* support will process these annotation during the construction of a JAR file that
* contains Controls.
*/
@Target({ElementType.TYPE})
public @interface ManifestAttribute
{
/* Specifies the manifest attribute name */
public String name();
/* Specifies the manifest attribute value */
public String value();
}

View File

@ -1,35 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.packaging;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
/**
* The ManifestAttributes annotation type enables a set of manifest attributes attributes
* to be defined for a given control type.
*
* @see org.apache.beehive.controls.api.packaging.ManifestAttribute
*/
@Target({ElementType.TYPE})
public @interface ManifestAttributes
{
/* Specifies the set of ManifestAttribute annotation values */
public ManifestAttribute [] value();
}

View File

@ -1,49 +0,0 @@
package org.apache.beehive.controls.api.packaging;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
import java.beans.PropertyEditor;
/**
* The PropertyInfo annotation type defines a JSR-175 syntax for annotating a Control
* property declaration to provide java.beans.PropertyDescriptor information. Generic
* feature information is defined using the <code>FeatureInfo</code> annotation type
* <p>
* The elements of PropertyInfo correspond 1-to-1 with the information exposed by the
* <code>java.beans.PropertyDescriptor</code> class.
*
* @see java.beans.PropertyDescriptor
*/
@Target({ElementType.METHOD}) // appears on PropertySet method declaration (i.e. properties)
public @interface PropertyInfo
{
/**
* The NoEditor class can be used as the value of the editorClass attribute to
* indicate that the property has no editor
*/
static public class NoEditor {};
public boolean bound() default false; // Sends PropertyChange events
public boolean constrained() default false; // Sends VetoableChange events
public Class editorClass() default NoEditor.class; // default == no editor
}

View File

@ -1,292 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.properties;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.annotation.Inherited;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import org.apache.beehive.controls.api.bean.ControlBean;
import org.apache.beehive.controls.api.bean.ControlExtension;
import org.apache.beehive.controls.api.bean.ControlInterface;
/**
* The AnnotatedElementMap represents a read-only PropertyMap where property values are
* derived from Java 5.0 (JSR-175) annotations.
*/
public class AnnotatedElementMap
extends BaseMap
implements PropertyMap,java.io.Serializable
{
/**
* Creates a new PropertyMap that is initialized based upon the type and annotations
* associated with an AnnotatedElement.
*/
public AnnotatedElementMap(AnnotatedElement annotElem)
{
if (annotElem instanceof Class)
setMapClass((Class)annotElem);
else if (annotElem instanceof Field)
setMapClass(((Field)annotElem).getType());
else if (annotElem instanceof Method)
{
Class mapClass = getMethodMapClass((Method)annotElem);
setMapClass(mapClass);
}
else
throw new IllegalArgumentException("Unsupported element type: " + annotElem.getClass());
_annotElem = annotElem;
}
// For methods, make sure we find a declaring class that is a valid
// map class. For extended callback methods, we need to walk up a bit
// further in the hierarchy.
Class getMethodMapClass(Method method) {
Class origMapClass = method.getDeclaringClass();
Class mapClass = origMapClass;
while (mapClass != null && !isValidMapClass(mapClass)) {
mapClass = mapClass.getDeclaringClass();
}
if (mapClass == null) {
mapClass = origMapClass;
}
return mapClass;
}
boolean isValidMapClass(Class mapClass) {
if (ControlBean.class.isAssignableFrom(mapClass))
{
return true;
}
else
{
if (mapClass.isAnnotation() ||
mapClass.isAnnotationPresent(ControlInterface.class) ||
mapClass.isAnnotationPresent(ControlExtension.class)) {
return true;
}
}
return false;
}
/**
* Sets the property specifed by 'key' within this map.
*/
public void setProperty(PropertyKey key, Object value)
{
throw new IllegalStateException("AnnotatedElementMap is a read-only PropertyMap");
}
/**
* Returns the property value specified by 'key' within this map.
*/
public Object getProperty(PropertyKey key)
{
if (!isValidKey(key))
throw new IllegalArgumentException("Key " + key + " is not valid for " + _mapClass);
//
// Look for the property value on the associated annotated element
//
Class propertySet = key.getPropertySet();
Annotation annot = _annotElem.getAnnotation(propertySet);
if (annot != null)
return key.extractValue(annot);
//
// If the property supports inheritance and the annotated element is an interface,
// then we'll search up the ControlInheritance/Extension hierachy to see if it is
// provided higher up the chain.
//
if (propertySet.isAnnotationPresent(Inherited.class) && _annotElem instanceof Class)
{
Class controlIntf = (Class)_annotElem;
do
{
Class [] superIntfs = controlIntf.getInterfaces();
controlIntf = null;
for (int i = 0; i < superIntfs.length; i++)
{
if (superIntfs[i].isAnnotationPresent(ControlInterface.class) ||
superIntfs[i].isAnnotationPresent(ControlExtension.class))
{
controlIntf = superIntfs[i];
annot = controlIntf.getAnnotation(propertySet);
if (annot != null)
return key.extractValue(annot);
}
}
}
while (controlIntf != null);
}
//
// Call up to superclass for delegation / default value
//
return super.getProperty(key);
}
/**
* Returns true if the PropertyMap contains one or more values for the specified
* PropertySet, false otherwise
*/
public boolean containsPropertySet(Class<? extends Annotation> propertySet)
{
if (_annotElem.isAnnotationPresent(propertySet))
return true;
//
// Call up to superclass for delegation
//
return super.containsPropertySet(propertySet);
}
/**
* Returns the AnnotatedElement used for PropertyMap values.
*/
public AnnotatedElement getAnnotatedElement()
{
return _annotElem;
}
/**
* Returns a String version of method argument lists based upon the method argument types
*/
private String getMethodArgs(Method m)
{
StringBuffer sb = new StringBuffer();
Class [] argTypes = m.getParameterTypes();
for (int i = 0; i < argTypes.length; i++)
{
if (i != 0) sb.append(",");
sb.append(argTypes[i].toString());
}
return sb.toString();
}
/**
* Overrides the standard Serialization writeObject method to compute and store the element
* information in a serializable form.
*/
private void writeObject(java.io.ObjectOutputStream out) throws IOException
{
//
// When serializing, compute sufficient information about the annotated element to
// allow it to be reassociated later in readObject
//
if (_annotElem instanceof Class)
{
_elemClass = (Class)_annotElem;
_elemDesc = null; // non required
}
else if (_annotElem instanceof Field)
{
Field f = (Field)_annotElem;
_elemClass = f.getDeclaringClass();
_elemDesc = f.getName();
}
else if (_annotElem instanceof Method)
{
Method m = (Method)_annotElem;
_elemClass = m.getDeclaringClass();
_elemDesc = m.getName() + "(" + getMethodArgs(m) + ")";
}
out.defaultWriteObject();
}
/**
* Overrides the standard Serialization readObject implementation to reassociated with the
* target AnnotatedElement after deserialization.
*/
private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException
{
in.defaultReadObject();
if (_elemDesc == null) // element is a Class
_annotElem = _elemClass;
else
{
int argsIndex = _elemDesc.indexOf('(');
if (argsIndex < 0) // element is a Field
{
try
{
_annotElem = _elemClass.getDeclaredField(_elemDesc);
}
catch (NoSuchFieldException nsfe)
{
throw new IOException("Unable to locate field " + nsfe);
}
}
else // element is a method
{
String methodName = _elemDesc.substring(0, argsIndex);
if (_elemDesc.charAt(argsIndex+1) == ')')
{
// At least handle the null args case quickly
try
{
_annotElem = _elemClass.getDeclaredMethod(methodName, new Class [] {});
}
catch (NoSuchMethodException nsme)
{
throw new IOException("Unable to locate method " +_elemDesc);
}
}
else
{
// Linear search for the rest :(
String methodArgs = _elemDesc.substring(argsIndex+1, _elemDesc.length()-1);
Method [] methods = _elemClass.getDeclaredMethods();
for (int i = 0; i < methods.length; i++)
{
if (methods[i].getName().equals(methodName) &&
getMethodArgs(methods[i]).equals(methodArgs))
{
_annotElem = methods[i];
break;
}
}
if (_annotElem == null)
{
throw new IOException("Unable to locate method " + _elemDesc);
}
}
}
}
}
// The AnnotatedElement upon which this PropertyMap is based. This is marked transient,
// because many Reflection types are not Serializable.
transient private AnnotatedElement _annotElem;
private Class _elemClass; // Class associated with the annotated element
private String _elemDesc; // Description of the element
}

View File

@ -1,217 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.properties;
import java.lang.annotation.Annotation;
import org.apache.beehive.controls.api.bean.ControlBean;
import org.apache.beehive.controls.api.bean.ControlExtension;
import org.apache.beehive.controls.api.bean.ControlInterface;
import org.apache.beehive.controls.api.bean.ExternalPropertySets;
/**
* The BaseMap class provide an abstract base PropertyMap class from which other
* concrete PropertyMap implementation can derive. It contains some common code
* (such as property key validation and the implementation of the base delegation model)
* that is generically useful.
*/
abstract public class BaseMap implements PropertyMap, java.io.Serializable
{
/**
* Sets the PropertySet or Control interface associated with this map. Only properties
* declared by the PropertySet or one of the PropertySets on the Control interface may
* be used with this map.
*/
protected void setMapClass(Class mapClass)
{
//
// If the provided map class is a ControlBean type, then locate associated control
// interface or extension that defines properties.
//
if (ControlBean.class.isAssignableFrom(mapClass))
{
Class [] intfs = mapClass.getInterfaces();
for (int i = 0; i < intfs.length; i++)
{
if (intfs[i].isAnnotationPresent(ControlInterface.class) ||
intfs[i].isAnnotationPresent(ControlExtension.class))
{
mapClass = intfs[i];
break;
}
}
}
else
{
if (!mapClass.isAnnotation() &&
!mapClass.isAnnotationPresent(ControlInterface.class) &&
!mapClass.isAnnotationPresent(ControlExtension.class))
throw new IllegalArgumentException(mapClass+" must be Control or annotation type");
}
_mapClass = mapClass;
}
/**
* Returns the PropertySet or Control interface class associated with the PropertyMap.
*/
public Class getMapClass() { return _mapClass; }
/**
* Checks to see if the provided class is a control or property set interface that is
* compatible with the local PropertyMap.
*/
private boolean isCompatibleClass(Class checkClass)
{
//
// If the check class is equal to or a super-interface of the map class, then
// they are compatible.
//
if (_mapClass.isAssignableFrom(checkClass))
return true;
//
// If the check class is a property set declared by the map class or a super interface
// of the map class, then they are compatible.
//
if (checkClass.isAnnotationPresent(PropertySet.class))
{
Class declaringClass = checkClass.getDeclaringClass();
// External property sets are always compatible.
// TODO: Could do a more extensive check..
if (declaringClass == null)
return true;
if (declaringClass.isAssignableFrom(_mapClass))
return true;
}
//
// If the map class is a property set declared by the check class or a super interface
// of the check class, then they are compatible. This is the inverse of the last check,
// and happens e.g. when a programatically instantiated control w/ an initial property
// map needs to delegate to the control interface's property map.
//
if (_mapClass.isAnnotationPresent(PropertySet.class))
{
Class declaringClass = _mapClass.getDeclaringClass();
if (declaringClass != null &&
declaringClass.isAssignableFrom(checkClass))
return true;
// External property sets have no declaring class
if (declaringClass == null)
{
ExternalPropertySets eps = (ExternalPropertySets) checkClass.getAnnotation(ExternalPropertySets.class);
if (eps != null)
{
Class[] propSets = eps.value();
if (propSets != null)
{
for (Class ps : propSets)
{
if (_mapClass.equals(ps))
return true;
}
}
}
}
}
return false;
}
/**
* Checks to ensure that the provided key is a valid key for this PropertyMap
*/
protected boolean isValidKey(PropertyKey key)
{
return isCompatibleClass(key.getPropertySet());
}
/**
* Sets a delegate base property map from which values will be derived if not found within
* the local property map.
*/
public synchronized void setDelegateMap(PropertyMap delegateMap)
{
if (!isCompatibleClass(delegateMap.getMapClass()))
throw new IllegalArgumentException("The delegate map type (" + delegateMap.getMapClass() + " is an incompatible type with " + _mapClass);
_delegateMap = delegateMap;
}
/**
* Returns a delegate base property map from which values will be derived if not found within
* the local property map.
*/
public PropertyMap getDelegateMap()
{
return _delegateMap;
}
/**
* Returns the property value specified by 'key' within this map.
*/
public Object getProperty(PropertyKey key)
{
//
// Delegate up to any parent map
//
if (_delegateMap != null)
return _delegateMap.getProperty(key);
//
// If neither found a value, return the default value
//
return key.getDefaultValue();
}
/**
* Returns true if the PropertyMap contains one or more values for the specified
* PropertySet, false otherwise.
*/
public boolean containsPropertySet(Class<? extends Annotation> propertySet)
{
//
// Defer to any delegate map
//
if (_delegateMap != null)
return _delegateMap.containsPropertySet(propertySet);
return false;
}
/**
* Returns a PropertySet proxy instance that derives its data from the contents of
* the property map. Will return null if the PropertyMap does not contain any properties
* associated with the specified PropertySet.
*/
public <T extends Annotation> T getPropertySet(Class<T> propertySet)
{
if (!containsPropertySet(propertySet))
return null;
return PropertySetProxy.getProxy(propertySet, this);
}
Class _mapClass; // associated Control or PropertySet class
PropertyMap _delegateMap; // wrapped PropertyMap (or null)
}

View File

@ -1,40 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.properties;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Base properties that are present intrinsically on all controls.
*/
@PropertySet
@Target( {ElementType.TYPE, ElementType.FIELD} )
@Retention( RetentionPolicy.RUNTIME )
public @interface BaseProperties
{
/**
* Fully qualified classname of the implementation class for the control. If null,
* the default algorithm for * determining the implementation class will be used --
* basically, adding "Impl" to the control interface name.
*/
String controlImplementation() default "";
}

View File

@ -1,186 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.properties;
import java.lang.annotation.Annotation;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
/**
* The BeanPropertyMap class represents a collection of property values where properties are
* stored in a local HashMap.
*/
public class BeanPropertyMap extends BaseMap implements PropertyMap,java.io.Serializable
{
private static final HashMap _primToObject = new HashMap();
static
{
_primToObject.put(Integer.TYPE, Integer.class);
_primToObject.put(Long.TYPE, Long.class);
_primToObject.put(Short.TYPE, Short.class);
_primToObject.put(Byte.TYPE, Byte.class);
_primToObject.put(Float.TYPE, Float.class);
_primToObject.put(Double.TYPE, Double.class);
_primToObject.put(Character.TYPE, Character.class);
_primToObject.put(Boolean.TYPE, Boolean.class);
}
/**
* Creates an empty BeanPropertyMap associated with the specific Control public
* interface, PropertySet, or annotation type.
*/
public BeanPropertyMap(Class mapClass)
{
setMapClass(mapClass);
}
/**
* Creates a BeanPropertyMap that wraps another PropertyMap. Any changes via setProperty
* will be maintained locally on the constructed map, but getProperty will delegate to the
* base PropertyMap for properties not set locally.
*/
public BeanPropertyMap(PropertyMap map)
{
setMapClass(map.getMapClass());
setDelegateMap(map);
}
/**
* Creates a BeanPropertyMap where default values are derived from a single annotation
* type instance. This can be used to create a map from a property getter return value,
* to modify element values.
*/
public <T extends Annotation> BeanPropertyMap(T annot)
{
// If the annotation value is actually a PropertySetProxy, then unwrap it and use
// the standard delegation model
try
{
Object handler = Proxy.getInvocationHandler(annot);
if (handler instanceof PropertySetProxy)
{
PropertySetProxy psp = (PropertySetProxy)handler;
setMapClass(psp.getPropertySet());
setDelegateMap(psp.getPropertyMap());
return;
}
}
catch (IllegalArgumentException iae) {} // regular annotation
_annot = annot;
setMapClass(annot.getClass());
}
/**
* Sets the property specifed by 'key' within this map.
*/
public synchronized void setProperty(PropertyKey key, Object value)
{
if (!isValidKey(key))
throw new IllegalArgumentException("Key " + key + " is not valid for " + getMapClass());
//
// Validate the value argument, based upon the property type reference by the key
//
Class propType = key.getPropertyType();
if (value == null)
{
if (propType.isPrimitive() || propType.isAnnotation())
throw new IllegalArgumentException("Invalid null value for key " + key);
}
else
{
if (propType.isPrimitive())
propType = (Class)_primToObject.get(propType);
if (!propType.isAssignableFrom(value.getClass()))
{
throw new IllegalArgumentException("Value class (" + value.getClass() +
") not of expected type: " + propType);
}
}
_properties.put(key, value);
_propertySets.add(key.getPropertySet());
}
/**
* Returns the property value specified by 'key' within this map.
*/
public Object getProperty(PropertyKey key)
{
if (!isValidKey(key))
throw new IllegalArgumentException("Key " + key + " is not valid for " + getMapClass());
//
// Check local properties first
//
if (_properties.containsKey(key))
return _properties.get(key);
//
// Return the value of the annotation type instance (if any)
//
if (_annot != null)
return key.extractValue(_annot);
//
// Call up to superclass, for delegation model / default value
//
return super.getProperty(key);
}
/**
* Returns true if the PropertyMap contains one or more values for the specified
* PropertySet, false otherwise
*/
public boolean containsPropertySet(Class<? extends Annotation> propertySet)
{
// If we have an annotation type instance and it matches up with the requested
// type, then return true
if (_annot != null && _annot.getClass().equals(propertySet))
return true;
if (_propertySets.contains(propertySet))
return true;
//
// Call up to superclass, for delegation model
//
return super.containsPropertySet(propertySet);
}
/**
* Returns the set of PropertyKeys that are locally set in this property map. Note:
* this <b>does not</b> include any properties that might be set as a result of
* property lookup delegation.
*/
public Set<PropertyKey> getPropertyKeys() { return _properties.keySet(); }
// local default annotation value, only set if annot constructor form is used
Annotation _annot;
// locally maintained property values
HashMap<PropertyKey,Object> _properties = new HashMap<PropertyKey,Object>();
// locally maintained PropertySets
HashSet<Class> _propertySets = new HashSet<Class>();
}

View File

@ -1,159 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.properties;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import org.apache.beehive.controls.api.ControlException;
/**
* The PropertyKey class represents a key that can be used to set a JSR-175 attribute member
* value within a <code>PropertyMap</code>.
*/
public class PropertyKey implements java.io.Serializable
{
/**
* This constructor takes the JSR-175 metadata interface that is associated with
* the contained attributes.
*/
public PropertyKey(Class<? extends Annotation> propertySet, String propertyName)
{
if (!propertySet.isAnnotation())
{
throw new IllegalArgumentException("Class " + propertySet + " is not a valid annotation type");
}
try
{
_getMethod = propertySet.getMethod(propertyName, (Class [])null);
_propertySet = propertySet;
_propertyName = propertyName;
_propertyType = _getMethod.getReturnType();
//
// Compute a hash code for the key instance that will be constant for all keys
// that reference the same interface/member combo
//
_hashCode = new String(propertySet.getName() + "." + propertyName).hashCode();
}
catch (NoSuchMethodException nsme)
{
throw new IllegalArgumentException(propertyName +
"is not a valid member of the metadata interface " + propertySet);
}
}
protected Method getMethod()
{
if (null == _getMethod)
{
try
{
_getMethod = _propertySet.getMethod(_propertyName, (Class [])null);
}
catch(NoSuchMethodException nsmEx)
{
// This can only happen if a PropertySet is incompatibly changed after
// serialization of a PropertyKey (since it is initially validated in
// the constructor).
throw new ControlException("Unable to locate PropertyKey accessor method", nsmEx);
}
}
return _getMethod;
}
/**
* Computes the default value for the value of this property key, or null if there
* is no defined default.
*/
public Object getDefaultValue()
{
// Query the accessor method for the default value
// This method will return 'null' if there is no defined default
return getMethod().getDefaultValue();
}
/**
* Extracts the value of the key from an Annotation instance
*/
/* package */ Object extractValue(Annotation annot)
{
try
{
return getMethod().invoke(annot, new Object [] {});
}
// TODO -- cleanup exception handling, property defining a PropertyException
catch (RuntimeException re) { throw re; }
catch (Exception e)
{
throw new RuntimeException("Unable to extract value for " + _propertyName, e);
}
}
public boolean equals(Object obj)
{
// fast success for static key declaration cases
if (this == obj)
return true;
// fast fail on obvious differences
if (obj == null || !(obj instanceof PropertyKey) || _hashCode != obj.hashCode())
return false;
// slower success on two equivalent keys constructed independently
PropertyKey keyObj = (PropertyKey)obj;
return _propertySet.equals(keyObj._propertySet) &&
_propertyName.equals(keyObj._propertyName);
}
public int hashCode() {
return _hashCode;
}
public String toString()
{
return "PropertyKey: " + _propertySet.getName() + "." + _propertyName;
}
public Class<? extends Annotation> getPropertySet() {
return _propertySet;
}
public String getPropertyName() {
return _propertyName;
}
public Class getPropertyType() {
return _propertyType;
}
public Annotation[] getAnnotations() {
return getMethod().getAnnotations();
}
Class<? extends Annotation> _propertySet;
String _propertyName;
Class _propertyType;
int _hashCode;
// WARNING: This field should never be accessed directly but instead via the getMethod()
// API. This ensures that the (transient) value is appropriately recomputed when necessary.
private transient Method _getMethod;
}

View File

@ -1,69 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.properties;
import java.lang.annotation.Annotation;
/**
* The PropertyMap interface represents a collection of ControlBean properties. Concrete
* implementations of this interface might derive property values from a local Map, Java 5.0
* annotations, external configuration, or other property sources.
*/
public interface PropertyMap
{
/**
* Returns the PropertySet or Control interface class associated with the PropertyMap.
*/
public Class getMapClass();
/**
* Sets a delegate base property map from which values will be derived if not found within
* the local property map.
*/
public void setDelegateMap(PropertyMap delegateMap);
/**
* Returns a delegate base property map from which values will be derived if not found within
* the local property map.
*/
public PropertyMap getDelegateMap();
/**
* Sets the property specifed by 'key' within this map.
*/
public void setProperty(PropertyKey key, Object value);
/**
* Returns the property value specified by 'key' within this map.
*/
public Object getProperty(PropertyKey key);
/**
* Returns true if the PropertyMap contains one or more values for the specified
* PropertySet, false otherwise
*/
public boolean containsPropertySet(Class<? extends Annotation> propertySet);
/**
* Returns a PropertySet proxy instance that derives its data from the contents of
* the property map. Will return null if the PropertyMap does not contain any properties
* associated with the specified PropertySet.
*/
public <T extends Annotation> T getPropertySet(Class<T> propertySet);
}

View File

@ -1,99 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.properties;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* The PropertySet annotation type is used to mark an interface that defines a set of
* properties that are associated with a Java Control. By convention, property sets
* are declared as an inner annotation types on the Java Control public interface.
* <p>
* Each member of the annotation type targeted by the <code>PropertySet</code> annotation
* will define a new property for the control.
* <p>
* Here is a simple example:
* <code><pre>
* public interface MyControl extends org.apache.beehive.controls.api.Control
* {
* <sp>@PropertySet
* public @interface MyProperties
* {
* public String aStringProperty();
* public int anIntProperty();
* ...
}
* }
* </pre></code>
* <p>
* A Java Control can have multiple property sets associated with it.
*/
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.ANNOTATION_TYPE})
public @interface PropertySet
{
/**
* The prefix member defines a prefix that will be used in all property setter/getter
* methods for properties in the <code>PropertySet</code>. It is necessary to specify
* a prefixes when a control interface has multiple property sets that contain
* properties with the same name.
* <p>
* The following code shows the basic conventions for setter/getter methods on a Java
* Control Bean:
* <code><pre>
* public void set&lt;prefix&gt;&lt;propertyName&gt;(&lt;propertyType&gt; value);
* public &lt;propertyType&gt; get&lt;prefix&gt;&lt;propertyName&gt;();
* </pre>/code>
* where <code>prefix</code> is the prefix member value, <code>propertyName</code> is
* the name of the declared property member, and <code>propertyType</code> is the
* type associated with the declared property member.
*/
String prefix() default "";
/**
* The externalConfig member defines whether properties in the set will be settable
* via external configuration.
*/
boolean externalConfig() default true;
/**
* The optional member specifies that this property set may optionally be associated
* with the control. Because there is no way to represent an 'unset' property value,
* optional properties will not expose a getter method to clients; a control
* implementation class can determine whether a property is/is not set, because the
* PropertySet query APIs on ControlBeanContext will return null if unset. For
* properties that are not optional, a PropertySet instance with all default values
* will be returned if unset.
*
* @see org.apache.beehive.controls.api.context.ControlBeanContext#getControlPropertySet
* @see org.apache.beehive.controls.api.context.ControlBeanContext#getMethodPropertySet
*/
boolean optional() default false;
/**
* The hasSetters member defines whether properties in the set will have programmatic
* setter methods.
*/
boolean hasSetters() default true;
}

View File

@ -1,139 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.properties;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* The PropertySetProxy class is a dynamic proxy {@link InvocationHandler} class that exposes the
* values held within a PropertyMap as an Object implementing an annotation type interface.
* <p>
* This enables properties resolved using the {@link PropertyMap}'s hiearchical resolution mechanism to
* be exposed to the client of the proxy in the same way that Java 5 annotations are
* exposed using raw Java reflection APIs. A proxy of this type should behave identically
* to the one returned from a call to <code>AnnotatedElement.getAnnotation()</code>, but backed
* by a richer, more dynamic resolution mechanism.
*
* @see java.lang.reflect.Proxy
* @see java.lang.reflect.InvocationHandler
* @see java.lang.reflect.AnnotatedElement#getAnnotation
* @see org.apache.beehive.controls.api.properties.PropertySet
* @see org.apache.beehive.controls.api.properties.PropertyMap
*/
public class PropertySetProxy <T extends Annotation> implements InvocationHandler
{
/**
* Creates a new proxy instance implementing the PropertySet interface and backed
* by the data from the property map.
*
* @param propertySet an annotation type that has the PropertySet meta-annotation
* @param propertyMap the PropertyMap containing property values backing the proxy
* @return proxy that implements the PropertySet interface
*/
public static <T extends Annotation> T getProxy(Class<T> propertySet, PropertyMap propertyMap)
{
assert propertySet != null && propertyMap != null;
if (!propertySet.isAnnotation())
throw new IllegalArgumentException(propertySet + " is not an annotation type");
return (T)Proxy.newProxyInstance(propertySet.getClassLoader(),
new Class [] {propertySet },
new PropertySetProxy(propertySet, propertyMap));
}
/**
* Private constructor, called only from the getProxy factory method
*/
private PropertySetProxy(Class<T> propertySet, PropertyMap propertyMap)
{
_propertySet = propertySet;
_propertyMap = propertyMap;
}
//
// InvocationHandler.invoke
//
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
// Handle cases where Object/Annotation methods are called on this
// proxy. We were getting null back from Annotation.annotationType.
Object value = null;
if (method.getDeclaringClass() == Object.class)
{
try {
if (method.getName().equals("getClass"))
{
value = _propertySet;
}
else
{
value = method.invoke(_propertyMap, args);
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
else if (method.getDeclaringClass() == Annotation.class &&
method.getName().equals("annotationType"))
{
value = _propertySet;
}
else
{
// Query the nested value in the property map
PropertyKey key = new PropertyKey(_propertySet, method.getName());
value = _propertyMap.getProperty(key);
// If the returned value is itself a PropertyMap (i.e. a nested annotation type),
// then wrap it in a PropertySetProxy instance before returning.
if (value instanceof PropertyMap)
{
PropertyMap propertyMap = (PropertyMap)value;
value = getProxy(propertyMap.getMapClass(), propertyMap);
}
}
return value;
}
/**
* Returns the PropertySet annotation type associated with the proxy
*/
public Class<T> getPropertySet() {
return _propertySet;
}
/**
* Returns the underlying PropertyMap containing the property values exposed by the
* proxy.
*/
public PropertyMap getPropertyMap() {
return _propertyMap;
}
private Class<T> _propertySet;
private PropertyMap _propertyMap;
}

View File

@ -1,46 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.versioning;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Used by the control author to specify the version (major.minor) of the control interface.
* Allowed on interfaces annotated with @ControlInterface. This version number
* is the basis for control versioning, and versioning constraints against it are enforced both at
* compile time and runtime.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface Version
{
/**
* Major version number, typically used to track significant functionality changes.
*/
int major();
/**
* Minor version number, typically used to track small internal changes/fixes. Version
* constraints default to ignoring the minor version number in their comparisons, but may
* be configured to specify a particular minor version.
*/
int minor() default 0;
}

View File

@ -1,56 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.versioning;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Specifies the minimum version of the control interface that this extension
* requires. Allowed on control extensions (interfaces annotated with
* <sp>@ControlExtension), and on control field declarations (fields annotated
* with @Control). The version requirement is enforced at compile time of
* extensions and control client, and at runtime when the appropriate control
* bean is classloaded.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.FIELD})
public @interface VersionRequired
{
/**
* The major version value required for this control extension or instance
* declaration to work. Any version number greater than or equal to this
* value will suffice, implying that this requirement is valid only when
* back compatibility is part of the contract when increasing the version
* number. Negative values mean that any major version is
* acceptable (in which case this annotation should probably just not be
* present).
*/
int major();
/**
* The minor version value required for this control extension or instance
* declaration to work. Any version number greater than or equal to this
* value will suffice. Negative values mean that any minor version is
* acceptable (the default case).
*/
int minor() default -1;
}

View File

@ -1,53 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.api.versioning;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Specifies the maximum version of the control interface that this implementation
* supports. Allowed on control implementations (interfaces annotated with
* <sp>@ControlImplementation). This version requirement is enforced at compile time
* of the implementation, and at runtime when the implementation is classloaded.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface VersionSupported
{
/**
* The major version of the control interface that this implementation
* supports. Any version number less than or equal to this value will suffice,
* implying that this constraint is only valid when backwards compatibility
* is part of the contract when increasing the version number. Negative
* values mean that any major version is acceptable (in which case this
* annotation should probably just not be
* present).
*/
int major();
/**
* The minor version of the control interface that this implementation
* supports. Any version number less than or equal to this value will suffice.
* Negative values mean that any minor version is acceptable (the default case).
*/
int minor() default -1;
}

View File

@ -1,64 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.assembly;
import org.apache.beehive.controls.api.assembly.ControlAssemblyContext;
import org.apache.beehive.controls.api.assembly.ControlAssemblyException;
import java.io.File;
import java.util.Map;
import java.util.Set;
/**
* A ControlAssemblyContext implementation supporting standard Enterprise app modules
*/
public class AppAssemblyContext
extends BaseAssemblyContext
implements ControlAssemblyContext.EntAppModule
{
public static class Factory
implements ControlAssemblyContext.Factory
{
public AppAssemblyContext newInstance( Class controlIntfOrExt,
Map<String,String> bindings,
Set<String> clients,
File moduleRoot,
String moduleName,
File srcOutputRoot )
throws ControlAssemblyException
{
return new AppAssemblyContext( controlIntfOrExt, bindings, clients,
moduleRoot, moduleName, srcOutputRoot );
}
}
protected AppAssemblyContext( Class controlIntfOrExt, Map<String,String> bindings,
Set<String> clients, File moduleRoot,
String moduleName, File srcOutputRoot )
throws ControlAssemblyException
{
super( controlIntfOrExt, bindings, clients, moduleRoot, moduleName, srcOutputRoot );
}
public File getApplicationXml()
{
return new File( getModuleDir(), "META-INF" + File.separator + "application.xml" );
}
}

View File

@ -1,268 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.assembly;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.Set;
import java.util.TreeSet;
import java.net.URL;
import java.net.URLClassLoader;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.FileSet;
import org.apache.beehive.controls.runtime.generator.apt.ControlClientManifest;
import org.apache.beehive.controls.api.assembly.ControlAssemblyException;
/**
* AssembleTask defines a custom ant task to perform control assembly.
* <p>
* The core assembly algorithm is documented and implemented in {@link Assembler}.
* <p>
* Required attributes:<br>
* <b>moduleDir</b>: path to the root of J2EE module on which to perform assembly.<br>
* <b>srcOutputDir</b>: path to the dir where control assemblers may output source files.
* It may be necessary to run additional build steps in order to process such files (for example,
* if an assembler outputs Java source code, that code may need to be compiled).<br>
* <b>contextFactoryClassname</b>: fully qualified classname of a factory class that implements
* {@link org.apache.beehive.controls.api.assembly.ControlAssemblyContext.Factory}. Typically this
* would depend on the type of module on which assembly is being run (EJB, webapp, etc). Different
* contexts will expose different APIs to control assemblers (making different descriptors available,
* etc).
* <p>
* Supported nested elements:<br>
* <b>classpath</b>: specifies the classpath that will be searched for control interfaces/implementations,
* control clients and control assemblers.<br>
* <b>fileset</b>: specifies the control client manifests that should be processed by this assembly call.<br>
* <p>
* An example usage of the AssembleTask in an ant build script (build.xml):
* <p>
<xmp>
<taskdef name="assemble" classname="org.apache.beehive.controls.runtime.assembly.AssembleTask"
classpathref="controls.dependency.path" onerror="report" />
<assemble moduleDir="${build.beans}"
srcOutputDir="${build.beansrc}"
contextFactoryClassname="org.apache.beehive.controls.runtime.assembly.EJBAssemblyContext$Factory">
<classpath>
<path refid="test.classpath"/>
<pathelement location="${build.beans}"/>
</classpath>
<fileset dir="${build.beans}">
<include name="**\*.controls.properties"/>
</fileset>
</assemble>
</xmp>
*/
public class AssembleTask extends Task
{
public AssembleTask()
{
// do nothing
}
public void setContextFactoryClassName(String contextFactoryClassName)
{
_contextFactoryClassName = contextFactoryClassName;
}
public void setModuleDir( File moduleDir )
{
_moduleDir = moduleDir;
}
public void setModuleName( String moduleName )
{
_moduleName = moduleName;
}
public void setSrcOutputDir( File srcOutputDir )
{
_srcOutputDir = srcOutputDir;
}
public void setBindingFile(File bindingFile)
{
_bindingFile = bindingFile;
}
public FileSet createFileset()
{
_clientManifestFileSet = new FileSet();
return _clientManifestFileSet;
}
// used to set classpath as an attribute
public void setClasspath(Path classpath)
{
_classPath = new Path(getProject());
_classPath.append(classpath);
}
// used to set classpath as a nested element
public Path createClasspath()
{
_classPath = new Path(getProject());
return _classPath;
}
public void execute()
{
validateAttributeSettings();
if (_clientManifestFileSet == null)
{
log("No input fileset specified, nothing to do.");
return;
}
// get list of input files as list of ControlRefs files
File filesetDir = _clientManifestFileSet.getDir(getProject());
String[] clientManifests = _clientManifestFileSet.
getDirectoryScanner(getProject()).getIncludedFiles();
if (clientManifests.length == 0)
{
log("Input fileset contained no files, nothing to do.");
return;
}
List<File> manifestFiles = new ArrayList<File>();
for ( String mf : clientManifests )
{
File f = new File(filesetDir, mf );
if (!f.exists())
{
log("File " + f.getAbsolutePath() +
" in input fileset does not exist.");
continue;
}
manifestFiles.add(f);
}
// REVIEW: nested control usage is handled poorly right now.
// Need to refine how we pick up control client manifests, especially
// for manifests inside control jars (instead of blindly scanning and
// including all manifests inside all jars, should base it on actual nested
// control usage as analyzed by starting at non-control clients).
try
{
// Build map of control types to assemble by scanning supplied manifests
Map<String,String> controlTypesToImpls = new HashMap<String,String>();
Map<String,Set<String>> controlTypesToClients =
new HashMap<String, Set<String>>();
for ( File mf : manifestFiles )
{
ControlClientManifest ccmf = new ControlClientManifest( mf );
String controlClient = ccmf.getControlClient();
List<String> controlTypes = ccmf.getControlTypes();
for ( String ct : controlTypes )
{
controlTypesToImpls.put( ct, ccmf.getDefaultImpl( ct ) );
Set<String> clients = controlTypesToClients.get( ct );
if (clients == null)
{
clients = new TreeSet<String>();
controlTypesToClients.put( ct, clients );
}
clients.add( controlClient );
}
}
// Build classloader to do loading
//
// TODO: The module dir should probably be in the classpath, since it seems reasonable
// for assemblers to want access to the classes in the module.
String[] classpaths = _classPath == null ? new String[0] : _classPath.list();
ClassLoader cl = buildClassLoader( classpaths, Assembler.class.getClassLoader() );
Assembler.assemble( _moduleDir, _moduleName, _srcOutputDir, _contextFactoryClassName,
controlTypesToImpls, controlTypesToClients, cl );
}
catch (Exception e)
{
e.printStackTrace();
throw new BuildException("Assembly failed.", e);
}
}
private void validateAttributeSettings() throws BuildException
{
if (_contextFactoryClassName == null)
throw new BuildException("The contextFactoryClassName attribute must be set");
if (_moduleDir == null)
throw new BuildException("The moduleDir attribute must be set");
if (_srcOutputDir == null)
throw new BuildException("The srcOutputDir attribute must be set");
}
private ClassLoader buildClassLoader( String[] paths, ClassLoader parentCL)
throws ControlAssemblyException
{
List list = new ArrayList();
for (int i=0; i<paths.length; i++)
{
try
{
File file = new File(paths[i]);
String filePath = file.getCanonicalPath();
// ending slash is important for URLs that represent directories
if (!filePath.toLowerCase().endsWith(".jar") &&
!filePath.endsWith("/") )
{
filePath += "/";
}
URL url = new URL("file:" + filePath);
list.add(url);
}
catch (IOException e)
{
throw new ControlAssemblyException("Unable to include path " +
paths[i] + " in classpath. Caught " +
e.getClass().getName() + " trying to form this path as a URL.", e);
}
}
URL[] urlArray = new URL[list.size()];
urlArray = (URL[])list.toArray(urlArray);
return new URLClassLoader(urlArray, parentCL);
}
// ant parameter values
protected String _contextFactoryClassName;
protected File _moduleDir;
protected String _moduleName;
protected File _srcOutputDir;
protected File _bindingFile;
protected Path _classPath;
protected FileSet _clientManifestFileSet;
}

View File

@ -1,119 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.assembly;
import org.apache.beehive.controls.api.bean.ControlImplementation;
import org.apache.beehive.controls.api.assembly.ControlAssemblyContext;
import org.apache.beehive.controls.api.assembly.ControlAssemblyException;
import org.apache.beehive.controls.api.assembly.ControlAssembler;
import org.apache.beehive.controls.api.assembly.DefaultControlAssembler;
import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.Set;
/**
* Helper class to execute assembly logic.
*/
public class Assembler
{
/**
* Executes basic assembly algorithm. For each control type & impl specified, query each impl for the presence
* of an assembler -- for each assembler present, build the specified ControlAssemblyContext implementation,
* create an instance of the assembler and execute it.
*
* @param moduleRoot dir root of the module
* @param moduleName name of the module
* @param srcOutputRoot dir where assemblers can output source files
* @param factoryName name of the ControlAssemblyContext factory to use
* @param controlTypeToImpl map of control type name to control impl for all control types to be assembled in this module
* @param controlTypeToClients map of control type name to a set of control clients (in this module) that use this type
* @param cl classloader used to load factories and assemblers
* @throws ControlAssemblyException
* @throws IOException
*/
public static void assemble( File moduleRoot,
String moduleName,
File srcOutputRoot,
String factoryName,
Map<String,String> controlTypeToImpl,
Map<String,Set<String>> controlTypeToClients,
ClassLoader cl )
throws ControlAssemblyException, IOException
{
if ( !moduleRoot.exists() || !srcOutputRoot.exists() )
throw new IOException( "Directories " + moduleRoot + " or " + srcOutputRoot + " don't exist!");
if ( factoryName == null )
throw new ControlAssemblyException( "Missing context factory names" );
if ( cl == null )
throw new ControlAssemblyException( "Must specify a classloader" );
ClassLoader origCL = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader( cl );
try
{
// Create the requested ControlAssemblyContext.Factory
Class factoryClass = cl.loadClass( factoryName );
ControlAssemblyContext.Factory factory = (ControlAssemblyContext.Factory)factoryClass.newInstance();
// Iterate over control types
Set<String> controlTypes = controlTypeToImpl.keySet();
for ( String ct : controlTypes )
{
// Search for applicable ControlAssemblers as specified on the control impls
String cImpl = controlTypeToImpl.get( ct );
Class cImplClass = cl.loadClass( cImpl );
ControlImplementation a = (ControlImplementation)cImplClass.getAnnotation(ControlImplementation.class);
if ( a == null )
throw new ControlAssemblyException( "Control implementation class=" + cImpl + " missing ControlImplementation annotation" );
// For each non-default ControlAssembler, create one and call it.
Class<? extends ControlAssembler> assemblerClass = a.assembler();
if ( !assemblerClass.equals(DefaultControlAssembler.class) )
{
ControlAssembler assembler = assemblerClass.newInstance();
Set<String> clients = controlTypeToClients.get( ct );
ControlAssemblyContext cac = factory.newInstance(
cl.loadClass(ct), null, clients, moduleRoot, moduleName, srcOutputRoot );
assembler.assemble( cac );
}
}
}
catch ( ControlAssemblyException cae )
{
// just rethrow ControlAssemblyExceptions, which will typically come from user-provided assemblers.
throw cae;
}
catch ( Throwable t )
{
// Not expecting any throwables other than ControlAssemblyExceptions, so consider them as
// unexpected infrastructure issues and wrap them in a CAE.
throw new ControlAssemblyException( "Assembly infrastructure exception", t);
}
finally
{
Thread.currentThread().setContextClassLoader( origCL );
}
}
}

View File

@ -1,204 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.assembly;
import java.io.File;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Set;
import java.util.LinkedList;
import java.util.Queue;
import com.sun.mirror.apt.Messager;
import com.sun.mirror.util.SourcePosition;
import org.apache.beehive.controls.api.bean.ControlInterface;
import org.apache.beehive.controls.api.assembly.ControlAssemblyContext;
import org.apache.beehive.controls.api.assembly.ControlAssemblyException;
import org.apache.beehive.controls.runtime.bean.ControlUtils;
/**
* Abstract ControlAssemblyContext implementation. Provides a basic implementation of most non-module-specific
* APIs, meant to be extended by module-specific types.
*/
public abstract class BaseAssemblyContext implements ControlAssemblyContext
{
protected BaseAssemblyContext( Class controlIntfOrExt, Map<String,String> bindings,
Set<String> clients, File moduleRoot,
String moduleName, File srcOutputRoot )
throws ControlAssemblyException
{
_controlIntfOrExt = controlIntfOrExt;
_bindings = bindings;
_clients = clients;
_moduleRoot = moduleRoot;
_moduleName = moduleName;
_srcOutputRoot = srcOutputRoot;
_messager = new DefaultAssemblyMessager();
// Compute and cache "most derived ControlInterface"
Queue<Class> q = new LinkedList<Class>();
Class ci = controlIntfOrExt;
while ( ci != null )
{
if ( ci.isAnnotationPresent(ControlInterface.class) )
{
_controlMostDerivedIntf = ci;
break;
}
Class[] supers = ci.getInterfaces();
for ( Class s : supers )
q.offer( s );
ci = q.poll();
}
if ( _controlMostDerivedIntf == null )
throw new ControlAssemblyException( "Invalid control type: " + controlIntfOrExt.getName() );
}
public Class getControlType()
{
return _controlIntfOrExt;
}
public Class getMostDerivedControlInterface()
{
return _controlMostDerivedIntf;
}
// TODO - if we want to override class annotations on instance then here is where we will do it
public <T extends Annotation> T
getControlAnnotation(Class<T> annotationClass)
{
Class controlInterface = getControlType();
return (T)controlInterface.getAnnotation(annotationClass);
}
public <T extends Annotation> T
getControlMethodAnnotation(Class<T> annotationClass, Method m)
throws NoSuchMethodException
{
Class controlInterface = getControlType();
Method controlMethod = controlInterface.getMethod(
m.getName(), m.getParameterTypes());
return (T)controlMethod.getAnnotation(annotationClass);
}
public String getDefaultImplClassName()
{
Class ci = getMostDerivedControlInterface();
ControlInterface a = (ControlInterface)
ci.getAnnotation(ControlInterface.class);
return ControlUtils.resolveDefaultBinding( a.defaultBinding(), ci.getName() );
}
public File getSrcOutputDir()
{
return _srcOutputRoot;
}
public File getModuleDir()
{
return _moduleRoot;
}
public String getModuleName()
{
return _moduleName;
}
public Set<String> getClients()
{
return _clients;
}
public Messager getMessager()
{
return _messager;
}
public boolean hasErrors()
{
return _nErrors > 0;
}
private class DefaultAssemblyMessager implements Messager
{
public void printError( SourcePosition pos, String msg )
{
printDiagnostic( "Error", pos, msg );
_nErrors++;
}
public void printError( String msg )
{
printError( null, msg );
}
public void printNotice( SourcePosition pos, String msg )
{
printDiagnostic( "Notice", pos, msg );
}
public void printNotice( String msg )
{
printNotice( null, msg );
}
public void printWarning( SourcePosition pos, String msg )
{
printDiagnostic( "Warning", pos, msg );
}
public void printWarning( String msg )
{
printWarning( null, msg );
}
protected void printDiagnostic( String type, SourcePosition pos, String msg )
{
String fn = "<not available>";
int line = 0;
int column = 0;
if ( pos != null )
{
fn = pos.file().getName();
line = pos.line();
column = pos.column();
}
System.out.println( type + ": (" + fn + ":" + line + ":" + column + ") " + msg );
}
}
private File _moduleRoot;
private String _moduleName;
private File _srcOutputRoot;
private Class _controlIntfOrExt;
private Map<String,String> _bindings;
private Set<String> _clients;
private Messager _messager;
private int _nErrors = 0;
private Class _controlMostDerivedIntf;
}

View File

@ -1,62 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.assembly;
import org.apache.beehive.controls.api.assembly.ControlAssemblyContext;
import org.apache.beehive.controls.api.assembly.ControlAssemblyException;
import java.io.File;
import java.util.Map;
import java.util.Set;
/**
* A ControlAssemblyContext implementation supporting standard EJB modules
*/
public class EJBAssemblyContext
extends BaseAssemblyContext
implements ControlAssemblyContext.EJBModule
{
public static class Factory implements ControlAssemblyContext.Factory
{
public EJBAssemblyContext newInstance( Class controlIntfOrExt,
Map<String,String> bindings,
Set<String> clients,
File moduleRoot,
String moduleName,
File srcOutputRoot )
throws ControlAssemblyException
{
return new EJBAssemblyContext( controlIntfOrExt, bindings, clients,
moduleRoot, moduleName, srcOutputRoot );
}
}
protected EJBAssemblyContext( Class controlIntfOrExt, Map<String,String> bindings,
Set<String> clients, File moduleRoot,
String moduleName, File srcOutputRoot )
throws ControlAssemblyException
{
super( controlIntfOrExt, bindings, clients, moduleRoot, moduleName, srcOutputRoot );
}
public File getEjbJarXml()
{
return new File( getModuleDir(), "META-INF" + File.separator + "ejb-jar.xml");
}
}

View File

@ -1,66 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.assembly;
import org.apache.beehive.controls.api.assembly.ControlAssemblyContext;
import org.apache.beehive.controls.api.assembly.ControlAssemblyException;
import java.io.File;
import java.util.Map;
import java.util.Set;
/**
* A ControlAssemblyContext implementation supporting standard web-app modules
*/
public class WebAppAssemblyContext
extends BaseAssemblyContext
implements ControlAssemblyContext.WebAppModule
{
public static class Factory
implements ControlAssemblyContext.Factory
{
public WebAppAssemblyContext newInstance( Class controlIntfOrExt,
Map<String,String> bindings,
Set<String> clients,
File moduleRoot,
String moduleName,
File srcOutputRoot )
throws ControlAssemblyException
{
return new WebAppAssemblyContext( controlIntfOrExt, bindings, clients,
moduleRoot, moduleName, srcOutputRoot );
}
}
protected WebAppAssemblyContext(Class controlIntfOrExt,
Map<String,String> bindings,
Set<String> clients,
File moduleRoot,
String moduleName,
File srcOutputRoot )
throws ControlAssemblyException
{
super( controlIntfOrExt, bindings, clients, moduleRoot, moduleName, srcOutputRoot );
}
public File getWebXml()
{
return new File( getModuleDir(), "WEB-INF" + File.separator + "web.xml");
}
}

View File

@ -1,64 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.bean;
import java.beans.DefaultPersistenceDelegate;
import java.beans.Encoder;
import java.beans.Expression;
/**
* The AdaptorPersistenceDelegate class supports the XML persistance of Control Client Event
* Adaptor instances by implementing the <code>java.beans.PersistenceDelegate</b> API, and
* overriding the default persistance algorithm based upon the runtime structure for Controls.
*/
public class AdaptorPersistenceDelegate extends DefaultPersistenceDelegate
{
/**
* PersistenceDelegate.instantiate()
*/
protected Expression instantiate(Object oldInstance, Encoder out)
{
if (! (oldInstance instanceof EventAdaptor))
return super.instantiate(oldInstance, out);
//
// An implementation instance is actually constructed at decode time by calling
// ControlBean.ensureControl on the parent bean. This will create a new impl
// instance and run the impl initializer on it.
//
return new Expression(oldInstance, oldInstance.getClass(), "new",
new Object[] { ((EventAdaptor)oldInstance).getClient() });
}
/**
* PersistenceDelegate.initialize()
*/
protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out)
{
super.initialize(type, oldInstance, newInstance, out);
}
/**
* PersistenceDelegate.writeObject()
*/
public void writeObject(Object oldInstance, Encoder out)
{
super.writeObject(oldInstance, out);
}
}

View File

@ -1,43 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.bean;
import java.beans.PersistenceDelegate;
import java.beans.Encoder;
import java.beans.Expression;
import org.apache.beehive.controls.api.properties.AnnotatedElementMap;
/**
* The AnnotatedElementMapPersistenceDelegate is an XMLEncoder PersistenceDelegate for
* the <code>org.apache.beehive.controls.api.properties.AnnotatedElementMap</code>
* class.
*/
public class AnnotatedElementMapPersistenceDelegate extends PersistenceDelegate
{
protected Expression instantiate(Object oldInstance, Encoder out)
{
//
// Modify the default constructor to pass in the AnnotatedElement wrapped by the map
//
AnnotatedElementMap aem = (AnnotatedElementMap)oldInstance;
return new Expression(aem, aem.getClass(), "new",
new Object [] { aem.getAnnotatedElement() });
}
}

View File

@ -1,574 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.bean;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.text.ParsePosition;
import java.util.Date;
import org.apache.beehive.controls.api.bean.AnnotationMemberTypes;
import org.apache.beehive.controls.api.bean.AnnotationConstraints.MembershipRule;
import org.apache.beehive.controls.api.bean.AnnotationConstraints.MembershipRuleValues;
import org.apache.beehive.controls.api.properties.PropertyKey;
/**
* This class offers methods for validating values assigned to a control property.
* The validation process will ensure
* 1. The value is appropriate for the property's property type
* 2. The value satisfies the constraints defined on the property type
* 3. The value satisfies the constraints defined on the property set that the property is defined in.
* Refer to {@link org.apache.beehive.controls.api.bean.AnnotationMemberTypes AnnotationMemberTypes} and
* {@link org.apache.beehive.controls.api.bean.AnnotationConstraints AnnotationConstraints} for more
* information on property constraints.
*/
public class AnnotationConstraintValidator
{
public AnnotationConstraintValidator()
{
super();
}
/**
* This method ensures that any control property value assignment satisfies
* all property constraints. This method should be called by control
* property setters to ensure values assigned to properties at runtime are
* validated.
*
* @param key
* The property that the specified key is assigned to
* @param value
* The value assigned to the specified property key
* @throws IllegalArgumentException
* when the value assigned to the specified property key does
* not satisfy a property constraint.
*/
public static void validate(PropertyKey key, Object value)
throws IllegalArgumentException
{
validate(key.getAnnotations(), value);
}
/**
* This method ensures the membership constraints defined on a property set
* is satisfied.
*
* @param propertySet the property set to validate
*/
public static void validateMembership(Annotation propertySet)
{
Class c = propertySet.annotationType();
MembershipRule rule = (MembershipRule) c.getAnnotation(MembershipRule.class);
if (rule == null)
return;
MembershipRuleValues ruleValue = rule.value();
String[] memberNames = rule.memberNames();
Method[] members = getMembers(c, memberNames);
int i = getNumOfMembersSet(propertySet, members);
if (ruleValue == MembershipRuleValues.ALL_IF_ANY)
{
if (i != 0 && i != members.length)
throw new IllegalArgumentException("The membership rule on " + propertySet.toString() +
" is not satisfied. Either all members must be set or none is set");
}
else if (ruleValue == MembershipRuleValues.EXACTLY_ONE)
{
if (i != 1)
throw new IllegalArgumentException("The membership rule on " + propertySet.toString() +
" is not satisfied. Exactly one member must be set");
}
else if (ruleValue == MembershipRuleValues.AT_LEAST_ONE)
{
if (i < 1)
throw new IllegalArgumentException("The membership rule on " + propertySet.toString() +
" is not satisfied. At least one member must be set");
}
else if (ruleValue == MembershipRuleValues.AT_MOST_ONE)
{
if (i > 1)
throw new IllegalArgumentException("The membership rule on " + propertySet.toString() +
" is not satisfied. At most one member may be set");
}
}
private static Method[] getMembers(Class<? extends Annotation> c, String[] memberNames)
{
Method[] methods = null;
if (memberNames == null || memberNames.length == 0)
{
methods = c.getDeclaredMethods();
}
else
{
methods = new Method[memberNames.length];
for (int i = 0; i < memberNames.length; i++)
{
try
{
methods[i] = c.getMethod(memberNames[i], (Class[]) null);
}
catch (Exception e)
{
// method is not found, so the member is ignored.
}
}
}
return methods;
}
private static int getNumOfMembersSet(Annotation propertySet,
Method[] members)
{
int num = 0;
for (Method m : members)
{
Class returnType = m.getReturnType();
Object o = null;
try
{
o = m.invoke(propertySet, (Object[]) null);
}
catch (Exception e)
{
// This should never happen.
throw new RuntimeException(e);
}
if ((returnType == String.class && !((String) o)
.equals(AnnotationMemberTypes.OPTIONAL_STRING))
|| (returnType == int.class && ((Integer) o).intValue() != AnnotationMemberTypes.OPTIONAL_INT)
|| (returnType == short.class && ((Short) o)
.shortValue() != AnnotationMemberTypes.OPTIONAL_SHORT)
|| (returnType == long.class && ((Long) o).longValue() != AnnotationMemberTypes.OPTIONAL_LONG)
|| (returnType == float.class && ((Float) o)
.floatValue() != AnnotationMemberTypes.OPTIONAL_FLOAT)
|| (returnType == double.class && ((Double) o)
.doubleValue() != AnnotationMemberTypes.OPTIONAL_DOUBLE)
|| (returnType == char.class && ((Character) o)
.charValue() != AnnotationMemberTypes.OPTIONAL_CHAR)
|| (returnType == byte.class && ((Byte) o).byteValue() != AnnotationMemberTypes.OPTIONAL_BYTE)
|| (returnType == boolean.class && !((Boolean) o)
.booleanValue()))
num++;
}
return num;
}
protected static synchronized void validate(Annotation[] annotations,
Object value) throws IllegalArgumentException
{
// Determine if the member is optional. This is done in a separate loop
// because a control property may have multiple constraints and the
// optional
// annotation may be declared after another constraint annotation.
boolean optional = false;
for (Annotation a : annotations)
{
if (a instanceof AnnotationMemberTypes.Optional)
{
optional = true;
break;
}
}
for (Annotation a : annotations)
{
if (a instanceof AnnotationMemberTypes.Text)
validateText((AnnotationMemberTypes.Text) a, value, optional);
else if (a instanceof AnnotationMemberTypes.Decimal)
validateDecimal((AnnotationMemberTypes.Decimal) a, value,
optional);
else if (a instanceof AnnotationMemberTypes.Int)
validateInt((AnnotationMemberTypes.Int) a, value, optional);
else if (a instanceof AnnotationMemberTypes.Date)
validateDate((AnnotationMemberTypes.Date) a, value, optional);
else if (a instanceof AnnotationMemberTypes.FilePath)
validateFilePath((AnnotationMemberTypes.FilePath) a, value,
optional);
else if (a instanceof AnnotationMemberTypes.JndiName)
validateJndiName((AnnotationMemberTypes.JndiName) a, value,
optional);
else if (a instanceof AnnotationMemberTypes.QName)
validateQName((AnnotationMemberTypes.QName) a, value, optional);
else if (a instanceof AnnotationMemberTypes.URI)
validateURI((AnnotationMemberTypes.URI) a, value, optional);
else if (a instanceof AnnotationMemberTypes.URL)
validateURL((AnnotationMemberTypes.URL) a, value, optional);
else if (a instanceof AnnotationMemberTypes.URN)
validateURN((AnnotationMemberTypes.URN) a, value, optional);
else if (a instanceof AnnotationMemberTypes.XML)
validateXML((AnnotationMemberTypes.XML) a, value, optional);
}
}
private static void validateXML(AnnotationMemberTypes.XML a, Object value,
boolean optional)
{
}
private static void validateURN(AnnotationMemberTypes.URN a, Object value,
boolean optional)
{
if (optional
&& (value == null || value
.equals(AnnotationMemberTypes.OPTIONAL_STRING)))
return;
if (!(value instanceof String))
{
error("The value, "
+ value
+ ", assigned to an URN property must be of type java.lang.String.");
}
URI.create((String) value);
}
private static void validateURL(AnnotationMemberTypes.URL a, Object value,
boolean optional)
{
if (optional
&& (value == null || value
.equals(AnnotationMemberTypes.OPTIONAL_STRING)))
return;
if (!(value instanceof String))
{
error("The value, "
+ value
+ ", assigned to an URL property must be of type java.lang.String.");
}
try
{
new URL((String) value);
}
catch (MalformedURLException mue)
{
error("The value, " + value
+ ", assigned to the URL property is a malformed URL.", mue);
}
}
private static void validateURI(AnnotationMemberTypes.URI a, Object value, boolean optional)
{
if (optional
&& (value == null || value
.equals(AnnotationMemberTypes.OPTIONAL_STRING)))
return;
if (!(value instanceof String))
{
error("The value, "
+ value
+ ", assigned to an URI property must be of type java.lang.String.");
}
URI.create((String) value);
}
private static void validateQName(AnnotationMemberTypes.QName a, Object value, boolean optional)
{
}
private static void validateJndiName(AnnotationMemberTypes.JndiName a, Object value, boolean optional)
{
}
private static void validateFilePath(AnnotationMemberTypes.FilePath a, Object value, boolean optional)
{
if (optional
&& (value == null || value
.equals(AnnotationMemberTypes.OPTIONAL_STRING)))
return;
if (!(value instanceof String))
{
error("The value, "
+ value
+ ", assigned to a FilePath property must be of type java.lang.String.");
}
//Temporarily commenting out the following check on FilePath until
//an agreement is reached on what is a valid FilePath.
//
// File file = new File((String) value);
// if (!file.isFile() || !file.canRead())
// {
// error("The value, "
// + value
// + ", assigned to a FilePath property must be a readable file.");
// }
}
private static void validateDate(AnnotationMemberTypes.Date a, Object value, boolean optional) {
if (optional && (value == null || value.equals(AnnotationMemberTypes.OPTIONAL_STRING)))
return;
if (!(value instanceof String))
error("The value, "
+ value
+ ", assigned to a date property must be of type java.lang.String.");
String format = a.format();
Date date = null;
try {
date = parseDate(format , (String)value);
} catch (ParseException pe) {
error("The value, "
+ value
+ ", assigned to a date property is not in the specified format of: "
+ format);
}
String minValue = a.minValue();
if (minValue != null && minValue.length() > 0) {
Date minDate = null;
try {
minDate = parseDate(format, a.minValue());
} catch (ParseException pe) {
error("The value, "
+ minValue
+ ", assigned to minValue date constraint property is not in the specified format of: "
+ format);
}
if (minDate.compareTo(date) > 0) {
error("The value, "
+ value
+ ", assigned to a date property is earlier than the earliest date allowed: "
+ minValue);
}
}
String maxValue = a.maxValue();
if (maxValue != null && maxValue.length() > 0) {
Date maxDate = null;
try {
maxDate = parseDate(format, a.maxValue());
} catch (ParseException pe) {
error("The value, "
+ maxValue
+ ", assigned to maxValue date constraint property is not in the specified format of: "
+ format);
}
if (maxDate.compareTo(date) < 0) {
error("The date, "
+ value
+ ", assigned to a date property is later than the latest date allowed: "
+ maxValue);
}
}
}
/**
* Parse a date value into the specified format. Pay special attention to the case of the value
* having trailing characters, ex. 12/02/2005xx which will not cause the parse of the date to fail
* but should be still treated as an error for our purposes.
*
* @param format Format string for the date.
* @param value A String containing the date value to parse.
* @return A Date instance if the parse was successful.
* @throws ParseException If the value is not a valid date.
*/
public static Date parseDate(String format, String value)
throws ParseException {
SimpleDateFormat sdFormat = new SimpleDateFormat(format);
sdFormat.setLenient(false);
ParsePosition pp = new ParsePosition(0);
Date d = sdFormat.parse(value, pp);
/*
a date value such as: 12/01/2005x will not cause a parse error,
use the parse position to detect this case.
*/
if (d == null || pp.getIndex() < value.length())
throw new ParseException("Parsing date value, "
+ value
+ ", failed at index " + pp.getIndex(), pp.getIndex());
else return d;
}
/**
* @param value
*/
private static void validateInt(AnnotationMemberTypes.Int a, Object value, boolean optional) {
if (optional
&& (value == null ||
value.equals(AnnotationMemberTypes.OPTIONAL_STRING) ||
value.equals(AnnotationMemberTypes.OPTIONAL_INT)))
return;
int intValue = 0;
if (value instanceof String)
{
try
{
intValue = Integer.parseInt((String) value);
}
catch (NumberFormatException nfe)
{
error("The value ,"
+ value
+ ", assigned to an int property does not represent an integer.");
}
}
else if (value instanceof Integer)
{
intValue = ((Integer) value).intValue();
}
else
{
error("The value, "
+ value
+ ", assigned to an int property must be of type java.lang.String or int.");
}
if (intValue < a.minValue())
error("The value, "
+ intValue
+ ", assigned to an int property is less than the minimum value allowed: "
+ a.minValue() + ".");
else if (intValue > a.maxValue())
error("The value, "
+ intValue
+ ", assigned to an int property exeeds the maximum value allowed: "
+ a.maxValue() + ".");
}
private static void validateDecimal(AnnotationMemberTypes.Decimal a,
Object value, boolean optional)
{
if (optional
&& (value == null ||
value.equals(AnnotationMemberTypes.OPTIONAL_STRING) ||
value.equals(AnnotationMemberTypes.OPTIONAL_FLOAT) ||
value.equals(AnnotationMemberTypes.OPTIONAL_DOUBLE)))
return;
double doubleValue = 0;
String doubleString = null;
if (value instanceof String)
{
doubleValue = Double.parseDouble((String)value);
doubleString = (String)value;
}
else if (value instanceof Float)
{
doubleValue = ((Float)value).doubleValue();
doubleString = ((Float)value).toString();
}
else if (value instanceof Double)
{
doubleValue = ((Double)value).doubleValue();
doubleString = ((Double)value).toString();
}
else
{
error("The value, "
+ value
+ ", assigned to a decimal property must be of type float, double, or java.lang.String.");
}
if (doubleValue < a.minValue())
error("The value, "
+ doubleValue
+ ", assigned to a decimal property is less than the the minimum value allowed: "
+ a.minValue() + ".");
if (doubleValue > a.maxValue())
error("The value, "
+ doubleValue
+ ", assigned to a decimal property exceeds the maximum value allowed: "
+ a.maxValue() + ".");
int decimalPos = doubleString.indexOf('.');
if (decimalPos == -1 || a.places() == AnnotationMemberTypes.UNLIMITED_PLACES)
return;
if (doubleString.length() - decimalPos - 1 > a.places())
error("The decimal places in the value, " + doubleString
+ ", assigned to a decimal property exceeds " + a.places()
+ ", the number of decimal places allowed.");
}
private static void validateText(AnnotationMemberTypes.Text a,
Object value, boolean optional)
{
if (optional
&& (value == null || value
.equals(AnnotationMemberTypes.OPTIONAL_STRING)))
return;
if (!(value instanceof String))
error("The value, "
+ value
+ ", assigned to a text property must be of type java.lang.String.");
String str = (String) value;
if (str.length() > a.maxLength())
error("The value, "
+ str
+ ", assigned to a text property exceeds the maximum length allowed: "
+ a.maxLength());
if (a.isLong())
{
try
{
Long.parseLong(str);
}
catch (NumberFormatException nfe)
{
error("The value, "
+ str
+ ", assigned to a text property with a long number constraint does not represent a long number.");
}
}
}
private static void error(String message)
{
error(message, null);
}
private static void error(String message, Throwable t)
{
throw new IllegalArgumentException(message, t);
}
}

View File

@ -1,45 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.bean;
/**
* The BeanListener class acts as the abstract base class for generated event listeners
* associated with a ControlBean.
*/
abstract public class BeanListener
implements java.io.Serializable
{
protected BeanListener()
{
this(null);
}
protected BeanListener(Object source)
{
_source = source;
}
abstract public BeanListener cloneListener(Object source);
public Object getSource() {
return _source;
}
Object _source;
}

View File

@ -1,312 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.bean;
import java.beans.BeanInfo;
import java.beans.DefaultPersistenceDelegate;
import java.beans.Encoder;
import java.beans.EventSetDescriptor;
import java.beans.Expression;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PersistenceDelegate;
import java.beans.PropertyDescriptor;
import java.beans.Statement;
import java.beans.XMLEncoder;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Iterator;
import org.apache.beehive.controls.api.ControlException;
import org.apache.beehive.controls.api.properties.AnnotatedElementMap;
import org.apache.beehive.controls.api.properties.BeanPropertyMap;
import org.apache.beehive.controls.api.properties.PropertyKey;
import org.apache.beehive.controls.api.properties.PropertyMap;
/**
* The BeanPersistenceDelegate class supports the XML persistence of Control JavaBeans by
* implementing the <code>java.beans.PersistenceDelegate</b> API, and overriding the default
* persistence algorithm based upon the runtime structure for Controls. It selectively registers
* other PersistenceDelegate instances for other nested entities, as required, to ensure that
* runtime-defined state and object relationships are properly maintained.
* <p>
* For the BeanInfo of all generated ControlJavaBeans, a BeanPersistenceDelegate instance will
* be registered as the "persistenceDelegate" attribute in the BeanDescriptor. The standard
* <code>java.beans.Encoder</code> persistence delegate lookup mechanism recognizes this attribute
* and will use the instance to persist an ControlBeans written to the encoding stream.
* <p>
* The BeanPersistence class implements optimized property persistence based upon the
* fact that the ControlBean already has a map containing all non-default property state. Rather
* than using the standard (and slower) algorithm of comparing the encoding instance against a
* 'clean' instance, the delegate can simply retrieve the map and persist the values contained
* within it.
*
* @see java.beans.XMLEncoder
* @see java.beans.PersistenceDelegate
*/
public class BeanPersistenceDelegate extends DefaultPersistenceDelegate
{
/**
* The FieldPersistencersistence is an XMLEncoder PersistenceDelegate for the
* <code>java.lang.reflect.Field</code> claass. It is similar to the one that comes
* bundled with the JDK with one key exception: it works for non-public fields as
* well.
*/
class FieldPersistenceDelegate extends PersistenceDelegate
{
protected Expression instantiate(Object oldInstance, Encoder out)
{
Field f = (Field)oldInstance;
return new Expression(oldInstance, f.getDeclaringClass(), "getDeclaredField",
new Object[]{f.getName()});
}
}
/**
* PersistenceDelegate.instantiate()
*/
protected Expression instantiate(Object oldInstance, Encoder out)
{
XMLEncoder xmlOut = (XMLEncoder)out;
ControlBean control = (ControlBean)oldInstance;
//
// If processing a nested control, then use the parent bean's context as the
// constructor context
//
ControlBeanContext cbc = null;
if (xmlOut.getOwner() != null)
cbc = ((ControlBean)xmlOut.getOwner()).getControlBeanContext();
//
// See if the ControlBean has any associated PropertyMap in its delegation chain
// that was derived from an AnnotatedElement so this relationship (and any associated
// external config delegates) will be restored as part of the decoding process.
//
// BUGBUG: What about a user-created PropertyMap that was passed into the constructor?
//
AnnotatedElementMap aem = null;
PropertyMap pMap = control.getPropertyMap();
while (pMap != null)
{
if (pMap instanceof AnnotatedElementMap)
{
aem = (AnnotatedElementMap)pMap;
//
// Ignore a class-valued AnnotationElementMap.. this just refers to the
// Control type, and will be automatically reassociated at construction
// time
//
if (aem.getAnnotatedElement() instanceof Class)
aem = null;
xmlOut.setPersistenceDelegate(AnnotatedElementMap.class,
new AnnotatedElementMapPersistenceDelegate());
break;
}
pMap = pMap.getDelegateMap();
}
//
// Create a constructor that that uses the following form:
// new <BeanClass>(ControlBeanContext cbc, String id, PropertyMap map)
// The context is set to null, so the current active container context will be
// used, the id will be the ID of the original control and the map will be
// any AnnotatedElementMap that was passed into the original constructor.
//
return new Expression(control, control.getClass(), "new",
new Object [] {cbc, control.getLocalID(), aem});
}
/**
* PersistenceDelegate.initialize()
*/
protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out)
{
//
// Get the bean and associated beanInfo for the source instance
//
ControlBean control = (ControlBean)oldInstance;
BeanInfo beanInfo;
try
{
beanInfo = Introspector.getBeanInfo(control.getClass());
}
catch (IntrospectionException ie)
{
throw new ControlException("Unable to locate BeanInfo", ie);
}
//
// Cast the encoding stream to an XMLEncoder (only encoding supported) and then set
// the stream owner to the bean being persisted
//
XMLEncoder xmlOut = (XMLEncoder)out;
Object owner = xmlOut.getOwner();
xmlOut.setOwner(control);
try
{
//
// The default implementation of property persistence will use BeanInfo to
// incrementally compare oldInstance property values to newInstance property values.
// Because the bean instance PropertyMap holds only the values that have been
// modified, this process can be optimized by directly writing out only the properties
// found in the map.
//
BeanPropertyMap beanMap = control.getPropertyMap();
PropertyDescriptor [] propDescriptors = beanInfo.getPropertyDescriptors();
for (PropertyKey pk : beanMap.getPropertyKeys())
{
//
// Locate the PropertyDescriptor for the modified property, and use it to write
// the property value to the encoder stream
//
String propName = pk.getPropertyName();
boolean found = false;
for (int i = 0; i < propDescriptors.length; i++)
{
if (propName.equals(propDescriptors[i].getName()))
{
found = true;
// Only write the property if it is not flagged as transient
Object transientVal = propDescriptors[i].getValue("transient");
if (transientVal == null || transientVal.equals(Boolean.FALSE))
{
xmlOut.writeStatement(
new Statement(oldInstance,
propDescriptors[i].getWriteMethod().getName(),
new Object [] {beanMap.getProperty(pk)}));
}
}
}
if (found == false)
{
throw new ControlException("Unknown property in bean PropertyMap: " + pk);
}
}
//
// Get the bean context associated with the bean, and persist any nested controls
//
ControlBeanContext cbc = control.getControlBeanContext();
if (cbc.size() != 0)
{
xmlOut.setPersistenceDelegate(ControlBeanContext.class,
new ContextPersistenceDelegate());
Iterator nestedIter = cbc.iterator();
while (nestedIter.hasNext())
{
Object bean = nestedIter.next();
if (bean instanceof ControlBean)
{
xmlOut.writeStatement(
new Statement(cbc, "add", new Object [] { bean } ));
}
}
}
//
// Restore any listeners associated with the control
//
EventSetDescriptor [] eventSetDescriptors = beanInfo.getEventSetDescriptors();
for (int i = 0; i < eventSetDescriptors.length; i++)
{
EventSetDescriptor esd = eventSetDescriptors[i];
Method listenersMethod = esd.getGetListenerMethod();
String addListenerName = esd.getAddListenerMethod().getName();
if (listenersMethod != null)
{
//
// Get the list of listeners, and then add statements to incrementally
// add them in the same order
//
try
{
Object [] lstnrs = (Object [])listenersMethod.invoke(control,
new Object []{});
for (int j = 0; j < lstnrs.length; j++)
{
//
// If this is a generated EventAdaptor class, then set the delegate
// explicitly
//
if (lstnrs[j] instanceof EventAdaptor)
xmlOut.setPersistenceDelegate(lstnrs[j].getClass(),
new AdaptorPersistenceDelegate());
xmlOut.writeStatement(
new Statement(control, addListenerName, new Object [] {lstnrs[j]}));
}
}
catch (Exception iae)
{
throw new ControlException("Unable to initialize listeners", iae);
}
}
}
//
// See if the control holds an implementation instance, if so, we need to include
// it (and any nested controls or state) in the encoding stream
//
Object impl = control.getImplementation();
if (impl != null)
{
//
// Set the persistence delegate for the impl class to the Impl delegate,
// set the current stream owner to the bean, and then write the implementation
//
Class implClass = impl.getClass();
if (xmlOut.getPersistenceDelegate(implClass) instanceof DefaultPersistenceDelegate)
xmlOut.setPersistenceDelegate(implClass, new ImplPersistenceDelegate());
//
// HACK: This bit of hackery pushes the impl into the persistence stream
// w/out actually requiring it be used as an argument elsewhere, since there
// is no public API on the bean that takes an impl instance as an argument.
//
xmlOut.writeStatement(
new Statement(impl, "toString", null));
}
}
finally
{
// Restore the previous encoding stream owner
xmlOut.setOwner(owner);
}
}
/**
* PersistenceDelegate.writeObject()
*/
public void writeObject(Object oldInstance, Encoder out)
{
// Override the default FieldPersistence algorithm for the encoder, so private fields
// can also be encoded
out.setPersistenceDelegate(Field.class, new FieldPersistenceDelegate());
super.writeObject(oldInstance, out);
}
}

View File

@ -1,63 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.bean;
import java.lang.reflect.AnnotatedElement;
import org.apache.beehive.controls.api.context.ControlBeanContext;
import org.apache.beehive.controls.api.properties.PropertyMap;
import org.apache.beehive.controls.api.properties.AnnotatedElementMap;
import org.apache.beehive.controls.api.versioning.VersionRequired;
import org.apache.beehive.controls.api.versioning.Version;
/**
* The ClientInitializer class is an abstract base class that all generated Control
* client initializer classes will extend. It provides common utilities and supporting code
* for initialization, and has a shared package relationship with the base ControlBean
* class providing access to internals not available in a more general context.
*/
abstract public class ClientInitializer
{
/**
* Enforces the VersionRequired annotation at runtime (called when an instance of a control is annotated
* with VersionRequired). Throws a ControlException if enforcement fails.
*
* @param versionRequired the value of the VersionRequired annotation on a control field
*/
protected static void enforceVersionRequired( ControlBean control, VersionRequired versionRequired )
{
Class controlIntf = ControlUtils.getMostDerivedInterface( control.getControlInterface() );
Version versionPresent = (Version) controlIntf.getAnnotation( Version.class );
if ( versionPresent != null )
{
ControlBean.enforceVersionRequired( controlIntf.getCanonicalName(), versionPresent, versionRequired );
}
}
/**
* Returns the annotation map for the specified element.
*/
public static PropertyMap getAnnotationMap(ControlBeanContext cbc, AnnotatedElement annotElem)
{
if ( cbc == null )
return new AnnotatedElementMap(annotElem);
return cbc.getAnnotationMap(annotElem);
}
}

View File

@ -1,61 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.bean;
import java.beans.DefaultPersistenceDelegate;
import java.beans.Encoder;
import java.beans.Expression;
import java.beans.XMLEncoder;
/**
* The ContextPersistenceDelegate class supports the XML persistance of ControlBeanContext
* instances by implementing the <code>java.beans.PersistenceDelegate</b> API, and overriding
* the default persistance algorithm based upon the runtime structure for Controls.
* <p>
*/
public class ContextPersistenceDelegate extends DefaultPersistenceDelegate
{
/**
* PersistenceDelegate.instantiate()
*/
protected Expression instantiate(Object oldInstance, Encoder out)
{
//
// Instead of directly creating a context instance, simply ask the containing
// bean to return the associated context.
//
return new Expression(((XMLEncoder)out).getOwner(), "getControlBeanContext", null);
}
/**
* PersistenceDelegate.initialize()
*/
protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out)
{
//super.initialize(type, oldInstance, newInstance, out);
}
/**
* PersistenceDelegate.writeObject()
*/
public void writeObject(Object oldInstance, Encoder out)
{
super.writeObject(oldInstance, out);
}
}

View File

@ -1,89 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.bean;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
/**
* The ControlBeanInfo class is an abstract base class for the JavaBean BeanInfo classes generated
* to support Beehive controls. It is used to bundle helper code common across all generated
* BeanInfo classes.
*/
abstract public class ControlBeanInfo extends java.beans.SimpleBeanInfo
{
/**
* Protected constructor that is called from generated BeanInfo subclasses.
* @param beanClass the JavaBean class for which BeanInfo is being provided.
*/
protected ControlBeanInfo(Class beanClass)
{
super();
_beanClass = beanClass;
}
/*
* Gets a possibly-localized string for the given input string.
* @param input This the the string that may be localizable. If it is of the form
* "%foo.bar.Baz%", then the resource Baz will be looked up in the foo.bar bundle using
* standard ResourceBundle rules for the default Locale using the control's classloader.
* If the input does not start and end with '%', or if the bundle is not located, the string
* will be returned verbatim.
* @return the string to be displayed, or the input string if no resource is found.
*/
final protected String localizeString(String input)
{
if (input == null || !input.startsWith("%") || !input.endsWith("%"))
return input;
String bundleName = input.substring(1, input.length()-1);
String resourceName = null;
int lastDot = bundleName.lastIndexOf('.');
while (lastDot != -1 && lastDot != 0 && (lastDot+1 < bundleName.length()))
{
// move last element from bundle to resource. foo.bar.Baz could be the
// Baz property in foo.bar, or the bar.Baz property in foo.
if (resourceName == null)
resourceName = bundleName.substring(lastDot+1);
else
resourceName = bundleName.substring(lastDot+1) + '.' + resourceName;
bundleName = bundleName.substring(0, lastDot);
try
{
ResourceBundle bundle = ResourceBundle.getBundle(bundleName, Locale.getDefault(),
_beanClass.getClassLoader());
if (bundle != null)
{
String lookup = bundle.getString(resourceName);
if (lookup != null)
return lookup;
}
}
catch (MissingResourceException mre)
{ }
lastDot = bundleName.lastIndexOf('.');
}
return input;
}
Class _beanClass;
}

View File

@ -1,190 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.bean;
import java.lang.reflect.InvocationTargetException;
import java.util.Stack;
import org.apache.beehive.controls.api.context.ControlHandle;
import org.apache.beehive.controls.api.context.ControlThreadContext;
import org.apache.beehive.controls.api.context.ResourceContext;
import org.apache.beehive.controls.api.events.EventDispatcher;
import org.apache.beehive.controls.api.events.EventRef;
/**
* The ControlContainerContext class provides a base class implementation for external containers
* of ControlBeans. It provides additional services, such as:
*
* - defines a contextual service provider for the ResourceManager interface
* - defines a simplified contract for the external container to interact with resource
* management (beginContext/endContext)
*/
public class ControlContainerContext
extends ControlBeanContext
implements EventDispatcher, org.apache.beehive.controls.api.context.ControlContainerContext
{
public ControlContainerContext()
{
super(null);
}
protected ControlContainerContext(BeanContextServicesFactory beanContextServicesFactory) {
super(null, beanContextServicesFactory);
}
/**
* Defines the beginning of a new control container execution context.
*/
public void beginContext()
{
ControlThreadContext.beginContext(this);
}
/**
* Ends the current control container execution context
*/
public void endContext()
{
try
{
//
// Release all resources associated with the current execution context.
//
releaseResources();
}
finally
{
ControlThreadContext.endContext(this);
}
}
/**
* Called by BeanContextSupport superclass during construction and deserialization to
* initialize subclass transient state
*/
public void initialize()
{
super.initialize();
//
// Register the ResourceContext provider on all new ControlContainerContext instances.
//
addService(org.apache.beehive.controls.api.context.ResourceContext.class,
ResourceContextImpl.getProvider());
}
/**
* Adds a new managed ResourceContext to the ControlContainerContext. This method
* is used to register a resource context that has just acquired resources
* @param resourceContext the ResourceContext service that has acquired resources
* @param bean the acquiring ControlBean. Unused by the base implementation, but
* available so subclassed containers can have access to the bean.
*/
protected synchronized void addResourceContext(ResourceContext resourceContext, ControlBean bean)
{
if (!resourceContext.hasResources())
_resourceContexts.push(resourceContext);
}
/**
* Removes a managed ResourceContext from the ControlContainerContext. This method
* is used to unregister a resource context that has already acquired resources
* @param resourceContext the ResourceContext service to be removed
* @param bean the acquiring ControlBean. Unused by the base implementation, but
* available so subclassed containers can have access to the bean.
*/
protected synchronized void removeResourceContext(ResourceContext resourceContext, ControlBean bean)
{
//
// Ignore removal requests received within the context of global cleanup. The
// stack is already being popped, so these are just requests for resources that
// already have in-flight removal taking place.
//
if (!_releasingAll && resourceContext.hasResources())
_resourceContexts.remove(resourceContext);
}
/**
* Releases all ResourceContexts associated with the current ControlContainerContext.
* This method is called by the associated container whenever all managed ResourceContexts
* that have acquired resources should release them.
*/
protected synchronized void releaseResources()
{
// Set the local flag indicating global resource release is occuring
_releasingAll = true;
//
// Iterate through the list of acquired ResourceContexts and release them
//
while (!_resourceContexts.empty())
{
ResourceContext resourceContext = _resourceContexts.pop();
resourceContext.release();
}
// Clear the local flag indicating global resource release is occuring
_releasingAll = false;
}
/**
* Dispatch an operation or an event to a bean within this container bean context.
* @param handle the control handle identifying the target bean
* @param event the event to be invoked on the target bean
* @param args the arguments to be passed to the target method invocation
*/
public Object dispatchEvent(ControlHandle handle, EventRef event, Object [] args)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException
{
ControlBean bean = getBean(handle.getControlID());
if (bean == null)
throw new IllegalArgumentException("Invalid bean ID: " + handle.getControlID());
return bean.dispatchEvent(event, args);
}
/**
* Returns a ControlHandle to the component containing the control. This handle can be
* used to dispatch events and operations to a control instance. This method will return
* null if the containing component does not support direct dispatch.
*
* @param bean the target control bean
*/
public ControlHandle getControlHandle(org.apache.beehive.controls.api.bean.ControlBean bean)
{
//
// The base implementation doesn't support dispatch. Containers should override
// and return a valid service handle that does component-specific dispatch.
//
return null;
}
/**
* Returns true if this container guarantees single-threaded behaviour. By default, top-level
* containers are assumed to NOT guarantee this; specific container implementations (for example,
* for EJB containers) should override this appropriately.
*/
public boolean isSingleThreadedContainer()
{
return false;
}
boolean _releasingAll;
Stack<ResourceContext> _resourceContexts = new Stack<ResourceContext>();
}

View File

@ -1,97 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.bean;
import org.apache.beehive.controls.api.bean.ControlInterface;
import org.apache.beehive.controls.api.bean.ControlExtension;
import org.apache.beehive.controls.api.ControlException;
/**
* Utilities used by the Controls runtime.
*/
public final class ControlUtils {
private ControlUtils() {}
/**
* Implements the default control implementation binding algorithm ( <InterfaceName> + "Impl" ). See
* documentation for the org.apache.beehive.controls.api.bean.ControlInterface annotation.
*
* @param implBinding the value of the defaultBinding attribute returned from a ControlInterface annotation
* @param controlClass the actual name of the interface decorated by the ControlInterface annotation
* @return the resolved defaultBinding value
*/
public static String resolveDefaultBinding( String implBinding, String controlClass )
{
int intfIndex = implBinding.indexOf(ControlInterface.INTERFACE_NAME);
if (intfIndex >= 0)
{
implBinding = implBinding.substring(0,intfIndex) + controlClass +
implBinding.substring(intfIndex +
ControlInterface.INTERFACE_NAME.length());
}
return implBinding;
}
/**
* Returns the default binding based entirely upon annotations or naming conventions.
* @param controlIntf the control interface class
* @return the class name of the default control implementation binding
*/
static String getDefaultControlBinding(Class controlIntf)
{
controlIntf = getMostDerivedInterface(controlIntf);
ControlInterface intfAnnot =
(ControlInterface)controlIntf.getAnnotation(ControlInterface.class);
String implBinding = intfAnnot.defaultBinding();
implBinding = resolveDefaultBinding( implBinding, controlIntf.getName() );
return implBinding;
}
/**
* Computes the most derived ControlInterface for the specified ControlExtension.
* @param controlIntf
* @return the most derived ControlInterface
*/
static Class getMostDerivedInterface(Class controlIntf)
{
while (controlIntf.isAnnotationPresent(ControlExtension.class))
{
Class [] intfs = controlIntf.getInterfaces();
boolean found = false;
for (int i = 0; i < intfs.length; i++)
{
if (intfs[i].isAnnotationPresent(ControlExtension.class) ||
intfs[i].isAnnotationPresent(ControlInterface.class))
{
controlIntf = intfs[i];
found = true;
break;
}
}
if (!found)
{
throw new ControlException("Can't find base control interface for " + controlIntf);
}
}
return controlIntf;
}
}

View File

@ -1,57 +0,0 @@
/*
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You 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.
$Header:$
*/
package org.apache.beehive.controls.runtime.bean;
import org.apache.beehive.controls.api.bean.ControlBean;
import org.apache.beehive.controls.api.context.ControlBeanContext;
import org.apache.beehive.controls.spi.context.ControlBeanContextFactory;
/**
* Default implementation of the {@link ControlBeanContextFactory} that simply creates an instance of a
* {@link ControlBeanContext} given the current {@link ControlBean}.
*/
/* package */ class DefaultControlBeanContextFactory
implements ControlBeanContextFactory {
/**
* Create the {@link ControlBeanContext} for the {@link ControlBean}.
* @param controlBean
* @return the {@link ControlBeanContext}
*/
public ControlBeanContext instantiate(ControlBean controlBean) {
if(!(controlBean instanceof org.apache.beehive.controls.runtime.bean.ControlBean))
throw new IllegalArgumentException("The ControlBean of type \"" +
controlBean.getClass().getName() +
"\" is unsupported. The ControlBean must extend " +
org.apache.beehive.controls.runtime.bean.ControlBean.class.getName());
/*
The provided ControlBean is a "api.bean.ControlBean"; this factory implementation only creates
ControlBeanContext implementations for "runtime.bean.ControlBean" types. Ensuare that this is
of that type.
*/
org.apache.beehive.controls.runtime.bean.ControlBean runtimeControlBean =
(org.apache.beehive.controls.runtime.bean.ControlBean)controlBean;
/*
Create a simple new ControlBeanContext.
*/
return new org.apache.beehive.controls.runtime.bean.ControlBeanContext(runtimeControlBean);
}
}

View File

@ -1,31 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.bean;
/**
* The EventAdaptor interface will be implemented by all code-generated event adaptor classes
* used to deliver control events to clients.
*/
public interface EventAdaptor
{
/**
* Returns the client instance that will be the target of the event.
*/
Object getClient();
}

View File

@ -1,74 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.bean;
import java.util.Iterator;
import java.util.LinkedList;
/**
* The EventNotifier class provides basic callback listener management and event delivery
* services for ControlBean instances.
*/
public class EventNotifier implements java.io.Serializable
{
/**
* Adds a new callback event listener for this EventNotifier
*/
synchronized public void addListener(Object listener)
{
_listeners.add(listener);
}
/**
* Remove an existing callback event listener for this EventNotifier
*/
synchronized public void removeListener(Object listener)
{
if (!_listeners.contains(listener))
throw new IllegalStateException("Invalid listener, not currently registered");
_listeners.remove(listener);
}
/**
* Returns an iterator over the full set of listeners
*/
public Iterator listenerIterator()
{
return _listeners.iterator();
}
/**
* Returns the number of registered listeners
*/
public int getListenerCount()
{
return _listeners.size();
}
/**
* Returns the listener list in array form
*/
public void getListeners(Object [] listeners)
{
_listeners.toArray(listeners);
}
private LinkedList _listeners = new LinkedList();
}

View File

@ -1,75 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.bean;
/**
* The ImplInitializer class is an abstract base class that all generated Control
* initalization classes will extend. It provides common utilities and supporting code
* for initialization, and has a shared package relationship with the base ControlBean
* class providing access to internals not available in a more general context.
*/
abstract public class ImplInitializer
{
/**
* Initializes a new ControlImplementation instance associated with the specified bean.
*/
public void initialize(ControlBean bean, Object target)
{
initServices(bean, target);
initControls(bean, target);
initEventProxies(bean, target);
}
/**
* Initializes all contextual services required by the target implementation instance.
* The default initializer implementation is a noop, but will be overridden by
* generated subclasses that contain contextual services.
*/
public void initServices(ControlBean bean, Object target) { };
/**
* Resets all contextual services on the target implementation instance to null.
* The default initializer implementation is a noop, but will be overridden by
* generated subclasses that contain contextual services.
*/
public void resetServices(ControlBean bean, Object target) { };
/**
* Initializes all nested controls required by the target implementation instance.
* The default initializer implementation is a noop, but will be overridden by
* generated subclasses that contain nested controls
*/
public void initControls(ControlBean bean, Object target) { };
/**
* Initializes all event proxies required by the target implementation instance.
* The default initializer implementation is a noop, but will be overridden by
* generated subclasses that contain event proxies
*/
public void initEventProxies(ControlBean bean, Object target) { };
/**
* Returns the ControlBean event notifier for the specified eventSet
*/
public Object getEventNotifier(ControlBean bean, Class eventSet)
{
return bean.getEventNotifier(eventSet);
}
}

View File

@ -1,71 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.bean;
import java.beans.BeanInfo;
import java.beans.DefaultPersistenceDelegate;
import java.beans.Encoder;
import java.beans.Expression;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PersistenceDelegate;
import java.beans.PropertyDescriptor;
import java.beans.Statement;
import java.beans.XMLEncoder;
import java.util.Set;
import org.apache.beehive.controls.api.ControlException;
/**
* The ImplPersistenceDelegate class supports the XML persistance of Control Implementation
* instances by implementing the <code>java.beans.PersistenceDelegate</b> API, and overriding
* the default persistance algorithm based upon the runtime structure for Controls.
* <p>
*/
public class ImplPersistenceDelegate extends DefaultPersistenceDelegate
{
/**
* PersistenceDelegate.instantiate()
*/
protected Expression instantiate(Object oldInstance, Encoder out)
{
//
// An implementation instance is actually constructed at decode time by calling
// ControlBean.ensureControl on the parent bean. This will create a new impl
// instance and run the impl initializer on it.
//
return new Expression(((XMLEncoder)out).getOwner(), "ensureControl", null);
}
/**
* PersistenceDelegate.initialize()
*/
protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out)
{
super.initialize(type, oldInstance, newInstance, out);
}
/**
* PersistenceDelegate.writeObject()
*/
public void writeObject(Object oldInstance, Encoder out)
{
super.writeObject(oldInstance, out);
}
}

View File

@ -1,118 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.bean;
import java.util.ArrayList;
import java.util.Set;
import java.util.HashSet;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;
/**
* Class used to support prioritizing interceptors on methods of a {@link ControlBean}.
*/
public final class InterceptorUtils {
private InterceptorUtils() {}
/**
* Filename that contains ordering priority for controls interceptor services.
* Each line in the file is a fully qualified interface name. The first line in the file
* is highest priority.
*/
public static final String INTERCEPTOR_CONFIG_FILE = "controls-interceptors.config";
// todo: this interceptor priority list should be stored by ClassLoader instead of shared between them
/**
* List that keeps track of the interceptors in their priority order.
*/
private static ArrayList<String> _interceptorPriorities;
/**
* Applies externally defined (via {@link #INTERCEPTOR_CONFIG_FILE}) ordering priority for
* controls interceptor services.
*
* @param interceptors
* @return String[]
*/
public static String[] prioritizeInterceptors( String [] interceptors )
{
if ( interceptors == null )
return null;
// Read external configuration to obtain desired prioritization.
if ( _interceptorPriorities == null )
{
// Only attempt to read the external configuration once; bounce the VM if you
// want to try again.
_interceptorPriorities = new ArrayList<String>();
BufferedReader in = null;
try
{
InputStream configFileStream =
ControlBeanContext.class.getClassLoader().getResourceAsStream( INTERCEPTOR_CONFIG_FILE );
if ( configFileStream != null )
{
in = new BufferedReader(new InputStreamReader(configFileStream));
String str;
while ((str = in.readLine()) != null)
_interceptorPriorities.add(str);
}
}
catch (IOException e)
{
// ignore
}
finally
{
try {
if (in != null)
in.close();
}
catch ( IOException ie ) { /* ignore */ }
}
}
// Put input list of interceptors into a Set for easy lookup
Set<String> input = new HashSet<String>();
for ( String ii : interceptors )
input.add( ii );
// Scan through priorities list, building a prioritized list
ArrayList<String> prioritized = new ArrayList<String>(interceptors.length);
for ( String p : _interceptorPriorities )
{
if ( input.contains(p) )
{
input.remove(p);
prioritized.add(p);
}
}
// Anything still left in the input set did not have a priority associated with it,
// so they just go at the end in arbitrary order.
for ( String p : input )
prioritized.add(p);
return prioritized.toArray(new String[prioritized.size()]);
}
}

View File

@ -1,42 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.bean;
import java.lang.reflect.Method;
/**
* The InvokeListener interface can be implemented by contextual services or helper
* classes associated with a ControlBean that want pre/post hook notifications of
* invocations occuring on a ControlBean.
*
* Hooking is "read only". An InvokeListener cannot modify the invoked method,
* arguments, return value or thrown exceptions in any way.
*/
public interface InvokeListener extends java.util.EventListener
{
/**
* Called just prior to invoking an operation or callback event on a control.
*/
public void preInvoke(Method m, Object [] args);
/**
* Called just after inovcation of an operation or callback event on a control
*/
public void postInvoke(Object retval, Throwable t);
}

View File

@ -1,172 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.bean;
import java.beans.beancontext.BeanContextServiceProvider;
import java.beans.beancontext.BeanContextServices;
import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.Vector;
import org.apache.beehive.controls.api.context.ResourceContext;
/**
* The ResourceContextImpl class provides an implementation of the ResourceContext service,
* as well as a simple singleton provider that can be used to obtain new instances.
*/
public class ResourceContextImpl implements ResourceContext, InvokeListener
{
/**
* The ResourceContextProvider inner class acts as a single BeanContext service
* provider for the ResourceContext service class.
*/
private static class ResourceContextProvider
implements BeanContextServiceProvider {
//
// BeanContextServiceProvider.getService()
//
public Object getService(BeanContextServices bcs, Object requestor, Class serviceClass, Object serviceSelector)
{
//
// There is an implied contract between ControlContainerContext and ControlBean
// classes required to implement the resource management contract. This cannot
// be supported for any generic BeanContextChild class.
//
if (requestor instanceof ControlBean)
{
return new ResourceContextImpl((ControlContainerContext)bcs, (ControlBean)requestor);
}
return null;
}
//
// BeanContextServiceProvider.releaseService()
//
public void releaseService(BeanContextServices bcs, Object requestor, Object service)
{
return; // Should not happen, service is never unregistered
}
//
// BeanContextServiceProvider.getContextServiceSelectors()
//
public Iterator getCurrentServiceSelectors(BeanContextServices bcs, Class serviceClass)
{
return null; // no selectors
}
}
/**
* A singleton instance of the ResourceContextProvider class is what will be registered
* on all ControlContainerContext instances. The provider can be a singleton because it is
* completely stateless and thread-safe.
*/
static private ResourceContextProvider _theProvider = new ResourceContextProvider();
/**
* Returns the ResourceContextProvider used to create new ResourceContext instances
*/
static /* package */ ResourceContextProvider getProvider() { return _theProvider; }
/**
* Constructs a new ResourceContext service implementation to manage resources for
* a target ControlBean within a specific ControlContainerContext
*/
public ResourceContextImpl(ControlContainerContext containerContext, ControlBean bean)
{
_containerContext = containerContext;
_bean = bean;
//
// Register to receive invocation notifications from the target bean
//
_bean.addInvokeListener(this);
}
/**
* Implements the InvokeListener.preInvoke method. This hook will be called before the
* managed beans' operations are invoked
*/
public void preInvoke(Method m, Object [] args)
{
if (!_hasAcquired)
acquire();
}
/**
* Implements the InvokeListener.postInvoke method.
*/
public void postInvoke(Object retval, Throwable t) {}
// ResourceContext.acquire()
public void acquire()
{
if (_hasAcquired)
return;
// Deliver the onAcquire event to registered listeners
for (ResourceEvents resourceListener : _listeners)
resourceListener.onAcquire();
// Register this ResourceContext with associated container context
_containerContext.addResourceContext(this, _bean);
// Set the flag to indicate resources have been acquired.
_hasAcquired = true;
}
// ResourceContext.release()
public void release()
{
if (!_hasAcquired)
return;
// Deliver the onRelease event to the registered listeners
for (ResourceEvents resourceListener : _listeners)
resourceListener.onRelease();
// Unregister this ResourceContext with associated container context
_containerContext.removeResourceContext(this, _bean);
// Reset the flag to indicate resources have been released.
_hasAcquired = false;
}
// ResourceContext.hasResources()
public boolean hasResources() { return _hasAcquired; }
// ResourceContext.addResourceEventsListener
public void addResourceEventsListener(ResourceEvents resourceListener)
{
_listeners.add(resourceListener);
}
// ResourceContext.removeResourceEventsListener
public void removeResourceEventsListener(ResourceEvents resourceListener)
{
_listeners.remove(resourceListener);
}
private Vector<ResourceEvents> _listeners = new Vector<ResourceEvents>();
private boolean _hasAcquired = false;
private ControlContainerContext _containerContext;
private ControlBean _bean;
}

View File

@ -1,80 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.bean;
import java.util.TooManyListenersException;
/**
* The UnicastEventNotifier class provides basic callback listener management and event delivery
* services for unicast EventSets on ControlBean instances.
*/
public class UnicastEventNotifier implements java.io.Serializable
{
/**
* Adds a new callback event listener for this EventNotifier. This method will also
* perform a check to see if there is already a register listener, and throw a
* <code>java.util.TooManyListenersException</code> if there is already a registered
* listener.
*/
synchronized public void addListener(Object listener) throws TooManyListenersException
{
if (_listener != null)
throw new TooManyListenersException("Callback listener is already registered");
_listener = listener;
}
/**
* Remove an existing callback event listener for this EventNotifier
*/
synchronized public void removeListener(Object listener)
{
if (_listener != listener)
{
throw new IllegalStateException("Invalid listener, not currently registered");
}
_listener = null;
}
/**
* Returns the listener associated with this EventNotifier
*/
public Object getListener()
{
return _listener;
}
/**
* Returns the number of registered listeners
*/
public int getListenerCount()
{
return (_listener != null) ? 1 : 0;
}
/**
* Returns the listener list in array form
*/
public void getListeners(Object [] listeners)
{
if (_listener != null)
listeners[0] = _listener;
}
private Object _listener;
}

View File

@ -1,105 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.bean;
import java.beans.beancontext.BeanContextServices;
import java.beans.beancontext.BeanContextServiceProvider;
import java.util.Iterator;
import java.util.Collections;
import org.apache.beehive.controls.spi.context.ControlBeanContextFactory;
import org.apache.beehive.controls.runtime.webcontext.ControlBeanContextServicesSupport;
/**
* <p>
* This class acts as a ControlBeanContextFactoryProvider that exposes this factory as a contextual service
* from inside of a ControlBeanContext.
* </p>
* <p>
* <b>Note:</b> This class, the service provider, and the contextual service it provides are considerd an implementation
* detail and <b>should not</b> be used from user code.
* </p>
*/
public class WebContextFactoryProvider
implements BeanContextServiceProvider {
private static final WebContextFactoryProvider theProvider = new WebContextFactoryProvider();
private static final WebControlBeanContextFactory theFactory = new WebControlBeanContextFactory();
public static final ControlBeanContext.BeanContextServicesFactory WEB_CONTEXT_BCS_FACTORY =
new WebContextBeanContextServicesFactory();
public static BeanContextServiceProvider getProvider() {
return theProvider;
}
private WebContextFactoryProvider() {
}
public Object getService(BeanContextServices bcs, Object requestor, Class serviceClass, Object serviceSelector) {
return theFactory;
}
public void releaseService(BeanContextServices bcs, Object requestor, Object service) {
}
public Iterator getCurrentServiceSelectors(BeanContextServices bcs, Class serviceClass) {
return Collections.EMPTY_LIST.iterator();
}
/**
* <p>
* {@link ControlBeanContextFactory} implementation that provides a {@link ControlBeanContext} object
* used for web-tier control containment.
* </p>
* <p>
* <b>Note:</b> This factory is considerd an implementation detail and <b>should not</b> be referenced from user code.
* </p>
*/
/*package*/ static class WebControlBeanContextFactory
implements ControlBeanContextFactory {
public org.apache.beehive.controls.api.context.ControlBeanContext instantiate
(org.apache.beehive.controls.api.bean.ControlBean controlBean) {
if(!(controlBean instanceof ControlBean))
throw new IllegalArgumentException("The ControlBean of type \"" +
controlBean.getClass().getName() +
"\" is unsupported. The ControlBean must extend " +
ControlBean.class.getName());
ControlBean runtimeControlBean = (ControlBean)controlBean;
return new ControlBeanContext(runtimeControlBean, WEB_CONTEXT_BCS_FACTORY);
}
}
/*package*/ static class WebContextBeanContextServicesFactory
extends ControlBeanContext.BeanContextServicesFactory {
protected BeanContextServices instantiate(ControlBeanContext controlBeanContext) {
return new ControlBeanContextServicesSupport(controlBeanContext);
/* The java implementation of the BeanContext support classes,
not currently used by Beehive due to performance issues.
return new java.beans.beancontext.BeanContextServicesSupport(controlBeanContext);
*/
}
}
}

View File

@ -1,87 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.generator;
import java.util.HashMap;
import java.util.Map;
import com.sun.mirror.declaration.AnnotationMirror;
import com.sun.mirror.declaration.AnnotationTypeElementDeclaration;
import com.sun.mirror.declaration.AnnotationValue;
/**
* The AptAnnotationHelper class is a helper class that aids in the reading of annotation
* values using APT metadata
*/
public class AptAnnotationHelper
{
/**
* Initialize a new helper instance based upon a specific annotation declaration.
* @param annot The annotation value declaration
*/
public AptAnnotationHelper(AnnotationMirror annot)
{
//
// Build maps from the element name to its declaration and values
//
Map <AnnotationTypeElementDeclaration,AnnotationValue> elemValues =
annot.getElementValues();
for (AnnotationTypeElementDeclaration ated : elemValues.keySet())
{
_elementMap.put(ated.getSimpleName(), ated);
_valueMap.put(ated.getSimpleName(), elemValues.get(ated));
}
};
/**
* Returns the AnnotationTypeElementDeclaration for a particular element
*/
public AnnotationTypeElementDeclaration getElementDeclaration(String elemName)
{
if (_elementMap.containsKey(elemName))
return _elementMap.get(elemName);
return null;
}
/**
* Returns the value of a particular element as a String
*/
public String getStringValue(String elemName)
{
if (_valueMap.containsKey(elemName))
return _valueMap.get(elemName).toString();
return null;
}
/**
* Returns the value of a particular element as an Object
*/
public Object getObjectValue(String elemName)
{
if (_valueMap.containsKey(elemName))
return _valueMap.get(elemName).getValue();
return null;
}
private HashMap<String,AnnotationTypeElementDeclaration> _elementMap =
new HashMap<String,AnnotationTypeElementDeclaration>();
private HashMap<String,AnnotationValue> _valueMap =
new HashMap<String,AnnotationValue>();
}

View File

@ -1,43 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.generator;
import java.util.ArrayList;
import com.sun.mirror.apt.AnnotationProcessorEnvironment;
import com.sun.mirror.declaration.FieldDeclaration;
/**
* The AptClientField class describes a reference to a client callback notifier within an
* AptControlImplementation class.
*/
public class AptClientField extends AptField
{
/**
* Base constructor, protected so only a custom subclass can invoke
* @param controlImpl the declaring AptControlImplementation
*/
public AptClientField(AptControlImplementation controlImpl, FieldDeclaration fieldDecl)
{
super(fieldDecl);
_controlImpl = controlImpl;
};
private AptControlImplementation _controlImpl;
}

View File

@ -1,67 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.generator;
import com.sun.mirror.declaration.FieldDeclaration;
import com.sun.mirror.type.InterfaceType;
import com.sun.mirror.type.TypeMirror;
import org.apache.beehive.controls.runtime.generator.apt.TwoPhaseAnnotationProcessor;
/**
* The AptContextField class contains information about a field referring to a contextual
* service with an AptControlImplementation class.
*/
public class AptContextField extends AptEventField
{
/**
* Base constructor, protected so only a custom subclass can invoke
* @param controlImpl the declaring ControlImplementation
*/
public AptContextField(AptControlImplementation controlImpl, FieldDeclaration fieldDecl,
TwoPhaseAnnotationProcessor ap)
{
super(fieldDecl);
_controlImpl = controlImpl;
_ap = ap;
};
/**
* Initializes a ControlInterface associated with this context field. Because
* contextual services can expose both APIs and events, they are similar to controls.
*/
protected AptControlInterface initControlInterface()
{
TypeMirror fieldType = _fieldDecl.getType();
if (! (fieldType instanceof InterfaceType))
{
_ap.printError( _fieldDecl, "context.field.badinterface" );
return null;
}
//
// For contextual services, the declared type of the field is always the public
// interface for the contextual service.
//
return new AptControlInterface(((InterfaceType)_fieldDecl.getType()).getDeclaration(),
_ap);
}
private AptControlImplementation _controlImpl;
private TwoPhaseAnnotationProcessor _ap;
}

View File

@ -1,406 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.generator;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.io.IOException;
import java.io.Writer;
import com.sun.mirror.apt.Filer;
import com.sun.mirror.declaration.*;
import com.sun.mirror.type.TypeMirror;
import com.sun.mirror.type.ClassType;
import org.apache.beehive.controls.api.events.EventHandler;
import org.apache.beehive.controls.runtime.generator.apt.TwoPhaseAnnotationProcessor;
/**
* The AptControlClient class contains metadata about a class that contains nested control
* references (AptControlField).
*/
public class AptControlClient extends AptType implements Generator
{
/**
* Constructs a new ControlClient instance where information is derived
* from APT metadata
* @param decl the annotated declaration
*/
public AptControlClient(Declaration decl, TwoPhaseAnnotationProcessor ap)
{
_ap = ap;
if (! (decl instanceof ClassDeclaration))
{
_ap.printError( decl, "control.illegal.usage" );
return;
}
_clientDecl = (ClassDeclaration)decl;
setDeclaration(_clientDecl);
_controls = initControls();
initEventAdaptors();
//
// Construct a new initializer class from this implementation class
//
_init = new ClientInitializer(this);
}
/**
* Returns true if this type of client requires that nested controls have unique identifiers
*/
protected boolean needsUniqueID()
{
//
// BUGBUG:
// Pageflows need to have a more unique ID generated for fields, because multiple pageflows
// may be shared within a single ControlContainerContext, and just using the field name could
// result in collisions. A better (and less hard-wired) approach is needed than searching for
// specific annotations. Perhaps a model that enables particular client types to subclass
// AptControlClient and override getID() would be much better.
//
for (AnnotationMirror annotMirror : _clientDecl.getAnnotationMirrors())
{
String annotType = annotMirror.getAnnotationType().toString();
if (annotType.equals("org.apache.beehive.netui.pageflow.annotations.Jpf.Controller") ||
annotType.equals("org.apache.beehive.netui.pageflow.annotations.Jpf.Backing"))
return true;
}
return false;
}
/**
* Returns a unique ID for a control field
*/
public String getID(AptControlField control)
{
if (!needsUniqueID())
return "\"" + control.getName() + "\"";
return "client.getClass() + \"@\" + client.hashCode() + \"." + control.getClassName() + "." + control.getName() + "\"";
}
/**
* Returns the list of ControlFields declared directly by this ControlImpl
*/
public ArrayList<AptControlField> getControls() { return _controls; }
/**
* Returns true if the implemenation class contains any nested controls
*/
public boolean hasControls() { return _controls.size() != 0; }
/**
* Returns true if the control client needs field initialization support
*/
public boolean needsFieldInit()
{
return hasControls();
}
/**
* Returns the field with the specified name
*/
public AptField getField(String name)
{
for (AptField field : _controls)
if (field.getName().equals(name))
return field;
return null;
}
/**
* Returns the list of fully qualified class names for types that are derived
* from this Generator
*/
public String [] getGeneratedTypes()
{
return new String [] { _init.getClassName() };
}
/**
* Returns the information necessary to generate a ImplInitializer from this
* ControlImplementation.
*/
public List<GeneratorOutput> getCheckOutput(Filer filer) throws IOException
{
return null;
}
/**
* Returns the information necessary to generate a ClientInitializer from this control
*/
public List<GeneratorOutput> getGenerateOutput(Filer filer) throws IOException
{
HashMap<String,Object> map = new HashMap<String,Object>();
map.put("client", this); // control client
map.put("init", _init); // control client initializer
Writer writer = new IndentingWriter(filer.createSourceFile(_init.getClassName()));
GeneratorOutput genOut =
new GeneratorOutput(writer,"org/apache/beehive/controls/runtime/generator/ClientInitializer.vm",
map);
ArrayList<GeneratorOutput> genList = new ArrayList<GeneratorOutput>(1);
genList.add(genOut);
return genList;
}
/**
* Initializes the list of ControlFields declared directly by this ControlClient
*/
protected ArrayList<AptControlField> initControls()
{
ArrayList<AptControlField> controls = new ArrayList<AptControlField>();
if ( _clientDecl == null || _clientDecl.getFields() == null )
return controls;
Collection<FieldDeclaration> declaredFields = _clientDecl.getFields();
for (FieldDeclaration fieldDecl : declaredFields)
{
if (fieldDecl.getAnnotation(org.apache.beehive.controls.api.bean.Control.class) != null)
controls.add(new AptControlField(this, fieldDecl, _ap));
}
return controls;
}
public boolean hasSuperClient()
{
return ( getSuperClientName() != null );
}
/**
* Returns the fully qualified classname of the closest control client in the inheritance chain.
* @return class name of the closest control client
*/
public String getSuperClientName()
{
ClassType superType = _clientDecl.getSuperclass();
while ( superType != null )
{
ClassDeclaration superDecl = superType.getDeclaration();
Collection<FieldDeclaration> declaredFields = superDecl.getFields();
for (FieldDeclaration fieldDecl : declaredFields)
{
if (fieldDecl.getAnnotation(org.apache.beehive.controls.api.bean.Control.class) != null)
{
// Found an @control annotated field, so return this class name
return superDecl.getQualifiedName();
}
}
superType = superType.getSuperclass();
}
return null;
}
/**
* Returns the super class for this class
*/
public AptControlClient getSuperClass() { return null; }
/**
* Initializes the list of EventAdaptors for this ControlImpl
*/
protected void initEventAdaptors()
{
if ( _clientDecl == null || _clientDecl.getMethods() == null )
return;
for (MethodDeclaration clientMethod : _clientDecl.getMethods())
{
//
// Do a quick check for the presence of the EventHandler annotation on methods
//
if (clientMethod.getAnnotation(EventHandler.class) == null ||
clientMethod.toString().equals("<clinit>()"))
continue;
//
// EventHandler annotations on private methods cause compilation error.
//
if (isPrivateMethod(clientMethod))
{
_ap.printError( clientMethod, "eventhandler.method.is.private");
continue;
}
//
// If found, we must actually read the value using an AnnotationMirror, since it
// contains a Class element (eventSet) that cannot be loaded
//
AnnotationMirror handlerMirror = null;
for (AnnotationMirror annot : clientMethod.getAnnotationMirrors())
{
if ( annot == null ||
annot.getAnnotationType() == null ||
annot.getAnnotationType().getDeclaration() == null ||
annot.getAnnotationType().getDeclaration().getQualifiedName() == null )
return;
if ( annot.getAnnotationType().getDeclaration().getQualifiedName().equals(
"org.apache.beehive.controls.api.events.EventHandler"))
{
handlerMirror = annot;
break;
}
}
if (handlerMirror == null)
{
throw new CodeGenerationException("Unable to find EventHandler annotation on " +
clientMethod);
}
AptAnnotationHelper handlerAnnot = new AptAnnotationHelper(handlerMirror);
//
// Locate the EventField based upon the field element value
//
String fieldName = (String)handlerAnnot.getObjectValue("field");
AptEventField eventField = (AptEventField)getField(fieldName);
if (eventField == null)
{
// Deliberately not issuing a diagnostic if an event handler specifies
// a field that isn't a control. Other annotation processors also
// handle event handlers, so delegate diagnostic responsibility to them.
continue;
}
//
// Locate the EventSet based upon the eventSet element value
//
Object tmo = handlerAnnot.getObjectValue("eventSet");
if (!(tmo instanceof TypeMirror))
continue;
TypeMirror tm = (TypeMirror)tmo;
String setName = tm.toString();
AptControlInterface controlIntf = eventField.getControlInterface();
AptEventSet eventSet = controlIntf.getEventSet(setName);
// todo: remove workaround once bug has been resolved.
/* Workaround JIRA issue BEEHIVE-1143, eventset name may
contain a '$' seperator between the outer class and inner class.
Should be a '.' seperator. Only applies to Eclipse APT. This
workaround is also present in AptControlImplementation.initEventAdapters
*/
if (tm.getClass().getName().startsWith("org.eclipse.")) {
setName = setName.replace('$', '.');
}
// end of workaround
if (eventSet == null)
{
_ap.printError( clientMethod, "eventhandler.eventset.not.found", setName );
continue;
}
//
// Register a new EventAdaptor for the EventSet, if none exists already
//
EventAdaptor adaptor = eventField.getEventAdaptor(eventSet);
if (adaptor == null)
{
adaptor = new EventAdaptor(eventField, eventSet);
eventField.addEventAdaptor(eventSet, adaptor);
}
//
// Locate the EventSet method based upon the eventName element value. Once
// found, add a new AptEventHandler to the adaptor for this event.
//
boolean found = false;
String eventName = (String)handlerAnnot.getObjectValue("eventName");
AptMethod handlerMethod = new AptMethod(clientMethod, _ap);
//
// Will start at the currrent event set and look up through any ones it
// extends to try and find a matching event
//
while (eventSet != null)
{
for (AptEvent controlEvent : eventSet.getEvents())
{
if (controlEvent == null ||
controlEvent.getName() == null ||
!controlEvent.getName().equals(eventName))
continue;
if ( controlEvent.getArgTypes() == null )
continue;
//
// BUGBUG: If the arguments are parameterized, then the event handler
// might declare a specific bound version of the type, so a direct
// comparison will fail. If parameterized, we don't validate.
//
if (controlEvent.hasParameterizedArguments() ||
(controlEvent.getArgTypes().equals(handlerMethod.getArgTypes()) &&
controlEvent.getReturnType().equals(handlerMethod.getReturnType())
)
)
{
HashSet<String> throwSet = new HashSet<String>(controlEvent.getThrowsList());
ArrayList<String> handlerThrows = handlerMethod.getThrowsList();
boolean throwsMatches = true;
for ( String t : handlerThrows )
{
if ( !throwSet.contains(t) )
throwsMatches = false;
}
if ( !throwsMatches )
{
_ap.printError( clientMethod, "eventhandler.throws.mismatch", handlerMethod.getName() );
}
adaptor.addHandler(controlEvent,
new AptEventHandler(controlEvent, clientMethod, _ap ));
found = true;
break;
}
}
if (found) // outer loop too
break;
//
// Look up on the super event set if not found at the current level
//
eventSet = eventSet.getSuperEventSet();
}
if (!found)
{
_ap.printError( clientMethod, "eventhandler.method.not.found", setName );
}
}
}
ClassDeclaration _clientDecl;
TwoPhaseAnnotationProcessor _ap;
ArrayList<AptControlField> _controls;
ClientInitializer _init;
}

View File

@ -1,181 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.generator;
import java.util.Collection;
import com.sun.mirror.declaration.ClassDeclaration;
import com.sun.mirror.declaration.FieldDeclaration;
import com.sun.mirror.declaration.InterfaceDeclaration;
import com.sun.mirror.declaration.TypeDeclaration;
import com.sun.mirror.type.DeclaredType;
import com.sun.mirror.type.InterfaceType;
import com.sun.mirror.type.TypeMirror;
import com.sun.mirror.type.MirroredTypeException;
import org.apache.beehive.controls.api.bean.ControlExtension;
import org.apache.beehive.controls.api.bean.ControlInterface;
import org.apache.beehive.controls.api.bean.Control;
import org.apache.beehive.controls.api.versioning.VersionRequired;
import org.apache.beehive.controls.runtime.generator.apt.TwoPhaseAnnotationProcessor;
/**
* The AptControlField class contains information about a field that refers to a nested control.
*/
public class AptControlField extends AptEventField
{
/**
* Base constructor, protected so only a custom subclass can invoke
* @param controlClient the declaring AptType
*/
public AptControlField(AptType controlClient, FieldDeclaration controlDecl,
TwoPhaseAnnotationProcessor ap)
{
super( controlDecl );
_controlClient = controlClient;
_ap = ap;
_controlBean = new ControlBean(getControlInterface());
}
/**
* Does this control field have a VersionRequired annotation?
* @return <code>true</code> if there is a version required annotation; <code>false</code> otherwise
*/
public boolean hasVersionRequired()
{
return ( _fieldDecl.getAnnotation( VersionRequired.class ) != null );
}
/**
* Initializes the ControlInterface associated with this ControlField
*/
protected AptControlInterface initControlInterface()
{
TypeMirror controlType = _fieldDecl.getType();
if (! (controlType instanceof DeclaredType))
{
_ap.printError( _fieldDecl, "control.field.bad.type" );
return null;
}
//
// The field can either be declared as the bean type or the public interface type.
// If it is the bean type, then we need to reflect to find the public interface
// type it implements.
//
TypeDeclaration typeDecl = ((DeclaredType)controlType).getDeclaration();
InterfaceDeclaration controlIntf = null;
//
// It is possible that the declared type is associated with a to-be-generated
// bean type. In this case, look for the associated control interface on the
// processor input list.
//
if ( typeDecl == null )
{
String className = controlType.toString();
String intfName = className.substring(0, className.length() - 4);
String interfaceHint = getControlInterfaceHint();
controlIntf = (InterfaceDeclaration)_ap.getAnnotationProcessorEnvironment().getTypeDeclaration(intfName);
if (controlIntf == null)
{
// The specified class name may not be fully qualified. In this case, the
// best we can do is look for a best fit match against the input types
for (TypeDeclaration td :_ap.getAnnotationProcessorEnvironment().getSpecifiedTypeDeclarations())
{
// if an interface hint was provided, use it to find the control interface,
// if not provided try to find the control interface by matching simple names.
if (interfaceHint != null) {
if (td instanceof InterfaceDeclaration &&
td.getQualifiedName().equals(interfaceHint))
{
controlIntf = (InterfaceDeclaration)td;
break;
}
}
else {
if (td instanceof InterfaceDeclaration &&
td.getSimpleName().equals(intfName))
{
controlIntf = (InterfaceDeclaration)td;
break;
}
}
}
}
}
else if (typeDecl instanceof ClassDeclaration)
{
Collection<InterfaceType> implIntfs = ((ClassDeclaration)typeDecl).getSuperinterfaces();
for (InterfaceType intfType : implIntfs)
{
InterfaceDeclaration intfDecl = intfType.getDeclaration();
if ( intfDecl == null )
return null;
if (intfDecl.getAnnotation(ControlInterface.class) != null||
intfDecl.getAnnotation(ControlExtension.class) != null)
{
controlIntf = intfDecl;
break;
}
}
}
else if (typeDecl instanceof InterfaceDeclaration)
{
controlIntf = (InterfaceDeclaration)typeDecl;
}
if (controlIntf == null)
{
_ap.printError( _fieldDecl, "control.field.bad.type.2" );
return null;
}
return new AptControlInterface(controlIntf, _ap);
}
/**
* Get the interface hint attribute value (as a string) from the Control annotation,
* if it wasn't specified return null.
*/
private String getControlInterfaceHint() {
Control controlAnnotation = _fieldDecl.getAnnotation(Control.class);
String interfaceHint = null;
try {
// always excepts
controlAnnotation.interfaceHint();
} catch (MirroredTypeException mte) {
interfaceHint = ("java.lang.Object".equals(mte.getQualifiedName())) ? null : mte.getQualifiedName();
}
return interfaceHint;
}
/**
* Returns the ControlBean associated with this ControlField
*/
public ControlBean getControlBean() { return _controlBean; }
private TwoPhaseAnnotationProcessor _ap;
private AptType _controlClient;
private ControlBean _controlBean;
}

View File

@ -1,516 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.generator;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import com.sun.mirror.apt.Filer;
import com.sun.mirror.declaration.AnnotationMirror;
import com.sun.mirror.declaration.ClassDeclaration;
import com.sun.mirror.declaration.Declaration;
import com.sun.mirror.declaration.FieldDeclaration;
import com.sun.mirror.declaration.InterfaceDeclaration;
import com.sun.mirror.declaration.MethodDeclaration;
import com.sun.mirror.type.InterfaceType;
import com.sun.mirror.type.TypeMirror;
import org.apache.beehive.controls.api.bean.ControlImplementation;
import org.apache.beehive.controls.api.events.Client;
import org.apache.beehive.controls.api.events.EventHandler;
import org.apache.beehive.controls.api.versioning.VersionSupported;
import org.apache.beehive.controls.api.versioning.Version;
import org.apache.beehive.controls.runtime.generator.apt.TwoPhaseAnnotationProcessor;
/**
* The AptControlImplementation class provides validation and metadata management when
* processing a ControlImplementation class.
*/
public class AptControlImplementation extends AptType implements Generator
{
/**
* Constructs a new AptControlImplementation instance where information is derived
* from APT metadata
* @param decl the annotated declaration
*/
public AptControlImplementation(Declaration decl, TwoPhaseAnnotationProcessor ap)
{
_ap = ap;
if (! (decl instanceof ClassDeclaration))
{
_ap.printError( decl, "control.implementation.badclass" );
return;
}
_implDecl = (ClassDeclaration)decl;
setDeclaration(_implDecl);
_superClass = initSuperClass();
_contexts = initContexts();
_controls = initControls();
_clients = initClients();
initEventAdaptors();
//
// Check serializability of the implementation class. Any non-transient implementation
// must implement the java.io.Serializable marker interface to indicate that the author
// has considered serializability.
//
ControlImplementation implAnnot = _implDecl.getAnnotation(ControlImplementation.class);
if (!implAnnot.isTransient())
{
if (!isSerializable())
{
_ap.printError( decl, "control.implementation.unserializable" );
}
}
//
// Construct a new initializer class from this implementation class
//
_init = new ImplInitializer(this);
if ( getControlInterface() == null )
{
_ap.printError( decl, "control.implementation.missing.interface" );
return;
}
_versionSupported = initVersionSupported();
enforceVersionSupported();
}
/**
* Initializes the super interface that this ControlImpl extends (or null if a
* base class)
*/
private AptControlImplementation initSuperClass()
{
if ( _implDecl == null || _implDecl.getSuperclass() == null )
return null;
ClassDeclaration superDecl = _implDecl.getSuperclass().getDeclaration();
if (superDecl != null &&
superDecl.getAnnotation(org.apache.beehive.controls.api.bean.ControlImplementation.class) != null)
{
return new AptControlImplementation(superDecl, _ap);
}
return null;
}
/**
* Returns the super interface for this interface
*/
public AptControlImplementation getSuperClass() { return _superClass; }
/**
* Initializes the list of ContextField declared directly by this ControlImpl
*/
private ArrayList<AptContextField> initContexts()
{
ArrayList<AptContextField> contexts = new ArrayList<AptContextField>();
if ( _implDecl == null || _implDecl.getFields() == null )
return contexts;
Collection<FieldDeclaration> declaredFields = _implDecl.getFields();
for (FieldDeclaration fieldDecl : declaredFields)
{
if (fieldDecl.getAnnotation(org.apache.beehive.controls.api.context.Context.class) != null)
contexts.add(new AptContextField(this, fieldDecl, _ap));
}
return contexts;
}
/**
* Returns the list of ContextFields declared directly by this ControlImplementation
*/
public ArrayList<AptContextField> getContexts() { return _contexts; }
/**
* Returns true if the implemenation class contains any nested services
*/
public boolean hasContexts() { return _contexts.size() != 0; }
/**
* Initializes the list of ControlFields for this ControlImpl
*/
private ArrayList<AptControlField> initControls()
{
ArrayList<AptControlField> fields = new ArrayList<AptControlField>();
if ( _implDecl == null || _implDecl.getFields() == null )
return fields;
Collection<FieldDeclaration> declaredFields = _implDecl.getFields();
for (FieldDeclaration fieldDecl : declaredFields)
{
if (fieldDecl.getAnnotation(org.apache.beehive.controls.api.bean.Control.class) != null)
fields.add(new AptControlField(this, fieldDecl, _ap));
}
return fields;
}
/**
* Returns true if the implemenation class contains any nested controls
*/
public boolean hasControls() { return _controls.size() != 0; }
/**
* Initializes the list of ClientFields declared directly by this ControlImpl
*/
protected ArrayList<AptClientField> initClients()
{
ArrayList<AptClientField> clients = new ArrayList<AptClientField>();
if ( _implDecl == null || _implDecl.getFields() == null )
return clients;
Collection<FieldDeclaration> declaredFields = _implDecl.getFields();
for (FieldDeclaration fieldDecl : declaredFields)
{
if (fieldDecl.getAnnotation(Client.class) != null)
clients.add(new AptClientField(this, fieldDecl));
}
return clients;
}
/**
* Returns the list of ClientFields declared directly by this ControlImplementation
*/
public ArrayList<AptClientField> getClients() { return _clients; }
/**
* Returns the VersionSupported annotation, if any.
*/
public VersionSupported getVersionSupported() { return _versionSupported; }
/**
* Returns true if the implemenation class contains any nested event proxies
*/
public boolean hasClients() { return _clients.size() != 0; }
/**
* Returns the field with the specified name
*/
public AptField getField(String name)
{
for (AptField genField : _contexts)
if (genField.getName().equals(name))
return genField;
for (AptField genField : _clients)
if (genField.getName().equals(name))
return genField;
return null;
}
public AptEventField getControlField(String name)
{
for (AptControlField controlField : _controls)
if (controlField.getName().equals(name))
return controlField;
return null;
}
/**
* Returns the list of fully qualified class names for types that are derived
* from this Generator
*/
public String [] getGeneratedTypes()
{
return new String [] { _init.getClassName() };
}
/**
* Returns the information necessary to generate a ImplInitializer from this
* ControlImplementation.
*/
public List<GeneratorOutput> getCheckOutput(Filer filer) throws IOException
{
HashMap<String,Object> map = new HashMap<String,Object>();
map.put("impl", this); // control implementation
map.put("init", _init); // control impl initializer
Writer writer = new IndentingWriter(filer.createSourceFile(_init.getClassName()));
GeneratorOutput genOut =
new GeneratorOutput(writer,"org/apache/beehive/controls/runtime/generator/ImplInitializer.vm",
map);
ArrayList<GeneratorOutput> genList = new ArrayList<GeneratorOutput>(1);
genList.add(genOut);
return genList;
}
/**
* Returns the list of generated files derived from this Generator during the
* generate phase of annotation processing.
*/
public List<GeneratorOutput> getGenerateOutput(Filer filer) throws IOException
{
return null;
}
/**
* Returns the ControlInterface implemented by this ControlImpl.
*/
public AptControlInterface getControlInterface()
{
if ( _implDecl == null || _implDecl.getSuperinterfaces() == null )
return null;
Collection<InterfaceType> superInterfaces = _implDecl.getSuperinterfaces();
for (InterfaceType intfType : superInterfaces)
{
InterfaceDeclaration intfDecl = intfType.getDeclaration();
if (intfDecl != null &&
intfDecl.getAnnotation(org.apache.beehive.controls.api.bean.ControlInterface.class) != null)
return new AptControlInterface(intfDecl, _ap);
}
return null;
}
/**
* Initializes the list of EventAdaptors for this ControlImpl
*/
protected void initEventAdaptors()
{
if ( _implDecl == null || _implDecl.getMethods() == null )
return;
for (MethodDeclaration implMethod : _implDecl.getMethods())
{
//
// Do a quick check for the presence of the EventHandler annotation on methods
//
if (implMethod.getAnnotation(EventHandler.class) == null ||
implMethod.toString().equals("<clinit>()"))
continue;
//
// EventHandler annotations on private methods cause compilation error.
//
if (isPrivateMethod(implMethod))
{
_ap.printError(implMethod, "eventhandler.method.is.private");
continue;
}
//
// If found, we must actually read the value using an AnnotationMirror, since it
// contains a Class element (eventSet) that cannot be loaded
//
AnnotationMirror handlerMirror = null;
for (AnnotationMirror annot : implMethod.getAnnotationMirrors())
{
if ( annot == null ||
annot.getAnnotationType() == null ||
annot.getAnnotationType().getDeclaration() == null ||
annot.getAnnotationType().getDeclaration().getQualifiedName() == null )
return;
if ( annot.getAnnotationType().getDeclaration().getQualifiedName().equals(
"org.apache.beehive.controls.api.events.EventHandler"))
{
handlerMirror = annot;
break;
}
}
if (handlerMirror == null)
{
throw new CodeGenerationException("Unable to find EventHandler annotation on " +
implMethod);
}
AptAnnotationHelper handlerAnnot = new AptAnnotationHelper(handlerMirror);
//
// Locate the EventField based upon the field element value
//
String fieldName = (String)handlerAnnot.getObjectValue("field");
AptEventField eventField = (AptEventField)getField(fieldName);
if (eventField == null)
{
// eventField == null means this field isn't interesting for the purposes
// of this processor (control impls). However, only emit an error message
// if the field isn't on a nested control
if ( getControlField(fieldName) == null )
_ap.printError( implMethod, "eventhandler.field.not.found", fieldName );
continue;
}
//
// Locate the EventSet based upon the eventSet element value
//
TypeMirror tm = (TypeMirror)( handlerAnnot.getObjectValue("eventSet") );
if ( tm == null )
continue;
String setName = tm.toString();
AptControlInterface controlIntf = eventField.getControlInterface();
// todo: remove workaround once bug has been resolved.
/* Workaround for JIRA issue BEEHIVE-1143, eventset name may
contain a '$' seperator between the outer class and inner class.
Should be a '.' seperator. Only applies to Eclipse APT. This
workaround is also present in AptControlClient.initEventAdapters
*/
if (tm.getClass().getName().startsWith("org.eclipse.")) {
setName = setName.replace('$', '.');
}
// end of workaround
AptEventSet eventSet = controlIntf.getEventSet(setName);
if (eventSet == null)
{
_ap.printError( implMethod, "eventhandler.eventset.not.found", setName );
continue;
}
//
// Register a new EventAdaptor for the EventSet, if none exists already
//
EventAdaptor adaptor = eventField.getEventAdaptor(eventSet);
if (adaptor == null)
{
adaptor = new EventAdaptor(eventField, eventSet);
eventField.addEventAdaptor(eventSet, adaptor);
}
//
// Locate the EventSet method based upon the eventName element value. Once
// found, add a new AptEventHandler to the adaptor for this event.
//
boolean found = false;
String eventName = (String)handlerAnnot.getObjectValue("eventName");
AptMethod handlerMethod = new AptMethod(implMethod, _ap);
for (AptEvent controlEvent : eventSet.getEvents())
{
if (controlEvent == null || controlEvent.getName() == null ||
!controlEvent.getName().equals(eventName))
continue;
if ( controlEvent.getArgTypes() == null )
continue;
//
// BUGBUG: If the arguments are parameterized, then the event handler
// might declare a specific bound version of the type, so a direct
// comparison will fail. If parameterized, we don't validate.
//
if (controlEvent.hasParameterizedArguments() ||
controlEvent.getArgTypes().equals(handlerMethod.getArgTypes()))
{
adaptor.addHandler(controlEvent,
new AptEventHandler(controlEvent, implMethod, _ap));
found = true;
break;
}
}
if (!found)
{
_ap.printError( implMethod, "eventhandler.method.not.found", setName );
}
}
}
private VersionSupported initVersionSupported()
{
if ( _implDecl == null )
return null;
return _implDecl.getAnnotation(VersionSupported.class);
}
/**
* Enforces the VersionRequired annotation for control extensions.
*/
private void enforceVersionSupported()
{
if ( _versionSupported != null )
{
int majorSupported = _versionSupported.major();
int minorSupported = _versionSupported.minor();
if ( majorSupported < 0 ) // no real version support requirement
return;
AptControlInterface ci = getControlInterface();
if ( ci == null )
return;
int majorPresent = -1;
int minorPresent = -1;
Version ciVersion = ci.getVersion();
if ( ciVersion != null )
{
majorPresent = ciVersion.major();
minorPresent = ciVersion.minor();
if ( majorSupported >= majorPresent &&
(minorSupported < 0 || minorSupported >= minorPresent) )
{
// Version requirement is satisfied
return;
}
}
//
// Version requirement failed
//
_ap.printError( _implDecl, "versionsupported.failed", _implDecl.getSimpleName(), majorSupported, minorSupported,
majorPresent, minorPresent );
}
}
/**
* Does this control impl on one of it superclasses implement java.io.Serializable?
* @return true if this control impl or one of its superclasses implements java.io.Serializable.
*/
protected boolean isSerializable() {
for (InterfaceType superIntf: _implDecl.getSuperinterfaces()) {
if (superIntf.toString().equals("java.io.Serializable")) {
return true;
}
}
// check to see if the superclass is serializable
return _superClass != null && _superClass.isSerializable();
}
private ClassDeclaration _implDecl;
private TwoPhaseAnnotationProcessor _ap;
private AptControlImplementation _superClass;
private ArrayList<AptContextField> _contexts;
private ArrayList<AptClientField> _clients;
private ArrayList<AptControlField> _controls;
private ImplInitializer _init;
private VersionSupported _versionSupported;
}

View File

@ -1,87 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.generator;
/**
* A property derived from a getter/setter method of the control interface.
*/
public final class AptControlInterfaceProperty {
private final String _name;
private String _setterName;
private String _getterName;
/**
* Constructs a new AptControlInterfaceProperty instance.
*
* @param name Property name, may not be null.
* @param getterName Getter method name, may be null.
* @param setterName Setter method name, may be null.
*/
public AptControlInterfaceProperty(String name, String getterName, String setterName) {
assert name != null;
_name = name;
_getterName = getterName;
_setterName = setterName;
}
/**
* Set the setter method name.
*
* @param setterName
*/
protected void setSetterName(String setterName) {
_setterName = setterName;
}
/**
* Set the getter method name.
*
* @param getterName
*/
protected void setGetterName(String getterName) {
_getterName = getterName;
}
/**
* Get the setter method name.
*
* @return setter method name, may be null.
*/
public String getSetterName() {
return _setterName;
}
/**
* Get the getter method name.
*
* @return getter method name, may be null.
*/
public String getGetterName() {
return _getterName;
}
/**
* Get the property name.
*
* @return Property name.
*/
public String getName() {
return _name;
}
}

View File

@ -1,82 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.generator;
import com.sun.mirror.declaration.MethodDeclaration;
import com.sun.mirror.type.VoidType;
import org.apache.beehive.controls.runtime.generator.apt.TwoPhaseAnnotationProcessor;
/**
* The AptEvent class represents a control Property where the event attributes
* are derived using APT metadata
*/
public class AptEvent extends AptMethod
{
/**
* Constructs a new AptEvent instance from APT metadata
* @param eventSet the declaring EventSet
* @param eventDecl the event annotation type element declaration
*/
public AptEvent(AptEventSet eventSet, MethodDeclaration eventDecl, TwoPhaseAnnotationProcessor ap)
{
super(eventDecl, ap);
_eventSet = eventSet;
_eventDecl = eventDecl;
//
// If the event is in multicast event set but does not return 'void', then generate
// an error. Only unicast events can have a return value, to avoid ambiguity over
// which listener gets to provide the value.
//
if (!eventSet.isUnicast() && !(eventDecl.getReturnType() instanceof VoidType))
{
ap.printError( eventDecl, "eventset.illegal.multicast" );
}
}
/**
* Returns the name of the static field that holds the name of this method.
*/
public String getMethodField()
{
//
// Both the event set and event name must be used for the generated field to avoid
// conflicts between same-named events in different event sets.
//
StringBuffer sb = new StringBuffer();
sb.append("_");
sb.append(_eventSet.getShortName());
sb.append("_");
sb.append(getName());
int methodIndex = getIndex();
if (methodIndex != -1)
sb.append(methodIndex);
sb.append("Event");
return sb.toString();
}
/**
* Returns the EventSet associated with the event
*/
public AptEventSet getEventSet() { return _eventSet; }
MethodDeclaration _eventDecl;
private AptEventSet _eventSet;
}

View File

@ -1,162 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.generator;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import com.sun.mirror.declaration.FieldDeclaration;
import com.sun.mirror.declaration.TypeDeclaration;
import com.sun.mirror.declaration.TypeParameterDeclaration;
import com.sun.mirror.type.DeclaredType;
import com.sun.mirror.type.ReferenceType;
import com.sun.mirror.type.TypeMirror;
/**
* The AptEventField class represents a field type that is also an event source
*/
abstract public class AptEventField extends AptField
{
public AptEventField(FieldDeclaration fieldDecl)
{
super(fieldDecl);
}
/**
* Inits the ControlInterface associated with this event field. The public interface
* for controls and contextual services, and their associated events can be modeled in the
* same way. Subclasses will override this to assign an appropriate interface.
*/
abstract protected AptControlInterface initControlInterface();
/**
* Computes the binding from any formal type parameters declared on the control interface
* to bound types on the field declaration.
*/
private void initTypeParameterBindings()
{
//
// Get an iterator to both the declared type arguments and the original type
// declaration on the associated control interface
//
DeclaredType fieldType = (DeclaredType)_fieldDecl.getType();
Iterator<TypeMirror> paramBoundIter = fieldType.getActualTypeArguments().iterator();
TypeDeclaration intfDecl = (TypeDeclaration)_controlIntf.getTypeDeclaration();
Iterator<TypeParameterDeclaration> paramDeclIter =
intfDecl.getFormalTypeParameters().iterator();
//
// Iterate through them in parallel, creating a mapping from the original formal
// type parameter name to the actual bound type. In parallel, also build up a
// representation of the bound type declaration.
//
// NOTE: If no type binding is done on the field declaration, then loop below
// will not execute and no mappings/empty bound decl will be the result.
//
StringBuffer sb = new StringBuffer();
boolean isFirst = true;
while (paramBoundIter.hasNext())
{
TypeMirror paramBound = paramBoundIter.next();
TypeParameterDeclaration paramDecl = paramDeclIter.next();
//
// Save a mapping from the formal type name to the bound mirror type
//
_typeBindingMap.put(paramDecl.getSimpleName(), paramBound);
if (isFirst)
{
sb.append("<");
isFirst = false;
}
else
sb.append(", ");
sb.append(paramBound);
}
if (!isFirst)
sb.append(">");
_boundParameterDecl = sb.toString();
}
/**
* Returns the ControlInterface associated with this event field
*/
public AptControlInterface getControlInterface()
{
if (_controlIntf == null)
{
_controlIntf = initControlInterface();
if (_controlIntf != null)
initTypeParameterBindings();
}
return _controlIntf;
}
/**
* Gets the EventAdaptor for a particular EventSet
*/
public EventAdaptor getEventAdaptor(AptEventSet eventSet)
{
return _eventAdaptors.get(eventSet);
}
/**
* Adds a EventAdaptor for a particular EventSet
*/
public void addEventAdaptor(AptEventSet eventSet, EventAdaptor eventAdaptor)
{
assert !_eventAdaptors.containsKey(eventSet);
_eventAdaptors.put(eventSet, eventAdaptor);
}
/**
* Returns all EventAdaptors for this EventField
*/
public Collection<EventAdaptor> getEventAdaptors()
{
return _eventAdaptors.values();
}
/**
* Returns the bound parameter declaration for this event field
*/
public String getBoundParameters()
{
return _boundParameterDecl;
}
/**
* Returns the formal type binding map (from name to bound type) for the event field
*/
public HashMap<String, TypeMirror> getTypeBindingMap()
{
return _typeBindingMap;
}
HashMap<AptEventSet, EventAdaptor> _eventAdaptors =
new HashMap<AptEventSet, EventAdaptor>();
String _boundParameterDecl;
HashMap<String,TypeMirror> _typeBindingMap = new HashMap<String,TypeMirror>();
private AptControlInterface _controlIntf;
}

View File

@ -1,51 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.generator;
import com.sun.mirror.declaration.MethodDeclaration;
import org.apache.beehive.controls.runtime.generator.apt.TwoPhaseAnnotationProcessor;
/**
* The AptEventHandler class represents a control EventHandler where the event attributes
* are derived using APT metadata
*/
public class AptEventHandler extends AptMethod
{
/**
* Constructs a new AptEventHandler instance
* from APT metadata
* @param event the handled ControlEvent
* @param handlerDecl the handler method declaration
*/
public AptEventHandler(AptEvent event, MethodDeclaration handlerDecl, TwoPhaseAnnotationProcessor ap)
{
super(handlerDecl, ap);
_event = event;
_handlerDecl = handlerDecl;
}
/**
* Returns the ControlEvent associated with the ControlEventHandler
*/
public AptEvent getEvent() { return _event; }
MethodDeclaration _handlerDecl;
private AptEvent _event;
}

View File

@ -1,352 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.generator;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import com.sun.mirror.declaration.InterfaceDeclaration;
import com.sun.mirror.declaration.MethodDeclaration;
import com.sun.mirror.declaration.TypeDeclaration;
import com.sun.mirror.declaration.TypeParameterDeclaration;
import com.sun.mirror.type.InterfaceType;
import org.apache.beehive.controls.api.events.EventSet;
import org.apache.beehive.controls.api.packaging.EventSetInfo;
import org.apache.beehive.controls.runtime.generator.apt.TwoPhaseAnnotationProcessor;
/**
* The AptEventSet class represents a control EventSet where the events
* are derived using APT metadata.
*/
public class AptEventSet extends AptType
{
/**
* Constructs a new AptEventSet instance from APT metadata
* @param controlIntf the declaring control interface
* @param eventSet the EventSet class
* @param ap the associated AnnotationProcessor
*/
public AptEventSet(AptControlInterface controlIntf, InterfaceDeclaration eventSet,
TwoPhaseAnnotationProcessor ap)
{
_controlIntf = controlIntf;
_eventSet = eventSet;
_ap = ap;
setDeclaration(eventSet);
EventSet eventSetAnnot = eventSet.getAnnotation(EventSet.class);
if (eventSetAnnot != null)
_unicast = eventSetAnnot.unicast();
//
// If an EventSet interface has formal type parameters, they must be a subset of
// the original formal type parameters declared on the original control interface.
// This is required because it must be possible to bind the types of events immediately
// upon construction of the bean... there is no opportunity to separately specify
// parameterization for the event set for the purpose of creating listeners, client
// notifiers, etc.
//
TypeDeclaration intfDecl = controlIntf.getTypeDeclaration();
for (TypeParameterDeclaration estpd : _eventSet.getFormalTypeParameters())
{
boolean found = false;
for (TypeParameterDeclaration citpd : intfDecl.getFormalTypeParameters())
{
if (estpd.getSimpleName().equals(citpd.getSimpleName()))
{
found = true;
break;
}
}
if (! found)
{
//
// BUGBUG: Ideally, this would be estpd.getPosition, but this seems to return
// 0,0 for the current APT implementation, so we use the event set position
// instead.
// Once this works, the 'break' below can also be removed to present errors
// for multiple invalid parameters
//
_ap.printError( eventSet, "eventset.formal.parameter.mismatch" );
break;
}
}
_superEventSet = initSuperEventSet();
_events = initEvents();
}
/**
* Checks to see if this EventSet extends an EventSet declared on a parent control interface. If
* found it will return the parent EventSet, or return null if not found.
*/
public AptEventSet initSuperEventSet()
{
// This will be common, so short circuit quickly
AptControlInterface superControl = _controlIntf.getSuperClass();
if (superControl == null)
return null;
// Compute a hash set containing the qualified names of all super interfaces
// for this EventSet
HashSet<String> extendNames = new HashSet<String>();
for (InterfaceType superType: _eventSet.getSuperinterfaces())
{
InterfaceDeclaration superDecl = superType.getDeclaration();
if (superDecl != null)
extendNames.add(superDecl.getQualifiedName());
}
// Starting with the parent of the ControlInterface declaring this EventSet, look
// for a parent interface that declares ones of these super interfaces as an event
// set
while (superControl != null)
{
Collection<AptEventSet> superEventSets = superControl.getEventSets();
for (AptEventSet superEventSet : superEventSets)
{
if (extendNames.contains(superEventSet.getClassName()))
return superEventSet;
}
superControl = superControl.getSuperClass();
}
// Nothing found, so no super event set
return null;
}
/**
* Returns any EventSet from which this event set derives (or null if none)
*/
public AptEventSet getSuperEventSet() { return _superEventSet; }
/**
* Initializes the list of Events associated with this EventSet
*/
protected AptMethodSet<AptEvent> initEvents()
{
AptMethodSet<AptEvent> events = new AptMethodSet<AptEvent>();
if ( _eventSet == null || _eventSet.getMethods() == null )
return events;
//
// Add all of the public methods directly declared and inherited from extended
// interfaces, except for the EventSet super interface (if any)
//
ArrayList<InterfaceDeclaration> intfList = new ArrayList<InterfaceDeclaration>();
intfList.add(_eventSet);
for (int i = 0; i < intfList.size(); i++)
{
InterfaceDeclaration intfDecl = intfList.get(i);
//
// Don't add events that are derived from a super event set. These are not added because
// this class picks a single super interface to extend from when building a hierarchy
// of callback notifiers (etc). So, the super event set that was chosen first is left out
// of the list of event methods since they're captured in superclasses in the Control's implementation
//
if (_superEventSet != null && _superEventSet.getClassName().equals(intfDecl.getQualifiedName()))
continue;
// Add all declared methods, but ignore the mystery <clinit> methods
for (MethodDeclaration methodDecl : intfDecl.getMethods())
if (!methodDecl.toString().equals("<clinit>()"))
events.add(new AptEvent(this, methodDecl, _ap));
//
// Add all superinterfaces of the target interface to the list
//
for (InterfaceType superType: intfDecl.getSuperinterfaces())
{
InterfaceDeclaration superDecl = superType.getDeclaration();
if (superDecl != null && !intfList.contains(superDecl))
intfList.add(superDecl);
}
}
return events;
}
/**
* Returns the list of Events associated with this EventSet
*/
public Collection<AptEvent> getEvents() { return _events.getMethods(); }
/**
* Returns 'true' if the event set support only unicast (single listener) events,
* false otherwise.
*/
public boolean isUnicast()
{
return _unicast;
}
/**
* Returns the number of Events for this EventSet and any super event set
*/
public int getEventCount()
{
int count = _events.size();
if (_superEventSet != null)
count += _superEventSet.getEventCount();
return count;
}
/**
* Returns the programmatic descriptor name to be returned by the EventDescriptor
* for the event set.
*/
public String getDescriptorName()
{
//
// The javadocs for java.beans.EventSetDescriptor suggest that the programmatic name
// should start w/ a lowercase letter. So we use the unqualified event set interface
// name w/ the first character lowercased.
//
String name = getShortName();
return Character.toLowerCase(name.charAt(0)) + name.substring(1);
}
/**
* Returns the name of the generated notifier class for this ControlEventSet
*/
public String getNotifierClass()
{
StringBuffer sb = new StringBuffer(getShortName());
sb.append("Notifier");
//
// If the event set declaration has any parameterized types, then include them on
// the notifier class as well. Currently, these can only be parameterized types
// from the outer (control interface), since there is no other mechanism for specifying
// type values at notifier construction (other than propagation from the outer type).
//
sb.append(getFormalTypeParameterNames());
return sb.toString();
}
/**
* Returns any 'extends' clause that should be placed on the generated notifier class
*/
public String getNotifierExtends()
{
//
// All EventNotifiers are rooted from a common utility class, so if there is no
// super event set, then extend the utility notifier class.
//
if (_superEventSet == null)
{
if (_unicast)
return "org.apache.beehive.controls.runtime.bean.UnicastEventNotifier";
else
return "org.apache.beehive.controls.runtime.bean.EventNotifier";
}
//
// Otherwise, a generated notifier will extend the notifier of any parent event set
//
return _superEventSet.getNotifierClass();
}
/**
* Returns the short name for this notifier's base class.
*/
public String getNotifierExtendsShortName() {
if (_superEventSet == null)
{
if (_unicast)
return "UnicastEventNotifier";
else
return "EventNotifier";
}
return _superEventSet.getNotifierClass();
}
/**
* Return true if this notifier extends the UnicastEventNotifier or EventNotifier base class.
*/
public boolean isExtendsNotifierBase() {
return _superEventSet == null;
}
/**
* Returns the name of the method used to register a new EventSet listener
*/
public String getAddListenerMethod()
{
return "add" + getShortName() + "Listener";
}
/**
* Returns the name of the method used to register a new EventSet listener
*/
public String getRemoveListenerMethod()
{
return "remove" + getShortName() + "Listener";
}
/**
* Returns the name of the method used to retrieve the (unicast) EventSet listener
*/
public String getGetListenersMethod()
{
return "get" + getShortName() + "Listeners";
}
/**
* Returns the name of a custom-generated method to initialize MethodDescriptor bean
* info for the events in this EventSet
*/
public String getInfoInitializer()
{
return "init" + getShortName() + "Events";
}
/**
* Returns any EventSetInfo associated with the event set (or null if none)
*/
public EventSetInfo getEventSetInfo()
{
if ( _eventSet == null )
return null;
return _eventSet.getAnnotation(EventSetInfo.class);
}
/**
* Returns the underlying APT InterfaceDeclaration associated with this event set
*/
public InterfaceDeclaration getDeclaration()
{
return _eventSet;
}
private TwoPhaseAnnotationProcessor _ap;
private InterfaceDeclaration _eventSet;
private AptEventSet _superEventSet;
private AptControlInterface _controlIntf;
private AptMethodSet<AptEvent> _events;
private boolean _unicast;
}

View File

@ -1,109 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.generator;
import java.util.Collection;
import com.sun.mirror.declaration.FieldDeclaration;
import com.sun.mirror.declaration.Modifier;
/**
* The AptField class is a helper class that knows how to generate useful information
* about a Field using APT metadata
*/
public class AptField
{
AptField(FieldDeclaration fieldDecl)
{
_fieldDecl = fieldDecl;
}
/**
* Returns the name of the method
*/
public String getName()
{
if ( _fieldDecl == null )
return "";
return _fieldDecl.getSimpleName();
}
/**
* Returns a local variable used when setting the field value
*/
public String getLocalName() { return "_" + getName(); }
/**
* Returns the type of the field
*/
public String getType()
{
if ( _fieldDecl == null || _fieldDecl.getType() == null )
return "";
return _fieldDecl.getType().toString();
}
/**
* Returns the class name of the field (does not include any formal type parameters
*/
public String getClassName()
{
if ( _fieldDecl == null || _fieldDecl.getType() == null )
return "";
//
// This is lazily... but much easier than navigating the APT type system and just
// as effective ;)
String typeName = _fieldDecl.getType().toString();
int formalIndex = typeName.indexOf('<');
if (formalIndex > 0)
return typeName.substring(0, formalIndex);
return typeName;
}
/**
* Returns the access modifier associated with the field
*/
public String getAccessModifier()
{
if ( _fieldDecl == null )
return "";
Collection<Modifier> modifiers = _fieldDecl.getModifiers();
if (modifiers.contains(Modifier.PRIVATE))
return "private";
if (modifiers.contains(Modifier.PROTECTED))
return "protected";
if (modifiers.contains(Modifier.PUBLIC))
return "public";
return "";
}
/**
* Returns the name of a static local field using to refer to this Field
*/
public String getReflectField()
{
return "_" + getName() + "Field";
}
protected FieldDeclaration _fieldDecl;
}

Some files were not shown because too many files have changed in this diff Show More