mirror of
https://github.com/moparisthebest/JdbcMapper
synced 2024-11-21 08:35:00 -05:00
Fork from beehive
This commit is contained in:
parent
d8f7e6df4a
commit
59cf4ff2cd
177
BUILDING.txt
177
BUILDING.txt
@ -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
|
@ -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
|
50
LICENSE.txt
50
LICENSE.txt
@ -200,53 +200,3 @@
|
||||
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.
|
||||
|
||||
============================================
|
||||
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.
|
34
NOTICE.txt
34
NOTICE.txt
@ -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
|
21
README.txt
21
README.txt
@ -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.
|
||||
|
@ -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).
|
@ -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>
|
@ -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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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 { };
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
@ -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 @interface LastChanged
|
||||
* {
|
||||
* @AnnotationMemberTypes.Date()
|
||||
* public String date();
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* <p>The use of <code>@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();
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
@ -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();
|
||||
}
|
@ -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);
|
||||
}
|
@ -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
|
||||
}
|
@ -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
|
||||
}
|
@ -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;
|
||||
}
|
@ -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 {};
|
||||
}
|
@ -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 );
|
||||
}
|
||||
}
|
||||
}
|
@ -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) { };
|
||||
}
|
@ -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;
|
||||
}
|
@ -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();
|
||||
}
|
@ -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;
|
||||
}
|
@ -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
|
||||
}
|
@ -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
|
||||
{
|
||||
}
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
@ -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;
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
@ -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
|
||||
{
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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();
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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
|
||||
}
|
@ -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();
|
||||
}
|
@ -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 {};
|
||||
}
|
@ -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();
|
||||
}
|
@ -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();
|
||||
}
|
@ -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
|
||||
}
|
@ -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
|
||||
}
|
@ -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)
|
||||
}
|
@ -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 "";
|
||||
}
|
@ -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>();
|
||||
}
|
@ -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;
|
||||
}
|
@ -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);
|
||||
}
|
@ -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<prefix><propertyName>(<propertyType> value);
|
||||
* public <propertyType> get<prefix><propertyName>();
|
||||
* </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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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" );
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
@ -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 );
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
@ -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");
|
||||
}
|
||||
}
|
@ -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");
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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() });
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||
}
|
@ -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>();
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
@ -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();
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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()]);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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);
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
@ -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>();
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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
Loading…
Reference in New Issue
Block a user